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