xref: /dflybsd-src/contrib/gcc-4.7/libcpp/mkdeps.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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