aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-07 00:24:03 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-05-07 00:24:03 +0300
commited39daa568d162617a183497010d70a55a38ae73 (patch)
tree313c1caef8b42ab1800f5c1cef8dece9116fbd0d
parent18d7db07b9f369901300bf664d07d4b39032ce64 (diff)
downloadgrecs-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.330
-rw-r--r--doc/grecs_parse.326
-rw-r--r--doc/grecs_strdup.36
-rw-r--r--src/format.c2
-rw-r--r--src/grecs-lex.l4
-rw-r--r--src/grecs.h2
-rw-r--r--src/list.c8
-rw-r--r--src/lookup.c35
-rw-r--r--src/mem.c32
-rw-r--r--src/preproc.c20
-rw-r--r--src/tree.c16
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);
diff --git a/src/list.c b/src/list.c
index 2bd9797..33d56d8 100644
--- a/src/list.c
+++ b/src/list.c
@@ -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;
}
diff --git a/src/mem.c b/src/mem.c
index b18cc72..2e6a7cf 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -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);
diff --git a/src/tree.c b/src/tree.c
index 7d2eca8..22a169a 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -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;
}

Return to:

Send suggestions and report system problems to the System administrator.