OSDN Git Service

* gdbinit.in: Update to reflect new identifier structure.
[pf3gnuchains/gcc-fork.git] / gcc / mkdeps.c
1 /* Dependency generator for Makefile fragments.
2    Copyright (C) 2000, 2001 Free Software Foundation, Inc.
3    Contributed by Zack Weinberg, Mar 2000
4
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
8 later version.
9
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.
14
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.
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 "coretypes.h"
26 #include "tm.h"
27 #include "mkdeps.h"
28
29 /* Keep this structure local to this file, so clients don't find it
30    easy to start making assumptions.  */
31 struct deps
32 {
33   const char **targetv;
34   unsigned int ntargets;        /* number of slots actually occupied */
35   unsigned int targets_size;    /* amt of allocated space - in words */
36
37   const char **depv;
38   unsigned int ndeps;
39   unsigned int deps_size;
40 };
41
42 static const char *munge        PARAMS ((const char *));
43
44 /* Given a filename, quote characters in that filename which are
45    significant to Make.  Note that it's not possible to quote all such
46    characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
47    not properly handled.  It isn't possible to get this right in any
48    current version of Make.  (??? Still true?  Old comment referred to
49    3.76.1.)  */
50    
51 static const char *
52 munge (filename)
53      const char *filename;
54 {
55   int len;
56   const char *p, *q;
57   char *dst, *buffer;
58
59   for (p = filename, len = 0; *p; p++, len++)
60     {
61       switch (*p)
62         {
63         case ' ':
64         case '\t':
65           /* GNU make uses a weird quoting scheme for white space.
66              A space or tab preceded by 2N+1 backslashes represents
67              N backslashes followed by space; a space or tab
68              preceded by 2N backslashes represents N backslashes at
69              the end of a file name; and backslashes in other
70              contexts should not be doubled.  */
71           for (q = p - 1; filename <= q && *q == '\\';  q--)
72             len++;
73           len++;
74           break;
75
76         case '$':
77           /* '$' is quoted by doubling it.  */
78           len++;
79           break;
80         }
81     }
82
83   /* Now we know how big to make the buffer.  */
84   buffer = xmalloc (len + 1);
85
86   for (p = filename, dst = buffer; *p; p++, dst++)
87     {
88       switch (*p)
89         {
90         case ' ':
91         case '\t':
92           for (q = p - 1; filename <= q && *q == '\\';  q--)
93             *dst++ = '\\';
94           *dst++ = '\\';
95           break;
96
97         case '$':
98           *dst++ = '$';
99           break;
100
101         default:
102           /* nothing */;
103         }
104       *dst = *p;
105     }
106
107   *dst = '\0';
108   return buffer;
109 }
110
111 /* Public routines.  */
112
113 struct deps *
114 deps_init ()
115 {
116   struct deps *d = (struct deps *) xmalloc (sizeof (struct deps));
117
118   /* Allocate space for the vectors only if we need it.  */
119
120   d->targetv = 0;
121   d->depv = 0;
122
123   d->ntargets = 0;
124   d->targets_size = 0;
125   d->ndeps = 0;
126   d->deps_size = 0;
127
128   return d;
129 }
130
131 void
132 deps_free (d)
133      struct deps *d;
134 {
135   unsigned int i;
136
137   if (d->targetv)
138     {
139       for (i = 0; i < d->ntargets; i++)
140         free ((PTR) d->targetv[i]);
141       free (d->targetv);
142     }
143
144   if (d->depv)
145     {
146       for (i = 0; i < d->ndeps; i++)
147         free ((PTR) d->depv[i]);
148       free (d->depv);
149     }
150
151   free (d);
152 }
153
154 /* Adds a target T.  We make a copy, so it need not be a permanent
155    string.  QUOTE is true if the string should be quoted.  */
156 void
157 deps_add_target (d, t, quote)
158      struct deps *d;
159      const char *t;
160      int quote;
161 {
162   if (d->ntargets == d->targets_size)
163     {
164       d->targets_size = d->targets_size * 2 + 4;
165       d->targetv = (const char **) xrealloc (d->targetv,
166                              d->targets_size * sizeof (const char *));
167     }
168
169   if (quote)
170     t = munge (t);  /* Also makes permanent copy.  */
171   else
172     t = xstrdup (t);
173
174   d->targetv[d->ntargets++] = t;
175 }
176
177 /* Sets the default target if none has been given already.  An empty
178    string as the default target in interpreted as stdin.  The string
179    is quoted for MAKE.  */
180 void
181 deps_add_default_target (d, tgt)
182      struct deps *d;
183      const char *tgt;
184 {
185   /* Only if we have no targets.  */
186   if (d->ntargets)
187     return;
188
189   if (tgt[0] == '\0')
190     deps_add_target (d, "-", 1);
191   else
192     {
193 #ifndef TARGET_OBJECT_SUFFIX
194 # define TARGET_OBJECT_SUFFIX ".o"
195 #endif
196       const char *start = lbasename (tgt);
197       char *o = (char *) alloca (strlen (start) + strlen (TARGET_OBJECT_SUFFIX) + 1);
198       char *suffix;
199
200       strcpy (o, start);
201       
202       suffix = strrchr (o, '.');
203       if (!suffix)
204         suffix = o + strlen (o);
205       strcpy (suffix, TARGET_OBJECT_SUFFIX);
206       
207       deps_add_target (d, o, 1);
208     }
209 }
210
211 void
212 deps_add_dep (d, t)
213      struct deps *d;
214      const char *t;
215 {
216   t = munge (t);  /* Also makes permanent copy.  */
217
218   if (d->ndeps == d->deps_size)
219     {
220       d->deps_size = d->deps_size * 2 + 8;
221       d->depv = (const char **)
222         xrealloc (d->depv, d->deps_size * sizeof (const char *));
223     }
224   d->depv[d->ndeps++] = t;
225 }
226
227 void
228 deps_write (d, fp, colmax)
229      const struct deps *d;
230      FILE *fp;
231      unsigned int colmax;
232 {
233   unsigned int size, i, column;
234
235   column = 0;
236   if (colmax && colmax < 34)
237     colmax = 34;
238
239   for (i = 0; i < d->ntargets; i++)
240     {
241       size = strlen (d->targetv[i]);
242       column += size;
243       if (colmax && column > colmax)
244         {
245           fputs (" \\\n ", fp);
246           column = 1 + size;
247         }
248       if (i)
249         {
250           putc (' ', fp);
251           column++;
252         }
253       fputs (d->targetv[i], fp);
254     }
255
256   putc (':', fp);
257   putc (' ', fp);
258   column += 2;
259
260   for (i = 0; i < d->ndeps; i++)
261     {
262       size = strlen (d->depv[i]);
263       column += size;
264       if (colmax && column > colmax)
265         {
266           fputs (" \\\n ", fp);
267           column = 1 + size;
268         }
269       if (i)
270         {
271           putc (' ', fp);
272           column++;
273         }
274       fputs (d->depv[i], fp);
275     }
276   putc ('\n', fp);
277 }
278   
279 void
280 deps_phony_targets (d, fp)
281      const struct deps *d;
282      FILE *fp;
283 {
284   unsigned int i;
285
286   for (i = 1; i < d->ndeps; i++)
287     {
288       putc ('\n', fp);
289       fputs (d->depv[i], fp);
290       putc (':', fp);
291       putc ('\n', fp);
292     }
293 }
294
295 /* Write out a deps buffer to a file, in a form that can be read back
296    with deps_restore.  Returns nonzero on error, in which case the
297    error number will be in errno.  */
298
299 int
300 deps_save (deps, f)
301      struct deps *deps;
302      FILE *f;
303 {
304   unsigned int i;
305
306   /* The cppreader structure contains makefile dependences.  Write out this
307      structure.  */
308
309   /* The number of dependences.  */
310   if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1)
311       return -1;
312   /* The length of each dependence followed by the string.  */
313   for (i = 0; i < deps->ndeps; i++)
314     {
315       size_t num_to_write = strlen (deps->depv[i]);
316       if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1)
317           return -1;
318       if (fwrite (deps->depv[i], num_to_write, 1, f) != 1)
319           return -1;
320     }
321
322   return 0;
323 }
324
325 /* Read back dependency information written with deps_save into
326    the deps buffer.  The third argument may be NULL, in which case
327    the dependency information is just skipped, or it may be a filename,
328    in which case that filename is skipped.  */
329
330 int
331 deps_restore (deps, fd, self)
332      struct deps *deps;
333      FILE *fd;
334      const char *self;
335 {
336   unsigned int i, count;
337   size_t num_to_read;
338   size_t buf_size = 512;
339   char *buf = (char *) xmalloc (buf_size);
340
341   /* Number of dependences.  */
342   if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
343     return -1;
344
345   /* The length of each dependence string, followed by the string.  */
346   for (i = 0; i < count; i++)
347     {
348       /* Read in # bytes in string.  */
349       if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
350         return -1;
351       if (buf_size < num_to_read + 1)
352         {
353           buf_size = num_to_read + 1 + 127;
354           buf = xrealloc (buf, buf_size);
355         }
356       if (fread (buf, 1, num_to_read, fd) != num_to_read)
357         return -1;
358       buf[num_to_read] = '\0';
359
360       /* Generate makefile dependencies from .pch if -nopch-deps.  */ 
361       if (self != NULL && strcmp (buf, self) != 0)
362         deps_add_dep (deps, buf);
363     }
364
365   free (buf);
366   return 0;
367 }