1 /* Dependency generator for Makefile fragments.
2 Copyright (C) 2000, 2001, 2003, 2007, 2008, 2009
3 Free Software Foundation, Inc.
4 Contributed by Zack Weinberg, Mar 2000
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding! */
28 /* Keep this structure local to this file, so clients don't find it
29 easy to start making assumptions. */
33 unsigned int ntargets
; /* number of slots actually occupied */
34 unsigned int targets_size
; /* amt of allocated space - in words */
38 unsigned int deps_size
;
43 unsigned int vpaths_size
;
46 static const char *munge (const char *);
48 /* Given a filename, quote characters in that filename which are
49 significant to Make. Note that it's not possible to quote all such
50 characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
51 not properly handled. It isn't possible to get this right in any
52 current version of Make. (??? Still true? Old comment referred to
56 munge (const char *filename
)
62 for (p
= filename
, len
= 0; *p
; p
++, len
++)
68 /* GNU make uses a weird quoting scheme for white space.
69 A space or tab preceded by 2N+1 backslashes represents
70 N backslashes followed by space; a space or tab
71 preceded by 2N backslashes represents N backslashes at
72 the end of a file name; and backslashes in other
73 contexts should not be doubled. */
74 for (q
= p
- 1; filename
<= q
&& *q
== '\\'; q
--)
80 /* '$' is quoted by doubling it. */
85 /* '#' is quoted with a backslash. */
91 /* Now we know how big to make the buffer. */
92 buffer
= XNEWVEC (char, len
+ 1);
94 for (p
= filename
, dst
= buffer
; *p
; p
++, dst
++)
100 for (q
= p
- 1; filename
<= q
&& *q
== '\\'; q
--)
123 /* If T begins with any of the partial pathnames listed in d->vpathv,
124 then advance T to point beyond that pathname. */
126 apply_vpath (struct deps
*d
, const char *t
)
131 for (i
= 0; i
< d
->nvpaths
; i
++)
133 if (!filename_ncmp (d
->vpathv
[i
], t
, d
->vpathlv
[i
]))
135 const char *p
= t
+ d
->vpathlv
[i
];
136 if (!IS_DIR_SEPARATOR (*p
))
139 /* Do not simplify $(vpath)/../whatever. ??? Might not
141 if (p
[1] == '.' && p
[2] == '.' && IS_DIR_SEPARATOR (p
[3]))
145 t
= t
+ d
->vpathlv
[i
] + 1;
152 /* Remove leading ./ in any case. */
153 while (t
[0] == '.' && IS_DIR_SEPARATOR (t
[1]))
156 /* If we removed a leading ./, then also remove any /s after the
158 while (IS_DIR_SEPARATOR (t
[0]))
165 /* Public routines. */
170 return XCNEW (struct deps
);
174 deps_free (struct deps
*d
)
180 for (i
= 0; i
< d
->ntargets
; i
++)
181 free ((void *) d
->targetv
[i
]);
187 for (i
= 0; i
< d
->ndeps
; i
++)
188 free ((void *) d
->depv
[i
]);
194 for (i
= 0; i
< d
->nvpaths
; i
++)
195 free ((void *) d
->vpathv
[i
]);
203 /* Adds a target T. We make a copy, so it need not be a permanent
204 string. QUOTE is true if the string should be quoted. */
206 deps_add_target (struct deps
*d
, const char *t
, int quote
)
208 if (d
->ntargets
== d
->targets_size
)
210 d
->targets_size
= d
->targets_size
* 2 + 4;
211 d
->targetv
= XRESIZEVEC (const char *, d
->targetv
, d
->targets_size
);
214 t
= apply_vpath (d
, t
);
216 t
= munge (t
); /* Also makes permanent copy. */
220 d
->targetv
[d
->ntargets
++] = t
;
223 /* Sets the default target if none has been given already. An empty
224 string as the default target in interpreted as stdin. The string
225 is quoted for MAKE. */
227 deps_add_default_target (struct deps
*d
, const char *tgt
)
229 /* Only if we have no targets. */
234 deps_add_target (d
, "-", 1);
237 #ifndef TARGET_OBJECT_SUFFIX
238 # define TARGET_OBJECT_SUFFIX ".o"
240 const char *start
= lbasename (tgt
);
241 char *o
= (char *) alloca (strlen (start
)
242 + strlen (TARGET_OBJECT_SUFFIX
) + 1);
247 suffix
= strrchr (o
, '.');
249 suffix
= o
+ strlen (o
);
250 strcpy (suffix
, TARGET_OBJECT_SUFFIX
);
252 deps_add_target (d
, o
, 1);
257 deps_add_dep (struct deps
*d
, const char *t
)
259 t
= munge (apply_vpath (d
, t
)); /* Also makes permanent copy. */
261 if (d
->ndeps
== d
->deps_size
)
263 d
->deps_size
= d
->deps_size
* 2 + 8;
264 d
->depv
= XRESIZEVEC (const char *, d
->depv
, d
->deps_size
);
266 d
->depv
[d
->ndeps
++] = t
;
270 deps_add_vpath (struct deps
*d
, const char *vpath
)
272 const char *elem
, *p
;
276 for (elem
= vpath
; *elem
; elem
= p
)
278 for (p
= elem
; *p
&& *p
!= ':'; p
++);
280 copy
= XNEWVEC (char, len
+ 1);
281 memcpy (copy
, elem
, len
);
286 if (d
->nvpaths
== d
->vpaths_size
)
288 d
->vpaths_size
= d
->vpaths_size
* 2 + 8;
289 d
->vpathv
= XRESIZEVEC (const char *, d
->vpathv
, d
->vpaths_size
);
290 d
->vpathlv
= XRESIZEVEC (size_t, d
->vpathlv
, d
->vpaths_size
);
292 d
->vpathv
[d
->nvpaths
] = copy
;
293 d
->vpathlv
[d
->nvpaths
] = len
;
299 deps_write (const struct deps
*d
, FILE *fp
, unsigned int colmax
)
301 unsigned int size
, i
, column
;
304 if (colmax
&& colmax
< 34)
307 for (i
= 0; i
< d
->ntargets
; i
++)
309 size
= strlen (d
->targetv
[i
]);
313 if (colmax
&& column
> colmax
)
315 fputs (" \\\n ", fp
);
324 fputs (d
->targetv
[i
], fp
);
330 for (i
= 0; i
< d
->ndeps
; i
++)
332 size
= strlen (d
->depv
[i
]);
334 if (colmax
&& column
> colmax
)
336 fputs (" \\\n ", fp
);
344 fputs (d
->depv
[i
], fp
);
350 deps_phony_targets (const struct deps
*d
, FILE *fp
)
354 for (i
= 1; i
< d
->ndeps
; i
++)
357 fputs (d
->depv
[i
], fp
);
363 /* Write out a deps buffer to a file, in a form that can be read back
364 with deps_restore. Returns nonzero on error, in which case the
365 error number will be in errno. */
368 deps_save (struct deps
*deps
, FILE *f
)
372 /* The cppreader structure contains makefile dependences. Write out this
375 /* The number of dependences. */
376 if (fwrite (&deps
->ndeps
, sizeof (deps
->ndeps
), 1, f
) != 1)
378 /* The length of each dependence followed by the string. */
379 for (i
= 0; i
< deps
->ndeps
; i
++)
381 size_t num_to_write
= strlen (deps
->depv
[i
]);
382 if (fwrite (&num_to_write
, sizeof (size_t), 1, f
) != 1)
384 if (fwrite (deps
->depv
[i
], num_to_write
, 1, f
) != 1)
391 /* Read back dependency information written with deps_save into
392 the deps buffer. The third argument may be NULL, in which case
393 the dependency information is just skipped, or it may be a filename,
394 in which case that filename is skipped. */
397 deps_restore (struct deps
*deps
, FILE *fd
, const char *self
)
399 unsigned int i
, count
;
401 size_t buf_size
= 512;
402 char *buf
= XNEWVEC (char, buf_size
);
404 /* Number of dependences. */
405 if (fread (&count
, 1, sizeof (count
), fd
) != sizeof (count
))
408 /* The length of each dependence string, followed by the string. */
409 for (i
= 0; i
< count
; i
++)
411 /* Read in # bytes in string. */
412 if (fread (&num_to_read
, 1, sizeof (size_t), fd
) != sizeof (size_t))
414 if (buf_size
< num_to_read
+ 1)
416 buf_size
= num_to_read
+ 1 + 127;
417 buf
= XRESIZEVEC (char, buf
, buf_size
);
419 if (fread (buf
, 1, num_to_read
, fd
) != num_to_read
)
421 buf
[num_to_read
] = '\0';
423 /* Generate makefile dependencies from .pch if -nopch-deps. */
424 if (self
!= NULL
&& filename_cmp (buf
, self
) != 0)
425 deps_add_dep (deps
, buf
);