1 /* Dependency generator for Makefile fragments.
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Zack Weinberg, Mar 2000
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 In other words, you are welcome to use, share and improve this program.
20 You are forbidden to forbid anyone else to use, share and improve
21 what you give them. Help stamp out software-hoarding! */
27 /* Keep this structure local to this file, so clients don't find it
28 easy to start making assumptions. */
32 unsigned int ntargets; /* number of slots actually occupied */
33 unsigned int targets_size; /* amt of allocated space - in words */
37 unsigned int deps_size;
40 static const char *munge PARAMS ((const char *));
41 static const char *base_name PARAMS ((const char *));
43 /* Given a filename, quote characters in that filename which are
44 significant to Make. Note that it's not possible to quote all such
45 characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
46 not properly handled. It isn't possible to get this right in any
47 current version of Make. (??? Still true? Old comment referred to
58 for (p = filename, len = 0; *p; p++, len++)
64 /* GNU make uses a weird quoting scheme for white space.
65 A space or tab preceded by 2N+1 backslashes represents
66 N backslashes followed by space; a space or tab
67 preceded by 2N backslashes represents N backslashes at
68 the end of a file name; and backslashes in other
69 contexts should not be doubled. */
70 for (q = p - 1; filename <= q && *q == '\\'; q--)
76 /* '$' is quoted by doubling it. This can mishandle things
77 like "$(" but there's no easy fix. */
83 /* Now we know how big to make the buffer. */
84 buffer = xmalloc (len + 1);
86 for (p = filename, dst = buffer; *p; p++, dst++)
92 for (q = p - 1; filename <= q && *q == '\\'; q--)
111 /* Given a pathname, calculate the non-directory part. This always
112 knows how to handle Unix-style pathnames, and understands VMS and
113 DOS paths on those systems. */
115 /* Find the base name of a (partial) pathname FNAME.
116 Returns a pointer into the string passed in.
117 Accepts Unix (/-separated) paths on all systems,
118 DOS and VMS paths on those systems. */
124 const char *s = fname;
126 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
127 if (ISALPHA (s[0]) && s[1] == ':') s += 2;
128 if ((p = strrchr (s, '\\'))) s = p + 1;
130 if ((p = strrchr (s, ':'))) s = p + 1; /* Skip device. */
131 if ((p = strrchr (s, ']'))) s = p + 1; /* Skip directory. */
132 if ((p = strrchr (s, '>'))) s = p + 1; /* Skip alternate (int'n'l) dir. */
134 if ((p = strrchr (s, '/'))) s = p + 1;
138 /* Public routines. */
143 struct deps *d = (struct deps *) xmalloc (sizeof (struct deps));
145 /* Allocate space for the vectors now. */
147 d->targetv = (const char **) xmalloc (2 * sizeof (const char *));
148 d->depv = (const char **) xmalloc (8 * sizeof (const char *));
164 for (i = 0; i < d->ntargets; i++)
165 free ((PTR) d->targetv[i]);
167 for (i = 0; i < d->ndeps; i++)
168 free ((PTR) d->depv[i]);
176 deps_add_target (d, t)
180 t = munge (t); /* Also makes permanent copy. */
182 if (d->ntargets == d->targets_size)
184 d->targets_size *= 2;
185 d->targetv = (const char **) xrealloc (d->targetv,
186 d->targets_size * sizeof (const char *));
189 d->targetv[d->ntargets++] = t;
192 /* Sets the default target if none has been given already. An empty
193 string as the default target in interpreted as stdin. */
195 deps_add_default_target (d, tgt)
201 /* Only if we have no targets. */
206 deps_add_target (d, "-");
209 tgt = base_name (tgt);
210 o = (char *) alloca (strlen (tgt) + 8);
213 suffix = strrchr (o, '.');
215 #ifndef OBJECT_SUFFIX
216 # define OBJECT_SUFFIX ".o"
220 strcpy (suffix, OBJECT_SUFFIX);
222 strcat (o, OBJECT_SUFFIX);
223 deps_add_target (d, o);
232 t = munge (t); /* Also makes permanent copy. */
234 if (d->ndeps == d->deps_size)
237 d->depv = (const char **)
238 xrealloc (d->depv, d->deps_size * sizeof (const char *));
240 d->depv[d->ndeps++] = t;
244 deps_write (d, fp, colmax)
245 const struct deps *d;
249 unsigned int size, i, column;
252 if (colmax && colmax < 34)
255 for (i = 0; i < d->ntargets; i++)
257 size = strlen (d->targetv[i]);
259 if (colmax && column > colmax)
261 fputs (" \\\n ", fp);
269 fputs (d->targetv[i], fp);
276 for (i = 0; i < d->ndeps; i++)
278 size = strlen (d->depv[i]);
280 if (colmax && column > colmax)
282 fputs (" \\\n ", fp);
290 fputs (d->depv[i], fp);
296 deps_dummy_targets (d, fp)
297 const struct deps *d;
302 for (i = 1; i < d->ndeps; i++)
304 fputs (d->depv[i], fp);