summaryrefslogtreecommitdiff
path: root/ar.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2007-03-20 03:02:26 +0000
committerPaul Smith <psmith@gnu.org>2007-03-20 03:02:26 +0000
commit6ccf33cdbdfda2aea5d51e4d4991881c74d853d1 (patch)
treece963770c6d0dc0428a6bce65d96da4b710e2831 /ar.c
parente4da30858037b431880263676e8f90b1f8412a38 (diff)
downloadgunmake-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.c63
1 files changed, 25 insertions, 38 deletions
diff --git a/ar.c b/ar.c
index 9bf0cb7..a8b5ceb 100644
--- a/ar.c
+++ b/ar.c
@@ -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;