]> git.ipfire.org Git - thirdparty/gcc.git/blame - libcpp/mkdeps.cc
Update copyright years.
[thirdparty/gcc.git] / libcpp / mkdeps.cc
CommitLineData
49e6c08e 1/* Dependency generator for Makefile fragments.
a945c346 2 Copyright (C) 2000-2024 Free Software Foundation, Inc.
49e6c08e
ZW
3 Contributed by Zack Weinberg, Mar 2000
4
5This program is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
748086b7 7Free Software Foundation; either version 3, or (at your option) any
49e6c08e
ZW
8later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
748086b7
JJ
16along with this program; see the file COPYING3. If not see
17<http://www.gnu.org/licenses/>.
49e6c08e
ZW
18
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! */
22
23#include "config.h"
24#include "system.h"
25#include "mkdeps.h"
918e8b10 26#include "internal.h"
49e6c08e 27
d7b6aee8
NS
28/* Not set up to just include std::vector et al, here's a simple
29 implementation. */
30
03b9ab42
NB
31/* Keep this structure local to this file, so clients don't find it
32 easy to start making assumptions. */
6c1dae73 33class mkdeps
03b9ab42 34{
d7b6aee8
NS
35public:
36 /* T has trivial cctor & dtor. */
37 template <typename T>
38 class vec
39 {
40 private:
41 T *ary;
42 unsigned num;
43 unsigned alloc;
44
45 public:
46 vec ()
47 : ary (NULL), num (0), alloc (0)
48 {}
49 ~vec ()
50 {
51 XDELETEVEC (ary);
52 }
53
54 public:
55 unsigned size () const
49e6c08e 56 {
d7b6aee8 57 return num;
49e6c08e 58 }
d7b6aee8 59 const T &operator[] (unsigned ix) const
49e6c08e 60 {
d7b6aee8
NS
61 return ary[ix];
62 }
66d7749b
NS
63 T &operator[] (unsigned ix)
64 {
65 return ary[ix];
66 }
d7b6aee8
NS
67 void push (const T &elt)
68 {
69 if (num == alloc)
49e6c08e 70 {
d7b6aee8
NS
71 alloc = alloc ? alloc * 2 : 16;
72 ary = XRESIZEVEC (T, ary, alloc);
49e6c08e 73 }
d7b6aee8 74 ary[num++] = elt;
49e6c08e 75 }
d7b6aee8
NS
76 };
77 struct velt
78 {
79 const char *str;
80 size_t len;
81 };
82
83 mkdeps ()
024f135a
BB
84 : primary_output (NULL), module_name (NULL), cmi_name (NULL)
85 , is_header_unit (false), is_exported (false), quote_lwm (0)
d7b6aee8
NS
86 {
87 }
88 ~mkdeps ()
89 {
90 unsigned int i;
91
92 for (i = targets.size (); i--;)
93 free (const_cast <char *> (targets[i]));
024f135a
BB
94 free (const_cast <char *> (primary_output));
95 for (i = fdeps_targets.size (); i--;)
96 free (const_cast <char *> (fdeps_targets[i]));
d7b6aee8
NS
97 for (i = deps.size (); i--;)
98 free (const_cast <char *> (deps[i]));
99 for (i = vpath.size (); i--;)
100 XDELETEVEC (vpath[i].str);
db87f19a
NS
101 for (i = modules.size (); i--;)
102 XDELETEVEC (modules[i]);
103 XDELETEVEC (module_name);
104 free (const_cast <char *> (cmi_name));
d7b6aee8
NS
105 }
106
107public:
108 vec<const char *> targets;
109 vec<const char *> deps;
024f135a
BB
110 const char * primary_output;
111 vec<const char *> fdeps_targets;
d7b6aee8 112 vec<velt> vpath;
db87f19a 113 vec<const char *> modules;
d7b6aee8
NS
114
115public:
db87f19a
NS
116 const char *module_name;
117 const char *cmi_name;
118 bool is_header_unit;
024f135a 119 bool is_exported;
d7b6aee8
NS
120 unsigned short quote_lwm;
121};
49e6c08e 122
d7ab349c
NS
123/* Apply Make quoting to STR, TRAIL. Note that it's not possible to
124 quote all such characters - e.g. \n, %, *, ?, [, \ (in some
d7b6aee8
NS
125 contexts), and ~ are not properly handled. It isn't possible to
126 get this right in any current version of Make. (??? Still true?
127 Old comment referred to 3.76.1.) */
49e6c08e 128
c6e83800 129static const char *
d7ab349c 130munge (const char *str, const char *trail = nullptr)
49e6c08e 131{
d7b6aee8
NS
132 static unsigned alloc;
133 static char *buf;
134 unsigned dst = 0;
d7b6aee8 135
d7ab349c 136 for (; str; str = trail, trail = nullptr)
c6e83800 137 {
d7b6aee8
NS
138 unsigned slashes = 0;
139 char c;
140 for (const char *probe = str; (c = *probe++);)
c6e83800 141 {
d7b6aee8 142 if (alloc < dst + 4 + slashes)
c6e83800 143 {
d7b6aee8
NS
144 alloc = alloc * 2 + 32;
145 buf = XRESIZEVEC (char, buf, alloc);
146 }
c6e83800 147
d7b6aee8
NS
148 switch (c)
149 {
150 case '\\':
151 slashes++;
152 break;
c6e83800 153
d7b6aee8
NS
154 case '$':
155 buf[dst++] = '$';
156 goto def;
157
158 case ' ':
159 case '\t':
160 /* GNU make uses a weird quoting scheme for white space.
161 A space or tab preceded by 2N+1 backslashes
162 represents N backslashes followed by space; a space
163 or tab preceded by 2N backslashes represents N
164 backslashes at the end of a file name; and
165 backslashes in other contexts should not be
166 doubled. */
167 while (slashes--)
168 buf[dst++] = '\\';
169 /* FALLTHROUGH */
170
171 case '#':
d7b6aee8
NS
172 buf[dst++] = '\\';
173 /* FALLTHROUGH */
174
175 default:
176 def:
177 slashes = 0;
c6e83800
ZW
178 break;
179 }
d7b6aee8
NS
180
181 buf[dst++] = c;
c6e83800
ZW
182 }
183 }
d7b6aee8
NS
184
185 buf[dst] = 0;
186 return buf;
187}
188
189/* If T begins with any of the partial pathnames listed in d->vpathv,
190 then advance T to point beyond that pathname. */
191static const char *
99b1c316 192apply_vpath (class mkdeps *d, const char *t)
d7b6aee8
NS
193{
194 if (unsigned len = d->vpath.size ())
195 for (unsigned i = len; i--;)
196 {
197 if (!filename_ncmp (d->vpath[i].str, t, d->vpath[i].len))
198 {
199 const char *p = t + d->vpath[i].len;
200 if (!IS_DIR_SEPARATOR (*p))
201 goto not_this_one;
202
203 /* Do not simplify $(vpath)/../whatever. ??? Might not
204 be necessary. */
205 if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3]))
206 goto not_this_one;
207
208 /* found a match */
209 t = t + d->vpath[i].len + 1;
210 break;
211 }
212 not_this_one:;
213 }
49e6c08e 214
c6e83800
ZW
215 /* Remove leading ./ in any case. */
216 while (t[0] == '.' && IS_DIR_SEPARATOR (t[1]))
67e64439
TT
217 {
218 t += 2;
219 /* If we removed a leading ./, then also remove any /s after the
220 first. */
221 while (IS_DIR_SEPARATOR (t[0]))
222 ++t;
223 }
49e6c08e 224
c6e83800
ZW
225 return t;
226}
49e6c08e 227
c6e83800 228/* Public routines. */
49e6c08e 229
99b1c316 230class mkdeps *
c6e83800
ZW
231deps_init (void)
232{
d7b6aee8 233 return new mkdeps ();
49e6c08e
ZW
234}
235
236void
99b1c316 237deps_free (class mkdeps *d)
49e6c08e 238{
d7b6aee8 239 delete d;
49e6c08e
ZW
240}
241
a5a4ce3c
NB
242/* Adds a target T. We make a copy, so it need not be a permanent
243 string. QUOTE is true if the string should be quoted. */
49e6c08e 244void
99b1c316 245deps_add_target (class mkdeps *d, const char *t, int quote)
49e6c08e 246{
66d7749b
NS
247 t = xstrdup (apply_vpath (d, t));
248
d7b6aee8 249 if (!quote)
49e6c08e 250 {
66d7749b
NS
251 /* Sometimes unquoted items are added after quoted ones.
252 Swap out the lowest quoted. */
253 if (d->quote_lwm != d->targets.size ())
254 {
255 const char *lowest = d->targets[d->quote_lwm];
256 d->targets[d->quote_lwm] = t;
257 t = lowest;
258 }
d7b6aee8 259 d->quote_lwm++;
49e6c08e 260 }
05bccae2 261
66d7749b 262 d->targets.push (t);
49e6c08e
ZW
263}
264
03b9ab42 265/* Sets the default target if none has been given already. An empty
a5a4ce3c
NB
266 string as the default target in interpreted as stdin. The string
267 is quoted for MAKE. */
49e6c08e 268void
99b1c316 269deps_add_default_target (class mkdeps *d, const char *tgt)
49e6c08e 270{
03b9ab42 271 /* Only if we have no targets. */
d7b6aee8 272 if (d->targets.size ())
03b9ab42 273 return;
49e6c08e 274
03b9ab42 275 if (tgt[0] == '\0')
3b5757ea 276 d->targets.push (xstrdup ("-"));
49e6c08e 277 else
03b9ab42 278 {
45936a85
DD
279#ifndef TARGET_OBJECT_SUFFIX
280# define TARGET_OBJECT_SUFFIX ".o"
03b9ab42 281#endif
0821bff7 282 const char *start = lbasename (tgt);
c3f829c1
GDR
283 char *o = (char *) alloca (strlen (start)
284 + strlen (TARGET_OBJECT_SUFFIX) + 1);
48ce6bbb 285 char *suffix;
03b9ab42 286
48ce6bbb 287 strcpy (o, start);
0c20a65f 288
48ce6bbb
NS
289 suffix = strrchr (o, '.');
290 if (!suffix)
291 suffix = o + strlen (o);
45936a85 292 strcpy (suffix, TARGET_OBJECT_SUFFIX);
0c20a65f 293
a5a4ce3c 294 deps_add_target (d, o, 1);
03b9ab42 295 }
49e6c08e
ZW
296}
297
024f135a
BB
298/* Adds a target O. We make a copy, so it need not be a permanent
299 string.
300
301 This is the target associated with the rule that (in a C++ modules build)
302 compiles the source that is being scanned for dynamic dependencies. It is
303 used to associate the structured dependency information with that rule as
304 needed. */
305void
306fdeps_add_target (struct mkdeps *d, const char *o, bool is_primary)
307{
308 o = apply_vpath (d, o);
309 if (is_primary)
310 {
311 if (d->primary_output)
312 d->fdeps_targets.push (d->primary_output);
313 d->primary_output = xstrdup (o);
314 } else
315 d->fdeps_targets.push (xstrdup (o));
316}
317
49e6c08e 318void
99b1c316 319deps_add_dep (class mkdeps *d, const char *t)
49e6c08e 320{
61145d93
NS
321 gcc_assert (*t);
322
d7b6aee8 323 t = apply_vpath (d, t);
49e6c08e 324
d7b6aee8 325 d->deps.push (xstrdup (t));
49e6c08e
ZW
326}
327
c6e83800 328void
99b1c316 329deps_add_vpath (class mkdeps *d, const char *vpath)
c6e83800
ZW
330{
331 const char *elem, *p;
c6e83800
ZW
332
333 for (elem = vpath; *elem; elem = p)
334 {
d7b6aee8
NS
335 for (p = elem; *p && *p != ':'; p++)
336 continue;
337 mkdeps::velt elt;
338 elt.len = p - elem;
339 char *str = XNEWVEC (char, elt.len + 1);
340 elt.str = str;
341 memcpy (str, elem, elt.len);
342 str[elt.len] = '\0';
c6e83800
ZW
343 if (*p == ':')
344 p++;
345
d7b6aee8 346 d->vpath.push (elt);
c6e83800
ZW
347 }
348}
349
db87f19a
NS
350/* Add a new module target (there can only be one). M is the module
351 name. */
352
353void
354deps_add_module_target (struct mkdeps *d, const char *m,
024f135a 355 const char *cmi, bool is_header_unit, bool is_exported)
db87f19a
NS
356{
357 gcc_assert (!d->module_name);
358
359 d->module_name = xstrdup (m);
360 d->is_header_unit = is_header_unit;
024f135a 361 d->is_exported = is_exported;
db87f19a
NS
362 d->cmi_name = xstrdup (cmi);
363}
364
365/* Add a new module dependency. M is the module name. */
366
367void
368deps_add_module_dep (struct mkdeps *d, const char *m)
369{
370 d->modules.push (xstrdup (m));
371}
372
d7b6aee8
NS
373/* Write NAME, with a leading space to FP, a Makefile. Advance COL as
374 appropriate, wrap at COLMAX, returning new column number. Iff
375 QUOTE apply quoting. Append TRAIL. */
49e6c08e 376
d7b6aee8
NS
377static unsigned
378make_write_name (const char *name, FILE *fp, unsigned col, unsigned colmax,
379 bool quote = true, const char *trail = NULL)
380{
381 if (quote)
d7ab349c 382 name = munge (name, trail);
d7b6aee8 383 unsigned size = strlen (name);
49e6c08e 384
d7b6aee8 385 if (col)
49e6c08e 386 {
d7b6aee8 387 if (colmax && col + size> colmax)
49e6c08e 388 {
d7b6aee8
NS
389 fputs (" \\\n", fp);
390 col = 0;
49e6c08e 391 }
d7b6aee8
NS
392 col++;
393 fputs (" ", fp);
49e6c08e
ZW
394 }
395
d7b6aee8
NS
396 col += size;
397 fputs (name, fp);
49e6c08e 398
d7b6aee8 399 return col;
49e6c08e 400}
0c20a65f 401
d7b6aee8
NS
402/* Write all the names in VEC via make_write_name. */
403
404static unsigned
405make_write_vec (const mkdeps::vec<const char *> &vec, FILE *fp,
406 unsigned col, unsigned colmax, unsigned quote_lwm = 0,
407 const char *trail = NULL)
49e6c08e 408{
d7b6aee8
NS
409 for (unsigned ix = 0; ix != vec.size (); ix++)
410 col = make_write_name (vec[ix], fp, col, colmax, ix >= quote_lwm, trail);
411 return col;
412}
49e6c08e 413
d7b6aee8
NS
414/* Write the dependencies to a Makefile. If PHONY is true, add
415 .PHONY targets for all the dependencies too. */
416
417static void
918e8b10 418make_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax)
d7b6aee8 419{
918e8b10
NS
420 const mkdeps *d = pfile->deps;
421
d7b6aee8
NS
422 unsigned column = 0;
423 if (colmax && colmax < 34)
424 colmax = 34;
425
024f135a
BB
426 /* Write out C++ modules information if no other `-fdeps-format=`
427 option is given. */
428 cpp_fdeps_format fdeps_format = CPP_OPTION (pfile, deps.fdeps_format);
429 bool write_make_modules_deps = (fdeps_format == FDEPS_FMT_NONE
430 && CPP_OPTION (pfile, deps.modules));
431
d7b6aee8 432 if (d->deps.size ())
49e6c08e 433 {
d7b6aee8 434 column = make_write_vec (d->targets, fp, 0, colmax, d->quote_lwm);
024f135a 435 if (write_make_modules_deps && d->cmi_name)
db87f19a 436 column = make_write_name (d->cmi_name, fp, column, colmax);
d7b6aee8
NS
437 fputs (":", fp);
438 column++;
8ba6ea87 439 make_write_vec (d->deps, fp, column, colmax);
d7b6aee8 440 fputs ("\n", fp);
918e8b10 441 if (CPP_OPTION (pfile, deps.phony_targets))
d7b6aee8
NS
442 for (unsigned i = 1; i < d->deps.size (); i++)
443 fprintf (fp, "%s:\n", munge (d->deps[i]));
49e6c08e 444 }
db87f19a 445
024f135a 446 if (!write_make_modules_deps)
db87f19a
NS
447 return;
448
449 if (d->modules.size ())
450 {
451 column = make_write_vec (d->targets, fp, 0, colmax, d->quote_lwm);
452 if (d->cmi_name)
453 column = make_write_name (d->cmi_name, fp, column, colmax);
454 fputs (":", fp);
455 column++;
456 column = make_write_vec (d->modules, fp, column, colmax, 0, ".c++m");
457 fputs ("\n", fp);
458 }
459
460 if (d->module_name)
461 {
462 if (d->cmi_name)
463 {
464 /* module-name : cmi-name */
465 column = make_write_name (d->module_name, fp, 0, colmax,
466 true, ".c++m");
467 fputs (":", fp);
468 column++;
469 column = make_write_name (d->cmi_name, fp, column, colmax);
470 fputs ("\n", fp);
471
472 column = fprintf (fp, ".PHONY:");
473 column = make_write_name (d->module_name, fp, column, colmax,
474 true, ".c++m");
475 fputs ("\n", fp);
476 }
477
478 if (d->cmi_name && !d->is_header_unit)
479 {
480 /* An order-only dependency.
481 cmi-name :| first-target
482 We can probably drop this this in favour of Make-4.3's grouped
483 targets '&:' */
484 column = make_write_name (d->cmi_name, fp, 0, colmax);
485 fputs (":|", fp);
486 column++;
487 column = make_write_name (d->targets[0], fp, column, colmax);
488 fputs ("\n", fp);
489 }
490 }
491
492 if (d->modules.size ())
493 {
494 column = fprintf (fp, "CXX_IMPORTS +=");
495 make_write_vec (d->modules, fp, column, colmax, 0, ".c++m");
496 fputs ("\n", fp);
497 }
49e6c08e 498}
17211ab5 499
d7b6aee8
NS
500/* Write out dependencies according to the selected format (which is
501 only Make at the moment). */
918e8b10 502/* Really we should be opening fp here. */
d7b6aee8
NS
503
504void
918e8b10 505deps_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax)
d7b6aee8 506{
918e8b10 507 make_write (pfile, fp, colmax);
d7b6aee8
NS
508}
509
024f135a
BB
510/* Write out a a filepath for P1689R5 output. */
511
512static void
513p1689r5_write_filepath (const char *name, FILE *fp)
514{
515 if (cpp_valid_utf8_p (name, strlen (name)))
516 {
517 fputc ('"', fp);
518 for (const char* c = name; *c; c++)
519 {
520 // Escape control characters.
521 if (ISCNTRL (*c))
522 fprintf (fp, "\\u%04x", *c);
523 // JSON escape characters.
524 else if (*c == '"' || *c == '\\')
525 {
526 fputc ('\\', fp);
527 fputc (*c, fp);
528 }
529 // Everything else.
530 else
531 fputc (*c, fp);
532 }
533 fputc ('"', fp);
534 }
535 else
536 {
537 // TODO: print an error
538 }
539}
540
541/* Write a JSON array from a `vec` for P1689R5 output.
542
543 In P1689R5, all array values are filepaths. */
544
545static void
546p1689r5_write_vec (const mkdeps::vec<const char *> &vec, FILE *fp)
547{
548 for (unsigned ix = 0; ix != vec.size (); ix++)
549 {
550 p1689r5_write_filepath (vec[ix], fp);
551 if (ix < vec.size () - 1)
552 fputc (',', fp);
553 fputc ('\n', fp);
554 }
555}
556
557/* Write out the P1689R5 format using the module dependency tracking
558 information gathered while scanning and/or compiling.
559
560 Ideally this (and the above `p1689r5_` functions) would use `gcc/json.h`,
561 but since this is `libcpp`, we cannot use `gcc/` code.
562
563 TODO: move `json.h` to libiberty. */
564
565void
566deps_write_p1689r5 (const struct mkdeps *d, FILE *fp)
567{
568 fputs ("{\n", fp);
569
570 fputs ("\"rules\": [\n", fp);
571 fputs ("{\n", fp);
572
573 if (d->primary_output)
574 {
575 fputs ("\"primary-output\": ", fp);
576 p1689r5_write_filepath (d->primary_output, fp);
577 fputs (",\n", fp);
578 }
579
580 if (d->fdeps_targets.size ())
581 {
582 fputs ("\"outputs\": [\n", fp);
583 p1689r5_write_vec (d->fdeps_targets, fp);
584 fputs ("],\n", fp);
585 }
586
587 if (d->module_name)
588 {
589 fputs ("\"provides\": [\n", fp);
590 fputs ("{\n", fp);
591
592 fputs ("\"logical-name\": ", fp);
593 p1689r5_write_filepath (d->module_name, fp);
594 fputs (",\n", fp);
595
596 fprintf (fp, "\"is-interface\": %s\n", d->is_exported ? "true" : "false");
597
598 // TODO: header-unit information
599
600 fputs ("}\n", fp);
601 fputs ("],\n", fp);
602 }
603
604 fputs ("\"requires\": [\n", fp);
605 for (size_t i = 0; i < d->modules.size (); i++)
606 {
607 if (i != 0)
608 fputs (",\n", fp);
609 fputs ("{\n", fp);
610
611 fputs ("\"logical-name\": ", fp);
612 p1689r5_write_filepath (d->modules[i], fp);
613 fputs ("\n", fp);
614
615 // TODO: header-unit information
616
617 fputs ("}\n", fp);
618 }
619 fputs ("]\n", fp);
620
621 fputs ("}\n", fp);
622
623 fputs ("],\n", fp);
624
625 fputs ("\"version\": 0,\n", fp);
626 fputs ("\"revision\": 0\n", fp);
627
628 fputs ("}\n", fp);
629}
630
17211ab5
GK
631/* Write out a deps buffer to a file, in a form that can be read back
632 with deps_restore. Returns nonzero on error, in which case the
633 error number will be in errno. */
634
635int
99b1c316 636deps_save (class mkdeps *deps, FILE *f)
17211ab5
GK
637{
638 unsigned int i;
d7b6aee8 639 size_t size;
17211ab5
GK
640
641 /* The cppreader structure contains makefile dependences. Write out this
642 structure. */
643
644 /* The number of dependences. */
d7b6aee8
NS
645 size = deps->deps.size ();
646 if (fwrite (&size, sizeof (size), 1, f) != 1)
647 return -1;
648
17211ab5 649 /* The length of each dependence followed by the string. */
d7b6aee8 650 for (i = 0; i < deps->deps.size (); i++)
17211ab5 651 {
d7b6aee8
NS
652 size = strlen (deps->deps[i]);
653 if (fwrite (&size, sizeof (size), 1, f) != 1)
654 return -1;
655 if (fwrite (deps->deps[i], size, 1, f) != 1)
656 return -1;
17211ab5
GK
657 }
658
659 return 0;
660}
661
662/* Read back dependency information written with deps_save into
d7b6aee8 663 the deps sizefer. The third argument may be NULL, in which case
17211ab5
GK
664 the dependency information is just skipped, or it may be a filename,
665 in which case that filename is skipped. */
666
667int
99b1c316 668deps_restore (class mkdeps *deps, FILE *fd, const char *self)
17211ab5 669{
d7b6aee8
NS
670 size_t size;
671 char *buf = NULL;
672 size_t buf_size = 0;
17211ab5
GK
673
674 /* Number of dependences. */
d7b6aee8 675 if (fread (&size, sizeof (size), 1, fd) != 1)
17211ab5
GK
676 return -1;
677
678 /* The length of each dependence string, followed by the string. */
d7b6aee8 679 for (unsigned i = size; i--;)
17211ab5
GK
680 {
681 /* Read in # bytes in string. */
d7b6aee8
NS
682 if (fread (&size, sizeof (size), 1, fd) != 1)
683 return -1;
684
685 if (size >= buf_size)
17211ab5 686 {
d7b6aee8 687 buf_size = size + 512;
c3f829c1 688 buf = XRESIZEVEC (char, buf, buf_size);
17211ab5 689 }
d7b6aee8 690 if (fread (buf, 1, size, fd) != size)
55e7f907 691 {
d7b6aee8 692 XDELETEVEC (buf);
55e7f907
TB
693 return -1;
694 }
d7b6aee8 695 buf[size] = 0;
17211ab5 696
0c20a65f 697 /* Generate makefile dependencies from .pch if -nopch-deps. */
4489800d 698 if (self != NULL && filename_cmp (buf, self) != 0)
17211ab5
GK
699 deps_add_dep (deps, buf);
700 }
701
d7b6aee8 702 XDELETEVEC (buf);
17211ab5
GK
703 return 0;
704}