Fri Aug 28 19:14:07 2020 UTC ()
make(1): clean up targ.c

The main part is removing redundant or outdated information from
comments.  In a few places, the expression cond ? TRUE : FALSE has been
simplified.


(rillig)
diff -r1.128 -r1.129 src/usr.bin/make/make.h
diff -r1.76 -r1.77 src/usr.bin/make/targ.c

cvs diff -r1.128 -r1.129 src/usr.bin/make/make.h (switch to unified diff)

--- src/usr.bin/make/make.h 2020/08/28 03:35:45 1.128
+++ src/usr.bin/make/make.h 2020/08/28 19:14:07 1.129
@@ -1,582 +1,582 @@ @@ -1,582 +1,582 @@
1/* $NetBSD: make.h,v 1.128 2020/08/28 03:35:45 rillig Exp $ */ 1/* $NetBSD: make.h,v 1.129 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.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors 18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * from: @(#)make.h 8.3 (Berkeley) 6/13/95 34 * from: @(#)make.h 8.3 (Berkeley) 6/13/95
35 */ 35 */
36 36
37/* 37/*
38 * Copyright (c) 1989 by Berkeley Softworks 38 * Copyright (c) 1989 by Berkeley Softworks
39 * All rights reserved. 39 * All rights reserved.
40 * 40 *
41 * This code is derived from software contributed to Berkeley by 41 * This code is derived from software contributed to Berkeley by
42 * Adam de Boor. 42 * Adam de Boor.
43 * 43 *
44 * Redistribution and use in source and binary forms, with or without 44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions 45 * modification, are permitted provided that the following conditions
46 * are met: 46 * are met:
47 * 1. Redistributions of source code must retain the above copyright 47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer. 48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright 49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the 50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution. 51 * documentation and/or other materials provided with the distribution.
52 * 3. All advertising materials mentioning features or use of this software 52 * 3. All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement: 53 * must display the following acknowledgement:
54 * This product includes software developed by the University of 54 * This product includes software developed by the University of
55 * California, Berkeley and its contributors. 55 * California, Berkeley and its contributors.
56 * 4. Neither the name of the University nor the names of its contributors 56 * 4. Neither the name of the University nor the names of its contributors
57 * may be used to endorse or promote products derived from this software 57 * may be used to endorse or promote products derived from this software
58 * without specific prior written permission. 58 * without specific prior written permission.
59 * 59 *
60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70 * SUCH DAMAGE. 70 * SUCH DAMAGE.
71 * 71 *
72 * from: @(#)make.h 8.3 (Berkeley) 6/13/95 72 * from: @(#)make.h 8.3 (Berkeley) 6/13/95
73 */ 73 */
74 74
75/*- 75/*-
76 * make.h -- 76 * make.h --
77 * The global definitions for pmake 77 * The global definitions for pmake
78 */ 78 */
79 79
80#ifndef MAKE_MAKE_H 80#ifndef MAKE_MAKE_H
81#define MAKE_MAKE_H 81#define MAKE_MAKE_H
82 82
83#include <sys/types.h> 83#include <sys/types.h>
84#include <sys/param.h> 84#include <sys/param.h>
85 85
86#include <assert.h> 86#include <assert.h>
87#include <ctype.h> 87#include <ctype.h>
88#include <fcntl.h> 88#include <fcntl.h>
89#include <stdio.h> 89#include <stdio.h>
90#include <stdlib.h> 90#include <stdlib.h>
91#include <string.h> 91#include <string.h>
92#include <unistd.h> 92#include <unistd.h>
93 93
94#ifdef BSD4_4 94#ifdef BSD4_4
95# include <sys/cdefs.h> 95# include <sys/cdefs.h>
96#endif 96#endif
97 97
98#ifndef FD_CLOEXEC 98#ifndef FD_CLOEXEC
99#define FD_CLOEXEC 1 99#define FD_CLOEXEC 1
100#endif 100#endif
101 101
102#if defined(__GNUC__) 102#if defined(__GNUC__)
103#define MAKE_GNUC_PREREQ(x, y) \ 103#define MAKE_GNUC_PREREQ(x, y) \
104 ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \ 104 ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
105 (__GNUC__ > (x))) 105 (__GNUC__ > (x)))
106#else /* defined(__GNUC__) */ 106#else /* defined(__GNUC__) */
107#define MAKE_GNUC_PREREQ(x, y) 0 107#define MAKE_GNUC_PREREQ(x, y) 0
108#endif /* defined(__GNUC__) */ 108#endif /* defined(__GNUC__) */
109 109
110#if MAKE_GNUC_PREREQ(2, 7) 110#if MAKE_GNUC_PREREQ(2, 7)
111#define MAKE_ATTR_UNUSED __attribute__((__unused__)) 111#define MAKE_ATTR_UNUSED __attribute__((__unused__))
112#else 112#else
113#define MAKE_ATTR_UNUSED /* delete */ 113#define MAKE_ATTR_UNUSED /* delete */
114#endif 114#endif
115 115
116#if MAKE_GNUC_PREREQ(2, 5) 116#if MAKE_GNUC_PREREQ(2, 5)
117#define MAKE_ATTR_DEAD __attribute__((__noreturn__)) 117#define MAKE_ATTR_DEAD __attribute__((__noreturn__))
118#elif defined(__GNUC__) 118#elif defined(__GNUC__)
119#define MAKE_ATTR_DEAD __volatile 119#define MAKE_ATTR_DEAD __volatile
120#else 120#else
121#define MAKE_ATTR_DEAD /* delete */ 121#define MAKE_ATTR_DEAD /* delete */
122#endif 122#endif
123 123
124#if MAKE_GNUC_PREREQ(2, 7) 124#if MAKE_GNUC_PREREQ(2, 7)
125#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) \ 125#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) \
126 __attribute__((__format__ (__printf__, fmtarg, firstvararg))) 126 __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
127#else 127#else
128#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */ 128#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */
129#endif 129#endif
130 130
131/* 131/*
132 * A boolean type is defined as an integer, not an enum. This allows a 132 * A boolean type is defined as an integer, not an enum. This allows a
133 * boolean argument to be an expression that isn't strictly 0 or 1 valued. 133 * boolean argument to be an expression that isn't strictly 0 or 1 valued.
134 */ 134 */
135 135
136typedef int Boolean; 136typedef int Boolean;
137#ifndef TRUE 137#ifndef TRUE
138#define TRUE 1 138#define TRUE 1
139#endif /* TRUE */ 139#endif /* TRUE */
140#ifndef FALSE 140#ifndef FALSE
141#define FALSE 0 141#define FALSE 0
142#endif /* FALSE */ 142#endif /* FALSE */
143 143
144/* 144/*
145 * Functions that must return a status can return a ReturnStatus to 145 * Functions that must return a status can return a ReturnStatus to
146 * indicate success or type of failure. 146 * indicate success or type of failure.
147 */ 147 */
148 148
149typedef int ReturnStatus; 149typedef int ReturnStatus;
150 150
151/* 151/*
152 * The following statuses overlap with the first 2 generic statuses 152 * The following statuses overlap with the first 2 generic statuses
153 * defined in status.h: 153 * defined in status.h:
154 * 154 *
155 * SUCCESS There was no error. 155 * SUCCESS There was no error.
156 * FAILURE There was a general error. 156 * FAILURE There was a general error.
157 */ 157 */
158 158
159#define SUCCESS 0x00000000 159#define SUCCESS 0x00000000
160#define FAILURE 0x00000001 160#define FAILURE 0x00000001
161 161
162#include "lst.h" 162#include "lst.h"
163#include "enum.h" 163#include "enum.h"
164#include "hash.h" 164#include "hash.h"
165#include "config.h" 165#include "config.h"
166#include "buf.h" 166#include "buf.h"
167#include "make_malloc.h" 167#include "make_malloc.h"
168 168
169typedef enum { 169typedef enum {
170 UNMADE, /* Not examined yet */ 170 UNMADE, /* Not examined yet */
171 DEFERRED, /* Examined once (building child) */ 171 DEFERRED, /* Examined once (building child) */
172 REQUESTED, /* on toBeMade list */ 172 REQUESTED, /* on toBeMade list */
173 BEINGMADE, /* Target is already being made. 173 BEINGMADE, /* Target is already being made.
174 * Indicates a cycle in the graph. */ 174 * Indicates a cycle in the graph. */
175 MADE, /* Was out-of-date and has been made */ 175 MADE, /* Was out-of-date and has been made */
176 UPTODATE, /* Was already up-to-date */ 176 UPTODATE, /* Was already up-to-date */
177 ERROR, /* An error occurred while it was being 177 ERROR, /* An error occurred while it was being
178 * made (used only in compat mode) */ 178 * made (used only in compat mode) */
179 ABORTED /* The target was aborted due to an error 179 ABORTED /* The target was aborted due to an error
180 * making an inferior (compat). */ 180 * making an inferior (compat). */
181} GNodeMade; 181} GNodeMade;
182 182
183/* The OP_ constants are used when parsing a dependency line as a way of 183/* The OP_ constants are used when parsing a dependency line as a way of
184 * communicating to other parts of the program the way in which a target 184 * communicating to other parts of the program the way in which a target
185 * should be made. 185 * should be made.
186 * 186 *
187 * These constants are bitwise-OR'ed together and placed in the 'type' field 187 * These constants are bitwise-OR'ed together and placed in the 'type' field
188 * of each node. Any node that has a 'type' field which satisfies the OP_NOP 188 * of each node. Any node that has a 'type' field which satisfies the OP_NOP
189 * function was never never on the left-hand side of an operator, though it 189 * function was never never on the left-hand side of an operator, though it
190 * may have been on the right-hand side... */ 190 * may have been on the right-hand side... */
191typedef enum { 191typedef enum {
192 /* Execution of commands depends on children (:) */ 192 /* Execution of commands depends on children (:) */
193 OP_DEPENDS = 1 << 0, 193 OP_DEPENDS = 1 << 0,
194 /* Always execute commands (!) */ 194 /* Always execute commands (!) */
195 OP_FORCE = 1 << 1, 195 OP_FORCE = 1 << 1,
196 /* Execution of commands depends on children per line (::) */ 196 /* Execution of commands depends on children per line (::) */
197 OP_DOUBLEDEP = 1 << 2, 197 OP_DOUBLEDEP = 1 << 2,
198 198
199 OP_OPMASK = OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP, 199 OP_OPMASK = OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP,
200 200
201 /* Don't care if the target doesn't exist and can't be created */ 201 /* Don't care if the target doesn't exist and can't be created */
202 OP_OPTIONAL = 1 << 3, 202 OP_OPTIONAL = 1 << 3,
203 /* Use associated commands for parents */ 203 /* Use associated commands for parents */
204 OP_USE = 1 << 4, 204 OP_USE = 1 << 4,
205 /* Target is never out of date, but always execute commands anyway. 205 /* Target is never out of date, but always execute commands anyway.
206 * Its time doesn't matter, so it has none...sort of */ 206 * Its time doesn't matter, so it has none...sort of */
207 OP_EXEC = 1 << 5, 207 OP_EXEC = 1 << 5,
208 /* Ignore errors when creating the node */ 208 /* Ignore errors when creating the node */
209 OP_IGNORE = 1 << 6, 209 OP_IGNORE = 1 << 6,
210 /* Don't remove the target when interrupted */ 210 /* Don't remove the target when interrupted */
211 OP_PRECIOUS = 1 << 7, 211 OP_PRECIOUS = 1 << 7,
212 /* Don't echo commands when executed */ 212 /* Don't echo commands when executed */
213 OP_SILENT = 1 << 8, 213 OP_SILENT = 1 << 8,
214 /* Target is a recursive make so its commands should always be executed 214 /* Target is a recursive make so its commands should always be executed
215 * when it is out of date, regardless of the state of the -n or -t flags */ 215 * when it is out of date, regardless of the state of the -n or -t flags */
216 OP_MAKE = 1 << 9, 216 OP_MAKE = 1 << 9,
217 /* Target is out-of-date only if any of its children was out-of-date */ 217 /* Target is out-of-date only if any of its children was out-of-date */
218 OP_JOIN = 1 << 10, 218 OP_JOIN = 1 << 10,
219 /* Assume the children of the node have been already made */ 219 /* Assume the children of the node have been already made */
220 OP_MADE = 1 << 11, 220 OP_MADE = 1 << 11,
221 /* Special .BEGIN, .END, .INTERRUPT */ 221 /* Special .BEGIN, .END, .INTERRUPT */
222 OP_SPECIAL = 1 << 12, 222 OP_SPECIAL = 1 << 12,
223 /* Like .USE, only prepend commands */ 223 /* Like .USE, only prepend commands */
224 OP_USEBEFORE = 1 << 13, 224 OP_USEBEFORE = 1 << 13,
225 /* The node is invisible to its parents. I.e. it doesn't show up in the 225 /* The node is invisible to its parents. I.e. it doesn't show up in the
226 * parents' local variables. */ 226 * parents' local variables. */
227 OP_INVISIBLE = 1 << 14, 227 OP_INVISIBLE = 1 << 14,
228 /* The node is exempt from normal 'main target' processing in parse.c */ 228 /* The node is exempt from normal 'main target' processing in parse.c */
229 OP_NOTMAIN = 1 << 15, 229 OP_NOTMAIN = 1 << 15,
230 /* Not a file target; run always */ 230 /* Not a file target; run always */
231 OP_PHONY = 1 << 16, 231 OP_PHONY = 1 << 16,
232 /* Don't search for file in the path */ 232 /* Don't search for file in the path */
233 OP_NOPATH = 1 << 17, 233 OP_NOPATH = 1 << 17,
234 /* .WAIT phony node */ 234 /* .WAIT phony node */
235 OP_WAIT = 1 << 18, 235 OP_WAIT = 1 << 18,
236 /* .NOMETA do not create a .meta file */ 236 /* .NOMETA do not create a .meta file */
237 OP_NOMETA = 1 << 19, 237 OP_NOMETA = 1 << 19,
238 /* .META we _do_ want a .meta file */ 238 /* .META we _do_ want a .meta file */
239 OP_META = 1 << 20, 239 OP_META = 1 << 20,
240 /* Do not compare commands in .meta file */ 240 /* Do not compare commands in .meta file */
241 OP_NOMETA_CMP = 1 << 21, 241 OP_NOMETA_CMP = 1 << 21,
242 /* Possibly a submake node */ 242 /* Possibly a submake node */
243 OP_SUBMAKE = 1 << 22, 243 OP_SUBMAKE = 1 << 22,
244 244
245 /* Attributes applied by PMake */ 245 /* Attributes applied by PMake */
246 246
247 /* The node is a transformation rule */ 247 /* The node is a transformation rule */
248 OP_TRANSFORM = 1 << 31, 248 OP_TRANSFORM = 1 << 31,
249 /* Target is a member of an archive */ 249 /* Target is a member of an archive */
250 OP_MEMBER = 1 << 30, 250 OP_MEMBER = 1 << 30,
251 /* Target is a library */ 251 /* Target is a library */
252 OP_LIB = 1 << 29, 252 OP_LIB = 1 << 29,
253 /* Target is an archive construct */ 253 /* Target is an archive construct */
254 OP_ARCHV = 1 << 28, 254 OP_ARCHV = 1 << 28,
255 /* Target has all the commands it should. Used when parsing to catch 255 /* Target has all the commands it should. Used when parsing to catch
256 * multiple commands for a target. */ 256 * multiple commands for a target. */
257 OP_HAS_COMMANDS = 1 << 27, 257 OP_HAS_COMMANDS = 1 << 27,
258 /* Saving commands on .END (Compat) */ 258 /* Saving commands on .END (Compat) */
259 OP_SAVE_CMDS = 1 << 26, 259 OP_SAVE_CMDS = 1 << 26,
260 /* Already processed by Suff_FindDeps */ 260 /* Already processed by Suff_FindDeps */
261 OP_DEPS_FOUND = 1 << 25, 261 OP_DEPS_FOUND = 1 << 25,
262 /* Node found while expanding .ALLSRC */ 262 /* Node found while expanding .ALLSRC */
263 OP_MARK = 1 << 24 263 OP_MARK = 1 << 24
264} GNodeType; 264} GNodeType;
265 265
266typedef enum { 266typedef enum {
267 REMAKE = 0x0001, /* this target needs to be (re)made */ 267 REMAKE = 0x0001, /* this target needs to be (re)made */
268 CHILDMADE = 0x0002, /* children of this target were made */ 268 CHILDMADE = 0x0002, /* children of this target were made */
269 FORCE = 0x0004, /* children don't exist, and we pretend made */ 269 FORCE = 0x0004, /* children don't exist, and we pretend made */
270 DONE_WAIT = 0x0008, /* Set by Make_ProcessWait() */ 270 DONE_WAIT = 0x0008, /* Set by Make_ProcessWait() */
271 DONE_ORDER = 0x0010, /* Build requested by .ORDER processing */ 271 DONE_ORDER = 0x0010, /* Build requested by .ORDER processing */
272 FROM_DEPEND = 0x0020, /* Node created from .depend */ 272 FROM_DEPEND = 0x0020, /* Node created from .depend */
273 DONE_ALLSRC = 0x0040, /* We do it once only */ 273 DONE_ALLSRC = 0x0040, /* We do it once only */
274 CYCLE = 0x1000, /* Used by MakePrintStatus */ 274 CYCLE = 0x1000, /* Used by MakePrintStatus */
275 DONECYCLE = 0x2000, /* Used by MakePrintStatus */ 275 DONECYCLE = 0x2000, /* Used by MakePrintStatus */
276 INTERNAL = 0x4000 /* Internal use only */ 276 INTERNAL = 0x4000 /* Internal use only */
277} GNodeFlags; 277} GNodeFlags;
278 278
279/* A graph node represents a target that can possibly be made, including its 279/* A graph node represents a target that can possibly be made, including its
280 * relation to other targets and a lot of other details. */ 280 * relation to other targets and a lot of other details. */
281typedef struct GNode { 281typedef struct GNode {
282 /* The target's name, such as "clean" or "make.c" */ 282 /* The target's name, such as "clean" or "make.c" */
283 char *name; 283 char *name;
284 /* The unexpanded name of a .USE node */ 284 /* The unexpanded name of a .USE node */
285 char *uname; 285 char *uname;
286 /* The full pathname of the file belonging to the target. 286 /* The full pathname of the file belonging to the target.
287 * XXX: What about .PHONY targets? These don't have an associated path. */ 287 * XXX: What about .PHONY targets? These don't have an associated path. */
288 char *path; 288 char *path;
289 289
290 /* The type of operator used to define the sources (see the OP flags below). 290 /* The type of operator used to define the sources (see the OP flags below).
291 * XXX: This looks like a wild mixture of type and flags. */ 291 * XXX: This looks like a wild mixture of type and flags. */
292 GNodeType type; 292 GNodeType type;
293 /* whether it is involved in this invocation of make */ 293 /* whether it is involved in this invocation of make */
294 GNodeFlags flags; 294 GNodeFlags flags;
295 295
296 /* The state of processing on this node */ 296 /* The state of processing on this node */
297 GNodeMade made; 297 GNodeMade made;
298 int unmade; /* The number of unmade children */ 298 int unmade; /* The number of unmade children */
299 299
300 time_t mtime; /* Its modification time */ 300 time_t mtime; /* Its modification time */
301 struct GNode *cmgn; /* The youngest child */ 301 struct GNode *cmgn; /* The youngest child */
302 302
303 /* Links to parents for which this is an implied source. May be empty. 303 /* Links to parents for which this is an implied source. May be empty.
304 * Nodes that depend on this, as gleaned from the transformation rules. */ 304 * Nodes that depend on this, as gleaned from the transformation rules. */
305 Lst iParents; 305 Lst iParents;
306 306
307 /* Other nodes of the same name for the :: operator. */ 307 /* Other nodes of the same name for the :: operator. */
308 Lst cohorts; 308 Lst cohorts;
309 309
310 /* The nodes that depend on this one, or in other words, the nodes for 310 /* The nodes that depend on this one, or in other words, the nodes for
311 * which this is a source. */ 311 * which this is a source. */
312 Lst parents; 312 Lst parents;
313 /* The nodes on which this one depends. */ 313 /* The nodes on which this one depends. */
314 Lst children; 314 Lst children;
315 315
316 /* .ORDER nodes we need made. The nodes that must be made (if they're 316 /* .ORDER nodes we need made. The nodes that must be made (if they're
317 * made) before this node can be made, but that do not enter into the 317 * made) before this node can be made, but that do not enter into the
318 * datedness of this node. */ 318 * datedness of this node. */
319 Lst order_pred; 319 Lst order_pred;
320 /* .ORDER nodes who need us. The nodes that must be made (if they're made 320 /* .ORDER nodes who need us. The nodes that must be made (if they're made
321 * at all) after this node is made, but that do not depend on this node, 321 * at all) after this node is made, but that do not depend on this node,
322 * in the normal sense. */ 322 * in the normal sense. */
323 Lst order_succ; 323 Lst order_succ;
324 324
325 /* #n for this cohort */ 325 /* #n for this cohort */
326 char cohort_num[8]; 326 char cohort_num[8];
327 /* The number of unmade instances on the cohorts list */ 327 /* The number of unmade instances on the cohorts list */
328 int unmade_cohorts; 328 int unmade_cohorts;
329 /* Pointer to the first instance of a :: node; only set when on a cohorts 329 /* Pointer to the first instance of a '::' node; only set when on a
330 * list */ 330 * cohorts list */
331 struct GNode *centurion; 331 struct GNode *centurion;
332 332
333 /* Last time (sequence number) we tried to make this node */ 333 /* Last time (sequence number) we tried to make this node */
334 unsigned int checked; 334 unsigned int checked;
335 335
336 /* The "local" variables that are specific to this target and this target 336 /* The "local" variables that are specific to this target and this target
337 * only, such as $@, $<, $?. */ 337 * only, such as $@, $<, $?. */
338 Hash_Table context; 338 Hash_Table context;
339 339
340 /* The commands to be given to a shell to create this target. */ 340 /* The commands to be given to a shell to create this target. */
341 Lst commands; 341 Lst commands;
342 342
343 /* Suffix for the node (determined by Suff_FindDeps and opaque to everyone 343 /* Suffix for the node (determined by Suff_FindDeps and opaque to everyone
344 * but the Suff module) */ 344 * but the Suff module) */
345 struct Suff *suffix; 345 struct Suff *suffix;
346 346
347 /* filename where the GNode got defined */ 347 /* filename where the GNode got defined */
348 const char *fname; 348 const char *fname;
349 /* line number where the GNode got defined */ 349 /* line number where the GNode got defined */
350 int lineno; 350 int lineno;
351} GNode; 351} GNode;
352 352
353#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute) 353#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute)
354/* 354/*
355 * OP_NOP will return TRUE if the node with the given type was not the 355 * OP_NOP will return TRUE if the node with the given type was not the
356 * object of a dependency operator 356 * object of a dependency operator
357 */ 357 */
358#define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000) 358#define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000)
359 359
360#define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM) 360#define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM)
361 361
362/* 362/*
363 * The TARG_ constants are used when calling the Targ_FindNode and 363 * The TARG_ constants are used when calling the Targ_FindNode and
364 * Targ_FindList functions in targ.c. They simply tell the functions what to 364 * Targ_FindList functions in targ.c. They simply tell the functions what to
365 * do if the desired node(s) is (are) not found. If the TARG_CREATE constant 365 * do if the desired node(s) is (are) not found. If the TARG_CREATE constant
366 * is given, a new, empty node will be created for the target, placed in the 366 * is given, a new, empty node will be created for the target, placed in the
367 * table of all targets and its address returned. If TARG_NOCREATE is given, 367 * table of all targets and its address returned. If TARG_NOCREATE is given,
368 * a NULL pointer will be returned. 368 * a NULL pointer will be returned.
369 */ 369 */
370#define TARG_NOCREATE 0x00 /* don't create it */ 370#define TARG_NOCREATE 0x00 /* don't create it */
371#define TARG_CREATE 0x01 /* create node if not found */ 371#define TARG_CREATE 0x01 /* create node if not found */
372#define TARG_NOHASH 0x02 /* don't look in/add to hash table */ 372#define TARG_NOHASH 0x02 /* don't look in/add to hash table */
373 373
374/* 374/*
375 * Error levels for parsing. PARSE_FATAL means the process cannot continue 375 * Error levels for parsing. PARSE_FATAL means the process cannot continue
376 * once the makefile has been parsed. PARSE_WARNING means it can. Passed 376 * once the makefile has been parsed. PARSE_WARNING means it can. Passed
377 * as the first argument to Parse_Error. 377 * as the first argument to Parse_Error.
378 */ 378 */
379#define PARSE_INFO 3 379#define PARSE_INFO 3
380#define PARSE_WARNING 2 380#define PARSE_WARNING 2
381#define PARSE_FATAL 1 381#define PARSE_FATAL 1
382 382
383/* 383/*
384 * Values returned by Cond_Eval. 384 * Values returned by Cond_Eval.
385 */ 385 */
386typedef enum { 386typedef enum {
387 COND_PARSE, /* Parse the next lines */ 387 COND_PARSE, /* Parse the next lines */
388 COND_SKIP, /* Skip the next lines */ 388 COND_SKIP, /* Skip the next lines */
389 COND_INVALID /* Not a conditional statement */ 389 COND_INVALID /* Not a conditional statement */
390} CondEvalResult; 390} CondEvalResult;
391 391
392/* 392/*
393 * Definitions for the "local" variables. Used only for clarity. 393 * Definitions for the "local" variables. Used only for clarity.
394 */ 394 */
395#define TARGET "@" /* Target of dependency */ 395#define TARGET "@" /* Target of dependency */
396#define OODATE "?" /* All out-of-date sources */ 396#define OODATE "?" /* All out-of-date sources */
397#define ALLSRC ">" /* All sources */ 397#define ALLSRC ">" /* All sources */
398#define IMPSRC "<" /* Source implied by transformation */ 398#define IMPSRC "<" /* Source implied by transformation */
399#define PREFIX "*" /* Common prefix */ 399#define PREFIX "*" /* Common prefix */
400#define ARCHIVE "!" /* Archive in "archive(member)" syntax */ 400#define ARCHIVE "!" /* Archive in "archive(member)" syntax */
401#define MEMBER "%" /* Member in "archive(member)" syntax */ 401#define MEMBER "%" /* Member in "archive(member)" syntax */
402 402
403#define FTARGET "@F" /* file part of TARGET */ 403#define FTARGET "@F" /* file part of TARGET */
404#define DTARGET "@D" /* directory part of TARGET */ 404#define DTARGET "@D" /* directory part of TARGET */
405#define FIMPSRC "<F" /* file part of IMPSRC */ 405#define FIMPSRC "<F" /* file part of IMPSRC */
406#define DIMPSRC "<D" /* directory part of IMPSRC */ 406#define DIMPSRC "<D" /* directory part of IMPSRC */
407#define FPREFIX "*F" /* file part of PREFIX */ 407#define FPREFIX "*F" /* file part of PREFIX */
408#define DPREFIX "*D" /* directory part of PREFIX */ 408#define DPREFIX "*D" /* directory part of PREFIX */
409 409
410/* 410/*
411 * Global Variables 411 * Global Variables
412 */ 412 */
413extern Lst create; /* The list of target names specified on the 413extern Lst create; /* The list of target names specified on the
414 * command line. used to resolve #if 414 * command line. used to resolve #if
415 * make(...) statements */ 415 * make(...) statements */
416extern Lst dirSearchPath; /* The list of directories to search when 416extern Lst dirSearchPath; /* The list of directories to search when
417 * looking for targets */ 417 * looking for targets */
418 418
419extern Boolean compatMake; /* True if we are make compatible */ 419extern Boolean compatMake; /* True if we are make compatible */
420extern Boolean ignoreErrors; /* True if should ignore all errors */ 420extern Boolean ignoreErrors; /* True if should ignore all errors */
421extern Boolean beSilent; /* True if should print no commands */ 421extern Boolean beSilent; /* True if should print no commands */
422extern Boolean noExecute; /* True if should execute nothing */ 422extern Boolean noExecute; /* True if should execute nothing */
423extern Boolean noRecursiveExecute; /* True if should execute nothing */ 423extern Boolean noRecursiveExecute; /* True if should execute nothing */
424extern Boolean allPrecious; /* True if every target is precious */ 424extern Boolean allPrecious; /* True if every target is precious */
425extern Boolean deleteOnError; /* True if failed targets should be deleted */ 425extern Boolean deleteOnError; /* True if failed targets should be deleted */
426extern Boolean keepgoing; /* True if should continue on unaffected 426extern Boolean keepgoing; /* True if should continue on unaffected
427 * portions of the graph when have an error 427 * portions of the graph when have an error
428 * in one portion */ 428 * in one portion */
429extern Boolean touchFlag; /* TRUE if targets should just be 'touched' 429extern Boolean touchFlag; /* TRUE if targets should just be 'touched'
430 * if out of date. Set by the -t flag */ 430 * if out of date. Set by the -t flag */
431extern Boolean queryFlag; /* TRUE if we aren't supposed to really make 431extern Boolean queryFlag; /* TRUE if we aren't supposed to really make
432 * anything, just see if the targets are out- 432 * anything, just see if the targets are out-
433 * of-date */ 433 * of-date */
434extern Boolean doing_depend; /* TRUE if processing .depend */ 434extern Boolean doing_depend; /* TRUE if processing .depend */
435 435
436extern Boolean checkEnvFirst; /* TRUE if environment should be searched for 436extern Boolean checkEnvFirst; /* TRUE if environment should be searched for
437 * variables before the global context */ 437 * variables before the global context */
438 438
439extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are 439extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are
440 * treated as errors */ 440 * treated as errors */
441 441
442extern Boolean varNoExportEnv; /* TRUE if we should not export variables 442extern Boolean varNoExportEnv; /* TRUE if we should not export variables
443 * set on the command line to the env. */ 443 * set on the command line to the env. */
444 444
445extern GNode *DEFAULT; /* .DEFAULT rule */ 445extern GNode *DEFAULT; /* .DEFAULT rule */
446 446
447extern GNode *VAR_INTERNAL; /* Variables defined internally by make 447extern GNode *VAR_INTERNAL; /* Variables defined internally by make
448 * which should not override those set by 448 * which should not override those set by
449 * makefiles. 449 * makefiles.
450 */ 450 */
451extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g 451extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
452 * in the Makefile itself */ 452 * in the Makefile itself */
453extern GNode *VAR_CMD; /* Variables defined on the command line */ 453extern GNode *VAR_CMD; /* Variables defined on the command line */
454extern char var_Error[]; /* Value returned by Var_Parse when an error 454extern char var_Error[]; /* Value returned by Var_Parse when an error
455 * is encountered. It actually points to 455 * is encountered. It actually points to
456 * an empty string, so naive callers needn't 456 * an empty string, so naive callers needn't
457 * worry about it. */ 457 * worry about it. */
458 458
459extern time_t now; /* The time at the start of this whole 459extern time_t now; /* The time at the start of this whole
460 * process */ 460 * process */
461 461
462extern Boolean oldVars; /* Do old-style variable substitution */ 462extern Boolean oldVars; /* Do old-style variable substitution */
463 463
464extern Lst sysIncPath; /* The system include path. */ 464extern Lst sysIncPath; /* The system include path. */
465extern Lst defIncPath; /* The default include path. */ 465extern Lst defIncPath; /* The default include path. */
466 466
467extern char curdir[]; /* Startup directory */ 467extern char curdir[]; /* Startup directory */
468extern char *progname; /* The program name */ 468extern char *progname; /* The program name */
469extern char *makeDependfile; /* .depend */ 469extern char *makeDependfile; /* .depend */
470extern char **savedEnv; /* if we replaced environ this will be non-NULL */ 470extern char **savedEnv; /* if we replaced environ this will be non-NULL */
471 471
472extern int makelevel; 472extern int makelevel;
473 473
474/* 474/*
475 * We cannot vfork() in a child of vfork(). 475 * We cannot vfork() in a child of vfork().
476 * Most systems do not enforce this but some do. 476 * Most systems do not enforce this but some do.
477 */ 477 */
478#define vFork() ((getpid() == myPid) ? vfork() : fork()) 478#define vFork() ((getpid() == myPid) ? vfork() : fork())
479extern pid_t myPid; 479extern pid_t myPid;
480 480
481#define MAKEFLAGS ".MAKEFLAGS" 481#define MAKEFLAGS ".MAKEFLAGS"
482#define MAKEOVERRIDES ".MAKEOVERRIDES" 482#define MAKEOVERRIDES ".MAKEOVERRIDES"
483#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */ 483#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */
484#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */ 484#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */
485#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */ 485#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */
486#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */ 486#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */
487#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE" 487#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
488#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */ 488#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
489#define MAKE_MODE ".MAKE.MODE" 489#define MAKE_MODE ".MAKE.MODE"
490#ifndef MAKE_LEVEL_ENV 490#ifndef MAKE_LEVEL_ENV
491# define MAKE_LEVEL_ENV "MAKELEVEL" 491# define MAKE_LEVEL_ENV "MAKELEVEL"
492#endif 492#endif
493 493
494/* 494/*
495 * debug control: 495 * debug control:
496 * There is one bit per module. It is up to the module what debug 496 * There is one bit per module. It is up to the module what debug
497 * information to print. 497 * information to print.
498 */ 498 */
499extern FILE *debug_file; /* Output is written here - default stderr */ 499extern FILE *debug_file; /* Output is written here - default stderr */
500extern int debug; 500extern int debug;
501#define DEBUG_ARCH 0x00001 501#define DEBUG_ARCH 0x00001
502#define DEBUG_COND 0x00002 502#define DEBUG_COND 0x00002
503#define DEBUG_DIR 0x00004 503#define DEBUG_DIR 0x00004
504#define DEBUG_GRAPH1 0x00008 504#define DEBUG_GRAPH1 0x00008
505#define DEBUG_GRAPH2 0x00010 505#define DEBUG_GRAPH2 0x00010
506#define DEBUG_JOB 0x00020 506#define DEBUG_JOB 0x00020
507#define DEBUG_MAKE 0x00040 507#define DEBUG_MAKE 0x00040
508#define DEBUG_SUFF 0x00080 508#define DEBUG_SUFF 0x00080
509#define DEBUG_TARG 0x00100 509#define DEBUG_TARG 0x00100
510#define DEBUG_VAR 0x00200 510#define DEBUG_VAR 0x00200
511#define DEBUG_FOR 0x00400 511#define DEBUG_FOR 0x00400
512#define DEBUG_SHELL 0x00800 512#define DEBUG_SHELL 0x00800
513#define DEBUG_ERROR 0x01000 513#define DEBUG_ERROR 0x01000
514#define DEBUG_LOUD 0x02000 514#define DEBUG_LOUD 0x02000
515#define DEBUG_META 0x04000 515#define DEBUG_META 0x04000
516#define DEBUG_HASH 0x08000 516#define DEBUG_HASH 0x08000
517 517
518#define DEBUG_GRAPH3 0x10000 518#define DEBUG_GRAPH3 0x10000
519#define DEBUG_SCRIPT 0x20000 519#define DEBUG_SCRIPT 0x20000
520#define DEBUG_PARSE 0x40000 520#define DEBUG_PARSE 0x40000
521#define DEBUG_CWD 0x80000 521#define DEBUG_CWD 0x80000
522 522
523#define DEBUG_LINT 0x100000 523#define DEBUG_LINT 0x100000
524 524
525#define CONCAT(a,b) a##b 525#define CONCAT(a,b) a##b
526 526
527#define DEBUG(module) (debug & CONCAT(DEBUG_,module)) 527#define DEBUG(module) (debug & CONCAT(DEBUG_,module))
528 528
529#include "nonints.h" 529#include "nonints.h"
530 530
531int Make_TimeStamp(GNode *, GNode *); 531int Make_TimeStamp(GNode *, GNode *);
532Boolean Make_OODate(GNode *); 532Boolean Make_OODate(GNode *);
533void Make_ExpandUse(Lst); 533void Make_ExpandUse(Lst);
534time_t Make_Recheck(GNode *); 534time_t Make_Recheck(GNode *);
535void Make_HandleUse(GNode *, GNode *); 535void Make_HandleUse(GNode *, GNode *);
536void Make_Update(GNode *); 536void Make_Update(GNode *);
537void Make_DoAllVar(GNode *); 537void Make_DoAllVar(GNode *);
538Boolean Make_Run(Lst); 538Boolean Make_Run(Lst);
539int dieQuietly(GNode *, int); 539int dieQuietly(GNode *, int);
540void PrintOnError(GNode *, const char *); 540void PrintOnError(GNode *, const char *);
541void Main_ExportMAKEFLAGS(Boolean); 541void Main_ExportMAKEFLAGS(Boolean);
542Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); 542Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
543int mkTempFile(const char *, char **); 543int mkTempFile(const char *, char **);
544int str2Lst_Append(Lst, char *, const char *); 544int str2Lst_Append(Lst, char *, const char *);
545int cached_lstat(const char *, void *); 545int cached_lstat(const char *, void *);
546int cached_stat(const char *, void *); 546int cached_stat(const char *, void *);
547void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *); 547void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
548 548
549#ifdef __GNUC__ 549#ifdef __GNUC__
550#define UNCONST(ptr) ({ \ 550#define UNCONST(ptr) ({ \
551 union __unconst { \ 551 union __unconst { \
552 const void *__cp; \ 552 const void *__cp; \
553 void *__p; \ 553 void *__p; \
554 } __d; \ 554 } __d; \
555 __d.__cp = ptr, __d.__p; }) 555 __d.__cp = ptr, __d.__p; })
556#else 556#else
557#define UNCONST(ptr) (void *)(ptr) 557#define UNCONST(ptr) (void *)(ptr)
558#endif 558#endif
559 559
560#ifndef MIN 560#ifndef MIN
561#define MIN(a, b) ((a < b) ? a : b) 561#define MIN(a, b) ((a < b) ? a : b)
562#endif 562#endif
563#ifndef MAX 563#ifndef MAX
564#define MAX(a, b) ((a > b) ? a : b) 564#define MAX(a, b) ((a > b) ? a : b)
565#endif 565#endif
566 566
567/* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */ 567/* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */
568#include <limits.h> 568#include <limits.h>
569#ifndef MAXPATHLEN 569#ifndef MAXPATHLEN
570#define MAXPATHLEN 4096 570#define MAXPATHLEN 4096
571#endif 571#endif
572#ifndef PATH_MAX 572#ifndef PATH_MAX
573#define PATH_MAX MAXPATHLEN 573#define PATH_MAX MAXPATHLEN
574#endif 574#endif
575 575
576#if defined(SYSV) 576#if defined(SYSV)
577#define KILLPG(pid, sig) kill(-(pid), (sig)) 577#define KILLPG(pid, sig) kill(-(pid), (sig))
578#else 578#else
579#define KILLPG(pid, sig) killpg((pid), (sig)) 579#define KILLPG(pid, sig) killpg((pid), (sig))
580#endif 580#endif
581 581
582#endif /* MAKE_MAKE_H */ 582#endif /* MAKE_MAKE_H */

cvs diff -r1.76 -r1.77 src/usr.bin/make/targ.c (switch to unified diff)

--- src/usr.bin/make/targ.c 2020/08/28 04:48:57 1.76
+++ src/usr.bin/make/targ.c 2020/08/28 19:14:07 1.77
@@ -1,851 +1,632 @@ @@ -1,851 +1,632 @@
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.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors 18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Copyright (c) 1989 by Berkeley Softworks 36 * Copyright (c) 1989 by Berkeley Softworks
37 * All rights reserved. 37 * All rights reserved.
38 * 38 *
39 * This code is derived from software contributed to Berkeley by 39 * This code is derived from software contributed to Berkeley by
40 * Adam de Boor. 40 * Adam de Boor.
41 * 41 *
42 * Redistribution and use in source and binary forms, with or without 42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions 43 * modification, are permitted provided that the following conditions
44 * are met: 44 * are met:
45 * 1. Redistributions of source code must retain the above copyright 45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer. 46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright 47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the 48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution. 49 * documentation and/or other materials provided with the distribution.
50 * 3. All advertising materials mentioning features or use of this software 50 * 3. All advertising materials mentioning features or use of this software
51 * must display the following acknowledgement: 51 * must display the following acknowledgement:
52 * This product includes software developed by the University of 52 * This product includes software developed by the University of
53 * California, Berkeley and its contributors. 53 * California, Berkeley and its contributors.
54 * 4. Neither the name of the University nor the names of its contributors 54 * 4. Neither the name of the University nor the names of its contributors
55 * may be used to endorse or promote products derived from this software 55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission. 56 * without specific prior written permission.
57 * 57 *
58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
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
72static char rcsid[] = "$NetBSD: targ.c,v 1.76 2020/08/28 04:48:57 rillig Exp $"; 72static 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
77static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; 77static 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 *
102 * Targ_FindNode Find the node for a given target, creating 101 * Targ_FindNode Find the node for a given target, creating
103 * and storing it if it doesn't exist and the 102 * and storing it if it doesn't exist and the
104 * flags are right (TARG_CREATE) 103 * flags are right (TARG_CREATE)
105 * 104 *
106 * Targ_FindList Given a list of names, find nodes for all 105 * Targ_FindList Given a list of names, find nodes for all
107 * of them. If a name doesn't exist and the 106 * of them. If a name doesn't exist and the
108 * TARG_NOCREATE flag was given, an error message 107 * TARG_NOCREATE flag was given, an error message
109 * is printed. Else, if a name doesn't exist, 108 * is printed. Else, if a name doesn't exist,
110 * its node is created. 109 * its node is created.
111 * 110 *
112 * Targ_Ignore Return TRUE if errors should be ignored when 111 * Targ_Ignore Return TRUE if errors should be ignored when
113 * creating the given target. 112 * creating the given target.
114 * 113 *
115 * Targ_Silent Return TRUE if we should be silent when 114 * Targ_Silent Return TRUE if we should be silent when
116 * creating the given target. 115 * creating the given target.
117 * 116 *
118 * Targ_Precious Return TRUE if the target is precious and 117 * Targ_Precious Return TRUE if the target is precious and
119 * should not be removed if we are interrupted. 118 * should not be removed if we are interrupted.
120 * 119 *
121 * Targ_Propagate Propagate information between related 120 * Targ_Propagate Propagate information between related
122 * nodes. Should be called after the 121 * nodes. Should be called after the
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
139static Lst allTargets; /* the list of all targets found so far */ 137static Lst allTargets; /* the list of all targets found so far */
140#ifdef CLEANUP 138#ifdef CLEANUP
141static Lst allGNs; /* List of all the GNodes */ 139static Lst allGNs; /* List of all the GNodes */
142#endif 140#endif
143static Hash_Table targets; /* a hash table of same */ 141static 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
147static int TargPrintOnlySrc(void *, void *); 145static int TargPrintOnlySrc(void *, void *);
148static int TargPrintName(void *, void *); 146static int TargPrintName(void *, void *);
149#ifdef CLEANUP 147#ifdef CLEANUP
150static void TargFreeGN(void *); 148static void TargFreeGN(void *);
151#endif 149#endif
152static int TargPropagateCohort(void *, void *); 150static int TargPropagateCohort(void *, void *);
153static int TargPropagateNode(void *, void *); 151static 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 */ 
167void 153void
168Targ_Init(void) 154Targ_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 */ 
186void 160void
187Targ_End(void) 161Targ_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
198void 172void
199Targ_Stats(void) 173Targ_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 */ 
216Lst 179Lst
217Targ_List(void) 180Targ_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 */
238GNode * 191GNode *
239Targ_NewGN(const char *name) 192Targ_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 */ 
295static void 232static void
296TargFreeGN(void *gnp) 233TargFreeGN(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 */
338GNode * 270GNode *
339Targ_FindNode(const char *name, int flags) 271Targ_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;
350 return (GNode *)Hash_GetValue(he); 282 return (GNode *)Hash_GetValue(he);
351 } 283 }
352 284
353 if (!(flags & TARG_NOHASH)) { 285 if (!(flags & TARG_NOHASH)) {
354 he = Hash_CreateEntry(&targets, name, &isNew); 286 he = Hash_CreateEntry(&targets, name, &isNew);
355 if (!isNew) 287 if (!isNew)
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 */
388Lst 314Lst
389Targ_FindList(Lst names, int flags) 315Targ_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) {
400 name = Lst_Datum(ln); 326 name = Lst_Datum(ln);
401 gn = Targ_FindNode(name, flags); 327 gn = Targ_FindNode(name, flags);
402 if (gn != NULL) { 328 if (gn != NULL) {
403 /* 329 /*
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 */ 
432Boolean 344Boolean
433Targ_Ignore(GNode *gn) 345Targ_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 */ 
457Boolean 351Boolean
458Targ_Silent(GNode *gn) 352Targ_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 */ 
482Boolean 358Boolean
483Targ_Precious(GNode *gn) 359Targ_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
494static GNode *mainTarg; /* the main target, as set by Targ_SetMain */ 366static 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 */ 
511void 370void
512Targ_SetMain(GNode *gn) 371Targ_SetMain(GNode *gn)
513{ 372{
514 mainTarg = gn; 373 mainTarg = gn;
515} 374}
516 375
517static int 376static int
518TargPrintName(void *gnp, void *pflags MAKE_ATTR_UNUSED) 377TargPrintName(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
528int 387int
529Targ_PrintCmd(void *cmd, void *dummy MAKE_ATTR_UNUSED) 388Targ_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 */ 
549char * 396char *
550Targ_FmtTime(time_t tm) 397Targ_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 */ 
572void 408void
573Targ_PrintType(int type) 409Targ_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;
585 421
586 switch(tbit) { 422 switch(tbit) {
587 PRINTBIT(OPTIONAL); 423 PRINTBIT(OPTIONAL);
588 PRINTBIT(USE); 424 PRINTBIT(USE);
589 PRINTBIT(EXEC); 425 PRINTBIT(EXEC);
590 PRINTBIT(IGNORE); 426 PRINTBIT(IGNORE);
591 PRINTBIT(PRECIOUS); 427 PRINTBIT(PRECIOUS);
592 PRINTBIT(SILENT); 428 PRINTBIT(SILENT);
593 PRINTBIT(MAKE); 429 PRINTBIT(MAKE);
594 PRINTBIT(JOIN); 430 PRINTBIT(JOIN);
595 PRINTBIT(INVISIBLE); 431 PRINTBIT(INVISIBLE);
596 PRINTBIT(NOTMAIN); 432 PRINTBIT(NOTMAIN);
597 PRINTDBIT(LIB); 433 PRINTDBIT(LIB);
598 /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */ 434 /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
599 case OP_MEMBER: if (DEBUG(TARG))fprintf(debug_file, ".MEMBER "); break; 435 case OP_MEMBER: if (DEBUG(TARG))fprintf(debug_file, ".MEMBER "); break;
600 PRINTDBIT(ARCHV); 436 PRINTDBIT(ARCHV);
601 PRINTDBIT(MADE); 437 PRINTDBIT(MADE);
602 PRINTDBIT(PHONY); 438 PRINTDBIT(PHONY);
603 } 439 }
604 } 440 }
605} 441}
606 442
607static const char * 443static const char *
608made_name(GNodeMade made) 444made_name(GNodeMade made)
609{ 445{
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 */ 
629int 460int
630Targ_PrintNode(void *gnp, void *passp) 461Targ_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");
642 if (gn == mainTarg) { 473 if (gn == mainTarg) {
643 fprintf(debug_file, "# *** MAIN TARGET ***\n"); 474 fprintf(debug_file, "# *** MAIN TARGET ***\n");
644 } 475 }
645 if (pass >= 2) { 476 if (pass >= 2) {
646 if (gn->unmade) { 477 if (gn->unmade) {
647 fprintf(debug_file, "# %d unmade children\n", gn->unmade); 478 fprintf(debug_file, "# %d unmade children\n", gn->unmade);
648 } else { 479 } else {
649 fprintf(debug_file, "# No unmade children\n"); 480 fprintf(debug_file, "# No unmade children\n");
650 } 481 }
651 if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) { 482 if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) {
652 if (gn->mtime != 0) { 483 if (gn->mtime != 0) {
653 fprintf(debug_file, "# last modified %s: %s\n", 484 fprintf(debug_file, "# last modified %s: %s\n",
654 Targ_FmtTime(gn->mtime), 485 Targ_FmtTime(gn->mtime),
655 made_name(gn->made)); 486 made_name(gn->made));
656 } else if (gn->made != UNMADE) { 487 } else if (gn->made != UNMADE) {
657 fprintf(debug_file, "# non-existent (maybe): %s\n", 488 fprintf(debug_file, "# non-existent (maybe): %s\n",
658 made_name(gn->made)); 489 made_name(gn->made));
659 } else { 490 } else {
660 fprintf(debug_file, "# unmade\n"); 491 fprintf(debug_file, "# unmade\n");
661 } 492 }
662 } 493 }
663 if (!Lst_IsEmpty(gn->iParents)) { 494 if (!Lst_IsEmpty(gn->iParents)) {
664 fprintf(debug_file, "# implicit parents: "); 495 fprintf(debug_file, "# implicit parents: ");
665 Lst_ForEach(gn->iParents, TargPrintName, NULL); 496 Lst_ForEach(gn->iParents, TargPrintName, NULL);
666 fprintf(debug_file, "\n"); 497 fprintf(debug_file, "\n");
667 } 498 }
668 } else { 499 } else {
669 if (gn->unmade) 500 if (gn->unmade)
670 fprintf(debug_file, "# %d unmade children\n", gn->unmade); 501 fprintf(debug_file, "# %d unmade children\n", gn->unmade);
671 } 502 }
672 if (!Lst_IsEmpty(gn->parents)) { 503 if (!Lst_IsEmpty(gn->parents)) {
673 fprintf(debug_file, "# parents: "); 504 fprintf(debug_file, "# parents: ");
674 Lst_ForEach(gn->parents, TargPrintName, NULL); 505 Lst_ForEach(gn->parents, TargPrintName, NULL);
675 fprintf(debug_file, "\n"); 506 fprintf(debug_file, "\n");
676 } 507 }
677 if (!Lst_IsEmpty(gn->order_pred)) { 508 if (!Lst_IsEmpty(gn->order_pred)) {
678 fprintf(debug_file, "# order_pred: "); 509 fprintf(debug_file, "# order_pred: ");
679 Lst_ForEach(gn->order_pred, TargPrintName, NULL); 510 Lst_ForEach(gn->order_pred, TargPrintName, NULL);
680 fprintf(debug_file, "\n"); 511 fprintf(debug_file, "\n");
681 } 512 }
682 if (!Lst_IsEmpty(gn->order_succ)) { 513 if (!Lst_IsEmpty(gn->order_succ)) {
683 fprintf(debug_file, "# order_succ: "); 514 fprintf(debug_file, "# order_succ: ");
684 Lst_ForEach(gn->order_succ, TargPrintName, NULL); 515 Lst_ForEach(gn->order_succ, TargPrintName, NULL);
685 fprintf(debug_file, "\n"); 516 fprintf(debug_file, "\n");
686 } 517 }
687 518
688 fprintf(debug_file, "%-16s", gn->name); 519 fprintf(debug_file, "%-16s", gn->name);
689 switch (gn->type & OP_OPMASK) { 520 switch (gn->type & OP_OPMASK) {
690 case OP_DEPENDS: 521 case OP_DEPENDS:
691 fprintf(debug_file, ": "); break; 522 fprintf(debug_file, ": "); break;
692 case OP_FORCE: 523 case OP_FORCE:
693 fprintf(debug_file, "! "); break; 524 fprintf(debug_file, "! "); break;
694 case OP_DOUBLEDEP: 525 case OP_DOUBLEDEP:
695 fprintf(debug_file, ":: "); break; 526 fprintf(debug_file, ":: "); break;
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 */ 
722static int 542static int
723TargPrintOnlySrc(void *gnp, void *dummy MAKE_ATTR_UNUSED) 543TargPrintOnlySrc(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 */
753void 562void
754Targ_PrintGraph(int pass) 563Targ_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 */
795static int 593static int
796TargPropagateNode(void *gnp, void *junk MAKE_ATTR_UNUSED) 594TargPropagateNode(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 */
823static int 614static int
824TargPropagateCohort(void *cgnp, void *pgnp) 615TargPropagateCohort(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 */ 
847void 628void
848Targ_Propagate(void) 629Targ_Propagate(void)
849{ 630{
850 Lst_ForEach(allTargets, TargPropagateNode, NULL); 631 Lst_ForEach(allTargets, TargPropagateNode, NULL);
851} 632}