summaryrefslogtreecommitdiff
path: root/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'read.c')
-rw-r--r--read.c457
1 files changed, 254 insertions, 203 deletions
diff --git a/read.c b/read.c
index 6b0c0aa..e50a76c 100644
--- a/read.c
+++ b/read.c
@@ -88,14 +88,12 @@ static struct conditionals *conditionals = &toplevel_conditionals;
/* Default directories to search for include files in */
-static char *default_include_directories[] =
+static const char *default_include_directories[] =
{
#if defined(WINDOWS32) && !defined(INCLUDEDIR)
-/*
- * This completely up to the user when they install MSVC or other packages.
- * This is defined as a placeholder.
- */
-#define INCLUDEDIR "."
+/* This completely up to the user when they install MSVC or other packages.
+ This is defined as a placeholder. */
+# define INCLUDEDIR "."
#endif
INCLUDEDIR,
#ifndef _AMIGA
@@ -108,7 +106,7 @@ static char *default_include_directories[] =
/* List of directories to search for include files in */
-static char **include_directories;
+static const char **include_directories;
/* Maximum length of an element of the above. */
@@ -123,15 +121,15 @@ const struct floc *reading_file = 0;
static struct dep *read_makefiles = 0;
-static int eval_makefile (char *filename, int flags);
+static int eval_makefile (const char *filename, int flags);
static int eval (struct ebuffer *buffer, int flags);
static long readline (struct ebuffer *ebuf);
static void do_define (char *name, unsigned int namelen,
enum variable_origin origin, struct ebuffer *ebuf);
static int conditional_line (char *line, int len, const struct floc *flocp);
-static void record_files (struct nameseq *filenames, char *pattern,
- char *pattern_percent, struct dep *deps,
+static void record_files (struct nameseq *filenames, const char *pattern,
+ const char *pattern_percent, struct dep *deps,
unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon,
const struct floc *flocp);
@@ -147,7 +145,7 @@ static char *find_char_unquote (char *string, int stop1, int stop2,
/* Read in all the makefiles and return the chain of their names. */
struct dep *
-read_all_makefiles (char **makefiles)
+read_all_makefiles (const char **makefiles)
{
unsigned int num_makefiles = 0;
@@ -181,7 +179,7 @@ read_all_makefiles (char **makefiles)
MAKEFILES is updated for finding remaining tokens. */
p = value;
- while ((name = find_next_token (&p, &length)) != 0)
+ while ((name = find_next_token ((const char **)&p, &length)) != 0)
{
if (*p != '\0')
*p++ = '\0';
@@ -248,7 +246,7 @@ read_all_makefiles (char **makefiles)
for (p = default_makefiles; *p != 0; ++p)
{
struct dep *d = alloc_dep ();
- d->file = enter_file (*p);
+ d->file = enter_file (strcache_add (*p));
d->file->dontcare = 1;
/* Tell update_goal_chain to bail out as soon as this file is
made, and main not to die if we can't make this file. */
@@ -296,17 +294,17 @@ restore_conditionals (struct conditionals *saved)
}
static int
-eval_makefile (char *filename, int flags)
+eval_makefile (const char *filename, int flags)
{
struct dep *deps;
struct ebuffer ebuf;
const struct floc *curfile;
char *expanded = 0;
- char *included = 0;
int makefile_errno;
int r;
- ebuf.floc.filenm = strcache_add (filename);
+ filename = strcache_add (filename);
+ ebuf.floc.filenm = filename;
ebuf.floc.lineno = 1;
if (ISDB (DB_VERBOSE))
@@ -343,21 +341,17 @@ eval_makefile (char *filename, int flags)
search the included makefile search path for this makefile. */
if (ebuf.fp == 0 && (flags & RM_INCLUDED) && *filename != '/')
{
- register unsigned int i;
+ unsigned int i;
for (i = 0; include_directories[i] != 0; ++i)
{
- included = concat (include_directories[i], "/", filename);
+ const char *included = concat (include_directories[i], "/", filename);
ebuf.fp = fopen (included, "r");
if (ebuf.fp)
{
- filename = included;
+ filename = strcache_add (included);
break;
}
- free (included);
}
- /* If we're not using it, we already freed it above. */
- if (filename != included)
- included = 0;
}
/* Add FILENAME to the chain of read makefiles. */
@@ -366,7 +360,7 @@ eval_makefile (char *filename, int flags)
read_makefiles = deps;
deps->file = lookup_file (filename);
if (deps->file == 0)
- deps->file = enter_file (xstrdup (filename));
+ deps->file = enter_file (filename);
filename = deps->file->name;
deps->changed = flags;
if (flags & RM_DONTCARE)
@@ -374,8 +368,6 @@ eval_makefile (char *filename, int flags)
if (expanded)
free (expanded);
- if (included)
- free (included);
/* If the makefile can't be found at all, give up entirely. */
@@ -464,7 +456,8 @@ eval (struct ebuffer *ebuf, int set_default)
struct dep *deps = 0;
long nlines = 0;
int two_colon = 0;
- char *pattern = 0, *pattern_percent;
+ const char *pattern = 0;
+ const char *pattern_percent;
struct floc *fstart;
struct floc fi;
@@ -481,7 +474,7 @@ eval (struct ebuffer *ebuf, int set_default)
filenames = 0; \
commands_idx = 0; \
no_targets = 0; \
- if (pattern) { free(pattern); pattern = 0; } \
+ pattern = 0; \
} while (0)
pattern_percent = 0;
@@ -708,14 +701,15 @@ eval (struct ebuffer *ebuf, int set_default)
else
{
unsigned int l;
+ const char *cp;
char *ap;
/* Expand the line so we can use indirect and constructed
variable names in an export command. */
- p2 = ap = allocated_variable_expand (p2);
+ cp = ap = allocated_variable_expand (p2);
- for (p = find_next_token (&p2, &l); p != 0;
- p = find_next_token (&p2, &l))
+ for (p = find_next_token (&cp, &l); p != 0;
+ p = find_next_token (&cp, &l))
{
v = lookup_variable (p, l);
if (v == 0)
@@ -737,14 +731,15 @@ eval (struct ebuffer *ebuf, int set_default)
{
unsigned int l;
struct variable *v;
+ const char *cp;
char *ap;
/* Expand the line so we can use indirect and constructed
variable names in an unexport command. */
- p2 = ap = allocated_variable_expand (p2);
+ cp = ap = allocated_variable_expand (p2);
- for (p = find_next_token (&p2, &l); p != 0;
- p = find_next_token (&p2, &l))
+ for (p = find_next_token (&cp, &l); p != 0;
+ p = find_next_token (&cp, &l))
{
v = lookup_variable (p, l);
if (v == 0)
@@ -761,14 +756,15 @@ eval (struct ebuffer *ebuf, int set_default)
skip_conditionals:
if (word1eq ("vpath"))
{
+ const char *cp;
char *vpat;
unsigned int l;
- p2 = variable_expand (p2);
- p = find_next_token (&p2, &l);
+ cp = variable_expand (p2);
+ p = find_next_token (&cp, &l);
if (p != 0)
{
vpat = savestring (p, l);
- p = find_next_token (&p2, &l);
+ p = find_next_token (&cp, &l);
/* No searchpath means remove all previous
selective VPATH's with the same pattern. */
}
@@ -822,7 +818,7 @@ eval (struct ebuffer *ebuf, int set_default)
while (files != 0)
{
struct nameseq *next = files->next;
- char *name = files->name;
+ const char *name = files->name;
int r;
free (files);
@@ -832,7 +828,6 @@ eval (struct ebuffer *ebuf, int set_default)
| (noerror ? RM_DONTCARE : 0)));
if (!r && !noerror)
error (fstart, "%s: %s", name, strerror (errno));
- free (name);
}
/* Restore conditional state. */
@@ -1148,8 +1143,8 @@ eval (struct ebuffer *ebuf, int set_default)
fatal (fstart, _("missing target pattern"));
else if (target->next != 0)
fatal (fstart, _("multiple target patterns"));
+ pattern_percent = find_percent_cached (&target->name);
pattern = target->name;
- pattern_percent = find_percent (pattern);
if (pattern_percent == 0)
fatal (fstart, _("target pattern contains no `%%'"));
free (target);
@@ -1166,7 +1161,7 @@ eval (struct ebuffer *ebuf, int set_default)
{
/* Put all the prerequisites here; they'll be parsed later. */
deps = alloc_dep ();
- deps->name = savestring (beg, end - beg + 1);
+ deps->name = strcache_add_len (beg, end - beg + 1);
}
else
deps = 0;
@@ -1208,7 +1203,7 @@ eval (struct ebuffer *ebuf, int set_default)
if (**default_goal_name == '\0' && set_default)
{
- char* name;
+ const char *name;
struct dep *d;
struct nameseq *t = filenames;
@@ -1769,9 +1764,9 @@ record_target_var (struct nameseq *filenames, char *defn,
for (; filenames != 0; filenames = nextf)
{
struct variable *v;
- register char *name = filenames->name;
- char *fname;
- char *percent;
+ const char *name = filenames->name;
+ const char *fname;
+ const char *percent;
struct pattern_var *p;
nextf = filenames->next;
@@ -1779,7 +1774,7 @@ record_target_var (struct nameseq *filenames, char *defn,
/* If it's a pattern target, then add it to the pattern-specific
variable list. */
- percent = find_percent (name);
+ percent = find_percent_cached (&name);
if (percent)
{
/* Get a reference for this pattern-specific variable struct. */
@@ -1807,7 +1802,7 @@ record_target_var (struct nameseq *filenames, char *defn,
this situation. */
f = lookup_file (name);
if (!f)
- f = enter_file (name);
+ f = enter_file (strcache_add (name));
else if (f->double_colon)
f = f->double_colon;
@@ -1844,10 +1839,6 @@ record_target_var (struct nameseq *filenames, char *defn,
v->append = 0;
}
}
-
- /* Free name if not needed further. */
- if (name != fname && (name < fname || name > fname + strlen (fname)))
- free (name);
}
}
@@ -1863,15 +1854,16 @@ record_target_var (struct nameseq *filenames, char *defn,
that are not incorporated into other data structures. */
static void
-record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
- struct dep *deps, unsigned int cmds_started, char *commands,
+record_files (struct nameseq *filenames, const char *pattern,
+ const char *pattern_percent, struct dep *deps,
+ unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon,
const struct floc *flocp)
{
struct nameseq *nextf;
int implicit = 0;
unsigned int max_targets = 0, target_idx = 0;
- char **targets = 0, **target_percents = 0;
+ const char **targets = 0, **target_percents = 0;
struct commands *cmds;
/* If we've already snapped deps, that means we're in an eval being
@@ -1894,10 +1886,10 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
for (; filenames != 0; filenames = nextf)
{
- char *name = filenames->name;
+ const char *name = filenames->name;
struct file *f;
struct dep *this = 0;
- char *implicit_percent;
+ const char *implicit_percent;
nextf = filenames->next;
free (filenames);
@@ -1910,17 +1902,17 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
else if (streq (name, ".SECONDEXPANSION"))
second_expansion = 1;
- implicit_percent = find_percent (name);
+ implicit_percent = find_percent_cached (&name);
implicit |= implicit_percent != 0;
- if (implicit && pattern != 0)
- fatal (flocp, _("mixed implicit and static pattern rules"));
+ if (implicit)
+ {
+ if (pattern != 0)
+ fatal (flocp, _("mixed implicit and static pattern rules"));
- if (implicit && implicit_percent == 0)
- fatal (flocp, _("mixed implicit and normal rules"));
+ if (implicit_percent == 0)
+ fatal (flocp, _("mixed implicit and normal rules"));
- if (implicit)
- {
if (targets == 0)
{
max_targets = 5;
@@ -1960,7 +1952,7 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
{
/* Single-colon. Combine these dependencies
with others in file's existing record, if any. */
- f = enter_file (name);
+ f = enter_file (strcache_add (name));
if (f->double_colon)
fatal (flocp,
@@ -2066,7 +2058,7 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
if (f != 0 && f->is_target && !f->double_colon)
fatal (flocp,
_("target file `%s' has both : and :: entries"), f->name);
- f = enter_file (name);
+ f = enter_file (strcache_add (name));
/* If there was an existing entry and it was a double-colon entry,
enter_file will have returned a new one, making it the prev
pointer of the old one, and setting its double_colon pointer to
@@ -2085,25 +2077,19 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
commands. */
if (pattern)
{
- static char *percent = "%";
+ static const char *percent = "%";
char *buffer = variable_expand ("");
- char *o = patsubst_expand (buffer, name, pattern, percent,
- pattern_percent+1, percent+1);
- f->stem = savestring (buffer, o - buffer);
+ char *o = patsubst_expand_pat (buffer, name, pattern, percent,
+ pattern_percent+1, percent+1);
+ f->stem = strcache_add_len (buffer, o - buffer);
if (this)
{
this->staticpattern = 1;
- this->stem = xstrdup (f->stem);
+ this->stem = f->stem;
}
}
- /* Free name if not needed further. */
- if (f != 0 && name != f->name
- && (name < f->name || name > f->name + strlen (f->name)))
- {
- free (name);
- name = f->name;
- }
+ name = f->name;
/* If this target is a default target, update DEFAULT_GOAL_FILE. */
if (streq (*default_goal_name, name)
@@ -2114,12 +2100,10 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
if (implicit)
{
- targets[target_idx] = 0;
- target_percents[target_idx] = 0;
if (deps)
deps->need_2nd_expansion = second_expansion;
- create_pattern_rule (targets, target_percents, two_colon, deps, cmds, 1);
- free (target_percents);
+ create_pattern_rule (targets, target_percents, target_idx,
+ two_colon, deps, cmds, 1);
}
}
@@ -2137,7 +2121,7 @@ find_char_unquote (char *string, int stop1, int stop2, int blank,
int ignorevars)
{
unsigned int string_len = 0;
- register char *p = string;
+ char *p = string;
if (ignorevars)
ignorevars = '$';
@@ -2230,6 +2214,82 @@ find_percent (char *pattern)
{
return find_char_unquote (pattern, '%', 0, 0, 0);
}
+
+/* Search STRING for an unquoted % and handle quoting. Returns a pointer to
+ the % or NULL if no % was found.
+ This version is used with strings in the string cache: if there's a need to
+ modify the string a new version will be added to the string cache and
+ *STRING will be set to that. */
+
+const char *
+find_percent_cached (const char **string)
+{
+ const char *p = *string;
+ char *new = 0;
+ int slen;
+
+ /* If the first char is a % return now. This lets us avoid extra tests
+ inside the loop. */
+ if (*p == '%')
+ return p;
+
+ while (1)
+ {
+ while (*p != '\0' && *p != '%')
+ ++p;
+
+ if (*p == '\0')
+ break;
+
+ /* See if this % is escaped with a backslash; if not we're done. */
+ if (p[-1] != '\\')
+ break;
+
+ {
+ /* Search for more backslashes. */
+ char *pv;
+ int i = -2;
+
+ while (&p[i] >= *string && p[i] == '\\')
+ --i;
+ ++i;
+
+ /* At this point we know we'll need to allocate a new string.
+ Make a copy if we haven't yet done so. */
+ if (! new)
+ {
+ slen = strlen (*string);
+ new = alloca (slen + 1);
+ memcpy (new, *string, slen + 1);
+ p = new + (p - *string);
+ *string = new;
+ }
+
+ /* At this point *string, p, and new all point into the same string.
+ Get a non-const version of p so we can modify new. */
+ pv = new + (p - *string);
+
+ /* The number of backslashes is now -I.
+ Copy P over itself to swallow half of them. */
+ memmove (&pv[i], &pv[i/2], (slen - (pv - new)) - (i/2) + 1);
+ p += i/2;
+
+ /* If the backslashes quoted each other; the % was unquoted. */
+ if (i % 2 == 0)
+ break;
+ }
+ }
+
+ /* If we had to change STRING, add it to the strcache. */
+ if (new)
+ {
+ *string = strcache_add (*string);
+ p = *string + (p - new);
+ }
+
+ /* If we didn't find a %, return NULL. Otherwise return a ptr to it. */
+ return (*p == '\0') ? NULL : p;
+}
/* Parse a string into a sequence of filenames represented as a
chain of struct nameseq's in reverse order and return that chain.
@@ -2250,8 +2310,6 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
struct nameseq *new = 0;
struct nameseq *new1, *lastnew1;
char *p = *stringp;
- char *q;
- char *name;
#ifdef VMS
# define VMS_COMMA ','
@@ -2261,6 +2319,9 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
while (1)
{
+ const char *name;
+ char *q;
+
/* Skip whitespace; see if any more names are left. */
p = next_token (p);
if (*p == '\0')
@@ -2268,7 +2329,7 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
if (*p == stopchar)
break;
- /* Yes, find end of next name. */
+ /* There are, so find the end of the next name. */
q = p;
p = find_char_unquote (q, stopchar, VMS_COMMA, 1, 0);
#ifdef VMS
@@ -2280,9 +2341,7 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
if (stopchar == ':' && p && *p == ':'
&& !(isspace ((unsigned char)p[1]) || !p[1]
|| isspace ((unsigned char)p[-1])))
- {
p = find_char_unquote (p+1, stopchar, VMS_COMMA, 1, 0);
- }
#endif
#ifdef HAVE_DOS_PATHS
/* For DOS paths, skip a "C:\..." or a "C:/..." until we find the
@@ -2316,14 +2375,12 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
if (q == p)
/* ".///" was stripped to "". */
-#ifdef VMS
+#if defined(VMS)
continue;
+#elif defined(_AMIGA)
+ name = "";
#else
-#ifdef _AMIGA
- name = savestring ("", 0);
-#else
- name = savestring ("./", 2);
-#endif
+ name = "./";
#endif
else
#ifdef VMS
@@ -2347,11 +2404,11 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
}
*q2++ = *q1++;
}
- name = savestring (qbase, p1 - qbase);
+ name = strcache_add_len (qbase, p1 - qbase);
free (qbase);
}
#else
- name = savestring (q, p - q);
+ name = strcache_add_len (q, p - q);
#endif
/* Add it to the front of the chain. */
@@ -2407,7 +2464,6 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
/* N was just "lib(", part of something like "lib( a b)".
Edit it out of the chain and free its storage. */
lastn->next = n->next;
- free (n->name);
free (n);
/* LASTN->next is the new stopping elt for the loop below. */
n = lastn->next;
@@ -2415,9 +2471,7 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
else
{
/* Replace N's name with the full archive reference. */
- name = concat (libname, paren, ")");
- free (n->name);
- n->name = name;
+ n->name = strcache_add (concat (libname, paren, ")"));
}
if (new1->name[1] == '\0')
@@ -2430,15 +2484,12 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
lastnew1->next = new1->next;
lastn = new1;
new1 = new1->next;
- free (lastn->name);
free (lastn);
}
else
{
/* Replace also NEW1->name, which already has closing `)'. */
- name = concat (libname, new1->name, "");
- free (new1->name);
- new1->name = name;
+ new1->name = strcache_add (concat (libname, new1->name, ""));
new1 = new1->next;
}
@@ -2448,9 +2499,7 @@ parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
while (new1 != n)
{
- name = concat (libname, new1->name, ")");
- free (new1->name);
- new1->name = name;
+ new1->name = strcache_add (concat (libname, new1->name, ")"));
lastnew1 = new1;
new1 = new1->next;
}
@@ -2818,104 +2867,112 @@ get_next_mword (char *buffer, char *delim, char **startp, unsigned int *length)
from the arguments and the default list. */
void
-construct_include_path (char **arg_dirs)
+construct_include_path (const char **arg_dirs)
{
- register unsigned int i;
#ifdef VAXC /* just don't ask ... */
stat_t stbuf;
#else
struct stat stbuf;
#endif
- /* Table to hold the dirs. */
+ const char **dirs;
+ const char **cpp;
+ unsigned int idx;
- unsigned int defsize = (sizeof (default_include_directories)
- / sizeof (default_include_directories[0]));
- unsigned int max = 5;
- char **dirs = xmalloc ((5 + defsize) * sizeof (char *));
- unsigned int idx = 0;
+ /* Compute the number of pointers we need in the table. */
+ idx = sizeof (default_include_directories) / sizeof (const char *);
+ if (arg_dirs)
+ for (cpp = arg_dirs; *cpp != 0; ++cpp)
+ ++idx;
#ifdef __MSDOS__
- defsize++;
+ /* Add one for $DJDIR. */
+ ++idx;
#endif
+ dirs = xmalloc (idx * sizeof (const char *));
+
+ idx = 0;
+ max_incl_len = 0;
+
/* First consider any dirs specified with -I switches.
- Ignore dirs that don't exist. */
+ Ignore any that don't exist. Remember the maximum string length. */
- if (arg_dirs != 0)
+ if (arg_dirs)
while (*arg_dirs != 0)
{
- char *dir = *arg_dirs++;
+ const char *dir = *(arg_dirs++);
+ char *expanded = 0;
int e;
if (dir[0] == '~')
{
- char *expanded = tilde_expand (dir);
+ expanded = tilde_expand (dir);
if (expanded != 0)
dir = expanded;
}
EINTRLOOP (e, stat (dir, &stbuf));
if (e == 0 && S_ISDIR (stbuf.st_mode))
- {
- if (idx == max - 1)
- {
- max += 5;
- dirs = xrealloc (dirs, (max + defsize) * sizeof (char *));
- }
- dirs[idx++] = dir;
- }
- else if (dir != arg_dirs[-1])
- free (dir);
+ {
+ unsigned int len = strlen (dir);
+ /* If dir name is written with trailing slashes, discard them. */
+ while (len > 1 && dir[len - 1] == '/')
+ --len;
+ if (len > max_incl_len)
+ max_incl_len = len;
+ dirs[idx++] = strcache_add_len (dir, len);
+ }
+
+ if (expanded)
+ free (expanded);
}
- /* Now add at the end the standard default dirs. */
+ /* Now add the standard default dirs at the end. */
#ifdef __MSDOS__
{
- /* The environment variable $DJDIR holds the root of the
- DJGPP directory tree; add ${DJDIR}/include. */
+ /* The environment variable $DJDIR holds the root of the DJGPP directory
+ tree; add ${DJDIR}/include. */
struct variable *djdir = lookup_variable ("DJDIR", 5);
if (djdir)
{
- char *defdir = xmalloc (strlen (djdir->value) + 8 + 1);
+ unsigned int len = strlen (djdir->value) + 8;
+ char *defdir = alloca (len + 1);
strcat (strcpy (defdir, djdir->value), "/include");
- dirs[idx++] = defdir;
+ dirs[idx++] = strcache_add (defdir);
+
+ if (len > max_incl_len)
+ max_incl_len = len;
}
}
#endif
- for (i = 0; default_include_directories[i] != 0; ++i)
+ for (cpp = default_include_directories; *cpp != 0; ++cpp)
{
int e;
- EINTRLOOP (e, stat (default_include_directories[i], &stbuf));
+ EINTRLOOP (e, stat (*cpp, &stbuf));
if (e == 0 && S_ISDIR (stbuf.st_mode))
- dirs[idx++] = default_include_directories[i];
+ {
+ unsigned int len = strlen (*cpp);
+ /* If dir name is written with trailing slashes, discard them. */
+ while (len > 1 && (*cpp)[len - 1] == '/')
+ --len;
+ if (len > max_incl_len)
+ max_incl_len = len;
+ dirs[idx++] = strcache_add_len (*cpp, len - 1);
+ }
}
dirs[idx] = 0;
- /* Now compute the maximum length of any name in it. Also add each
- dir to the .INCLUDE_DIRS variable. */
+ /* Now add each dir to the .INCLUDE_DIRS variable. */
- max_incl_len = 0;
- for (i = 0; i < idx; ++i)
- {
- unsigned int len = strlen (dirs[i]);
- /* If dir name is written with a trailing slash, discard it. */
- if (dirs[i][len - 1] == '/')
- /* We can't just clobber a null in because it may have come from
- a literal string and literal strings may not be writable. */
- dirs[i] = savestring (dirs[i], len - 1);
- if (len > max_incl_len)
- max_incl_len = len;
-
- /* Append to .INCLUDE_DIRS. */
- do_variable_definition (NILF, ".INCLUDE_DIRS", dirs[i],
- o_default, f_append, 0);
- }
+ for (cpp = dirs; *cpp != 0; ++cpp)
+ do_variable_definition (NILF, ".INCLUDE_DIRS", *cpp,
+ o_default, f_append, 0);
include_directories = dirs;
}
@@ -2924,7 +2981,7 @@ construct_include_path (char **arg_dirs)
Return a newly malloc'd string or 0. */
char *
-tilde_expand (char *name)
+tilde_expand (const char *name)
{
#ifndef VMS
if (name[1] == '/' || name[1] == '\0')
@@ -2949,7 +3006,7 @@ tilde_expand (char *name)
free (home_dir);
home_dir = getenv ("HOME");
}
-#if !defined(_AMIGA) && !defined(WINDOWS32)
+# if !defined(_AMIGA) && !defined(WINDOWS32)
if (home_dir == 0 || home_dir[0] == '\0')
{
extern char *getlogin ();
@@ -2962,16 +3019,16 @@ tilde_expand (char *name)
home_dir = p->pw_dir;
}
}
-#endif /* !AMIGA && !WINDOWS32 */
+# endif /* !AMIGA && !WINDOWS32 */
if (home_dir != 0)
{
- char *new = concat (home_dir, "", name + 1);
+ char *new = xstrdup (concat (home_dir, "", name + 1));
if (is_variable)
free (home_dir);
return new;
}
}
-#if !defined(_AMIGA) && !defined(WINDOWS32)
+# if !defined(_AMIGA) && !defined(WINDOWS32)
else
{
struct passwd *pwent;
@@ -2984,12 +3041,12 @@ tilde_expand (char *name)
if (userend == 0)
return xstrdup (pwent->pw_dir);
else
- return concat (pwent->pw_dir, "/", userend + 1);
+ return xstrdup (concat (pwent->pw_dir, "/", userend + 1));
}
else if (userend != 0)
*userend = '/';
}
-#endif /* !AMIGA && !WINDOWS32 */
+# endif /* !AMIGA && !WINDOWS32 */
#endif /* !VMS */
return 0;
}
@@ -3007,9 +3064,9 @@ tilde_expand (char *name)
struct nameseq *
multi_glob (struct nameseq *chain, unsigned int size)
{
- extern void dir_setup_glob ();
- register struct nameseq *new = 0;
- register struct nameseq *old;
+ void dir_setup_glob (glob_t *);
+ struct nameseq *new = 0;
+ struct nameseq *old;
struct nameseq *nexto;
glob_t gl;
@@ -3017,44 +3074,37 @@ multi_glob (struct nameseq *chain, unsigned int size)
for (old = chain; old != 0; old = nexto)
{
+ const char *gname;
#ifndef NO_ARCHIVES
- char *memname;
+ char *arname = 0;
+ char *memname = 0;
#endif
-
nexto = old->next;
+ gname = old->name;
- if (old->name[0] == '~')
+ if (gname[0] == '~')
{
char *newname = tilde_expand (old->name);
if (newname != 0)
- {
- free (old->name);
- old->name = newname;
- }
+ gname = newname;
}
#ifndef NO_ARCHIVES
- if (ar_name (old->name))
+ if (ar_name (gname))
{
- /* OLD->name is an archive member reference.
- Replace it with the archive file name,
- and save the member name in MEMNAME.
- We will glob on the archive name and then
- reattach MEMNAME later. */
- char *arname;
- ar_parse_name (old->name, &arname, &memname);
- free (old->name);
- old->name = arname;
+ /* OLD->name is an archive member reference. Replace it with the
+ archive file name, and save the member name in MEMNAME. We will
+ glob on the archive name and then reattach MEMNAME later. */
+ ar_parse_name (gname, &arname, &memname);
+ gname = arname;
}
- else
- memname = 0;
#endif /* !NO_ARCHIVES */
- switch (glob (old->name, GLOB_NOCHECK|GLOB_ALTDIRFUNC, NULL, &gl))
+ switch (glob (gname, GLOB_NOCHECK|GLOB_ALTDIRFUNC, NULL, &gl))
{
case 0: /* Success. */
{
- register int i = gl.gl_pathc;
+ int i = gl.gl_pathc;
while (i-- > 0)
{
#ifndef NO_ARCHIVES
@@ -3063,21 +3113,22 @@ multi_glob (struct nameseq *chain, unsigned int size)
/* Try to glob on MEMNAME within the archive. */
struct nameseq *found
= ar_glob (gl.gl_pathv[i], memname, size);
- if (found == 0)
+ if (! found)
{
/* No matches. Use MEMNAME as-is. */
unsigned int alen = strlen (gl.gl_pathv[i]);
unsigned int mlen = strlen (memname);
+ char *name;
struct nameseq *elt = xmalloc (size);
- if (size > sizeof (struct nameseq))
- memset (((char *)elt)+sizeof (struct nameseq), '\0',
- size - sizeof (struct nameseq));
- elt->name = xmalloc (alen + 1 + mlen + 2);
- memcpy (elt->name, gl.gl_pathv[i], alen);
- elt->name[alen] = '(';
- memcpy (&elt->name[alen + 1], memname, mlen);
- elt->name[alen + 1 + mlen] = ')';
- elt->name[alen + 1 + mlen + 1] = '\0';
+ memset (elt, '\0', size);
+
+ name = alloca (alen + 1 + mlen + 2);
+ memcpy (name, gl.gl_pathv[i], alen);
+ name[alen] = '(';
+ memcpy (name+alen+1, memname, mlen);
+ name[alen + 1 + mlen] = ')';
+ name[alen + 1 + mlen + 1] = '\0';
+ elt->name = strcache_add (name);
elt->next = new;
new = elt;
}
@@ -3093,23 +3144,18 @@ multi_glob (struct nameseq *chain, unsigned int size)
f->next = new;
new = found;
}
-
- free (memname);
}
else
#endif /* !NO_ARCHIVES */
{
struct nameseq *elt = xmalloc (size);
- if (size > sizeof (struct nameseq))
- memset (((char *)elt)+sizeof (struct nameseq), '\0',
- size - sizeof (struct nameseq));
- elt->name = xstrdup (gl.gl_pathv[i]);
+ memset (elt, '\0', size);
+ elt->name = strcache_add (gl.gl_pathv[i]);
elt->next = new;
new = elt;
}
}
globfree (&gl);
- free (old->name);
free (old);
break;
}
@@ -3123,6 +3169,11 @@ multi_glob (struct nameseq *chain, unsigned int size)
new = old;
break;
}
+
+#ifndef NO_ARCHIVES
+ if (arname)
+ free (arname);
+#endif
}
return new;