diff options
author | Paul Smith <psmith@gnu.org> | 2007-03-20 03:02:26 +0000 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2007-03-20 03:02:26 +0000 |
commit | 6ccf33cdbdfda2aea5d51e4d4991881c74d853d1 (patch) | |
tree | ce963770c6d0dc0428a6bce65d96da4b710e2831 /ar.c | |
parent | e4da30858037b431880263676e8f90b1f8412a38 (diff) | |
download | gunmake-6ccf33cdbdfda2aea5d51e4d4991881c74d853d1.tar.gz |
This is a major update, which switches virtually every allocated-but-not-freed
string into the strcache. As a side-effect, many more structure members and
function arguments can/should be declared const.
As mentioned in the changelog, unfortunately measurement shows that this
change does not yet reduce memory. The problem is with secondary expansion:
because of this we store all the prerequisites in the string cache twice.
First we store the prerequisite string after initial expansion but before
secondary expansion, then we store each individual file after secondary
expansion and expand_deps(). I plan to change expand_deps() to be callable
in either context (eval or snap_deps) then have non-second-expansion
targets call expand_deps() during eval, so that we only need to store that
dependency list once.
Diffstat (limited to 'ar.c')
-rw-r--r-- | ar.c | 63 |
1 files changed, 25 insertions, 38 deletions
@@ -50,19 +50,19 @@ ar_name (const char *name) /* Parse the archive-member reference NAME into the archive and member names. - Put the malloc'd archive name in *ARNAME_P if ARNAME_P is non-nil; - put the malloc'd member name in *MEMNAME_P if MEMNAME_P is non-nil. */ + Creates one allocated string containing both names, pointed to by ARNAME_P. + MEMNAME_P points to the member. */ void ar_parse_name (const char *name, char **arname_p, char **memname_p) { - const char *p = strchr (name, '('), *end = name + strlen (name) - 1; + char *p; - if (arname_p != 0) - *arname_p = savestring (name, p - name); - - if (memname_p != 0) - *memname_p = savestring (p + 1, end - (p + 1)); + *arname_p = xstrdup (name); + p = strchr (*arname_p, '('); + *(p++) = '\0'; + p[strlen(p) - 1] = '\0'; + *memname_p = p; } @@ -86,7 +86,6 @@ ar_member_date (const char *name) { char *arname; char *memname; - int arname_used = 0; long int val; ar_parse_name (name, &arname, &memname); @@ -102,10 +101,7 @@ ar_member_date (const char *name) struct file *arfile; arfile = lookup_file (arname); if (arfile == 0 && file_exists_p (arname)) - { - arfile = enter_file (arname); - arname_used = 1; - } + arfile = enter_file (strcache_add (arname)); if (arfile != 0) (void) f_mtime (arfile, 0); @@ -113,9 +109,7 @@ ar_member_date (const char *name) val = ar_scan (arname, ar_member_date_1, memname); - if (!arname_used) - free (arname); - free (memname); + free (arname); return (val <= 0 ? (time_t) -1 : (time_t) val); } @@ -134,23 +128,16 @@ int ar_touch (const char *name) { char *arname, *memname; - int arname_used = 0; - register int val; + int val; ar_parse_name (name, &arname, &memname); /* Make sure we know the modtime of the archive itself before we - touch the member, since this will change the archive itself. */ + touch the member, since this will change the archive modtime. */ { struct file *arfile; - arfile = lookup_file (arname); - if (arfile == 0) - { - arfile = enter_file (arname); - arname_used = 1; - } - - (void) f_mtime (arfile, 0); + arfile = enter_file (strcache_add (arname)); + f_mtime (arfile, 0); } val = 1; @@ -177,9 +164,7 @@ ar_touch (const char *name) _("touch: Bad return code from ar_member_touch on `%s'"), name); } - if (!arname_used) - free (arname); - free (memname); + free (arname); return val; } @@ -189,7 +174,7 @@ ar_touch (const char *name) struct ar_glob_state { - char *arname; + const char *arname; const char *pattern; unsigned int size; struct nameseq *chain; @@ -211,7 +196,7 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED, { /* We have a match. Add it to the chain. */ struct nameseq *new = xmalloc (state->size); - new->name = concat (state->arname, mem, ")"); + new->name = strcache_add (concat (state->arname, mem, ")")); new->next = state->chain; state->chain = new; ++state->n; @@ -260,8 +245,9 @@ struct nameseq * ar_glob (const char *arname, const char *member_pattern, unsigned int size) { struct ar_glob_state state; - char **names; struct nameseq *n; + const char **names; + char *name; unsigned int i; if (! glob_pattern_p (member_pattern, 1)) @@ -270,10 +256,11 @@ ar_glob (const char *arname, const char *member_pattern, unsigned int size) /* Scan the archive for matches. ar_glob_match will accumulate them in STATE.chain. */ i = strlen (arname); - state.arname = alloca (i + 2); - memcpy (state.arname, arname, i); - state.arname[i] = '('; - state.arname[i + 1] = '\0'; + name = alloca (i + 2); + memcpy (name, arname, i); + name[i] = '('; + name[i + 1] = '\0'; + state.arname = name; state.pattern = member_pattern; state.size = size; state.chain = 0; @@ -284,7 +271,7 @@ ar_glob (const char *arname, const char *member_pattern, unsigned int size) return 0; /* Now put the names into a vector for sorting. */ - names = alloca (state.n * sizeof (char *)); + names = alloca (state.n * sizeof (const char *)); i = 0; for (n = state.chain; n != 0; n = n->next) names[i++] = n->name; |