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