/* Dependency generator for Makefile fragments.
- Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003, 2007, 2008, 2009
+ Free Software Foundation, Inc.
Contributed by Zack Weinberg, Mar 2000
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+along with this program; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
const char **depv;
unsigned int ndeps;
unsigned int deps_size;
+
+ const char **vpathv;
+ size_t *vpathlv;
+ unsigned int nvpaths;
+ unsigned int vpaths_size;
};
static const char *munge (const char *);
/* '$' is quoted by doubling it. */
len++;
break;
+
+ case '#':
+ /* '#' is quoted with a backslash. */
+ len++;
+ break;
}
}
/* Now we know how big to make the buffer. */
- buffer = xmalloc (len + 1);
+ buffer = XNEWVEC (char, len + 1);
for (p = filename, dst = buffer; *p; p++, dst++)
{
*dst++ = '$';
break;
+ case '#':
+ *dst++ = '\\';
+ break;
+
default:
/* nothing */;
}
return buffer;
}
-/* Public routines. */
-
-struct deps *
-deps_init (void)
+/* If T begins with any of the partial pathnames listed in d->vpathv,
+ then advance T to point beyond that pathname. */
+static const char *
+apply_vpath (struct deps *d, const char *t)
{
- struct deps *d = xmalloc (sizeof (struct deps));
+ if (d->vpathv)
+ {
+ unsigned int i;
+ for (i = 0; i < d->nvpaths; i++)
+ {
+ if (!filename_ncmp (d->vpathv[i], t, d->vpathlv[i]))
+ {
+ const char *p = t + d->vpathlv[i];
+ if (!IS_DIR_SEPARATOR (*p))
+ goto not_this_one;
+
+ /* Do not simplify $(vpath)/../whatever. ??? Might not
+ be necessary. */
+ if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3]))
+ goto not_this_one;
+
+ /* found a match */
+ t = t + d->vpathlv[i] + 1;
+ break;
+ }
+ not_this_one:;
+ }
+ }
- /* Allocate space for the vectors only if we need it. */
+ /* Remove leading ./ in any case. */
+ while (t[0] == '.' && IS_DIR_SEPARATOR (t[1]))
+ {
+ t += 2;
+ /* If we removed a leading ./, then also remove any /s after the
+ first. */
+ while (IS_DIR_SEPARATOR (t[0]))
+ ++t;
+ }
- d->targetv = 0;
- d->depv = 0;
+ return t;
+}
- d->ntargets = 0;
- d->targets_size = 0;
- d->ndeps = 0;
- d->deps_size = 0;
+/* Public routines. */
- return d;
+struct deps *
+deps_init (void)
+{
+ return XCNEW (struct deps);
}
void
free (d->depv);
}
+ if (d->vpathv)
+ {
+ for (i = 0; i < d->nvpaths; i++)
+ free ((void *) d->vpathv[i]);
+ free (d->vpathv);
+ free (d->vpathlv);
+ }
+
free (d);
}
if (d->ntargets == d->targets_size)
{
d->targets_size = d->targets_size * 2 + 4;
- d->targetv = xrealloc (d->targetv,
- d->targets_size * sizeof (const char *));
+ d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size);
}
+ t = apply_vpath (d, t);
if (quote)
t = munge (t); /* Also makes permanent copy. */
else
# define TARGET_OBJECT_SUFFIX ".o"
#endif
const char *start = lbasename (tgt);
- char *o = alloca (strlen (start) + strlen (TARGET_OBJECT_SUFFIX) + 1);
+ char *o = (char *) alloca (strlen (start)
+ + strlen (TARGET_OBJECT_SUFFIX) + 1);
char *suffix;
strcpy (o, start);
void
deps_add_dep (struct deps *d, const char *t)
{
- t = munge (t); /* Also makes permanent copy. */
+ t = munge (apply_vpath (d, t)); /* Also makes permanent copy. */
if (d->ndeps == d->deps_size)
{
d->deps_size = d->deps_size * 2 + 8;
- d->depv = xrealloc (d->depv, d->deps_size * sizeof (const char *));
+ d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size);
}
d->depv[d->ndeps++] = t;
}
void
+deps_add_vpath (struct deps *d, const char *vpath)
+{
+ const char *elem, *p;
+ char *copy;
+ size_t len;
+
+ for (elem = vpath; *elem; elem = p)
+ {
+ for (p = elem; *p && *p != ':'; p++);
+ len = p - elem;
+ copy = XNEWVEC (char, len + 1);
+ memcpy (copy, elem, len);
+ copy[len] = '\0';
+ if (*p == ':')
+ p++;
+
+ if (d->nvpaths == d->vpaths_size)
+ {
+ d->vpaths_size = d->vpaths_size * 2 + 8;
+ d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size);
+ d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size);
+ }
+ d->vpathv[d->nvpaths] = copy;
+ d->vpathlv[d->nvpaths] = len;
+ d->nvpaths++;
+ }
+}
+
+void
deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
{
unsigned int size, i, column;
{
size = strlen (d->targetv[i]);
column += size;
- if (colmax && column > colmax)
- {
- fputs (" \\\n ", fp);
- column = 1 + size;
- }
if (i)
{
- putc (' ', fp);
- column++;
+ if (colmax && column > colmax)
+ {
+ fputs (" \\\n ", fp);
+ column = 1 + size;
+ }
+ else
+ {
+ putc (' ', fp);
+ column++;
+ }
}
fputs (d->targetv[i], fp);
}
putc (':', fp);
- putc (' ', fp);
- column += 2;
+ column++;
for (i = 0; i < d->ndeps; i++)
{
fputs (" \\\n ", fp);
column = 1 + size;
}
- if (i)
+ else
{
putc (' ', fp);
column++;
unsigned int i, count;
size_t num_to_read;
size_t buf_size = 512;
- char *buf = xmalloc (buf_size);
+ char *buf = XNEWVEC (char, buf_size);
/* Number of dependences. */
if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
if (buf_size < num_to_read + 1)
{
buf_size = num_to_read + 1 + 127;
- buf = xrealloc (buf, buf_size);
+ buf = XRESIZEVEC (char, buf, buf_size);
}
if (fread (buf, 1, num_to_read, fd) != num_to_read)
return -1;
buf[num_to_read] = '\0';
/* Generate makefile dependencies from .pch if -nopch-deps. */
- if (self != NULL && strcmp (buf, self) != 0)
+ if (self != NULL && filename_cmp (buf, self) != 0)
deps_add_dep (deps, buf);
}