1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-03-22 06:38:37 -05:00

Add an extended version of ctrl_alloc which permits you to provide a

custom free function, in case you need to ctrl_alloc a structure which
then has additional dynamically allocated things dangling off it.

[originally from svn r9922]
This commit is contained in:
Simon Tatham 2013-07-14 10:46:29 +00:00
parent 2f6d6a839d
commit ff09d5379b
2 changed files with 28 additions and 3 deletions

View File

@ -47,6 +47,7 @@ struct controlbox *ctrl_new_box(void)
ret->ctrlsets = NULL; ret->ctrlsets = NULL;
ret->nfrees = ret->freesize = 0; ret->nfrees = ret->freesize = 0;
ret->frees = NULL; ret->frees = NULL;
ret->freefuncs = NULL;
return ret; return ret;
} }
@ -59,9 +60,10 @@ void ctrl_free_box(struct controlbox *b)
ctrl_free_set(b->ctrlsets[i]); ctrl_free_set(b->ctrlsets[i]);
} }
for (i = 0; i < b->nfrees; i++) for (i = 0; i < b->nfrees; i++)
sfree(b->frees[i]); b->freefuncs[i](b->frees[i]);
sfree(b->ctrlsets); sfree(b->ctrlsets);
sfree(b->frees); sfree(b->frees);
sfree(b->freefuncs);
sfree(b); sfree(b);
} }
@ -181,7 +183,8 @@ struct controlset *ctrl_getset(struct controlbox *b,
} }
/* Allocate some private data in a controlbox. */ /* Allocate some private data in a controlbox. */
void *ctrl_alloc(struct controlbox *b, size_t size) void *ctrl_alloc_with_free(struct controlbox *b, size_t size,
ctrl_freefn_t freefunc)
{ {
void *p; void *p;
/* /*
@ -192,11 +195,24 @@ void *ctrl_alloc(struct controlbox *b, size_t size)
if (b->nfrees >= b->freesize) { if (b->nfrees >= b->freesize) {
b->freesize = b->nfrees + 32; b->freesize = b->nfrees + 32;
b->frees = sresize(b->frees, b->freesize, void *); b->frees = sresize(b->frees, b->freesize, void *);
b->freefuncs = sresize(b->freefuncs, b->freesize, ctrl_freefn_t);
} }
b->frees[b->nfrees++] = p; b->frees[b->nfrees] = p;
b->freefuncs[b->nfrees] = freefunc;
b->nfrees++;
return p; return p;
} }
static void ctrl_default_free(void *p)
{
sfree(p);
}
void *ctrl_alloc(struct controlbox *b, size_t size)
{
return ctrl_alloc_with_free(b, size, ctrl_default_free);
}
static union control *ctrl_new(struct controlset *s, int type, static union control *ctrl_new(struct controlset *s, int type,
intorptr helpctx, handler_fn handler, intorptr helpctx, handler_fn handler,
intorptr context) intorptr context)

View File

@ -427,6 +427,8 @@ struct controlset {
union control **ctrls; /* actual array */ union control **ctrls; /* actual array */
}; };
typedef void (*ctrl_freefn_t)(void *); /* used by ctrl_alloc_with_free */
/* /*
* This is the container structure which holds a complete set of * This is the container structure which holds a complete set of
* controls. * controls.
@ -438,6 +440,7 @@ struct controlbox {
int nfrees; int nfrees;
int freesize; int freesize;
void **frees; /* array of aux data areas to free */ void **frees; /* array of aux data areas to free */
ctrl_freefn_t *freefuncs; /* parallel array of free functions */
}; };
struct controlbox *ctrl_new_box(void); struct controlbox *ctrl_new_box(void);
@ -464,8 +467,14 @@ void ctrl_free(union control *);
* and so data allocated through this function is better not used * and so data allocated through this function is better not used
* to hold modifiable per-instance things. It's mostly here for * to hold modifiable per-instance things. It's mostly here for
* allocating structures to be passed as control handler params. * allocating structures to be passed as control handler params.
*
* ctrl_alloc_with_free also allows you to provide a function to free
* the structure, in case there are other dynamically allocated bits
* and pieces dangling off it.
*/ */
void *ctrl_alloc(struct controlbox *b, size_t size); void *ctrl_alloc(struct controlbox *b, size_t size);
void *ctrl_alloc_with_free(struct controlbox *b, size_t size,
ctrl_freefn_t freefunc);
/* /*
* Individual routines to create `union control' structures in a controlset. * Individual routines to create `union control' structures in a controlset.