1*e4b17023SJohn Marino /* Dependency generator for Makefile fragments.
2*e4b17023SJohn Marino Copyright (C) 2000, 2001, 2003, 2007, 2008, 2009
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino Contributed by Zack Weinberg, Mar 2000
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino This program is free software; you can redistribute it and/or modify it
7*e4b17023SJohn Marino under the terms of the GNU General Public License as published by the
8*e4b17023SJohn Marino Free Software Foundation; either version 3, or (at your option) any
9*e4b17023SJohn Marino later version.
10*e4b17023SJohn Marino
11*e4b17023SJohn Marino This program is distributed in the hope that it will be useful,
12*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*e4b17023SJohn Marino GNU General Public License for more details.
15*e4b17023SJohn Marino
16*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
17*e4b17023SJohn Marino along with this program; see the file COPYING3. If not see
18*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.
19*e4b17023SJohn Marino
20*e4b17023SJohn Marino In other words, you are welcome to use, share and improve this program.
21*e4b17023SJohn Marino You are forbidden to forbid anyone else to use, share and improve
22*e4b17023SJohn Marino what you give them. Help stamp out software-hoarding! */
23*e4b17023SJohn Marino
24*e4b17023SJohn Marino #include "config.h"
25*e4b17023SJohn Marino #include "system.h"
26*e4b17023SJohn Marino #include "mkdeps.h"
27*e4b17023SJohn Marino
28*e4b17023SJohn Marino /* Keep this structure local to this file, so clients don't find it
29*e4b17023SJohn Marino easy to start making assumptions. */
30*e4b17023SJohn Marino struct deps
31*e4b17023SJohn Marino {
32*e4b17023SJohn Marino const char **targetv;
33*e4b17023SJohn Marino unsigned int ntargets; /* number of slots actually occupied */
34*e4b17023SJohn Marino unsigned int targets_size; /* amt of allocated space - in words */
35*e4b17023SJohn Marino
36*e4b17023SJohn Marino const char **depv;
37*e4b17023SJohn Marino unsigned int ndeps;
38*e4b17023SJohn Marino unsigned int deps_size;
39*e4b17023SJohn Marino
40*e4b17023SJohn Marino const char **vpathv;
41*e4b17023SJohn Marino size_t *vpathlv;
42*e4b17023SJohn Marino unsigned int nvpaths;
43*e4b17023SJohn Marino unsigned int vpaths_size;
44*e4b17023SJohn Marino };
45*e4b17023SJohn Marino
46*e4b17023SJohn Marino static const char *munge (const char *);
47*e4b17023SJohn Marino
48*e4b17023SJohn Marino /* Given a filename, quote characters in that filename which are
49*e4b17023SJohn Marino significant to Make. Note that it's not possible to quote all such
50*e4b17023SJohn Marino characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
51*e4b17023SJohn Marino not properly handled. It isn't possible to get this right in any
52*e4b17023SJohn Marino current version of Make. (??? Still true? Old comment referred to
53*e4b17023SJohn Marino 3.76.1.) */
54*e4b17023SJohn Marino
55*e4b17023SJohn Marino static const char *
munge(const char * filename)56*e4b17023SJohn Marino munge (const char *filename)
57*e4b17023SJohn Marino {
58*e4b17023SJohn Marino int len;
59*e4b17023SJohn Marino const char *p, *q;
60*e4b17023SJohn Marino char *dst, *buffer;
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino for (p = filename, len = 0; *p; p++, len++)
63*e4b17023SJohn Marino {
64*e4b17023SJohn Marino switch (*p)
65*e4b17023SJohn Marino {
66*e4b17023SJohn Marino case ' ':
67*e4b17023SJohn Marino case '\t':
68*e4b17023SJohn Marino /* GNU make uses a weird quoting scheme for white space.
69*e4b17023SJohn Marino A space or tab preceded by 2N+1 backslashes represents
70*e4b17023SJohn Marino N backslashes followed by space; a space or tab
71*e4b17023SJohn Marino preceded by 2N backslashes represents N backslashes at
72*e4b17023SJohn Marino the end of a file name; and backslashes in other
73*e4b17023SJohn Marino contexts should not be doubled. */
74*e4b17023SJohn Marino for (q = p - 1; filename <= q && *q == '\\'; q--)
75*e4b17023SJohn Marino len++;
76*e4b17023SJohn Marino len++;
77*e4b17023SJohn Marino break;
78*e4b17023SJohn Marino
79*e4b17023SJohn Marino case '$':
80*e4b17023SJohn Marino /* '$' is quoted by doubling it. */
81*e4b17023SJohn Marino len++;
82*e4b17023SJohn Marino break;
83*e4b17023SJohn Marino
84*e4b17023SJohn Marino case '#':
85*e4b17023SJohn Marino /* '#' is quoted with a backslash. */
86*e4b17023SJohn Marino len++;
87*e4b17023SJohn Marino break;
88*e4b17023SJohn Marino }
89*e4b17023SJohn Marino }
90*e4b17023SJohn Marino
91*e4b17023SJohn Marino /* Now we know how big to make the buffer. */
92*e4b17023SJohn Marino buffer = XNEWVEC (char, len + 1);
93*e4b17023SJohn Marino
94*e4b17023SJohn Marino for (p = filename, dst = buffer; *p; p++, dst++)
95*e4b17023SJohn Marino {
96*e4b17023SJohn Marino switch (*p)
97*e4b17023SJohn Marino {
98*e4b17023SJohn Marino case ' ':
99*e4b17023SJohn Marino case '\t':
100*e4b17023SJohn Marino for (q = p - 1; filename <= q && *q == '\\'; q--)
101*e4b17023SJohn Marino *dst++ = '\\';
102*e4b17023SJohn Marino *dst++ = '\\';
103*e4b17023SJohn Marino break;
104*e4b17023SJohn Marino
105*e4b17023SJohn Marino case '$':
106*e4b17023SJohn Marino *dst++ = '$';
107*e4b17023SJohn Marino break;
108*e4b17023SJohn Marino
109*e4b17023SJohn Marino case '#':
110*e4b17023SJohn Marino *dst++ = '\\';
111*e4b17023SJohn Marino break;
112*e4b17023SJohn Marino
113*e4b17023SJohn Marino default:
114*e4b17023SJohn Marino /* nothing */;
115*e4b17023SJohn Marino }
116*e4b17023SJohn Marino *dst = *p;
117*e4b17023SJohn Marino }
118*e4b17023SJohn Marino
119*e4b17023SJohn Marino *dst = '\0';
120*e4b17023SJohn Marino return buffer;
121*e4b17023SJohn Marino }
122*e4b17023SJohn Marino
123*e4b17023SJohn Marino /* If T begins with any of the partial pathnames listed in d->vpathv,
124*e4b17023SJohn Marino then advance T to point beyond that pathname. */
125*e4b17023SJohn Marino static const char *
apply_vpath(struct deps * d,const char * t)126*e4b17023SJohn Marino apply_vpath (struct deps *d, const char *t)
127*e4b17023SJohn Marino {
128*e4b17023SJohn Marino if (d->vpathv)
129*e4b17023SJohn Marino {
130*e4b17023SJohn Marino unsigned int i;
131*e4b17023SJohn Marino for (i = 0; i < d->nvpaths; i++)
132*e4b17023SJohn Marino {
133*e4b17023SJohn Marino if (!filename_ncmp (d->vpathv[i], t, d->vpathlv[i]))
134*e4b17023SJohn Marino {
135*e4b17023SJohn Marino const char *p = t + d->vpathlv[i];
136*e4b17023SJohn Marino if (!IS_DIR_SEPARATOR (*p))
137*e4b17023SJohn Marino goto not_this_one;
138*e4b17023SJohn Marino
139*e4b17023SJohn Marino /* Do not simplify $(vpath)/../whatever. ??? Might not
140*e4b17023SJohn Marino be necessary. */
141*e4b17023SJohn Marino if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3]))
142*e4b17023SJohn Marino goto not_this_one;
143*e4b17023SJohn Marino
144*e4b17023SJohn Marino /* found a match */
145*e4b17023SJohn Marino t = t + d->vpathlv[i] + 1;
146*e4b17023SJohn Marino break;
147*e4b17023SJohn Marino }
148*e4b17023SJohn Marino not_this_one:;
149*e4b17023SJohn Marino }
150*e4b17023SJohn Marino }
151*e4b17023SJohn Marino
152*e4b17023SJohn Marino /* Remove leading ./ in any case. */
153*e4b17023SJohn Marino while (t[0] == '.' && IS_DIR_SEPARATOR (t[1]))
154*e4b17023SJohn Marino {
155*e4b17023SJohn Marino t += 2;
156*e4b17023SJohn Marino /* If we removed a leading ./, then also remove any /s after the
157*e4b17023SJohn Marino first. */
158*e4b17023SJohn Marino while (IS_DIR_SEPARATOR (t[0]))
159*e4b17023SJohn Marino ++t;
160*e4b17023SJohn Marino }
161*e4b17023SJohn Marino
162*e4b17023SJohn Marino return t;
163*e4b17023SJohn Marino }
164*e4b17023SJohn Marino
165*e4b17023SJohn Marino /* Public routines. */
166*e4b17023SJohn Marino
167*e4b17023SJohn Marino struct deps *
deps_init(void)168*e4b17023SJohn Marino deps_init (void)
169*e4b17023SJohn Marino {
170*e4b17023SJohn Marino return XCNEW (struct deps);
171*e4b17023SJohn Marino }
172*e4b17023SJohn Marino
173*e4b17023SJohn Marino void
deps_free(struct deps * d)174*e4b17023SJohn Marino deps_free (struct deps *d)
175*e4b17023SJohn Marino {
176*e4b17023SJohn Marino unsigned int i;
177*e4b17023SJohn Marino
178*e4b17023SJohn Marino if (d->targetv)
179*e4b17023SJohn Marino {
180*e4b17023SJohn Marino for (i = 0; i < d->ntargets; i++)
181*e4b17023SJohn Marino free ((void *) d->targetv[i]);
182*e4b17023SJohn Marino free (d->targetv);
183*e4b17023SJohn Marino }
184*e4b17023SJohn Marino
185*e4b17023SJohn Marino if (d->depv)
186*e4b17023SJohn Marino {
187*e4b17023SJohn Marino for (i = 0; i < d->ndeps; i++)
188*e4b17023SJohn Marino free ((void *) d->depv[i]);
189*e4b17023SJohn Marino free (d->depv);
190*e4b17023SJohn Marino }
191*e4b17023SJohn Marino
192*e4b17023SJohn Marino if (d->vpathv)
193*e4b17023SJohn Marino {
194*e4b17023SJohn Marino for (i = 0; i < d->nvpaths; i++)
195*e4b17023SJohn Marino free ((void *) d->vpathv[i]);
196*e4b17023SJohn Marino free (d->vpathv);
197*e4b17023SJohn Marino free (d->vpathlv);
198*e4b17023SJohn Marino }
199*e4b17023SJohn Marino
200*e4b17023SJohn Marino free (d);
201*e4b17023SJohn Marino }
202*e4b17023SJohn Marino
203*e4b17023SJohn Marino /* Adds a target T. We make a copy, so it need not be a permanent
204*e4b17023SJohn Marino string. QUOTE is true if the string should be quoted. */
205*e4b17023SJohn Marino void
deps_add_target(struct deps * d,const char * t,int quote)206*e4b17023SJohn Marino deps_add_target (struct deps *d, const char *t, int quote)
207*e4b17023SJohn Marino {
208*e4b17023SJohn Marino if (d->ntargets == d->targets_size)
209*e4b17023SJohn Marino {
210*e4b17023SJohn Marino d->targets_size = d->targets_size * 2 + 4;
211*e4b17023SJohn Marino d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size);
212*e4b17023SJohn Marino }
213*e4b17023SJohn Marino
214*e4b17023SJohn Marino t = apply_vpath (d, t);
215*e4b17023SJohn Marino if (quote)
216*e4b17023SJohn Marino t = munge (t); /* Also makes permanent copy. */
217*e4b17023SJohn Marino else
218*e4b17023SJohn Marino t = xstrdup (t);
219*e4b17023SJohn Marino
220*e4b17023SJohn Marino d->targetv[d->ntargets++] = t;
221*e4b17023SJohn Marino }
222*e4b17023SJohn Marino
223*e4b17023SJohn Marino /* Sets the default target if none has been given already. An empty
224*e4b17023SJohn Marino string as the default target in interpreted as stdin. The string
225*e4b17023SJohn Marino is quoted for MAKE. */
226*e4b17023SJohn Marino void
deps_add_default_target(struct deps * d,const char * tgt)227*e4b17023SJohn Marino deps_add_default_target (struct deps *d, const char *tgt)
228*e4b17023SJohn Marino {
229*e4b17023SJohn Marino /* Only if we have no targets. */
230*e4b17023SJohn Marino if (d->ntargets)
231*e4b17023SJohn Marino return;
232*e4b17023SJohn Marino
233*e4b17023SJohn Marino if (tgt[0] == '\0')
234*e4b17023SJohn Marino deps_add_target (d, "-", 1);
235*e4b17023SJohn Marino else
236*e4b17023SJohn Marino {
237*e4b17023SJohn Marino #ifndef TARGET_OBJECT_SUFFIX
238*e4b17023SJohn Marino # define TARGET_OBJECT_SUFFIX ".o"
239*e4b17023SJohn Marino #endif
240*e4b17023SJohn Marino const char *start = lbasename (tgt);
241*e4b17023SJohn Marino char *o = (char *) alloca (strlen (start)
242*e4b17023SJohn Marino + strlen (TARGET_OBJECT_SUFFIX) + 1);
243*e4b17023SJohn Marino char *suffix;
244*e4b17023SJohn Marino
245*e4b17023SJohn Marino strcpy (o, start);
246*e4b17023SJohn Marino
247*e4b17023SJohn Marino suffix = strrchr (o, '.');
248*e4b17023SJohn Marino if (!suffix)
249*e4b17023SJohn Marino suffix = o + strlen (o);
250*e4b17023SJohn Marino strcpy (suffix, TARGET_OBJECT_SUFFIX);
251*e4b17023SJohn Marino
252*e4b17023SJohn Marino deps_add_target (d, o, 1);
253*e4b17023SJohn Marino }
254*e4b17023SJohn Marino }
255*e4b17023SJohn Marino
256*e4b17023SJohn Marino void
deps_add_dep(struct deps * d,const char * t)257*e4b17023SJohn Marino deps_add_dep (struct deps *d, const char *t)
258*e4b17023SJohn Marino {
259*e4b17023SJohn Marino t = munge (apply_vpath (d, t)); /* Also makes permanent copy. */
260*e4b17023SJohn Marino
261*e4b17023SJohn Marino if (d->ndeps == d->deps_size)
262*e4b17023SJohn Marino {
263*e4b17023SJohn Marino d->deps_size = d->deps_size * 2 + 8;
264*e4b17023SJohn Marino d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size);
265*e4b17023SJohn Marino }
266*e4b17023SJohn Marino d->depv[d->ndeps++] = t;
267*e4b17023SJohn Marino }
268*e4b17023SJohn Marino
269*e4b17023SJohn Marino void
deps_add_vpath(struct deps * d,const char * vpath)270*e4b17023SJohn Marino deps_add_vpath (struct deps *d, const char *vpath)
271*e4b17023SJohn Marino {
272*e4b17023SJohn Marino const char *elem, *p;
273*e4b17023SJohn Marino char *copy;
274*e4b17023SJohn Marino size_t len;
275*e4b17023SJohn Marino
276*e4b17023SJohn Marino for (elem = vpath; *elem; elem = p)
277*e4b17023SJohn Marino {
278*e4b17023SJohn Marino for (p = elem; *p && *p != ':'; p++);
279*e4b17023SJohn Marino len = p - elem;
280*e4b17023SJohn Marino copy = XNEWVEC (char, len + 1);
281*e4b17023SJohn Marino memcpy (copy, elem, len);
282*e4b17023SJohn Marino copy[len] = '\0';
283*e4b17023SJohn Marino if (*p == ':')
284*e4b17023SJohn Marino p++;
285*e4b17023SJohn Marino
286*e4b17023SJohn Marino if (d->nvpaths == d->vpaths_size)
287*e4b17023SJohn Marino {
288*e4b17023SJohn Marino d->vpaths_size = d->vpaths_size * 2 + 8;
289*e4b17023SJohn Marino d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size);
290*e4b17023SJohn Marino d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size);
291*e4b17023SJohn Marino }
292*e4b17023SJohn Marino d->vpathv[d->nvpaths] = copy;
293*e4b17023SJohn Marino d->vpathlv[d->nvpaths] = len;
294*e4b17023SJohn Marino d->nvpaths++;
295*e4b17023SJohn Marino }
296*e4b17023SJohn Marino }
297*e4b17023SJohn Marino
298*e4b17023SJohn Marino void
deps_write(const struct deps * d,FILE * fp,unsigned int colmax)299*e4b17023SJohn Marino deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
300*e4b17023SJohn Marino {
301*e4b17023SJohn Marino unsigned int size, i, column;
302*e4b17023SJohn Marino
303*e4b17023SJohn Marino column = 0;
304*e4b17023SJohn Marino if (colmax && colmax < 34)
305*e4b17023SJohn Marino colmax = 34;
306*e4b17023SJohn Marino
307*e4b17023SJohn Marino for (i = 0; i < d->ntargets; i++)
308*e4b17023SJohn Marino {
309*e4b17023SJohn Marino size = strlen (d->targetv[i]);
310*e4b17023SJohn Marino column += size;
311*e4b17023SJohn Marino if (i)
312*e4b17023SJohn Marino {
313*e4b17023SJohn Marino if (colmax && column > colmax)
314*e4b17023SJohn Marino {
315*e4b17023SJohn Marino fputs (" \\\n ", fp);
316*e4b17023SJohn Marino column = 1 + size;
317*e4b17023SJohn Marino }
318*e4b17023SJohn Marino else
319*e4b17023SJohn Marino {
320*e4b17023SJohn Marino putc (' ', fp);
321*e4b17023SJohn Marino column++;
322*e4b17023SJohn Marino }
323*e4b17023SJohn Marino }
324*e4b17023SJohn Marino fputs (d->targetv[i], fp);
325*e4b17023SJohn Marino }
326*e4b17023SJohn Marino
327*e4b17023SJohn Marino putc (':', fp);
328*e4b17023SJohn Marino column++;
329*e4b17023SJohn Marino
330*e4b17023SJohn Marino for (i = 0; i < d->ndeps; i++)
331*e4b17023SJohn Marino {
332*e4b17023SJohn Marino size = strlen (d->depv[i]);
333*e4b17023SJohn Marino column += size;
334*e4b17023SJohn Marino if (colmax && column > colmax)
335*e4b17023SJohn Marino {
336*e4b17023SJohn Marino fputs (" \\\n ", fp);
337*e4b17023SJohn Marino column = 1 + size;
338*e4b17023SJohn Marino }
339*e4b17023SJohn Marino else
340*e4b17023SJohn Marino {
341*e4b17023SJohn Marino putc (' ', fp);
342*e4b17023SJohn Marino column++;
343*e4b17023SJohn Marino }
344*e4b17023SJohn Marino fputs (d->depv[i], fp);
345*e4b17023SJohn Marino }
346*e4b17023SJohn Marino putc ('\n', fp);
347*e4b17023SJohn Marino }
348*e4b17023SJohn Marino
349*e4b17023SJohn Marino void
deps_phony_targets(const struct deps * d,FILE * fp)350*e4b17023SJohn Marino deps_phony_targets (const struct deps *d, FILE *fp)
351*e4b17023SJohn Marino {
352*e4b17023SJohn Marino unsigned int i;
353*e4b17023SJohn Marino
354*e4b17023SJohn Marino for (i = 1; i < d->ndeps; i++)
355*e4b17023SJohn Marino {
356*e4b17023SJohn Marino putc ('\n', fp);
357*e4b17023SJohn Marino fputs (d->depv[i], fp);
358*e4b17023SJohn Marino putc (':', fp);
359*e4b17023SJohn Marino putc ('\n', fp);
360*e4b17023SJohn Marino }
361*e4b17023SJohn Marino }
362*e4b17023SJohn Marino
363*e4b17023SJohn Marino /* Write out a deps buffer to a file, in a form that can be read back
364*e4b17023SJohn Marino with deps_restore. Returns nonzero on error, in which case the
365*e4b17023SJohn Marino error number will be in errno. */
366*e4b17023SJohn Marino
367*e4b17023SJohn Marino int
deps_save(struct deps * deps,FILE * f)368*e4b17023SJohn Marino deps_save (struct deps *deps, FILE *f)
369*e4b17023SJohn Marino {
370*e4b17023SJohn Marino unsigned int i;
371*e4b17023SJohn Marino
372*e4b17023SJohn Marino /* The cppreader structure contains makefile dependences. Write out this
373*e4b17023SJohn Marino structure. */
374*e4b17023SJohn Marino
375*e4b17023SJohn Marino /* The number of dependences. */
376*e4b17023SJohn Marino if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1)
377*e4b17023SJohn Marino return -1;
378*e4b17023SJohn Marino /* The length of each dependence followed by the string. */
379*e4b17023SJohn Marino for (i = 0; i < deps->ndeps; i++)
380*e4b17023SJohn Marino {
381*e4b17023SJohn Marino size_t num_to_write = strlen (deps->depv[i]);
382*e4b17023SJohn Marino if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1)
383*e4b17023SJohn Marino return -1;
384*e4b17023SJohn Marino if (fwrite (deps->depv[i], num_to_write, 1, f) != 1)
385*e4b17023SJohn Marino return -1;
386*e4b17023SJohn Marino }
387*e4b17023SJohn Marino
388*e4b17023SJohn Marino return 0;
389*e4b17023SJohn Marino }
390*e4b17023SJohn Marino
391*e4b17023SJohn Marino /* Read back dependency information written with deps_save into
392*e4b17023SJohn Marino the deps buffer. The third argument may be NULL, in which case
393*e4b17023SJohn Marino the dependency information is just skipped, or it may be a filename,
394*e4b17023SJohn Marino in which case that filename is skipped. */
395*e4b17023SJohn Marino
396*e4b17023SJohn Marino int
deps_restore(struct deps * deps,FILE * fd,const char * self)397*e4b17023SJohn Marino deps_restore (struct deps *deps, FILE *fd, const char *self)
398*e4b17023SJohn Marino {
399*e4b17023SJohn Marino unsigned int i, count;
400*e4b17023SJohn Marino size_t num_to_read;
401*e4b17023SJohn Marino size_t buf_size = 512;
402*e4b17023SJohn Marino char *buf = XNEWVEC (char, buf_size);
403*e4b17023SJohn Marino
404*e4b17023SJohn Marino /* Number of dependences. */
405*e4b17023SJohn Marino if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
406*e4b17023SJohn Marino return -1;
407*e4b17023SJohn Marino
408*e4b17023SJohn Marino /* The length of each dependence string, followed by the string. */
409*e4b17023SJohn Marino for (i = 0; i < count; i++)
410*e4b17023SJohn Marino {
411*e4b17023SJohn Marino /* Read in # bytes in string. */
412*e4b17023SJohn Marino if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
413*e4b17023SJohn Marino return -1;
414*e4b17023SJohn Marino if (buf_size < num_to_read + 1)
415*e4b17023SJohn Marino {
416*e4b17023SJohn Marino buf_size = num_to_read + 1 + 127;
417*e4b17023SJohn Marino buf = XRESIZEVEC (char, buf, buf_size);
418*e4b17023SJohn Marino }
419*e4b17023SJohn Marino if (fread (buf, 1, num_to_read, fd) != num_to_read)
420*e4b17023SJohn Marino return -1;
421*e4b17023SJohn Marino buf[num_to_read] = '\0';
422*e4b17023SJohn Marino
423*e4b17023SJohn Marino /* Generate makefile dependencies from .pch if -nopch-deps. */
424*e4b17023SJohn Marino if (self != NULL && filename_cmp (buf, self) != 0)
425*e4b17023SJohn Marino deps_add_dep (deps, buf);
426*e4b17023SJohn Marino }
427*e4b17023SJohn Marino
428*e4b17023SJohn Marino free (buf);
429*e4b17023SJohn Marino return 0;
430*e4b17023SJohn Marino }
431