| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: targ.c,v 1.76 2020/08/28 04:48:57 rillig Exp $ */ | | 1 | /* $NetBSD: targ.c,v 1.77 2020/08/28 19:14:07 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | | 4 | * Copyright (c) 1988, 1989, 1990, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -59,43 +59,42 @@ | | | @@ -59,43 +59,42 @@ |
59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
68 | * SUCH DAMAGE. | | 68 | * SUCH DAMAGE. |
69 | */ | | 69 | */ |
70 | | | 70 | |
71 | #ifndef MAKE_NATIVE | | 71 | #ifndef MAKE_NATIVE |
72 | static char rcsid[] = "$NetBSD: targ.c,v 1.76 2020/08/28 04:48:57 rillig Exp $"; | | 72 | static char rcsid[] = "$NetBSD: targ.c,v 1.77 2020/08/28 19:14:07 rillig Exp $"; |
73 | #else | | 73 | #else |
74 | #include <sys/cdefs.h> | | 74 | #include <sys/cdefs.h> |
75 | #ifndef lint | | 75 | #ifndef lint |
76 | #if 0 | | 76 | #if 0 |
77 | static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; | | 77 | static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; |
78 | #else | | 78 | #else |
79 | __RCSID("$NetBSD: targ.c,v 1.76 2020/08/28 04:48:57 rillig Exp $"); | | 79 | __RCSID("$NetBSD: targ.c,v 1.77 2020/08/28 19:14:07 rillig Exp $"); |
80 | #endif | | 80 | #endif |
81 | #endif /* not lint */ | | 81 | #endif /* not lint */ |
82 | #endif | | 82 | #endif |
83 | | | 83 | |
84 | /*- | | 84 | /*- |
85 | * targ.c -- | | 85 | * targ.c -- |
86 | * Functions for maintaining the Lst allTargets. Target nodes are | | 86 | * Functions for maintaining the Lst allTargets. Target nodes are |
87 | * kept in two structures: a Lst, maintained by the list library, and a | | 87 | * kept in two structures: a Lst and a hash table. |
88 | * hash table, maintained by the hash library. | | | |
89 | * | | 88 | * |
90 | * Interface: | | 89 | * Interface: |
91 | * Targ_Init Initialization procedure. | | 90 | * Targ_Init Initialization procedure. |
92 | * | | 91 | * |
93 | * Targ_End Cleanup the module | | 92 | * Targ_End Cleanup the module |
94 | * | | 93 | * |
95 | * Targ_List Return the list of all targets so far. | | 94 | * Targ_List Return the list of all targets so far. |
96 | * | | 95 | * |
97 | * Targ_NewGN Create a new GNode for the passed target | | 96 | * Targ_NewGN Create a new GNode for the passed target |
98 | * (string). The node is *not* placed in the | | 97 | * (string). The node is *not* placed in the |
99 | * hash table, though all its fields are | | 98 | * hash table, though all its fields are |
100 | * initialized. | | 99 | * initialized. |
101 | * | | 100 | * |
| @@ -123,227 +122,160 @@ __RCSID("$NetBSD: targ.c,v 1.76 2020/08/ | | | @@ -123,227 +122,160 @@ __RCSID("$NetBSD: targ.c,v 1.76 2020/08/ |
123 | * makefiles are parsed but before any | | 122 | * makefiles are parsed but before any |
124 | * action is taken. | | 123 | * action is taken. |
125 | * | | 124 | * |
126 | * Debugging: | | 125 | * Debugging: |
127 | * Targ_PrintGraph Print out the entire graphm all variables | | 126 | * Targ_PrintGraph Print out the entire graphm all variables |
128 | * and statistics for the directory cache. Should | | 127 | * and statistics for the directory cache. Should |
129 | * print something for suffixes, too, but... | | 128 | * print something for suffixes, too, but... |
130 | */ | | 129 | */ |
131 | | | 130 | |
132 | #include <stdio.h> | | 131 | #include <stdio.h> |
133 | #include <time.h> | | 132 | #include <time.h> |
134 | | | 133 | |
135 | #include "make.h" | | 134 | #include "make.h" |
136 | #include "hash.h" | | | |
137 | #include "dir.h" | | 135 | #include "dir.h" |
138 | | | 136 | |
139 | static Lst allTargets; /* the list of all targets found so far */ | | 137 | static Lst allTargets; /* the list of all targets found so far */ |
140 | #ifdef CLEANUP | | 138 | #ifdef CLEANUP |
141 | static Lst allGNs; /* List of all the GNodes */ | | 139 | static Lst allGNs; /* List of all the GNodes */ |
142 | #endif | | 140 | #endif |
143 | static Hash_Table targets; /* a hash table of same */ | | 141 | static Hash_Table targets; /* a hash table of same */ |
144 | | | 142 | |
145 | #define HTSIZE 191 /* initial size of hash table */ | | 143 | #define HTSIZE 191 /* initial size of hash table */ |
146 | | | 144 | |
147 | static int TargPrintOnlySrc(void *, void *); | | 145 | static int TargPrintOnlySrc(void *, void *); |
148 | static int TargPrintName(void *, void *); | | 146 | static int TargPrintName(void *, void *); |
149 | #ifdef CLEANUP | | 147 | #ifdef CLEANUP |
150 | static void TargFreeGN(void *); | | 148 | static void TargFreeGN(void *); |
151 | #endif | | 149 | #endif |
152 | static int TargPropagateCohort(void *, void *); | | 150 | static int TargPropagateCohort(void *, void *); |
153 | static int TargPropagateNode(void *, void *); | | 151 | static int TargPropagateNode(void *, void *); |
154 | | | 152 | |
155 | /*- | | | |
156 | *----------------------------------------------------------------------- | | | |
157 | * Targ_Init -- | | | |
158 | * Initialize this module | | | |
159 | * | | | |
160 | * Results: | | | |
161 | * None | | | |
162 | * | | | |
163 | * Side Effects: | | | |
164 | * The allTargets list and the targets hash table are initialized | | | |
165 | *----------------------------------------------------------------------- | | | |
166 | */ | | | |
167 | void | | 153 | void |
168 | Targ_Init(void) | | 154 | Targ_Init(void) |
169 | { | | 155 | { |
170 | allTargets = Lst_Init(); | | 156 | allTargets = Lst_Init(); |
171 | Hash_InitTable(&targets, HTSIZE); | | 157 | Hash_InitTable(&targets, HTSIZE); |
172 | } | | 158 | } |
173 | | | 159 | |
174 | /*- | | | |
175 | *----------------------------------------------------------------------- | | | |
176 | * Targ_End -- | | | |
177 | * Finalize this module | | | |
178 | * | | | |
179 | * Results: | | | |
180 | * None | | | |
181 | * | | | |
182 | * Side Effects: | | | |
183 | * All lists and gnodes are cleared | | | |
184 | *----------------------------------------------------------------------- | | | |
185 | */ | | | |
186 | void | | 160 | void |
187 | Targ_End(void) | | 161 | Targ_End(void) |
188 | { | | 162 | { |
189 | Targ_Stats(); | | 163 | Targ_Stats(); |
190 | #ifdef CLEANUP | | 164 | #ifdef CLEANUP |
191 | Lst_Free(allTargets); | | 165 | Lst_Free(allTargets); |
192 | if (allGNs != NULL) | | 166 | if (allGNs != NULL) |
193 | Lst_Destroy(allGNs, TargFreeGN); | | 167 | Lst_Destroy(allGNs, TargFreeGN); |
194 | Hash_DeleteTable(&targets); | | 168 | Hash_DeleteTable(&targets); |
195 | #endif | | 169 | #endif |
196 | } | | 170 | } |
197 | | | 171 | |
198 | void | | 172 | void |
199 | Targ_Stats(void) | | 173 | Targ_Stats(void) |
200 | { | | 174 | { |
201 | Hash_DebugStats(&targets, "targets"); | | 175 | Hash_DebugStats(&targets, "targets"); |
202 | } | | 176 | } |
203 | | | 177 | |
204 | /*- | | 178 | /* Return the list of all targets. */ |
205 | *----------------------------------------------------------------------- | | | |
206 | * Targ_List -- | | | |
207 | * Return the list of all targets | | | |
208 | * | | | |
209 | * Results: | | | |
210 | * The list of all targets. | | | |
211 | * | | | |
212 | * Side Effects: | | | |
213 | * None | | | |
214 | *----------------------------------------------------------------------- | | | |
215 | */ | | | |
216 | Lst | | 179 | Lst |
217 | Targ_List(void) | | 180 | Targ_List(void) |
218 | { | | 181 | { |
219 | return allTargets; | | 182 | return allTargets; |
220 | } | | 183 | } |
221 | | | 184 | |
222 | /*- | | 185 | /* Create and initialize a new graph node. The gnode is added to the list of |
223 | *----------------------------------------------------------------------- | | 186 | * all gnodes. |
224 | * Targ_NewGN -- | | | |
225 | * Create and initialize a new graph node | | | |
226 | * | | 187 | * |
227 | * Input: | | 188 | * Input: |
228 | * name the name to stick in the new node | | 189 | * name the name of the node, such as "clean", "src.c" |
229 | * | | | |
230 | * Results: | | | |
231 | * An initialized graph node with the name field filled with a copy | | | |
232 | * of the passed name | | | |
233 | * | | | |
234 | * Side Effects: | | | |
235 | * The gnode is added to the list of all gnodes. | | | |
236 | *----------------------------------------------------------------------- | | | |
237 | */ | | 190 | */ |
238 | GNode * | | 191 | GNode * |
239 | Targ_NewGN(const char *name) | | 192 | Targ_NewGN(const char *name) |
240 | { | | 193 | { |
241 | GNode *gn; | | 194 | GNode *gn; |
242 | | | 195 | |
243 | gn = bmake_malloc(sizeof(GNode)); | | 196 | gn = bmake_malloc(sizeof(GNode)); |
244 | gn->name = bmake_strdup(name); | | 197 | gn->name = bmake_strdup(name); |
245 | gn->uname = NULL; | | 198 | gn->uname = NULL; |
246 | gn->path = NULL; | | 199 | gn->path = NULL; |
247 | if (name[0] == '-' && name[1] == 'l') { | | 200 | gn->type = name[0] == '-' && name[1] == 'l' ? OP_LIB : 0; |
248 | gn->type = OP_LIB; | | | |
249 | } else { | | | |
250 | gn->type = 0; | | | |
251 | } | | | |
252 | gn->unmade = 0; | | 201 | gn->unmade = 0; |
253 | gn->unmade_cohorts = 0; | | 202 | gn->unmade_cohorts = 0; |
254 | gn->cohort_num[0] = 0; | | 203 | gn->cohort_num[0] = 0; |
255 | gn->centurion = NULL; | | 204 | gn->centurion = NULL; |
256 | gn->made = UNMADE; | | 205 | gn->made = UNMADE; |
257 | gn->flags = 0; | | 206 | gn->flags = 0; |
258 | gn->checked = 0; | | 207 | gn->checked = 0; |
259 | gn->mtime = 0; | | 208 | gn->mtime = 0; |
260 | gn->cmgn = NULL; | | 209 | gn->cmgn = NULL; |
261 | gn->iParents = Lst_Init(); | | 210 | gn->iParents = Lst_Init(); |
262 | gn->cohorts = Lst_Init(); | | 211 | gn->cohorts = Lst_Init(); |
263 | gn->parents = Lst_Init(); | | 212 | gn->parents = Lst_Init(); |
264 | gn->children = Lst_Init(); | | 213 | gn->children = Lst_Init(); |
265 | gn->order_pred = Lst_Init(); | | 214 | gn->order_pred = Lst_Init(); |
266 | gn->order_succ = Lst_Init(); | | 215 | gn->order_succ = Lst_Init(); |
267 | Hash_InitTable(&gn->context, 0); | | 216 | Hash_InitTable(&gn->context, 0); |
268 | gn->commands = Lst_Init(); | | 217 | gn->commands = Lst_Init(); |
269 | gn->suffix = NULL; | | 218 | gn->suffix = NULL; |
270 | gn->lineno = 0; | | | |
271 | gn->fname = NULL; | | 219 | gn->fname = NULL; |
| | | 220 | gn->lineno = 0; |
272 | | | 221 | |
273 | #ifdef CLEANUP | | 222 | #ifdef CLEANUP |
274 | if (allGNs == NULL) | | 223 | if (allGNs == NULL) |
275 | allGNs = Lst_Init(); | | 224 | allGNs = Lst_Init(); |
276 | Lst_Append(allGNs, gn); | | 225 | Lst_Append(allGNs, gn); |
277 | #endif | | 226 | #endif |
278 | | | 227 | |
279 | return gn; | | 228 | return gn; |
280 | } | | 229 | } |
281 | | | 230 | |
282 | #ifdef CLEANUP | | 231 | #ifdef CLEANUP |
283 | /*- | | | |
284 | *----------------------------------------------------------------------- | | | |
285 | * TargFreeGN -- | | | |
286 | * Destroy a GNode | | | |
287 | * | | | |
288 | * Results: | | | |
289 | * None. | | | |
290 | * | | | |
291 | * Side Effects: | | | |
292 | * None. | | | |
293 | *----------------------------------------------------------------------- | | | |
294 | */ | | | |
295 | static void | | 232 | static void |
296 | TargFreeGN(void *gnp) | | 233 | TargFreeGN(void *gnp) |
297 | { | | 234 | { |
298 | GNode *gn = (GNode *)gnp; | | 235 | GNode *gn = (GNode *)gnp; |
299 | | | 236 | |
300 | | | | |
301 | free(gn->name); | | 237 | free(gn->name); |
302 | free(gn->uname); | | 238 | free(gn->uname); |
303 | free(gn->path); | | 239 | free(gn->path); |
304 | /* gn->fname points to name allocated when file was opened, don't free */ | | | |
305 | | | 240 | |
306 | Lst_Free(gn->iParents); | | 241 | Lst_Free(gn->iParents); |
307 | Lst_Free(gn->cohorts); | | 242 | Lst_Free(gn->cohorts); |
308 | Lst_Free(gn->parents); | | 243 | Lst_Free(gn->parents); |
309 | Lst_Free(gn->children); | | 244 | Lst_Free(gn->children); |
310 | Lst_Free(gn->order_succ); | | 245 | Lst_Free(gn->order_succ); |
311 | Lst_Free(gn->order_pred); | | 246 | Lst_Free(gn->order_pred); |
312 | Hash_DeleteTable(&gn->context); | | 247 | Hash_DeleteTable(&gn->context); |
313 | Lst_Free(gn->commands); | | 248 | Lst_Free(gn->commands); |
| | | 249 | |
| | | 250 | /* XXX: does gn->suffix need to be freed? It is reference-counted. */ |
| | | 251 | /* gn->fname points to name allocated when file was opened, don't free */ |
| | | 252 | |
314 | free(gn); | | 253 | free(gn); |
315 | } | | 254 | } |
316 | #endif | | 255 | #endif |
317 | | | 256 | |
318 | | | 257 | |
319 | /*- | | 258 | /* Find a node in the list using the given name for matching. |
320 | *----------------------------------------------------------------------- | | 259 | * If the node is created, it is added to the .ALLTARGETS list. |
321 | * Targ_FindNode -- | | | |
322 | * Find a node in the list using the given name for matching | | | |
323 | * | | 260 | * |
324 | * Input: | | 261 | * Input: |
325 | * name the name to find | | 262 | * name the name to find |
326 | * flags flags governing events when target not | | 263 | * flags flags governing events when target not found |
327 | * found | | | |
328 | * | | 264 | * |
329 | * Results: | | 265 | * Results: |
330 | * The node in the list if it was. If it wasn't, return NULL of | | 266 | * The node in the list if it was. If it wasn't, return NULL if |
331 | * flags was TARG_NOCREATE or the newly created and initialized node | | 267 | * flags was TARG_NOCREATE or the newly created and initialized node |
332 | * if it was TARG_CREATE | | 268 | * if it was TARG_CREATE |
333 | * | | | |
334 | * Side Effects: | | | |
335 | * Sometimes a node is created and added to the list | | | |
336 | *----------------------------------------------------------------------- | | | |
337 | */ | | 269 | */ |
338 | GNode * | | 270 | GNode * |
339 | Targ_FindNode(const char *name, int flags) | | 271 | Targ_FindNode(const char *name, int flags) |
340 | { | | 272 | { |
341 | GNode *gn; /* node in that element */ | | 273 | GNode *gn; /* node in that element */ |
342 | Hash_Entry *he = NULL; /* New or used hash entry for node */ | | 274 | Hash_Entry *he = NULL; /* New or used hash entry for node */ |
343 | Boolean isNew; /* Set TRUE if Hash_CreateEntry had to create */ | | 275 | Boolean isNew; /* Set TRUE if Hash_CreateEntry had to create */ |
344 | /* an entry for the node */ | | 276 | /* an entry for the node */ |
345 | | | 277 | |
346 | if (!(flags & (TARG_CREATE | TARG_NOHASH))) { | | 278 | if (!(flags & (TARG_CREATE | TARG_NOHASH))) { |
347 | he = Hash_FindEntry(&targets, name); | | 279 | he = Hash_FindEntry(&targets, name); |
348 | if (he == NULL) | | 280 | if (he == NULL) |
349 | return NULL; | | 281 | return NULL; |
| @@ -356,44 +288,38 @@ Targ_FindNode(const char *name, int flag | | | @@ -356,44 +288,38 @@ Targ_FindNode(const char *name, int flag |
356 | return (GNode *)Hash_GetValue(he); | | 288 | return (GNode *)Hash_GetValue(he); |
357 | } | | 289 | } |
358 | | | 290 | |
359 | gn = Targ_NewGN(name); | | 291 | gn = Targ_NewGN(name); |
360 | if (!(flags & TARG_NOHASH)) | | 292 | if (!(flags & TARG_NOHASH)) |
361 | Hash_SetValue(he, gn); | | 293 | Hash_SetValue(he, gn); |
362 | Var_Append(".ALLTARGETS", name, VAR_GLOBAL); | | 294 | Var_Append(".ALLTARGETS", name, VAR_GLOBAL); |
363 | Lst_Append(allTargets, gn); | | 295 | Lst_Append(allTargets, gn); |
364 | if (doing_depend) | | 296 | if (doing_depend) |
365 | gn->flags |= FROM_DEPEND; | | 297 | gn->flags |= FROM_DEPEND; |
366 | return gn; | | 298 | return gn; |
367 | } | | 299 | } |
368 | | | 300 | |
369 | /*- | | 301 | /* Make a complete list of GNodes from the given list of names. |
370 | *----------------------------------------------------------------------- | | 302 | * If flags is TARG_CREATE, nodes will be created for all names in |
371 | * Targ_FindList -- | | 303 | * names which do not yet have graph nodes. If flags is TARG_NOCREATE, |
372 | * Make a complete list of GNodes from the given list of names | | 304 | * an error message will be printed for each name which can't be found. |
373 | * | | 305 | * |
374 | * Input: | | 306 | * Input: |
375 | * name list of names to find | | 307 | * name list of names to find |
376 | * flags flags used if no node is found for a given name | | 308 | * flags flags used if no node is found for a given name |
377 | * | | 309 | * |
378 | * Results: | | 310 | * Results: |
379 | * A complete list of graph nodes corresponding to all instances of all | | 311 | * A complete list of graph nodes corresponding to all instances of all |
380 | * the names in names. | | 312 | * the names in names. |
381 | * | | | |
382 | * Side Effects: | | | |
383 | * If flags is TARG_CREATE, nodes will be created for all names in | | | |
384 | * names which do not yet have graph nodes. If flags is TARG_NOCREATE, | | | |
385 | * an error message will be printed for each name which can't be found. | | | |
386 | * ----------------------------------------------------------------------- | | | |
387 | */ | | 313 | */ |
388 | Lst | | 314 | Lst |
389 | Targ_FindList(Lst names, int flags) | | 315 | Targ_FindList(Lst names, int flags) |
390 | { | | 316 | { |
391 | Lst nodes; /* result list */ | | 317 | Lst nodes; /* result list */ |
392 | LstNode ln; /* name list element */ | | 318 | LstNode ln; /* name list element */ |
393 | GNode *gn; /* node in tLn */ | | 319 | GNode *gn; /* node in tLn */ |
394 | char *name; | | 320 | char *name; |
395 | | | 321 | |
396 | nodes = Lst_Init(); | | 322 | nodes = Lst_Init(); |
397 | | | 323 | |
398 | Lst_Open(names); | | 324 | Lst_Open(names); |
399 | while ((ln = Lst_Next(names)) != NULL) { | | 325 | while ((ln = Lst_Next(names)) != NULL) { |
| @@ -404,181 +330,91 @@ Targ_FindList(Lst names, int flags) | | | @@ -404,181 +330,91 @@ Targ_FindList(Lst names, int flags) |
404 | * Note: Lst_Append must come before the Lst_Concat so the nodes | | 330 | * Note: Lst_Append must come before the Lst_Concat so the nodes |
405 | * are added to the list in the order in which they were | | 331 | * are added to the list in the order in which they were |
406 | * encountered in the makefile. | | 332 | * encountered in the makefile. |
407 | */ | | 333 | */ |
408 | Lst_Append(nodes, gn); | | 334 | Lst_Append(nodes, gn); |
409 | } else if (flags == TARG_NOCREATE) { | | 335 | } else if (flags == TARG_NOCREATE) { |
410 | Error("\"%s\" -- target unknown.", name); | | 336 | Error("\"%s\" -- target unknown.", name); |
411 | } | | 337 | } |
412 | } | | 338 | } |
413 | Lst_Close(names); | | 339 | Lst_Close(names); |
414 | return nodes; | | 340 | return nodes; |
415 | } | | 341 | } |
416 | | | 342 | |
417 | /*- | | 343 | /* Return true if should ignore errors when creating gn. */ |
418 | *----------------------------------------------------------------------- | | | |
419 | * Targ_Ignore -- | | | |
420 | * Return true if should ignore errors when creating gn | | | |
421 | * | | | |
422 | * Input: | | | |
423 | * gn node to check for | | | |
424 | * | | | |
425 | * Results: | | | |
426 | * TRUE if should ignore errors | | | |
427 | * | | | |
428 | * Side Effects: | | | |
429 | * None | | | |
430 | *----------------------------------------------------------------------- | | | |
431 | */ | | | |
432 | Boolean | | 344 | Boolean |
433 | Targ_Ignore(GNode *gn) | | 345 | Targ_Ignore(GNode *gn) |
434 | { | | 346 | { |
435 | if (ignoreErrors || gn->type & OP_IGNORE) { | | 347 | return ignoreErrors || gn->type & OP_IGNORE; |
436 | return TRUE; | | | |
437 | } else { | | | |
438 | return FALSE; | | | |
439 | } | | | |
440 | } | | 348 | } |
441 | | | 349 | |
442 | /*- | | 350 | /* Return true if be silent when creating gn. */ |
443 | *----------------------------------------------------------------------- | | | |
444 | * Targ_Silent -- | | | |
445 | * Return true if be silent when creating gn | | | |
446 | * | | | |
447 | * Input: | | | |
448 | * gn node to check for | | | |
449 | * | | | |
450 | * Results: | | | |
451 | * TRUE if should be silent | | | |
452 | * | | | |
453 | * Side Effects: | | | |
454 | * None | | | |
455 | *----------------------------------------------------------------------- | | | |
456 | */ | | | |
457 | Boolean | | 351 | Boolean |
458 | Targ_Silent(GNode *gn) | | 352 | Targ_Silent(GNode *gn) |
459 | { | | 353 | { |
460 | if (beSilent || gn->type & OP_SILENT) { | | 354 | return beSilent || gn->type & OP_SILENT; |
461 | return TRUE; | | | |
462 | } else { | | | |
463 | return FALSE; | | | |
464 | } | | | |
465 | } | | 355 | } |
466 | | | 356 | |
467 | /*- | | 357 | /* See if the given target is precious. */ |
468 | *----------------------------------------------------------------------- | | | |
469 | * Targ_Precious -- | | | |
470 | * See if the given target is precious | | | |
471 | * | | | |
472 | * Input: | | | |
473 | * gn the node to check | | | |
474 | * | | | |
475 | * Results: | | | |
476 | * TRUE if it is precious. FALSE otherwise | | | |
477 | * | | | |
478 | * Side Effects: | | | |
479 | * None | | | |
480 | *----------------------------------------------------------------------- | | | |
481 | */ | | | |
482 | Boolean | | 358 | Boolean |
483 | Targ_Precious(GNode *gn) | | 359 | Targ_Precious(GNode *gn) |
484 | { | | 360 | { |
485 | if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) { | | 361 | return allPrecious || gn->type & (OP_PRECIOUS | OP_DOUBLEDEP); |
486 | return TRUE; | | | |
487 | } else { | | | |
488 | return FALSE; | | | |
489 | } | | | |
490 | } | | 362 | } |
491 | | | 363 | |
492 | /******************* DEBUG INFO PRINTING ****************/ | | 364 | /******************* DEBUG INFO PRINTING ****************/ |
493 | | | 365 | |
494 | static GNode *mainTarg; /* the main target, as set by Targ_SetMain */ | | 366 | static GNode *mainTarg; /* the main target, as set by Targ_SetMain */ |
495 | /*- | | 367 | |
496 | *----------------------------------------------------------------------- | | 368 | /* Set our idea of the main target we'll be creating. Used for debugging |
497 | * Targ_SetMain -- | | 369 | * output. */ |
498 | * Set our idea of the main target we'll be creating. Used for | | | |
499 | * debugging output. | | | |
500 | * | | | |
501 | * Input: | | | |
502 | * gn The main target we'll create | | | |
503 | * | | | |
504 | * Results: | | | |
505 | * None. | | | |
506 | * | | | |
507 | * Side Effects: | | | |
508 | * "mainTarg" is set to the main target's node. | | | |
509 | *----------------------------------------------------------------------- | | | |
510 | */ | | | |
511 | void | | 370 | void |
512 | Targ_SetMain(GNode *gn) | | 371 | Targ_SetMain(GNode *gn) |
513 | { | | 372 | { |
514 | mainTarg = gn; | | 373 | mainTarg = gn; |
515 | } | | 374 | } |
516 | | | 375 | |
517 | static int | | 376 | static int |
518 | TargPrintName(void *gnp, void *pflags MAKE_ATTR_UNUSED) | | 377 | TargPrintName(void *gnp, void *pflags MAKE_ATTR_UNUSED) |
519 | { | | 378 | { |
520 | GNode *gn = (GNode *)gnp; | | 379 | GNode *gn = (GNode *)gnp; |
521 | | | 380 | |
522 | fprintf(debug_file, "%s%s ", gn->name, gn->cohort_num); | | 381 | fprintf(debug_file, "%s%s ", gn->name, gn->cohort_num); |
523 | | | 382 | |
524 | return 0; | | 383 | return 0; |
525 | } | | 384 | } |
526 | | | 385 | |
527 | | | 386 | |
528 | int | | 387 | int |
529 | Targ_PrintCmd(void *cmd, void *dummy MAKE_ATTR_UNUSED) | | 388 | Targ_PrintCmd(void *cmd, void *dummy MAKE_ATTR_UNUSED) |
530 | { | | 389 | { |
531 | fprintf(debug_file, "\t%s\n", (char *)cmd); | | 390 | fprintf(debug_file, "\t%s\n", (char *)cmd); |
532 | return 0; | | 391 | return 0; |
533 | } | | 392 | } |
534 | | | 393 | |
535 | /*- | | 394 | /* Format a modification time in some reasonable way and return it. |
536 | *----------------------------------------------------------------------- | | 395 | * The time is placed in a static area, so it is overwritten with each call. */ |
537 | * Targ_FmtTime -- | | | |
538 | * Format a modification time in some reasonable way and return it. | | | |
539 | * | | | |
540 | * Results: | | | |
541 | * The time reformatted. | | | |
542 | * | | | |
543 | * Side Effects: | | | |
544 | * The time is placed in a static area, so it is overwritten | | | |
545 | * with each call. | | | |
546 | * | | | |
547 | *----------------------------------------------------------------------- | | | |
548 | */ | | | |
549 | char * | | 396 | char * |
550 | Targ_FmtTime(time_t tm) | | 397 | Targ_FmtTime(time_t tm) |
551 | { | | 398 | { |
552 | struct tm *parts; | | 399 | struct tm *parts; |
553 | static char buf[128]; | | 400 | static char buf[128]; |
554 | | | 401 | |
555 | parts = localtime(&tm); | | 402 | parts = localtime(&tm); |
556 | (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts); | | 403 | (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts); |
557 | return buf; | | 404 | return buf; |
558 | } | | 405 | } |
559 | | | 406 | |
560 | /*- | | 407 | /* Print out a type field giving only those attributes the user can set. */ |
561 | *----------------------------------------------------------------------- | | | |
562 | * Targ_PrintType -- | | | |
563 | * Print out a type field giving only those attributes the user can | | | |
564 | * set. | | | |
565 | * | | | |
566 | * Results: | | | |
567 | * | | | |
568 | * Side Effects: | | | |
569 | * | | | |
570 | *----------------------------------------------------------------------- | | | |
571 | */ | | | |
572 | void | | 408 | void |
573 | Targ_PrintType(int type) | | 409 | Targ_PrintType(int type) |
574 | { | | 410 | { |
575 | int tbit; | | 411 | int tbit; |
576 | | | 412 | |
577 | #define PRINTBIT(attr) case CONCAT(OP_,attr): fprintf(debug_file, "." #attr " "); break | | 413 | #define PRINTBIT(attr) case CONCAT(OP_,attr): fprintf(debug_file, "." #attr " "); break |
578 | #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))fprintf(debug_file, "." #attr " "); break | | 414 | #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))fprintf(debug_file, "." #attr " "); break |
579 | | | 415 | |
580 | type &= ~OP_OPMASK; | | 416 | type &= ~OP_OPMASK; |
581 | | | 417 | |
582 | while (type) { | | 418 | while (type) { |
583 | tbit = 1 << (ffs(type) - 1); | | 419 | tbit = 1 << (ffs(type) - 1); |
584 | type &= ~tbit; | | 420 | type &= ~tbit; |
| @@ -610,32 +446,27 @@ made_name(GNodeMade made) | | | @@ -610,32 +446,27 @@ made_name(GNodeMade made) |
610 | switch (made) { | | 446 | switch (made) { |
611 | case UNMADE: return "unmade"; | | 447 | case UNMADE: return "unmade"; |
612 | case DEFERRED: return "deferred"; | | 448 | case DEFERRED: return "deferred"; |
613 | case REQUESTED: return "requested"; | | 449 | case REQUESTED: return "requested"; |
614 | case BEINGMADE: return "being made"; | | 450 | case BEINGMADE: return "being made"; |
615 | case MADE: return "made"; | | 451 | case MADE: return "made"; |
616 | case UPTODATE: return "up-to-date"; | | 452 | case UPTODATE: return "up-to-date"; |
617 | case ERROR: return "error when made"; | | 453 | case ERROR: return "error when made"; |
618 | case ABORTED: return "aborted"; | | 454 | case ABORTED: return "aborted"; |
619 | default: return "unknown enum_made value"; | | 455 | default: return "unknown enum_made value"; |
620 | } | | 456 | } |
621 | } | | 457 | } |
622 | | | 458 | |
623 | /*- | | 459 | /* Print the contents of a node. */ |
624 | *----------------------------------------------------------------------- | | | |
625 | * TargPrintNode -- | | | |
626 | * print the contents of a node | | | |
627 | *----------------------------------------------------------------------- | | | |
628 | */ | | | |
629 | int | | 460 | int |
630 | Targ_PrintNode(void *gnp, void *passp) | | 461 | Targ_PrintNode(void *gnp, void *passp) |
631 | { | | 462 | { |
632 | GNode *gn = (GNode *)gnp; | | 463 | GNode *gn = (GNode *)gnp; |
633 | int pass = passp ? *(int *)passp : 0; | | 464 | int pass = passp ? *(int *)passp : 0; |
634 | | | 465 | |
635 | fprintf(debug_file, "# %s%s", gn->name, gn->cohort_num); | | 466 | fprintf(debug_file, "# %s%s", gn->name, gn->cohort_num); |
636 | GNode_FprintDetails(debug_file, ", ", gn, "\n"); | | 467 | GNode_FprintDetails(debug_file, ", ", gn, "\n"); |
637 | if (gn->flags == 0) | | 468 | if (gn->flags == 0) |
638 | return 0; | | 469 | return 0; |
639 | | | 470 | |
640 | if (!OP_NOP(gn->type)) { | | 471 | if (!OP_NOP(gn->type)) { |
641 | fprintf(debug_file, "#\n"); | | 472 | fprintf(debug_file, "#\n"); |
| @@ -696,156 +527,106 @@ Targ_PrintNode(void *gnp, void *passp) | | | @@ -696,156 +527,106 @@ Targ_PrintNode(void *gnp, void *passp) |
696 | } | | 527 | } |
697 | Targ_PrintType(gn->type); | | 528 | Targ_PrintType(gn->type); |
698 | Lst_ForEach(gn->children, TargPrintName, NULL); | | 529 | Lst_ForEach(gn->children, TargPrintName, NULL); |
699 | fprintf(debug_file, "\n"); | | 530 | fprintf(debug_file, "\n"); |
700 | Lst_ForEach(gn->commands, Targ_PrintCmd, NULL); | | 531 | Lst_ForEach(gn->commands, Targ_PrintCmd, NULL); |
701 | fprintf(debug_file, "\n\n"); | | 532 | fprintf(debug_file, "\n\n"); |
702 | if (gn->type & OP_DOUBLEDEP) { | | 533 | if (gn->type & OP_DOUBLEDEP) { |
703 | Lst_ForEach(gn->cohorts, Targ_PrintNode, &pass); | | 534 | Lst_ForEach(gn->cohorts, Targ_PrintNode, &pass); |
704 | } | | 535 | } |
705 | } | | 536 | } |
706 | return 0; | | 537 | return 0; |
707 | } | | 538 | } |
708 | | | 539 | |
709 | /*- | | 540 | /* Print only those targets that are just a source. |
710 | *----------------------------------------------------------------------- | | 541 | * The name of each file is printed, preceded by #\t. */ |
711 | * TargPrintOnlySrc -- | | | |
712 | * Print only those targets that are just a source. | | | |
713 | * | | | |
714 | * Results: | | | |
715 | * 0. | | | |
716 | * | | | |
717 | * Side Effects: | | | |
718 | * The name of each file is printed preceded by #\t | | | |
719 | * | | | |
720 | *----------------------------------------------------------------------- | | | |
721 | */ | | | |
722 | static int | | 542 | static int |
723 | TargPrintOnlySrc(void *gnp, void *dummy MAKE_ATTR_UNUSED) | | 543 | TargPrintOnlySrc(void *gnp, void *dummy MAKE_ATTR_UNUSED) |
724 | { | | 544 | { |
725 | GNode *gn = (GNode *)gnp; | | 545 | GNode *gn = (GNode *)gnp; |
726 | if (!OP_NOP(gn->type)) | | 546 | if (!OP_NOP(gn->type)) |
727 | return 0; | | 547 | return 0; |
728 | | | 548 | |
729 | fprintf(debug_file, "#\t%s [%s] ", | | 549 | fprintf(debug_file, "#\t%s [%s] ", |
730 | gn->name, gn->path ? gn->path : gn->name); | | 550 | gn->name, gn->path ? gn->path : gn->name); |
731 | Targ_PrintType(gn->type); | | 551 | Targ_PrintType(gn->type); |
732 | fprintf(debug_file, "\n"); | | 552 | fprintf(debug_file, "\n"); |
733 | | | 553 | |
734 | return 0; | | 554 | return 0; |
735 | } | | 555 | } |
736 | | | 556 | |
737 | /*- | | 557 | /* Input: |
738 | *----------------------------------------------------------------------- | | 558 | * pass 1 => before processing |
739 | * Targ_PrintGraph -- | | 559 | * 2 => after processing |
740 | * print the entire graph. heh heh | | 560 | * 3 => after processing, an error occurred |
741 | * | | | |
742 | * Input: | | | |
743 | * pass Which pass this is. 1 => no processing | | | |
744 | * 2 => processing done | | | |
745 | * | | | |
746 | * Results: | | | |
747 | * none | | | |
748 | * | | | |
749 | * Side Effects: | | | |
750 | * lots o' output | | | |
751 | *----------------------------------------------------------------------- | | | |
752 | */ | | 561 | */ |
753 | void | | 562 | void |
754 | Targ_PrintGraph(int pass) | | 563 | Targ_PrintGraph(int pass) |
755 | { | | 564 | { |
756 | fprintf(debug_file, "#*** Input graph:\n"); | | 565 | fprintf(debug_file, "#*** Input graph:\n"); |
757 | Lst_ForEach(allTargets, Targ_PrintNode, &pass); | | 566 | Lst_ForEach(allTargets, Targ_PrintNode, &pass); |
758 | fprintf(debug_file, "\n\n"); | | 567 | fprintf(debug_file, "\n\n"); |
759 | fprintf(debug_file, "#\n# Files that are only sources:\n"); | | 568 | fprintf(debug_file, "#\n# Files that are only sources:\n"); |
760 | Lst_ForEach(allTargets, TargPrintOnlySrc, NULL); | | 569 | Lst_ForEach(allTargets, TargPrintOnlySrc, NULL); |
761 | fprintf(debug_file, "#*** Global Variables:\n"); | | 570 | fprintf(debug_file, "#*** Global Variables:\n"); |
762 | Var_Dump(VAR_GLOBAL); | | 571 | Var_Dump(VAR_GLOBAL); |
763 | fprintf(debug_file, "#*** Command-line Variables:\n"); | | 572 | fprintf(debug_file, "#*** Command-line Variables:\n"); |
764 | Var_Dump(VAR_CMD); | | 573 | Var_Dump(VAR_CMD); |
765 | fprintf(debug_file, "\n"); | | 574 | fprintf(debug_file, "\n"); |
766 | Dir_PrintDirectories(); | | 575 | Dir_PrintDirectories(); |
767 | fprintf(debug_file, "\n"); | | 576 | fprintf(debug_file, "\n"); |
768 | Suff_PrintAll(); | | 577 | Suff_PrintAll(); |
769 | } | | 578 | } |
770 | | | 579 | |
771 | /*- | | 580 | /* Propagate information from a single node to related nodes if appropriate. |
772 | *----------------------------------------------------------------------- | | 581 | * |
773 | * TargPropagateNode -- | | 582 | * Information is propagated from this node to cohort nodes. |
774 | * Propagate information from a single node to related nodes if | | 583 | * |
775 | * appropriate. | | 584 | * If the node was defined with "::", then TargPropagateCohort() will be |
| | | 585 | * called for each cohort node. |
776 | * | | 586 | * |
777 | * Input: | | 587 | * Input: |
778 | * gnp The node that we are processing. | | 588 | * gnp The node that we are processing. |
779 | * | | 589 | * |
780 | * Results: | | 590 | * Results: |
781 | * Always returns 0, for the benefit of Lst_ForEach(). | | 591 | * Always returns 0, for the benefit of Lst_ForEach(). |
782 | * | | | |
783 | * Side Effects: | | | |
784 | * Information is propagated from this node to cohort or child | | | |
785 | * nodes. | | | |
786 | * | | | |
787 | * If the node was defined with "::", then TargPropagateCohort() | | | |
788 | * will be called for each cohort node. | | | |
789 | * | | | |
790 | * If the node has recursive predecessors, then | | | |
791 | * TargPropagateRecpred() will be called for each recursive | | | |
792 | * predecessor. | | | |
793 | *----------------------------------------------------------------------- | | | |
794 | */ | | 592 | */ |
795 | static int | | 593 | static int |
796 | TargPropagateNode(void *gnp, void *junk MAKE_ATTR_UNUSED) | | 594 | TargPropagateNode(void *gnp, void *junk MAKE_ATTR_UNUSED) |
797 | { | | 595 | { |
798 | GNode *gn = (GNode *)gnp; | | 596 | GNode *gn = (GNode *)gnp; |
799 | | | 597 | |
800 | if (gn->type & OP_DOUBLEDEP) | | 598 | if (gn->type & OP_DOUBLEDEP) |
801 | Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp); | | 599 | Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp); |
802 | return 0; | | 600 | return 0; |
803 | } | | 601 | } |
804 | | | 602 | |
805 | /*- | | 603 | /* Propagate some bits in the type mask from a node to a related cohort node. |
806 | *----------------------------------------------------------------------- | | 604 | * cnp's type bitmask is modified to incorporate some of the bits from gnp's |
807 | * TargPropagateCohort -- | | 605 | * type bitmask. (XXX need a better explanation.) |
808 | * Propagate some bits in the type mask from a node to | | | |
809 | * a related cohort node. | | | |
810 | * | | 606 | * |
811 | * Input: | | 607 | * Input: |
812 | * cnp The node that we are processing. | | 608 | * cnp The node that we are processing. |
813 | * gnp Another node that has cnp as a cohort. | | 609 | * gnp Another node that has cnp as a cohort. |
814 | * | | 610 | * |
815 | * Results: | | 611 | * Results: |
816 | * Always returns 0, for the benefit of Lst_ForEach(). | | 612 | * Always returns 0, for the benefit of Lst_ForEach(). |
817 | * | | | |
818 | * Side Effects: | | | |
819 | * cnp's type bitmask is modified to incorporate some of the | | | |
820 | * bits from gnp's type bitmask. (XXX need a better explanation.) | | | |
821 | *----------------------------------------------------------------------- | | | |
822 | */ | | 613 | */ |
823 | static int | | 614 | static int |
824 | TargPropagateCohort(void *cgnp, void *pgnp) | | 615 | TargPropagateCohort(void *cgnp, void *pgnp) |
825 | { | | 616 | { |
826 | GNode *cgn = (GNode *)cgnp; | | 617 | GNode *cgn = (GNode *)cgnp; |
827 | GNode *pgn = (GNode *)pgnp; | | 618 | GNode *pgn = (GNode *)pgnp; |
828 | | | 619 | |
829 | cgn->type |= pgn->type & ~OP_OPMASK; | | 620 | cgn->type |= pgn->type & ~OP_OPMASK; |
830 | return 0; | | 621 | return 0; |
831 | } | | 622 | } |
832 | | | 623 | |
833 | /*- | | 624 | /* Propagate information between related nodes. Should be called after the |
834 | *----------------------------------------------------------------------- | | 625 | * makefiles are parsed but before any action is taken. |
835 | * Targ_Propagate -- | | | |
836 | * Propagate information between related nodes. Should be called | | | |
837 | * after the makefiles are parsed but before any action is taken. | | | |
838 | * | | 626 | * |
839 | * Results: | | 627 | * Information is propagated between related nodes throughout the graph. */ |
840 | * none | | | |
841 | * | | | |
842 | * Side Effects: | | | |
843 | * Information is propagated between related nodes throughout the | | | |
844 | * graph. | | | |
845 | *----------------------------------------------------------------------- | | | |
846 | */ | | | |
847 | void | | 628 | void |
848 | Targ_Propagate(void) | | 629 | Targ_Propagate(void) |
849 | { | | 630 | { |
850 | Lst_ForEach(allTargets, TargPropagateNode, NULL); | | 631 | Lst_ForEach(allTargets, TargPropagateNode, NULL); |
851 | } | | 632 | } |