diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-07 00:24:03 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-07 00:24:03 +0300 |
commit | ed39daa568d162617a183497010d70a55a38ae73 (patch) | |
tree | 313c1caef8b42ab1800f5c1cef8dece9116fbd0d | |
parent | 18d7db07b9f369901300bf664d07d4b39032ce64 (diff) | |
download | grecs-ed39daa568d162617a183497010d70a55a38ae73.tar.gz grecs-ed39daa568d162617a183497010d70a55a38ae73.tar.bz2 |
Redo memory management (2).
* src/grecs.h (grecs_free_fun): New extern.
(grecs_free): New proto.
* src/format.c: Use grecs_free where appropriate.
* src/grecs-lex.l: Likewise.
* src/preproc.c: Likewise.
* src/tree.c: Likewise.
* src/lookup.c (parse_label): Use grecs_value_list_create.
* src/mem.c: Initialize hooks with the default values.
(grecs_free_fun): New hook.
(grecs_free): New function.
* doc/grecs_malloc.3: Document grecs_free.
* doc/grecs_parse.3: Document the recent changes.
* doc/grecs_strdup.3: Update.
-rw-r--r-- | doc/grecs_malloc.3 | 30 | ||||
-rw-r--r-- | doc/grecs_parse.3 | 26 | ||||
-rw-r--r-- | doc/grecs_strdup.3 | 6 | ||||
-rw-r--r-- | src/format.c | 2 | ||||
-rw-r--r-- | src/grecs-lex.l | 4 | ||||
-rw-r--r-- | src/grecs.h | 2 | ||||
-rw-r--r-- | src/list.c | 8 | ||||
-rw-r--r-- | src/lookup.c | 35 | ||||
-rw-r--r-- | src/mem.c | 32 | ||||
-rw-r--r-- | src/preproc.c | 20 | ||||
-rw-r--r-- | src/tree.c | 16 |
11 files changed, 91 insertions, 90 deletions
diff --git a/doc/grecs_malloc.3 b/doc/grecs_malloc.3 index 58cc9a0..1d52eca 100644 --- a/doc/grecs_malloc.3 +++ b/doc/grecs_malloc.3 @@ -16,7 +16,7 @@ .\" This file is part of SLB. .\" Copyright (C) 2011 Sergey Poznyakoff .\" -.TH GRECS_MALLOC 3 "May 3, 2011" "GRECS" "Grecs User Reference" +.TH GRECS_MALLOC 3 "May 7, 2011" "GRECS" "Grecs User Reference" .SH NAME grecs_malloc, grecs_zalloc, grecs_calloc, grecs_realloc \- Allocate dynamic memory for \fBGrecs\fR. @@ -32,12 +32,16 @@ dynamic memory for \fBGrecs\fR. .br .BI "void *grecs_realloc(void " "*ptr" ", size_t " "size" ); .br +.BI "void grecs_free(void " "*ptr" ); +.br .BI "void grecs_alloc_die(void);" .sp .BI "void *(*grecs_malloc_fun)(size_t " "size" ); .br .BI "void *(*grecs_realloc_fun)(void " "*ptr" ", size_t " "size" ); .br +.BI "void (*grecs_free_fun)(void " "*ptr" ); +.br .BI "void (*grecs_alloc_die_fun)(void);" .SH DESCRIPTION .PP @@ -76,14 +80,24 @@ allocates bytes and returns a pointer to the allocated memory. The memory is set to zero. .PP -If \fBgrecs_malloc_fun\fR is not \fINULL\fR, it will be used by -\fBgrecs_malloc\fR, \fBgrecs_calloc\fR and \fBgrecs_zalloc\fR to -allocate new memory chunk. If it is not set, these function use -\fBmalloc(3)\fR. +.BR grecs_free () +frees the memory space pointed to by \fBptr\fR, which must have been +returned by a previous call to one of the memory allocation functions +discussed above. +.PP +The \fBgrecs_malloc_fun\fR hook is used \fBgrecs_malloc\fR, +\fBgrecs_calloc\fR and \fBgrecs_zalloc\fR to allocate new memory +chunk. By default it points to +.BR malloc (3). +.PP +Similarly, the \fBgrecs_realloc_fun\fR, is used by +\fBgrecs_realloc\fR function. By default it points to +.BR realloc (3). .PP -Similarly, the \fBgrecs_realloc_fun\fR, if set, is used by -\fBgrecs_realloc\fR function. Otherwise, this function uses -\fBrealloc(3)\fR. +The \fBgrecs_free_fun\fR is used by +.BR grecs_free (). +By default it points to +.BR free (3). .PP These hooks provide a way for the calling program to use its custom memory allocation routines. diff --git a/doc/grecs_parse.3 b/doc/grecs_parse.3 index 357889f..c51ef95 100644 --- a/doc/grecs_parse.3 +++ b/doc/grecs_parse.3 @@ -16,7 +16,7 @@ .\" This file is part of SLB. .\" Copyright (C) 2011 Sergey Poznyakoff .\" -.TH GRECS_PARSE 3 "May 4, 2011" "GRECS" "Grecs User Reference" +.TH GRECS_PARSE 3 "May 7, 2011" "GRECS" "Grecs User Reference" .SH NAME grecs_parse \- parse a configuration file. .SH SYNOPSIS @@ -48,14 +48,18 @@ typedef struct grecs_node { struct grecs_node *next; struct grecs_node *prev; char *ident; - struct grecs_value value; + union { + struct grecs_value *value; + struct grecs_symtab *texttab; + } v; } grecs_node_t; .in .fi .PP The \fItype\fR member describes the type of this node. Its value is -\fBgrecs_node_stmt\fR for simple statements, and -\fBgrecs_node_block\fR, for block statements. +\fBgrecs_node_stmt\fR for simple statements and +\fBgrecs_node_block\fR, for block statements. The topmost node (the +one returned by \fBgrecs_tree_parse\fR) has type \fBgrecs_node_root\fR. .PP The \fIlocus\fR describes the location in the input file, which this node described. See @@ -97,8 +101,14 @@ pidfile "/var/run/mypid"; .sp will have \fBident\fR pointing to the string \fB/var/run/mypid\fR. .PP -Finally, the \fBvalue\fR member keeps the value associated with this -statement. It is defined as: +The \fBv\fR union keeps data which depend on the type of this node. +The \fBv.texttab\fR member is defined only for the root node (type +\fBgrecs_node_root\fR). It points to a symbol table which holds shared +strings for this tree. In particular, this table holds file names +referenced by \fBlocus\fR members of all underlying nodes. +.PP +For non-root nodes,the \fBv.value\fR member is defined. It points to +the value associated with this statement. A value is defined as: .sp .nf .in +5 @@ -106,10 +116,10 @@ typedef struct grecs_value { int type; union { struct grecs_list *list; - const char *string; + char *string; struct { size_t c; - struct grecs_value *v; + struct grecs_value **v; } arg; } v; } grecs_value_t; diff --git a/doc/grecs_strdup.3 b/doc/grecs_strdup.3 index 441eb23..ae861e4 100644 --- a/doc/grecs_strdup.3 +++ b/doc/grecs_strdup.3 @@ -16,7 +16,7 @@ .\" This file is part of SLB. .\" Copyright (C) 2011 Sergey Poznyakoff .\" -.TH GRECS_STRDUP 3 "May 3, 2011" "GRECS" "Grecs User Reference" +.TH GRECS_STRDUP 3 "May 7, 2011" "GRECS" "Grecs User Reference" .SH NAME grecs_strdup \- duplicate a string .SH SYNOPSIS @@ -31,8 +31,8 @@ The function returns a pointer to a new string which is a duplicate of the string \fIstr\fR. Memory for the new string is obtained with .BR grecs_malloc (3), -and can be freed with -.BR free(3). +and must be freed with +.BR grecs_free (3). .SH "RETURN VALUE" The .BR grecs_strdup () diff --git a/src/format.c b/src/format.c index 41889b7..f12b465 100644 --- a/src/format.c +++ b/src/format.c @@ -232,7 +232,7 @@ grecs_format_value(struct grecs_value *val, int flags, FILE *fp) flags & GRECS_NODE_FLAG_QUOTE_HEX); cbuf[clen] = 0; fprintf(fp, "\"%s\"", cbuf); - free(cbuf); + grecs_free(cbuf); } else fprintf(fp, "%s", val->v.string); break; diff --git a/src/grecs-lex.l b/src/grecs-lex.l index 32a8913..d474548 100644 --- a/src/grecs-lex.l +++ b/src/grecs-lex.l @@ -137,7 +137,7 @@ P [1-9][0-9]* if (!strncmp(p, multiline_delimiter, multiline_delimiter_len) && isemptystr(p + multiline_delimiter_len - yytext)) { - free(multiline_delimiter); + grecs_free(multiline_delimiter); multiline_delimiter = NULL; BEGIN(INITIAL); yylval.string = grecs_line_finish(); @@ -173,7 +173,7 @@ yywrap() static void line_acc_free_entry(void *ptr) { - free(ptr); + grecs_free(ptr); } int diff --git a/src/grecs.h b/src/grecs.h index f6b88ab..dabcf7c 100644 --- a/src/grecs.h +++ b/src/grecs.h @@ -168,6 +168,7 @@ int grecs_version_cmp(const char *vstr); extern void *(*grecs_malloc_fun)(size_t size); extern void *(*grecs_realloc_fun)(void *ptr, size_t size); extern void (*grecs_alloc_die_fun)(void); +extern void (*grecs_free_fun)(void *ptr); void *grecs_malloc(size_t size); void *grecs_zalloc(size_t size); @@ -175,6 +176,7 @@ void *grecs_calloc(size_t nmemb, size_t size); void *grecs_realloc(void *ptr, size_t size); void grecs_alloc_die(void); char *grecs_strdup(const char *str); +void grecs_free(void *ptr); grecs_value_t *grecs_value_ptr_from_static(grecs_value_t *input); @@ -127,7 +127,7 @@ grecs_list_pop(struct grecs_list *lp) if (ep) { data = ep->data; grecs_list_remove_entry(lp, ep); - free(ep); + grecs_free(ep); } else data = NULL; return data; @@ -144,7 +144,7 @@ grecs_list_remove_tail(struct grecs_list *lp) ep = lp->tail; data = lp->tail->data; grecs_list_remove_entry(lp, ep); - free(ep); + grecs_free(ep); return data; } @@ -157,7 +157,7 @@ grecs_list_clear(struct grecs_list *lp) struct grecs_list_entry *next = ep->next; if (lp->free_entry) lp->free_entry(ep->data); - free(ep); + grecs_free(ep); ep = next; } lp->head = lp->tail = NULL; @@ -169,7 +169,7 @@ grecs_list_free(struct grecs_list *lp) { if (lp) { grecs_list_clear(lp); - free(lp); + grecs_free(lp); } } diff --git a/src/lookup.c b/src/lookup.c index 32ba2df..32674ad 100644 --- a/src/lookup.c +++ b/src/lookup.c @@ -123,36 +123,6 @@ split_cfg_path(const char *path, int *pargc, char ***pargv) return 0; } -static void -free_value_mem(struct grecs_value *p) -{ - switch (p->type) { - case GRECS_TYPE_STRING: - free((char*)p->v.string); - break; - - case GRECS_TYPE_LIST: - /* FIXME */ - break; - - case GRECS_TYPE_ARRAY: { - size_t i; - for (i = 0; i < p->v.arg.c; i++) - free_value_mem(p->v.arg.v[i]); - } - } -} - -static void -destroy_value(void *p) -{ - struct grecs_value*val = p; - if (val) { - free_value_mem(val); - free(val); - } -} - static struct grecs_value * parse_label(const char *str) { @@ -171,8 +141,7 @@ parse_label(const char *str) return NULL; } - lst = grecs_list_create(); - lst->free_entry = destroy_value; + lst = grecs_value_list_create(); for (i = 0; i < ws.ws_wordc; i++) { struct grecs_value *p = grecs_malloc(sizeof(*p)); p->type = GRECS_TYPE_STRING; @@ -267,7 +236,7 @@ grecs_find_node(struct grecs_node *node, const char *path) for (i = 0; i < clos.argc; i++) free(clos.argv[i]); free(clos.argv); - destroy_value(clos.label); + grecs_value_free(clos.label); return clos.node; } @@ -22,10 +22,6 @@ #include <string.h> #include <errno.h> -void *(*grecs_malloc_fun)(size_t size); -void *(*grecs_realloc_fun)(void *ptr, size_t size); -void (*grecs_alloc_die_fun) (void); - static void * def_malloc_fun(size_t size) { @@ -38,13 +34,27 @@ def_realloc_fun(void *ptr, size_t size) return realloc(ptr, size); } +static void +def_free_fun(void *ptr) +{ + free(ptr); +} + +void *(*grecs_malloc_fun)(size_t size) = def_malloc_fun; +void *(*grecs_realloc_fun)(void *ptr, size_t size) = def_realloc_fun; +void (*grecs_alloc_die_fun)(void); +void (*grecs_free_fun)(void *) = def_free_fun; + +void +grecs_free(void *ptr) +{ + grecs_free_fun(ptr); +} + void * grecs_malloc(size_t size) { - void *ptr; - if (!grecs_malloc_fun) - grecs_malloc_fun = def_malloc_fun; - ptr = grecs_malloc_fun(size); + void *ptr = grecs_malloc_fun(size); if (!ptr) grecs_alloc_die(); return ptr; @@ -67,11 +77,7 @@ grecs_calloc(size_t nmemb, size_t size) void * grecs_realloc(void *ptr, size_t size) { - void *newptr; - - if (!grecs_realloc_fun) - grecs_realloc_fun = def_realloc_fun; - newptr = grecs_realloc_fun(ptr, size); + void *newptr = grecs_realloc_fun(ptr, size); if (!newptr) grecs_alloc_die(); return newptr; diff --git a/src/preproc.c b/src/preproc.c index 06924c1..28f473f 100644 --- a/src/preproc.c +++ b/src/preproc.c @@ -269,7 +269,7 @@ pp_list_find(struct grecs_list *list, struct file_data *dptr) static void incl_free(void *data) { - free(data); + grecs_free(data); } void @@ -315,7 +315,7 @@ grecs_include_path_setup(const char *dir, ...) p = va_arg(ap, const char*); } grecs_include_path_setup_v(argv); - free(argv); + grecs_free(argv); va_end(ap); } @@ -452,7 +452,7 @@ pop_source() /* Restore previous context */ ctx = context_stack->prev; - free(context_stack); + grecs_free(context_stack); context_stack = ctx; if (!context_stack) { @@ -541,7 +541,7 @@ parse_include(const char *text, int once) if (p) rc = push_source(p, once); - free(tmp); + grecs_free(tmp); wordsplit_free(&ws); return rc; } @@ -556,9 +556,9 @@ void grecs_preproc_done() { grecs_symtab_free(incl_sources); - free(linebuf); - free(putback_buffer); - free(linebufbase); + grecs_free(linebuf); + grecs_free(putback_buffer); + free(linebufbase); /* Allocated via standard malloc/realloc */ } int @@ -579,7 +579,7 @@ grecs_preproc_run(const char *config_file, const char *extpp) if (grecs_asprintf(&cmd, &size, "%s %s -", extpp, setup_file)) grecs_alloc_die(); - free(setup_file); + grecs_free(setup_file); } else cmd = grecs_strdup (extpp); /*FIXME_DEBUG_F1 (2, "Running preprocessor: `%s'", cmd);*/ @@ -588,14 +588,14 @@ grecs_preproc_run(const char *config_file, const char *extpp) grecs_error(NULL, errno, _("Unable to start external preprocessor `%s'"), cmd); - free(cmd); + grecs_free(cmd); return 1; } while ((i = grecs_preproc_fill_buffer(buffer, sizeof buffer))) fwrite(buffer, 1, i, outfile); pclose(outfile); - free(cmd); + grecs_free(cmd); } else { while ((i = grecs_preproc_fill_buffer(buffer, sizeof buffer))) fwrite(buffer, 1, i, stdout); @@ -37,7 +37,7 @@ grecs_value_free(struct grecs_value *val) return; switch (val->type) { case GRECS_TYPE_STRING: - free(val->v.string); + grecs_free(val->v.string); break; case GRECS_TYPE_LIST: @@ -49,7 +49,7 @@ grecs_value_free(struct grecs_value *val) grecs_value_free(val->v.arg.v[i]); free(val->v.arg.v); } - free(val); + grecs_free(val); } struct grecs_node * @@ -111,7 +111,7 @@ grecs_node_unlink(struct grecs_node *node) static void listel_dispose(void *el) { - free(el); + grecs_free(el); } struct grecs_list * @@ -194,7 +194,7 @@ grecs_node_free(struct grecs_node *node) default: grecs_value_free(node->v.value); } - free(node); + grecs_free(node); } static enum grecs_tree_recurse_res @@ -350,10 +350,10 @@ string_to_sockaddr(struct grecs_sockaddr *sp, const char *string, grecs_error(locus, 0, _("%s: not a valid IP address or hostname"), host); - free(host); + grecs_free(host); return 1; } - free(host); + grecs_free(host); } if (p) { @@ -711,7 +711,7 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value, locus) == 0) grecs_list_append(list, ptr); else - free(ptr); + grecs_free(ptr); } } *(struct grecs_list**)target = list; @@ -743,7 +743,7 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value, ptr = grecs_malloc(size); if (grecs_string_convert(ptr, type, value->v.string, locus)) { - free(ptr); + grecs_free(ptr); grecs_list_free(list); return; } |