]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/mkdeps.c
Daily bump.
[thirdparty/gcc.git] / gcc / mkdeps.c
CommitLineData
49e6c08e
ZW
1/* Dependency generator for Makefile fragments.
2 Copyright (C) 2000 Free Software Foundation, Inc.
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
27static const char *munge PARAMS ((const char *));
28static const char *base_name PARAMS ((const char *));
29
30#ifndef OBJECT_SUFFIX
31# define OBJECT_SUFFIX ".o"
32#endif
33
34/* Given a filename, quote characters in that filename which are
35 significant to Make. Note that it's not possible to quote all such
36 characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
37 not properly handled. It isn't possible to get this right in any
38 current version of Make. (??? Still true? Old comment referred to
39 3.76.1.) */
40
41static const char *
42munge (filename)
43 const char *filename;
44{
45 int len;
46 const char *p, *q;
47 char *dst, *buffer;
48
49 for (p = filename, len = 0; *p; p++, len++)
50 {
51 switch (*p)
52 {
53 case ' ':
54 case '\t':
55 /* GNU make uses a weird quoting scheme for white space.
56 A space or tab preceded by 2N+1 backslashes represents
57 N backslashes followed by space; a space or tab
58 preceded by 2N backslashes represents N backslashes at
59 the end of a file name; and backslashes in other
60 contexts should not be doubled. */
e23c0ba3 61 for (q = p - 1; filename <= q && *q == '\\'; q--)
49e6c08e
ZW
62 len++;
63 len++;
64 break;
65
66 case '$':
67 /* '$' is quoted by doubling it. This can mishandle things
68 like "$(" but there's no easy fix. */
69 len++;
70 break;
71 }
72 }
73
74 /* Now we know how big to make the buffer. */
dd3b81b4 75 buffer = xmalloc (len + 1);
49e6c08e
ZW
76
77 for (p = filename, dst = buffer; *p; p++, dst++)
78 {
79 switch (*p)
80 {
81 case ' ':
82 case '\t':
e23c0ba3 83 for (q = p - 1; filename <= q && *q == '\\'; q--)
49e6c08e
ZW
84 *dst++ = '\\';
85 *dst++ = '\\';
86 break;
87
88 case '$':
89 *dst++ = '$';
90 break;
91
92 default:
93 /* nothing */;
94 }
95 *dst = *p;
96 }
97
98 *dst = '\0';
99 return buffer;
100}
101
102/* Given a pathname, calculate the non-directory part. This always
103 knows how to handle Unix-style pathnames, and understands VMS and
104 DOS paths on those systems. */
05bccae2 105
49e6c08e
ZW
106/* Find the base name of a (partial) pathname FNAME.
107 Returns a pointer into the string passed in.
108 Accepts Unix (/-separated) paths on all systems,
109 DOS and VMS paths on those systems. */
05bccae2 110
49e6c08e
ZW
111static const char *
112base_name (fname)
113 const char *fname;
114{
115 const char *s = fname;
116 const char *p;
117#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
118 if (ISALPHA (s[0]) && s[1] == ':') s += 2;
119 if ((p = strrchr (s, '\\'))) s = p + 1;
120#elif defined VMS
121 if ((p = strrchr (s, ':'))) s = p + 1; /* Skip device. */
122 if ((p = strrchr (s, ']'))) s = p + 1; /* Skip directory. */
123 if ((p = strrchr (s, '>'))) s = p + 1; /* Skip alternate (int'n'l) dir. */
124#endif
125 if ((p = strrchr (s, '/'))) s = p + 1;
126 return s;
127}
128
129/* Public routines. */
130
131struct deps *
fd05eb80 132deps_init ()
49e6c08e
ZW
133{
134 struct deps *d = (struct deps *) xmalloc (sizeof (struct deps));
135
136 /* Allocate space for the vectors now. */
137
e23c0ba3
ZW
138 d->targetv = (const char **) xmalloc (2 * sizeof (const char *));
139 d->depv = (const char **) xmalloc (8 * sizeof (const char *));
49e6c08e
ZW
140
141 d->ntargets = 0;
142 d->targets_size = 2;
143 d->ndeps = 0;
144 d->deps_size = 8;
145
146 return d;
147}
148
149void
150deps_free (d)
151 struct deps *d;
152{
153 unsigned int i;
05bccae2 154
49e6c08e
ZW
155 for (i = 0; i < d->ntargets; i++)
156 free ((PTR) d->targetv[i]);
05bccae2 157
49e6c08e
ZW
158 for (i = 0; i < d->ndeps; i++)
159 free ((PTR) d->depv[i]);
160
161 free (d->targetv);
162 free (d->depv);
163 free (d);
164}
165
166void
167deps_add_target (d, t)
168 struct deps *d;
169 const char *t;
170{
171 t = munge (t); /* Also makes permanent copy. */
172
173 if (d->ntargets == d->targets_size)
174 {
175 d->targets_size *= 2;
7ceb3598 176 d->targetv = (const char **) xrealloc (d->targetv,
49e6c08e
ZW
177 d->targets_size * sizeof (const char *));
178 }
05bccae2 179
49e6c08e
ZW
180 d->targetv[d->ntargets++] = t;
181}
182
183void
184deps_calc_target (d, t)
185 struct deps *d;
186 const char *t;
187{
92df03e1 188 char *o, *suffix;
49e6c08e
ZW
189
190 t = base_name (t);
e23c0ba3 191 o = (char *) alloca (strlen (t) + 8);
49e6c08e
ZW
192
193 strcpy (o, t);
194 suffix = strrchr (o, '.');
195 if (suffix)
196 strcpy (suffix, OBJECT_SUFFIX);
197 else
198 strcat (o, OBJECT_SUFFIX);
199
200 deps_add_target (d, o);
201}
202
203void
204deps_add_dep (d, t)
205 struct deps *d;
206 const char *t;
207{
208 t = munge (t); /* Also makes permanent copy. */
209
210 if (d->ndeps == d->deps_size)
211 {
212 d->deps_size *= 2;
7ceb3598
NB
213 d->depv = (const char **)
214 xrealloc (d->depv, d->deps_size * sizeof (const char *));
49e6c08e
ZW
215 }
216 d->depv[d->ndeps++] = t;
217}
218
219void
220deps_write (d, fp, colmax)
221 const struct deps *d;
222 FILE *fp;
223 unsigned int colmax;
224{
225 unsigned int size, i, column;
226
227 column = 0;
228 if (colmax && colmax < 34)
229 colmax = 34;
230
231 for (i = 0; i < d->ntargets; i++)
232 {
233 size = strlen (d->targetv[i]);
234 column += size;
235 if (colmax && column > colmax)
236 {
237 fputs (" \\\n ", fp);
238 column = 1 + size;
239 }
240 if (i)
241 {
242 putc (' ', fp);
243 column++;
244 }
245 fputs (d->targetv[i], fp);
246 }
247
248 putc (':', fp);
249 putc (' ', fp);
250 column += 2;
251
252 for (i = 0; i < d->ndeps; i++)
253 {
254 size = strlen (d->depv[i]);
255 column += size;
256 if (colmax && column > colmax)
257 {
258 fputs (" \\\n ", fp);
259 column = 1 + size;
260 }
261 if (i)
262 {
263 putc (' ', fp);
264 column++;
265 }
266 fputs (d->depv[i], fp);
267 }
268 putc ('\n', fp);
269}
270
271void
272deps_dummy_targets (d, fp)
273 const struct deps *d;
274 FILE *fp;
275{
05bccae2 276 unsigned int i;
49e6c08e
ZW
277
278 for (i = 1; i < d->ndeps; i++)
279 {
280 fputs (d->depv[i], fp);
281 putc (':', fp);
282 putc ('\n', fp);
283 }
284}