summaryrefslogtreecommitdiff
path: root/vpath.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 /vpath.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 'vpath.c')
-rw-r--r--vpath.c171
1 files changed, 85 insertions, 86 deletions
diff --git a/vpath.c b/vpath.c
index 992065b..4c79fcd 100644
--- a/vpath.c
+++ b/vpath.c
@@ -48,12 +48,10 @@ static struct vpath *general_vpath;
static struct vpath *gpaths;
-static int selective_vpath_search (struct vpath *path, char **file,
- FILE_TIMESTAMP *mtime_ptr);
-/* Reverse the chain of selective VPATH lists so they
- will be searched in the order given in the makefiles
- and construct the list from the VPATH variable. */
+/* Reverse the chain of selective VPATH lists so they will be searched in the
+ order given in the makefiles and construct the list from the VPATH
+ variable. */
void
build_vpath_lists ()
@@ -284,8 +282,8 @@ construct_vpath_list (char *pattern, char *dirpath)
/* Set up the members. */
path->pattern = strcache_add (pattern);
- path->percent = path->pattern + (percent - pattern);
path->patlen = strlen (pattern);
+ path->percent = percent ? path->pattern + (percent - pattern) : 0;
}
else
/* There were no entries, so free whatever space we allocated. */
@@ -308,57 +306,23 @@ gpath_search (const char *file, unsigned int len)
return 0;
}
-/* Search the VPATH list whose pattern matches *FILE for a directory
- where the name pointed to by FILE exists. If it is found, we set *FILE to
- the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is
- not NULL) to its modtime (or zero if no stat call was done), and return 1.
- Otherwise we return 0. */
-int
-vpath_search (char **file, FILE_TIMESTAMP *mtime_ptr)
-{
- struct vpath *v;
-
- /* If there are no VPATH entries or FILENAME starts at the root,
- there is nothing we can do. */
+/* Search the given VPATH list for a directory where the name pointed to by
+ FILE exists. If it is found, we return a cached name of the existing file
+ and set *MTIME_PTR (if MTIME_PTR is not NULL) to its modtime (or zero if no
+ stat call was done). Otherwise we return NULL. */
- if (**file == '/'
-#ifdef HAVE_DOS_PATHS
- || **file == '\\'
- || (*file)[1] == ':'
-#endif
- || (vpaths == 0 && general_vpath == 0))
- return 0;
-
- for (v = vpaths; v != 0; v = v->next)
- if (pattern_matches (v->pattern, v->percent, *file))
- if (selective_vpath_search (v, file, mtime_ptr))
- return 1;
-
- if (general_vpath != 0
- && selective_vpath_search (general_vpath, file, mtime_ptr))
- return 1;
-
- return 0;
-}
-
-
-/* Search the given VPATH list for a directory where the name pointed
- to by FILE exists. If it is found, we set *FILE to the newly malloc'd
- name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to
- its modtime (or zero if no stat call was done), and we return 1.
- Otherwise we return 0. */
-
-static int
-selective_vpath_search (struct vpath *path, char **file,
+static const char *
+selective_vpath_search (struct vpath *path, const char *file,
FILE_TIMESTAMP *mtime_ptr)
{
int not_target;
- char *name, *n;
- char *filename;
+ char *name;
+ const char *n;
+ const char *filename;
const char **vpath = path->searchpath;
unsigned int maxvpath = path->maxlen;
- register unsigned int i;
+ unsigned int i;
unsigned int flen, vlen, name_dplen;
int exists = 0;
@@ -366,73 +330,73 @@ selective_vpath_search (struct vpath *path, char **file,
If and only if it is NOT a target, we will accept prospective
files that don't exist but are mentioned in a makefile. */
{
- struct file *f = lookup_file (*file);
+ struct file *f = lookup_file (file);
not_target = f == 0 || !f->is_target;
}
- flen = strlen (*file);
+ flen = strlen (file);
/* Split *FILE into a directory prefix and a name-within-directory.
- NAME_DPLEN gets the length of the prefix; FILENAME gets the
- pointer to the name-within-directory and FLEN is its length. */
+ NAME_DPLEN gets the length of the prefix; FILENAME gets the pointer to
+ the name-within-directory and FLEN is its length. */
- n = strrchr (*file, '/');
+ n = strrchr (file, '/');
#ifdef HAVE_DOS_PATHS
/* We need the rightmost slash or backslash. */
{
- char *bslash = strrchr(*file, '\\');
+ const char *bslash = strrchr(file, '\\');
if (!n || bslash > n)
n = bslash;
}
#endif
- name_dplen = n != 0 ? n - *file : 0;
- filename = name_dplen > 0 ? n + 1 : *file;
+ name_dplen = n != 0 ? n - file : 0;
+ filename = name_dplen > 0 ? n + 1 : file;
if (name_dplen > 0)
flen -= name_dplen + 1;
- /* Allocate enough space for the biggest VPATH entry,
- a slash, the directory prefix that came with *FILE,
- another slash (although this one may not always be
- necessary), the filename, and a null terminator. */
- name = xmalloc (maxvpath + 1 + name_dplen + 1 + flen + 1);
+ /* Get enough space for the biggest VPATH entry, a slash, the directory
+ prefix that came with FILE, another slash (although this one may not
+ always be necessary), the filename, and a null terminator. */
+ name = alloca (maxvpath + 1 + name_dplen + 1 + flen + 1);
/* Try each VPATH entry. */
for (i = 0; vpath[i] != 0; ++i)
{
int exists_in_cache = 0;
+ char *p;
- n = name;
+ p = name;
- /* Put the next VPATH entry into NAME at N and increment N past it. */
+ /* Put the next VPATH entry into NAME at P and increment P past it. */
vlen = strlen (vpath[i]);
- memcpy (n, vpath[i], vlen);
- n += vlen;
+ memcpy (p, vpath[i], vlen);
+ p += vlen;
/* Add the directory prefix already in *FILE. */
if (name_dplen > 0)
{
#ifndef VMS
- *n++ = '/';
+ *p++ = '/';
#endif
- memcpy (n, *file, name_dplen);
- n += name_dplen;
+ memcpy (p, file, name_dplen);
+ p += name_dplen;
}
#ifdef HAVE_DOS_PATHS
/* Cause the next if to treat backslash and slash alike. */
- if (n != name && n[-1] == '\\' )
- n[-1] = '/';
+ if (p != name && p[-1] == '\\' )
+ p[-1] = '/';
#endif
/* Now add the name-within-directory at the end of NAME. */
#ifndef VMS
- if (n != name && n[-1] != '/')
+ if (p != name && p[-1] != '/')
{
- *n = '/';
- memcpy (n + 1, filename, flen + 1);
+ *p = '/';
+ memcpy (p + 1, filename, flen + 1);
}
else
#endif
- memcpy (n, filename, flen + 1);
+ memcpy (p, filename, flen + 1);
/* Check if the file is mentioned in a makefile. If *FILE is not
a target, that is enough for us to decide this file exists.
@@ -479,7 +443,7 @@ selective_vpath_search (struct vpath *path, char **file,
#else
/* Clobber a null into the name at the last slash.
Now NAME is the name of the directory to look in. */
- *n = '\0';
+ *p = '\0';
/* We know the directory is in the hash table now because either
construct_vpath_list or the code just above put it there.
@@ -500,7 +464,7 @@ selective_vpath_search (struct vpath *path, char **file,
#ifndef VMS
/* Put the slash back in NAME. */
- *n = '/';
+ *p = '/';
#endif
if (exists_in_cache) /* Makefile-mentioned file need not exist. */
@@ -523,21 +487,56 @@ selective_vpath_search (struct vpath *path, char **file,
}
/* We have found a file.
- Store the name we found into *FILE for the caller. */
-
- *file = savestring (name, (n + 1 - name) + flen);
-
- /* If we get here and mtime_ptr hasn't been set, record
+ If we get here and mtime_ptr hasn't been set, record
UNKNOWN_MTIME to indicate this. */
if (mtime_ptr != 0)
*mtime_ptr = UNKNOWN_MTIME;
- free (name);
- return 1;
+ /* Store the name we found and return it. */
+
+ return strcache_add_len (name, (p + 1 - name) + flen);
}
}
- free (name);
+ return 0;
+}
+
+
+/* Search the VPATH list whose pattern matches FILE for a directory where FILE
+ exists. If it is found, return the cached name of an existing file, and
+ set *MTIME_PTR (if MTIME_PTR is not NULL) to its modtime (or zero if no
+ stat call was done). Otherwise we return 0. */
+
+const char *
+vpath_search (const char *file, FILE_TIMESTAMP *mtime_ptr)
+{
+ struct vpath *v;
+
+ /* If there are no VPATH entries or FILENAME starts at the root,
+ there is nothing we can do. */
+
+ if (file[0] == '/'
+#ifdef HAVE_DOS_PATHS
+ || file[0] == '\\' || file[1] == ':'
+#endif
+ || (vpaths == 0 && general_vpath == 0))
+ return 0;
+
+ for (v = vpaths; v != 0; v = v->next)
+ if (pattern_matches (v->pattern, v->percent, file))
+ {
+ const char *p = selective_vpath_search (v, file, mtime_ptr);
+ if (p)
+ return p;
+ }
+
+ if (general_vpath != 0)
+ {
+ const char *p = selective_vpath_search (general_vpath, file, mtime_ptr);
+ if (p)
+ return p;
+ }
+
return 0;
}