From 86af3872a910e314d20ef911fad1819ad90c1291 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Tue, 14 Feb 2006 15:42:17 +0000 Subject: Some memory leak cleanups (found with valgrind). --- ChangeLog | 18 ++++++++++++++++++ doc/make.texi | 41 +++++++++++++++++++++++------------------ implicit.c | 23 +++++++++++++---------- main.c | 4 ++++ read.c | 19 ++++++++----------- variable.c | 25 +++++++++++++++++-------- variable.h | 1 + 7 files changed, 84 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52f7340..24732d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-02-14 Paul D. Smith + + * read.c (eval): Even if the included filenames expands to the + empty string we still need to free the allocated buffer. + + * implicit.c (pattern_search): If we allocated a variable set for + an impossible file, free it. + * variable.c (free_variable_set): New function. + * variable.h: Declare it. + + * read.c (read_all_makefiles): Makefile names are kept in the + strcache, so there's never any need to alloc/free them. + (eval): Ditto. + + * main.c (main): Add "archives" to the .FEATURES variable if + archive support is enabled. + * doc/make.texi (Special Variables): Document it. + 2006-02-13 Paul D. Smith * implicit.c (pattern_search): Add checking for DOS pathnames to diff --git a/doc/make.texi b/doc/make.texi index a99e9ad..c73649f 100644 --- a/doc/make.texi +++ b/doc/make.texi @@ -1369,28 +1369,33 @@ Expands to a list of special features supported by this version of @code{make}. Possible values include: @table @samp -@item target-specific -Supports target-specific and pattern-specific variable assignments. -@xref{Target-specific, ,Target-specific Variable Values}. -@item order-only -Supports order-only prerequisites. @xref{Prerequisite Types, ,Types -of Prerequisites}. +@item archives +Supports @code{ar} (archive) files using special filename syntax. +@xref{Archives, ,Using @code{make} to Update Archive Files}. -@item second-expansion -Supports secondary expansion of prerequisite lists. +@item check-symlink +Supports the @code{-L} (@code{--check-symlink-times}) flag. +@xref{Options Summary, ,Summary of Options}. + +@item else-if +Supports ``else if'' non-nested conditionals. @xref{Conditional +Syntax, ,Syntax of Conditionals}. @item jobserver Supports ``job server'' enhanced parallel builds. @xref{Parallel, ,Parallel Execution}. -@item else-if -Supports ``else if'' non-nested conditionals. @xref{Conditional -Syntax, ,Syntax of Conditionals}. +@item second-expansion +Supports secondary expansion of prerequisite lists. -@item check-symlink -Supports the @code{-L} (@code{--check-symlink-times}) flag. -@xref{Options Summary, ,Summary of Options}. +@item order-only +Supports order-only prerequisites. @xref{Prerequisite Types, ,Types +of Prerequisites}. + +@item target-specific +Supports target-specific and pattern-specific variable assignments. +@xref{Target-specific, ,Target-specific Variable Values}. @end table @@ -2047,10 +2052,10 @@ directory for each user (such as MS-DOS or MS-Windows), this functionality can be simulated by setting the environment variable @var{HOME}.@refill -Wildcard expansion happens automatically in targets, in prerequisites, -and in commands (where the shell does the expansion). In other -contexts, wildcard expansion happens only if you request it explicitly -with the @code{wildcard} function. +Wildcard expansion is performed by @code{make} automatically in +targets and in prerequisites. In commands the shell is responsible +for wildcard expansion. In other contexts, wildcard expansion happens +only if you request it explicitly with the @code{wildcard} function. The special significance of a wildcard character can be turned off by preceding it with a backslash. Thus, @file{foo\*bar} would refer to a diff --git a/implicit.c b/implicit.c index 7b34fba..d7c140a 100644 --- a/implicit.c +++ b/implicit.c @@ -77,24 +77,25 @@ struct idep }; static void -free_idep_chain (struct idep* p) +free_idep_chain (struct idep *p) { - register struct idep* n; - register struct file *f; + struct idep *n; + struct file *f; for (; p != 0; p = n) { n = p->next; if (p->name) - { - free (p->name); - - f = p->intermediate_file; + free (p->name); - if (f != 0 - && (f->stem < f->name - || f->stem > f->name + strlen (f->name))) + f = p->intermediate_file; + if (f != 0) + { + /* if (f->variables) + free_variable_set (f->variables); */ + if (f->stem < f->name + || f->stem > f->name + strlen (f->name)) free (f->stem); } @@ -742,6 +743,8 @@ pattern_search (struct file *file, int archive, /* If we have tried to find P as an intermediate file and failed, mark that name as impossible so we won't go through the search again later. */ + if (intermediate_file->variables) + free_variable_set (intermediate_file->variables); file_impossible (name); } diff --git a/main.c b/main.c index 82fe46f..a645e44 100644 --- a/main.c +++ b/main.c @@ -1110,6 +1110,10 @@ main (int argc, char **argv, char **envp) define_variable (".FEATURES", 9, "target-specific order-only second-expansion else-if", o_default, 0); +#ifndef NO_ARCHIVES + do_variable_definition (NILF, ".FEATURES", "archives", + o_default, f_append, 0); +#endif #ifdef MAKE_JOBSERVER do_variable_definition (NILF, ".FEATURES", "jobserver", o_default, f_append, 0); diff --git a/read.c b/read.c index 82bc253..0c78c7f 100644 --- a/read.c +++ b/read.c @@ -186,10 +186,7 @@ read_all_makefiles (char **makefiles) { if (*p != '\0') *p++ = '\0'; - name = xstrdup (name); - if (eval_makefile (name, - RM_NO_DEFAULT_GOAL|RM_INCLUDED|RM_DONTCARE) < 2) - free (name); + eval_makefile (name, RM_NO_DEFAULT_GOAL|RM_INCLUDED|RM_DONTCARE); } free (value); @@ -810,7 +807,10 @@ eval (struct ebuffer *ebuf, int set_default) /* If no filenames, it's a no-op. */ if (*p == '\0') - continue; + { + free (p); + continue; + } /* Parse the list of file names. */ p2 = p; @@ -840,12 +840,9 @@ eval (struct ebuffer *ebuf, int set_default) r = eval_makefile (name, (RM_INCLUDED | RM_NO_TILDE | (noerror ? RM_DONTCARE : 0))); - if (!r) - { - if (!noerror) - error (fstart, "%s: %s", name, strerror (errno)); - free (name); - } + if (!r && !noerror) + error (fstart, "%s: %s", name, strerror (errno)); + free (name); } /* Restore conditional state. */ diff --git a/variable.c b/variable.c index 54ac046..0ea71cd 100644 --- a/variable.c +++ b/variable.c @@ -539,14 +539,6 @@ initialize_file_variables (struct file *file, int reading) /* Pop the top set off the current variable set list, and free all its storage. */ -static void -free_variable_name_and_value (const void *item) -{ - struct variable *v = (struct variable *) item; - free (v->name); - free (v->value); -} - struct variable_set_list * create_new_variable_set (void) { @@ -565,6 +557,23 @@ create_new_variable_set (void) return setlist; } +static void +free_variable_name_and_value (const void *item) +{ + struct variable *v = (struct variable *) item; + free (v->name); + free (v->value); +} + +void +free_variable_set (struct variable_set_list *list) +{ + hash_map (&list->set->table, free_variable_name_and_value); + hash_free (&list->set->table, 1); + free ((char *) list->set); + free ((char *) list); +} + /* Create a new variable set and push it on the current setlist. If we're pushing a global scope (that is, the current scope is the global scope) then we need to "push" it the other way: file variable sets point diff --git a/variable.h b/variable.h index 6b20152..46b18fa 100644 --- a/variable.h +++ b/variable.h @@ -136,6 +136,7 @@ extern char *recursively_expand_for_file PARAMS ((struct variable *v, /* variable.c */ extern struct variable_set_list *create_new_variable_set PARAMS ((void)); +extern void free_variable_set PARAMS ((struct variable_set_list *)); extern struct variable_set_list *push_new_variable_scope PARAMS ((void)); extern void pop_variable_scope PARAMS ((void)); extern void define_automatic_variables PARAMS ((void)); -- cgit v1.2.3