From 56fb4d9a22b3296495fd0664ca3e10b64f37037b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 23 Aug 2010 09:04:21 +0900 Subject: [PATCH] allow safe bsp freeing any memory the bsp thinks it does not own will not be freed --- include/QF/bspfile.h | 21 +++++++++- libs/util/bspfile.c | 82 +++++++++++++++++++++++++++----------- tools/qfbsp/source/qfbsp.c | 4 ++ 3 files changed, 82 insertions(+), 25 deletions(-) diff --git a/include/QF/bspfile.h b/include/QF/bspfile.h index 67cebb100..efc9f6722 100644 --- a/include/QF/bspfile.h +++ b/include/QF/bspfile.h @@ -228,50 +228,66 @@ typedef struct dleaf_s { //============================================================================ typedef struct bsp_s { + int own_header; dheader_t *header; - int nummodels; - dmodel_t *models; + int own_models; + int nummodels; + dmodel_t *models; + int own_visdata; size_t visdatasize; byte *visdata; + int own_lightdata; size_t lightdatasize; byte *lightdata; + int own_texdata; size_t texdatasize; byte *texdata; // (dmiptexlump_t) + int own_entdata; size_t entdatasize; char *entdata; + int own_leafs; int numleafs; dleaf_t *leafs; + int own_planes; int numplanes; dplane_t *planes; + int own_vertexes; int numvertexes; dvertex_t *vertexes; + int own_nodes; int numnodes; dnode_t *nodes; + int own_texinfo; int numtexinfo; texinfo_t *texinfo; + int own_faces; int numfaces; dface_t *faces; + int own_clipnodes; int numclipnodes; dclipnode_t *clipnodes; + int own_edges; int numedges; dedge_t *edges; + int own_marksurfaces; int nummarksurfaces; uint16_t *marksurfaces; + int own_surfedges; int numsurfedges; int32_t *surfedges; } bsp_t; @@ -280,6 +296,7 @@ bsp_t *LoadBSPMem (void *mem, size_t size); bsp_t *LoadBSPFile (QFile *file, size_t size); void WriteBSPFile (const bsp_t *bsp, QFile *file); bsp_t *BSP_New (void); +void BSP_Free (bsp_t *bsp); void BSP_AddPlane (bsp_t *bsp, dplane_t *plane); void BSP_AddLeaf (bsp_t *bsp, dleaf_t *leaf); void BSP_AddVertex (bsp_t *bsp, dvertex_t *vertex); diff --git a/libs/util/bspfile.c b/libs/util/bspfile.c index 445517d27..6408819b4 100644 --- a/libs/util/bspfile.c +++ b/libs/util/bspfile.c @@ -358,98 +358,131 @@ BSP_New (void) return calloc (1, sizeof (bsp_t)); } +VISIBLE void +BSP_Free (bsp_t *bsp) +{ +#define FREE(X) \ + do { \ + if (bsp->own_##X && bsp->X) \ + free (bsp->X); \ + } while (0) + + FREE (models); + FREE (visdata); + FREE (lightdata); + FREE (texdata); + FREE (entdata); + FREE (leafs); + FREE (planes); + FREE (vertexes); + FREE (nodes); + FREE (texinfo); + FREE (faces); + FREE (clipnodes); + FREE (edges); + FREE (marksurfaces); + FREE (surfedges); + FREE (header); + + free (bsp); +} + +#define REALLOC(X) \ + do { \ + if (!bsp->own_##X) { \ + bsp->own_##X = 1; \ + bsp->X = 0; \ + } \ + bsp->X = realloc (bsp->X, (bsp->num##X + 1) * sizeof (bsp->X[0])); \ + } while (0) + VISIBLE void BSP_AddPlane (bsp_t *bsp, dplane_t *plane) { - bsp->planes = realloc (bsp->planes, - (bsp->numplanes + 1) * sizeof (dplane_t)); + REALLOC (planes); bsp->planes[bsp->numplanes++] = *plane; } VISIBLE void BSP_AddLeaf (bsp_t *bsp, dleaf_t *leaf) { - bsp->leafs = realloc (bsp->leafs, - (bsp->numleafs + 1) * sizeof (dleaf_t)); + REALLOC (leafs); bsp->leafs[bsp->numleafs++] = *leaf; } VISIBLE void BSP_AddVertex (bsp_t *bsp, dvertex_t *vertex) { - bsp->vertexes = realloc (bsp->vertexes, - (bsp->numvertexes + 1) * sizeof (dvertex_t)); + REALLOC (vertexes); bsp->vertexes[bsp->numvertexes++] = *vertex; } VISIBLE void BSP_AddNode (bsp_t *bsp, dnode_t *node) { - bsp->nodes = realloc (bsp->nodes, - (bsp->numnodes + 1) * sizeof (dnode_t)); + REALLOC (nodes); bsp->nodes[bsp->numnodes++] = *node; } VISIBLE void BSP_AddTexinfo (bsp_t *bsp, texinfo_t *texinfo) { - bsp->texinfo = realloc (bsp->texinfo, - (bsp->numtexinfo + 1) * sizeof (texinfo_t)); + REALLOC (texinfo); bsp->texinfo[bsp->numtexinfo++] = *texinfo; } VISIBLE void BSP_AddFace (bsp_t *bsp, dface_t *face) { - bsp->faces = realloc (bsp->faces, - (bsp->numfaces + 1) * sizeof (dface_t)); + REALLOC (faces); bsp->faces[bsp->numfaces++] = *face; } VISIBLE void BSP_AddClipnode (bsp_t *bsp, dclipnode_t *clipnode) { - bsp->clipnodes = realloc (bsp->clipnodes, - (bsp->numclipnodes + 1) * sizeof (dclipnode_t)); + REALLOC (clipnodes); bsp->clipnodes[bsp->numclipnodes++] = *clipnode; } VISIBLE void BSP_AddMarkSurface (bsp_t *bsp, int marksurface) { - bsp->marksurfaces = realloc (bsp->marksurfaces, - (bsp->nummarksurfaces + 1) - * sizeof (uint16_t)); + REALLOC (marksurfaces); bsp->marksurfaces[bsp->nummarksurfaces++] = marksurface; } VISIBLE void BSP_AddSurfEdge (bsp_t *bsp, int surfedge) { - bsp->surfedges = realloc (bsp->surfedges, - (bsp->numsurfedges + 1) * sizeof (int32_t)); + REALLOC (surfedges); bsp->surfedges[bsp->numsurfedges++] = surfedge; } VISIBLE void BSP_AddEdge (bsp_t *bsp, dedge_t *edge) { - bsp->edges = realloc (bsp->edges, - (bsp->numedges + 1) * sizeof (dedge_t)); + REALLOC (edges); bsp->edges[bsp->numedges++] = *edge; } VISIBLE void BSP_AddModel (bsp_t *bsp, dmodel_t *model) { - bsp->models = realloc (bsp->models, - (bsp->nummodels + 1) * sizeof (dmodel_t)); + REALLOC (models); bsp->models[bsp->nummodels++] = *model; } +#define OWN(X) \ + do { \ + FREE(X); \ + bsp->own_##X = 1; \ + } while (0) + VISIBLE void BSP_AddLighting (bsp_t *bsp, byte *lightdata, size_t lightdatasize) { + OWN (lightdata); bsp->lightdatasize = lightdatasize; bsp->lightdata = malloc (lightdatasize); memcpy (bsp->lightdata, lightdata, lightdatasize); @@ -458,6 +491,7 @@ BSP_AddLighting (bsp_t *bsp, byte *lightdata, size_t lightdatasize) VISIBLE void BSP_AddVisibility (bsp_t *bsp, byte *visdata, size_t visdatasize) { + OWN (visdata); bsp->visdatasize = visdatasize; bsp->visdata = malloc (visdatasize); memcpy (bsp->visdata, visdata, visdatasize); @@ -466,6 +500,7 @@ BSP_AddVisibility (bsp_t *bsp, byte *visdata, size_t visdatasize) VISIBLE void BSP_AddEntities (bsp_t *bsp, char *entdata, size_t entdatasize) { + OWN (entdata); bsp->entdatasize = entdatasize; bsp->entdata = malloc (entdatasize); memcpy (bsp->entdata, entdata, entdatasize); @@ -474,6 +509,7 @@ BSP_AddEntities (bsp_t *bsp, char *entdata, size_t entdatasize) VISIBLE void BSP_AddTextures (bsp_t *bsp, byte *texdata, size_t texdatasize) { + OWN (texdata); bsp->texdatasize = texdatasize; bsp->texdata = malloc (texdatasize); memcpy (bsp->texdata, texdata, texdatasize); diff --git a/tools/qfbsp/source/qfbsp.c b/tools/qfbsp/source/qfbsp.c index b8a15d41a..fda8ba300 100644 --- a/tools/qfbsp/source/qfbsp.c +++ b/tools/qfbsp/source/qfbsp.c @@ -290,6 +290,7 @@ UpdateEntLump (void) if (!f) Sys_Error ("couldn't open %s. %s", options.bspfile, strerror(errno)); WriteBSPFile (bsp, f); + BSP_Free (bsp); Qclose (f); } @@ -495,6 +496,7 @@ ProcessFile (void) extract_entities (); if (options.extract_hull) extract_hull (); + BSP_Free (bsp); return; } @@ -503,6 +505,7 @@ ProcessFile (void) if (options.onlyents) { UpdateEntLump (); + BSP_Free (bsp); return; } @@ -527,6 +530,7 @@ ProcessFile (void) WriteEntitiesToString (); FinishBSPFile (); + BSP_Free (bsp); } int