From f0ee0238ecb4627c4bff91394767a2168201ad4f Mon Sep 17 00:00:00 2001 From: simon Date: Sun, 14 Jul 2013 10:46:29 +0000 Subject: [PATCH] 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. git-svn-id: svn://svn.tartarus.org/sgt/putty@9922 cda61777-01e9-0310-a592-d414129be87e --- dialog.c | 22 +++++++++++++++++++--- dialog.h | 9 +++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/dialog.c b/dialog.c index 127783a3..84869195 100644 --- a/dialog.c +++ b/dialog.c @@ -47,6 +47,7 @@ struct controlbox *ctrl_new_box(void) ret->ctrlsets = NULL; ret->nfrees = ret->freesize = 0; ret->frees = NULL; + ret->freefuncs = NULL; return ret; } @@ -59,9 +60,10 @@ void ctrl_free_box(struct controlbox *b) ctrl_free_set(b->ctrlsets[i]); } for (i = 0; i < b->nfrees; i++) - sfree(b->frees[i]); + b->freefuncs[i](b->frees[i]); sfree(b->ctrlsets); sfree(b->frees); + sfree(b->freefuncs); sfree(b); } @@ -181,7 +183,8 @@ struct controlset *ctrl_getset(struct controlbox *b, } /* 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; /* @@ -192,11 +195,24 @@ void *ctrl_alloc(struct controlbox *b, size_t size) if (b->nfrees >= b->freesize) { b->freesize = b->nfrees + 32; 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; } +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, intorptr helpctx, handler_fn handler, intorptr context) diff --git a/dialog.h b/dialog.h index 59774138..9ea8599e 100644 --- a/dialog.h +++ b/dialog.h @@ -427,6 +427,8 @@ struct controlset { 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 * controls. @@ -438,6 +440,7 @@ struct controlbox { int nfrees; int freesize; void **frees; /* array of aux data areas to free */ + ctrl_freefn_t *freefuncs; /* parallel array of free functions */ }; 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 * to hold modifiable per-instance things. It's mostly here for * 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_with_free(struct controlbox *b, size_t size, + ctrl_freefn_t freefunc); /* * Individual routines to create `union control' structures in a controlset. -- 2.11.0