]>
Commit | Line | Data |
---|---|---|
49e6c08e | 1 | /* Dependency generator for Makefile fragments. |
03b9ab42 | 2 | Copyright (C) 2000, 2001 Free Software Foundation, Inc. |
49e6c08e ZW |
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 | ||
03b9ab42 NB |
27 | /* Keep this structure local to this file, so clients don't find it |
28 | easy to start making assumptions. */ | |
29 | struct 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 | ||
49e6c08e | 40 | static const char *munge PARAMS ((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.) */ | |
48 | ||
49 | static const char * | |
50 | munge (filename) | |
51 | const char *filename; | |
52 | { | |
53 | int len; | |
54 | const char *p, *q; | |
55 | char *dst, *buffer; | |
56 | ||
57 | for (p = filename, len = 0; *p; p++, len++) | |
58 | { | |
59 | switch (*p) | |
60 | { | |
61 | case ' ': | |
62 | case '\t': | |
63 | /* GNU make uses a weird quoting scheme for white space. | |
64 | A space or tab preceded by 2N+1 backslashes represents | |
65 | N backslashes followed by space; a space or tab | |
66 | preceded by 2N backslashes represents N backslashes at | |
67 | the end of a file name; and backslashes in other | |
68 | contexts should not be doubled. */ | |
e23c0ba3 | 69 | for (q = p - 1; filename <= q && *q == '\\'; q--) |
49e6c08e ZW |
70 | len++; |
71 | len++; | |
72 | break; | |
73 | ||
74 | case '$': | |
a5a4ce3c | 75 | /* '$' is quoted by doubling it. */ |
49e6c08e ZW |
76 | len++; |
77 | break; | |
78 | } | |
79 | } | |
80 | ||
81 | /* Now we know how big to make the buffer. */ | |
dd3b81b4 | 82 | buffer = xmalloc (len + 1); |
49e6c08e ZW |
83 | |
84 | for (p = filename, dst = buffer; *p; p++, dst++) | |
85 | { | |
86 | switch (*p) | |
87 | { | |
88 | case ' ': | |
89 | case '\t': | |
e23c0ba3 | 90 | for (q = p - 1; filename <= q && *q == '\\'; q--) |
49e6c08e ZW |
91 | *dst++ = '\\'; |
92 | *dst++ = '\\'; | |
93 | break; | |
94 | ||
95 | case '$': | |
96 | *dst++ = '$'; | |
97 | break; | |
98 | ||
99 | default: | |
100 | /* nothing */; | |
101 | } | |
102 | *dst = *p; | |
103 | } | |
104 | ||
105 | *dst = '\0'; | |
106 | return buffer; | |
107 | } | |
108 | ||
49e6c08e ZW |
109 | /* Public routines. */ |
110 | ||
111 | struct deps * | |
fd05eb80 | 112 | deps_init () |
49e6c08e ZW |
113 | { |
114 | struct deps *d = (struct deps *) xmalloc (sizeof (struct deps)); | |
115 | ||
f7114e17 | 116 | /* Allocate space for the vectors only if we need it. */ |
49e6c08e | 117 | |
f7114e17 NB |
118 | d->targetv = 0; |
119 | d->depv = 0; | |
49e6c08e ZW |
120 | |
121 | d->ntargets = 0; | |
f7114e17 | 122 | d->targets_size = 0; |
49e6c08e | 123 | d->ndeps = 0; |
f7114e17 | 124 | d->deps_size = 0; |
49e6c08e ZW |
125 | |
126 | return d; | |
127 | } | |
128 | ||
129 | void | |
130 | deps_free (d) | |
131 | struct deps *d; | |
132 | { | |
133 | unsigned int i; | |
05bccae2 | 134 | |
f7114e17 NB |
135 | if (d->targetv) |
136 | { | |
137 | for (i = 0; i < d->ntargets; i++) | |
138 | free ((PTR) d->targetv[i]); | |
139 | free (d->targetv); | |
140 | } | |
05bccae2 | 141 | |
f7114e17 NB |
142 | if (d->depv) |
143 | { | |
144 | for (i = 0; i < d->ndeps; i++) | |
145 | free ((PTR) d->depv[i]); | |
146 | free (d->depv); | |
147 | } | |
49e6c08e | 148 | |
49e6c08e ZW |
149 | free (d); |
150 | } | |
151 | ||
a5a4ce3c NB |
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. */ | |
49e6c08e | 154 | void |
a5a4ce3c | 155 | deps_add_target (d, t, quote) |
49e6c08e ZW |
156 | struct deps *d; |
157 | const char *t; | |
a5a4ce3c | 158 | int quote; |
49e6c08e | 159 | { |
49e6c08e ZW |
160 | if (d->ntargets == d->targets_size) |
161 | { | |
f7114e17 | 162 | d->targets_size = d->targets_size * 2 + 4; |
7ceb3598 | 163 | d->targetv = (const char **) xrealloc (d->targetv, |
49e6c08e ZW |
164 | d->targets_size * sizeof (const char *)); |
165 | } | |
05bccae2 | 166 | |
a5a4ce3c NB |
167 | if (quote) |
168 | t = munge (t); /* Also makes permanent copy. */ | |
169 | else | |
170 | t = xstrdup (t); | |
171 | ||
49e6c08e ZW |
172 | d->targetv[d->ntargets++] = t; |
173 | } | |
174 | ||
03b9ab42 | 175 | /* Sets the default target if none has been given already. An empty |
a5a4ce3c NB |
176 | string as the default target in interpreted as stdin. The string |
177 | is quoted for MAKE. */ | |
49e6c08e | 178 | void |
03b9ab42 | 179 | deps_add_default_target (d, tgt) |
49e6c08e | 180 | struct deps *d; |
03b9ab42 | 181 | const char *tgt; |
49e6c08e | 182 | { |
03b9ab42 NB |
183 | /* Only if we have no targets. */ |
184 | if (d->ntargets) | |
185 | return; | |
49e6c08e | 186 | |
03b9ab42 | 187 | if (tgt[0] == '\0') |
a5a4ce3c | 188 | deps_add_target (d, "-", 1); |
49e6c08e | 189 | else |
03b9ab42 | 190 | { |
45936a85 DD |
191 | #ifndef TARGET_OBJECT_SUFFIX |
192 | # define TARGET_OBJECT_SUFFIX ".o" | |
03b9ab42 | 193 | #endif |
2251fd78 | 194 | char *start = lbasename (tgt); |
45936a85 | 195 | char *o = (char *) alloca (strlen (start) + strlen (TARGET_OBJECT_SUFFIX) + 1); |
48ce6bbb | 196 | char *suffix; |
03b9ab42 | 197 | |
48ce6bbb NS |
198 | strcpy (o, start); |
199 | ||
200 | suffix = strrchr (o, '.'); | |
201 | if (!suffix) | |
202 | suffix = o + strlen (o); | |
45936a85 | 203 | strcpy (suffix, TARGET_OBJECT_SUFFIX); |
48ce6bbb | 204 | |
a5a4ce3c | 205 | deps_add_target (d, o, 1); |
03b9ab42 | 206 | } |
49e6c08e ZW |
207 | } |
208 | ||
209 | void | |
210 | deps_add_dep (d, t) | |
211 | struct deps *d; | |
212 | const char *t; | |
213 | { | |
214 | t = munge (t); /* Also makes permanent copy. */ | |
215 | ||
216 | if (d->ndeps == d->deps_size) | |
217 | { | |
fa6f74f6 | 218 | d->deps_size = d->deps_size * 2 + 8; |
7ceb3598 NB |
219 | d->depv = (const char **) |
220 | xrealloc (d->depv, d->deps_size * sizeof (const char *)); | |
49e6c08e ZW |
221 | } |
222 | d->depv[d->ndeps++] = t; | |
223 | } | |
224 | ||
225 | void | |
226 | deps_write (d, fp, colmax) | |
227 | const struct deps *d; | |
228 | FILE *fp; | |
229 | unsigned int colmax; | |
230 | { | |
231 | unsigned int size, i, column; | |
232 | ||
233 | column = 0; | |
234 | if (colmax && colmax < 34) | |
235 | colmax = 34; | |
236 | ||
237 | for (i = 0; i < d->ntargets; i++) | |
238 | { | |
239 | size = strlen (d->targetv[i]); | |
240 | column += size; | |
241 | if (colmax && column > colmax) | |
242 | { | |
243 | fputs (" \\\n ", fp); | |
244 | column = 1 + size; | |
245 | } | |
246 | if (i) | |
247 | { | |
248 | putc (' ', fp); | |
249 | column++; | |
250 | } | |
251 | fputs (d->targetv[i], fp); | |
252 | } | |
253 | ||
254 | putc (':', fp); | |
255 | putc (' ', fp); | |
256 | column += 2; | |
257 | ||
258 | for (i = 0; i < d->ndeps; i++) | |
259 | { | |
260 | size = strlen (d->depv[i]); | |
261 | column += size; | |
262 | if (colmax && column > colmax) | |
263 | { | |
264 | fputs (" \\\n ", fp); | |
265 | column = 1 + size; | |
266 | } | |
267 | if (i) | |
268 | { | |
269 | putc (' ', fp); | |
270 | column++; | |
271 | } | |
272 | fputs (d->depv[i], fp); | |
273 | } | |
274 | putc ('\n', fp); | |
275 | } | |
276 | ||
277 | void | |
a5a4ce3c | 278 | deps_phony_targets (d, fp) |
49e6c08e ZW |
279 | const struct deps *d; |
280 | FILE *fp; | |
281 | { | |
05bccae2 | 282 | unsigned int i; |
49e6c08e ZW |
283 | |
284 | for (i = 1; i < d->ndeps; i++) | |
285 | { | |
a5a4ce3c | 286 | putc ('\n', fp); |
49e6c08e ZW |
287 | fputs (d->depv[i], fp); |
288 | putc (':', fp); | |
289 | putc ('\n', fp); | |
290 | } | |
291 | } |