* src/mcs51/peeph.def: renamed rule 400 to 500, moved rule 253.x to 400.x for better...
[fw/sdcc] / support / cpp2 / mkdeps.c
1 /* Dependency generator for Makefile fragments.
2    Copyright (C) 2000, 2001, 2003 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 "mkdeps.h"
26 #include "cpplib.h"
27 #include "cpphash.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 (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 (const char *filename)
53 {
54   int len;
55   const char *p, *q;
56   char *dst, *buffer;
57
58   for (p = filename, len = 0; *p; p++, len++)
59     {
60       switch (*p)
61         {
62         case ' ':
63         case '\t':
64           /* GNU make uses a weird quoting scheme for white space.
65              A space or tab preceded by 2N+1 backslashes represents
66              N backslashes followed by space; a space or tab
67              preceded by 2N backslashes represents N backslashes at
68              the end of a file name; and backslashes in other
69              contexts should not be doubled.  */
70           for (q = p - 1; filename <= q && *q == '\\';  q--)
71             len++;
72           len++;
73           break;
74
75         case '$':
76           /* '$' is quoted by doubling it.  */
77           len++;
78           break;
79         }
80     }
81
82   /* Now we know how big to make the buffer.  */
83   buffer = xmalloc (len + 1);
84
85   for (p = filename, dst = buffer; *p; p++, dst++)
86     {
87       switch (*p)
88         {
89         case ' ':
90         case '\t':
91           for (q = p - 1; filename <= q && *q == '\\';  q--)
92             *dst++ = '\\';
93           *dst++ = '\\';
94           break;
95
96         case '$':
97           *dst++ = '$';
98           break;
99
100         default:
101           /* nothing */;
102         }
103       *dst = *p;
104     }
105
106   *dst = '\0';
107   return buffer;
108 }
109
110 /* Public routines.  */
111
112 struct deps *
113 deps_init (void)
114 {
115   struct deps *d = xmalloc (sizeof (struct deps));
116
117   /* Allocate space for the vectors only if we need it.  */
118
119   d->targetv = 0;
120   d->depv = 0;
121
122   d->ntargets = 0;
123   d->targets_size = 0;
124   d->ndeps = 0;
125   d->deps_size = 0;
126
127   return d;
128 }
129
130 void
131 deps_free (struct deps *d)
132 {
133   unsigned int i;
134
135   if (d->targetv)
136     {
137       for (i = 0; i < d->ntargets; i++)
138         free ((void *) d->targetv[i]);
139       free (d->targetv);
140     }
141
142   if (d->depv)
143     {
144       for (i = 0; i < d->ndeps; i++)
145         free ((void *) d->depv[i]);
146       free (d->depv);
147     }
148
149   free (d);
150 }
151
152 /* Adds a target T.  We make a copy, so it need not be a permanent
153    string.  QUOTE is true if the string should be quoted.  */
154 void
155 deps_add_target (struct deps *d, const char *t, int quote)
156 {
157   if (d->ntargets == d->targets_size)
158     {
159       d->targets_size = d->targets_size * 2 + 4;
160       d->targetv = xrealloc (d->targetv,
161                              d->targets_size * sizeof (const char *));
162     }
163
164   if (quote)
165     t = munge (t);  /* Also makes permanent copy.  */
166   else
167     t = xstrdup (t);
168
169   d->targetv[d->ntargets++] = t;
170 }
171
172 /* Sets the default target if none has been given already.  An empty
173    string as the default target in interpreted as stdin.  The string
174    is quoted for MAKE.  */
175 void
176 deps_add_default_target (cpp_reader *pfile, const char *tgt)
177 {
178   struct deps *d = pfile->deps;
179
180   /* Only if we have no targets.  */
181   if (d->ntargets)
182     return;
183
184   if (tgt[0] == '\0')
185     deps_add_target (d, "-", 1);
186   else
187     {
188 #ifndef TARGET_OBJECT_SUFFIX
189 # define TARGET_OBJECT_SUFFIX ".o"
190 #endif
191       const char *start = lbasename (tgt);
192       char *o;
193       char *suffix;
194       const char *obj_ext;
195
196       if (NULL == CPP_OPTION (pfile, obj_ext))
197         obj_ext = TARGET_OBJECT_SUFFIX;
198       else if (CPP_OPTION (pfile, obj_ext)[0] != '.')
199         {
200           char *t = alloca (strlen (CPP_OPTION (pfile, obj_ext)) + 2);
201           t[0] = '.';
202           strcpy (&t[1], CPP_OPTION (pfile, obj_ext));
203           obj_ext = t;
204         }
205       else
206         obj_ext = CPP_OPTION (pfile, obj_ext);
207
208       o = (char *) alloca (strlen (start) + strlen (obj_ext) + 1);
209
210       strcpy (o, start);
211
212       suffix = strrchr (o, '.');
213       if (!suffix)
214         suffix = o + strlen (o);
215       strcpy (suffix, obj_ext);
216
217       deps_add_target (d, o, 1);
218     }
219 }
220
221 void
222 deps_add_dep (struct deps *d, const char *t)
223 {
224   t = munge (t);  /* Also makes permanent copy.  */
225
226   if (d->ndeps == d->deps_size)
227     {
228       d->deps_size = d->deps_size * 2 + 8;
229       d->depv = xrealloc (d->depv, d->deps_size * sizeof (const char *));
230     }
231   d->depv[d->ndeps++] = t;
232 }
233
234 void
235 deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
236 {
237   unsigned int size, i, column;
238
239   column = 0;
240   if (colmax && colmax < 34)
241     colmax = 34;
242
243   for (i = 0; i < d->ntargets; i++)
244     {
245       size = strlen (d->targetv[i]);
246       column += size;
247       if (colmax && column > colmax)
248         {
249           fputs (" \\\n ", fp);
250           column = 1 + size;
251         }
252       if (i)
253         {
254           putc (' ', fp);
255           column++;
256         }
257       fputs (d->targetv[i], fp);
258     }
259
260   putc (':', fp);
261   putc (' ', fp);
262   column += 2;
263
264   for (i = 0; i < d->ndeps; i++)
265     {
266       size = strlen (d->depv[i]);
267       column += size;
268       if (colmax && column > colmax)
269         {
270           fputs (" \\\n ", fp);
271           column = 1 + size;
272         }
273       if (i)
274         {
275           putc (' ', fp);
276           column++;
277         }
278       fputs (d->depv[i], fp);
279     }
280   putc ('\n', fp);
281 }
282
283 void
284 deps_phony_targets (const struct deps *d, FILE *fp)
285 {
286   unsigned int i;
287
288   for (i = 1; i < d->ndeps; i++)
289     {
290       putc ('\n', fp);
291       fputs (d->depv[i], fp);
292       putc (':', fp);
293       putc ('\n', fp);
294     }
295 }
296
297 /* Write out a deps buffer to a file, in a form that can be read back
298    with deps_restore.  Returns nonzero on error, in which case the
299    error number will be in errno.  */
300
301 int
302 deps_save (struct deps *deps, 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 (struct deps *deps, FILE *fd, const char *self)
332 {
333   unsigned int i, count;
334   size_t num_to_read;
335   size_t buf_size = 512;
336   char *buf = xmalloc (buf_size);
337
338   /* Number of dependences.  */
339   if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
340     return -1;
341
342   /* The length of each dependence string, followed by the string.  */
343   for (i = 0; i < count; i++)
344     {
345       /* Read in # bytes in string.  */
346       if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
347         return -1;
348       if (buf_size < num_to_read + 1)
349         {
350           buf_size = num_to_read + 1 + 127;
351           buf = xrealloc (buf, buf_size);
352         }
353       if (fread (buf, 1, num_to_read, fd) != num_to_read)
354         return -1;
355       buf[num_to_read] = '\0';
356
357       /* Generate makefile dependencies from .pch if -nopch-deps.  */
358       if (self != NULL && strcmp (buf, self) != 0)
359         deps_add_dep (deps, buf);
360     }
361
362   free (buf);
363   return 0;
364 }