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.diff -r1.128 -r1.129 src/usr.bin/make/make.h
(rillig)
--- 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 | |||
136 | typedef int Boolean; | 136 | typedef 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 | |||
149 | typedef int ReturnStatus; | 149 | typedef 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 | |||
169 | typedef enum { | 169 | typedef 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... */ | |
191 | typedef enum { | 191 | typedef 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 | |||
266 | typedef enum { | 266 | typedef 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. */ | |
281 | typedef struct GNode { | 281 | typedef 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 | */ | |
386 | typedef enum { | 386 | typedef 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 | */ | |
413 | extern Lst create; /* The list of target names specified on the | 413 | extern 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 */ | |
416 | extern Lst dirSearchPath; /* The list of directories to search when | 416 | extern Lst dirSearchPath; /* The list of directories to search when | |
417 | * looking for targets */ | 417 | * looking for targets */ | |
418 | 418 | |||
419 | extern Boolean compatMake; /* True if we are make compatible */ | 419 | extern Boolean compatMake; /* True if we are make compatible */ | |
420 | extern Boolean ignoreErrors; /* True if should ignore all errors */ | 420 | extern Boolean ignoreErrors; /* True if should ignore all errors */ | |
421 | extern Boolean beSilent; /* True if should print no commands */ | 421 | extern Boolean beSilent; /* True if should print no commands */ | |
422 | extern Boolean noExecute; /* True if should execute nothing */ | 422 | extern Boolean noExecute; /* True if should execute nothing */ | |
423 | extern Boolean noRecursiveExecute; /* True if should execute nothing */ | 423 | extern Boolean noRecursiveExecute; /* True if should execute nothing */ | |
424 | extern Boolean allPrecious; /* True if every target is precious */ | 424 | extern Boolean allPrecious; /* True if every target is precious */ | |
425 | extern Boolean deleteOnError; /* True if failed targets should be deleted */ | 425 | extern Boolean deleteOnError; /* True if failed targets should be deleted */ | |
426 | extern Boolean keepgoing; /* True if should continue on unaffected | 426 | extern 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 */ | |
429 | extern Boolean touchFlag; /* TRUE if targets should just be 'touched' | 429 | extern 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 */ | |
431 | extern Boolean queryFlag; /* TRUE if we aren't supposed to really make | 431 | extern 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 */ | |
434 | extern Boolean doing_depend; /* TRUE if processing .depend */ | 434 | extern Boolean doing_depend; /* TRUE if processing .depend */ | |
435 | 435 | |||
436 | extern Boolean checkEnvFirst; /* TRUE if environment should be searched for | 436 | extern Boolean checkEnvFirst; /* TRUE if environment should be searched for | |
437 | * variables before the global context */ | 437 | * variables before the global context */ | |
438 | 438 | |||
439 | extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are | 439 | extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are | |
440 | * treated as errors */ | 440 | * treated as errors */ | |
441 | 441 | |||
442 | extern Boolean varNoExportEnv; /* TRUE if we should not export variables | 442 | extern 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 | |||
445 | extern GNode *DEFAULT; /* .DEFAULT rule */ | 445 | extern GNode *DEFAULT; /* .DEFAULT rule */ | |
446 | 446 | |||
447 | extern GNode *VAR_INTERNAL; /* Variables defined internally by make | 447 | extern 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 | */ | |
451 | extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g | 451 | extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g | |
452 | * in the Makefile itself */ | 452 | * in the Makefile itself */ | |
453 | extern GNode *VAR_CMD; /* Variables defined on the command line */ | 453 | extern GNode *VAR_CMD; /* Variables defined on the command line */ | |
454 | extern char var_Error[]; /* Value returned by Var_Parse when an error | 454 | extern 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 | |||
459 | extern time_t now; /* The time at the start of this whole | 459 | extern time_t now; /* The time at the start of this whole | |
460 | * process */ | 460 | * process */ | |
461 | 461 | |||
462 | extern Boolean oldVars; /* Do old-style variable substitution */ | 462 | extern Boolean oldVars; /* Do old-style variable substitution */ | |
463 | 463 | |||
464 | extern Lst sysIncPath; /* The system include path. */ | 464 | extern Lst sysIncPath; /* The system include path. */ | |
465 | extern Lst defIncPath; /* The default include path. */ | 465 | extern Lst defIncPath; /* The default include path. */ | |
466 | 466 | |||
467 | extern char curdir[]; /* Startup directory */ | 467 | extern char curdir[]; /* Startup directory */ | |
468 | extern char *progname; /* The program name */ | 468 | extern char *progname; /* The program name */ | |
469 | extern char *makeDependfile; /* .depend */ | 469 | extern char *makeDependfile; /* .depend */ | |
470 | extern char **savedEnv; /* if we replaced environ this will be non-NULL */ | 470 | extern char **savedEnv; /* if we replaced environ this will be non-NULL */ | |
471 | 471 | |||
472 | extern int makelevel; | 472 | extern 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()) | |
479 | extern pid_t myPid; | 479 | extern 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 | */ | |
499 | extern FILE *debug_file; /* Output is written here - default stderr */ | 499 | extern FILE *debug_file; /* Output is written here - default stderr */ | |
500 | extern int debug; | 500 | extern 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 | |||
531 | int Make_TimeStamp(GNode *, GNode *); | 531 | int Make_TimeStamp(GNode *, GNode *); | |
532 | Boolean Make_OODate(GNode *); | 532 | Boolean Make_OODate(GNode *); | |
533 | void Make_ExpandUse(Lst); | 533 | void Make_ExpandUse(Lst); | |
534 | time_t Make_Recheck(GNode *); | 534 | time_t Make_Recheck(GNode *); | |
535 | void Make_HandleUse(GNode *, GNode *); | 535 | void Make_HandleUse(GNode *, GNode *); | |
536 | void Make_Update(GNode *); | 536 | void Make_Update(GNode *); | |
537 | void Make_DoAllVar(GNode *); | 537 | void Make_DoAllVar(GNode *); | |
538 | Boolean Make_Run(Lst); | 538 | Boolean Make_Run(Lst); | |
539 | int dieQuietly(GNode *, int); | 539 | int dieQuietly(GNode *, int); | |
540 | void PrintOnError(GNode *, const char *); | 540 | void PrintOnError(GNode *, const char *); | |
541 | void Main_ExportMAKEFLAGS(Boolean); | 541 | void Main_ExportMAKEFLAGS(Boolean); | |
542 | Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); | 542 | Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); | |
543 | int mkTempFile(const char *, char **); | 543 | int mkTempFile(const char *, char **); | |
544 | int str2Lst_Append(Lst, char *, const char *); | 544 | int str2Lst_Append(Lst, char *, const char *); | |
545 | int cached_lstat(const char *, void *); | 545 | int cached_lstat(const char *, void *); | |
546 | int cached_stat(const char *, void *); | 546 | int cached_stat(const char *, void *); | |
547 | void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *); | 547 | void 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 */ |
--- 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 | |
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 | * | |
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 | |||
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; | |
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 | */ | |
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) { | |
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 | */ | |||
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; | |
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 | |||
607 | static const char * | 443 | static const char * | |
608 | made_name(GNodeMade made) | 444 | made_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 | */ | |||
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"); | |
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 | */ | |||
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 | } |