make(1): remove header sprite.h Make is independent of the Sprite operating system.diff -r1.93 -r1.94 src/usr.bin/make/Makefile
(rillig)
--- src/usr.bin/make/Makefile 2020/08/25 16:39:19 1.93
+++ src/usr.bin/make/Makefile 2020/08/26 23:00:47 1.94
@@ -1,190 +1,189 @@ | @@ -1,190 +1,189 @@ | |||
1 | # $NetBSD: Makefile,v 1.93 2020/08/25 16:39:19 rillig Exp $ | 1 | # $NetBSD: Makefile,v 1.94 2020/08/26 23:00:47 rillig Exp $ | |
2 | # @(#)Makefile 5.2 (Berkeley) 12/28/90 | 2 | # @(#)Makefile 5.2 (Berkeley) 12/28/90 | |
3 | 3 | |||
4 | PROG= make | 4 | PROG= make | |
5 | SRCS= arch.c | 5 | SRCS= arch.c | |
6 | SRCS+= buf.c | 6 | SRCS+= buf.c | |
7 | SRCS+= compat.c | 7 | SRCS+= compat.c | |
8 | SRCS+= cond.c | 8 | SRCS+= cond.c | |
9 | SRCS+= dir.c | 9 | SRCS+= dir.c | |
10 | SRCS+= enum.c | 10 | SRCS+= enum.c | |
11 | SRCS+= for.c | 11 | SRCS+= for.c | |
12 | SRCS+= hash.c | 12 | SRCS+= hash.c | |
13 | SRCS+= job.c | 13 | SRCS+= job.c | |
14 | SRCS+= lst.c | 14 | SRCS+= lst.c | |
15 | SRCS+= main.c | 15 | SRCS+= main.c | |
16 | SRCS+= make.c | 16 | SRCS+= make.c | |
17 | SRCS+= make_malloc.c | 17 | SRCS+= make_malloc.c | |
18 | SRCS+= metachar.c | 18 | SRCS+= metachar.c | |
19 | SRCS+= parse.c | 19 | SRCS+= parse.c | |
20 | SRCS+= str.c | 20 | SRCS+= str.c | |
21 | SRCS+= strlist.c | 21 | SRCS+= strlist.c | |
22 | SRCS+= suff.c | 22 | SRCS+= suff.c | |
23 | SRCS+= targ.c | 23 | SRCS+= targ.c | |
24 | SRCS+= trace.c | 24 | SRCS+= trace.c | |
25 | SRCS+= var.c | 25 | SRCS+= var.c | |
26 | SRCS+= util.c | 26 | SRCS+= util.c | |
27 | HDRS= buf.h | 27 | HDRS= buf.h | |
28 | HDRS+= config.h | 28 | HDRS+= config.h | |
29 | HDRS+= dir.h | 29 | HDRS+= dir.h | |
30 | HDRS+= enum.h | 30 | HDRS+= enum.h | |
31 | HDRS+= hash.h | 31 | HDRS+= hash.h | |
32 | HDRS+= job.h | 32 | HDRS+= job.h | |
33 | HDRS+= lst.h | 33 | HDRS+= lst.h | |
34 | HDRS+= make.h | 34 | HDRS+= make.h | |
35 | HDRS+= make_malloc.h | 35 | HDRS+= make_malloc.h | |
36 | HDRS+= meta.h | 36 | HDRS+= meta.h | |
37 | HDRS+= metachar.h | 37 | HDRS+= metachar.h | |
38 | HDRS+= nonints.h | 38 | HDRS+= nonints.h | |
39 | HDRS+= pathnames.h | 39 | HDRS+= pathnames.h | |
40 | HDRS+= sprite.h | |||
41 | HDRS+= strlist.h | 40 | HDRS+= strlist.h | |
42 | HDRS+= trace.h | 41 | HDRS+= trace.h | |
43 | 42 | |||
44 | # Whether to generate a coverage report after running the tests. | 43 | # Whether to generate a coverage report after running the tests. | |
45 | USE_COVERAGE?= no # works only with gcc; clang9 fails to link | 44 | USE_COVERAGE?= no # works only with gcc; clang9 fails to link | |
46 | .if ${USE_COVERAGE} == "yes" | 45 | .if ${USE_COVERAGE} == "yes" | |
47 | GCOV?= gcov | 46 | GCOV?= gcov | |
48 | COPTS+= --coverage -O0 -ggdb | 47 | COPTS+= --coverage -O0 -ggdb | |
49 | LDADD+= --coverage | 48 | LDADD+= --coverage | |
50 | .endif | 49 | .endif | |
51 | CLEANFILES+= *.gcda *.gcno *.gcov | 50 | CLEANFILES+= *.gcda *.gcno *.gcov | |
52 | 51 | |||
53 | # Whether to compile using the Undefined Behavior Sanitizer (GCC, Clang). | 52 | # Whether to compile using the Undefined Behavior Sanitizer (GCC, Clang). | |
54 | USE_UBSAN?= no | 53 | USE_UBSAN?= no | |
55 | .if ${USE_UBSAN} == "yes" | 54 | .if ${USE_UBSAN} == "yes" | |
56 | COPTS+= -fsanitize=undefined | 55 | COPTS+= -fsanitize=undefined | |
57 | LDADD+= -fsanitize=undefined | 56 | LDADD+= -fsanitize=undefined | |
58 | .endif | 57 | .endif | |
59 | 58 | |||
60 | # Whether to compile with GCC 10 from pkgsrc, during development. | 59 | # Whether to compile with GCC 10 from pkgsrc, during development. | |
61 | USE_GCC10?= no | 60 | USE_GCC10?= no | |
62 | .if ${USE_GCC10} == "yes" | 61 | .if ${USE_GCC10} == "yes" | |
63 | # CC is set further down in this file | 62 | # CC is set further down in this file | |
64 | COPTS+= -Wno-attributes # for abs and labs | 63 | COPTS+= -Wno-attributes # for abs and labs | |
65 | COPTS.arch.c+= -Wno-error=format-truncation | 64 | COPTS.arch.c+= -Wno-error=format-truncation | |
66 | COPTS.dir.c+= -Wno-error=format-truncation | 65 | COPTS.dir.c+= -Wno-error=format-truncation | |
67 | COPTS.main.c+= -Wno-error=format-truncation | 66 | COPTS.main.c+= -Wno-error=format-truncation | |
68 | COPTS.meta.c+= -Wno-error=format-truncation | 67 | COPTS.meta.c+= -Wno-error=format-truncation | |
69 | COPTS.parse.c+= -Wno-error=format-truncation | 68 | COPTS.parse.c+= -Wno-error=format-truncation | |
70 | .endif | 69 | .endif | |
71 | 70 | |||
72 | # Whether to compile with GCC 9 from pkgsrc, during development. | 71 | # Whether to compile with GCC 9 from pkgsrc, during development. | |
73 | USE_GCC9?= no | 72 | USE_GCC9?= no | |
74 | .if ${USE_GCC9} == "yes" | 73 | .if ${USE_GCC9} == "yes" | |
75 | # CC is set further down in this file | 74 | # CC is set further down in this file | |
76 | COPTS+= -Wno-attributes # for abs and labs | 75 | COPTS+= -Wno-attributes # for abs and labs | |
77 | COPTS.arch.c+= -Wno-error=format-truncation | 76 | COPTS.arch.c+= -Wno-error=format-truncation | |
78 | COPTS.dir.c+= -Wno-error=format-truncation | 77 | COPTS.dir.c+= -Wno-error=format-truncation | |
79 | COPTS.main.c+= -Wno-error=format-truncation | 78 | COPTS.main.c+= -Wno-error=format-truncation | |
80 | COPTS.meta.c+= -Wno-error=format-truncation | 79 | COPTS.meta.c+= -Wno-error=format-truncation | |
81 | COPTS.parse.c+= -Wno-error=format-truncation | 80 | COPTS.parse.c+= -Wno-error=format-truncation | |
82 | .endif | 81 | .endif | |
83 | 82 | |||
84 | # Whether to compile with GCC 8 from pkgsrc, during development. | 83 | # Whether to compile with GCC 8 from pkgsrc, during development. | |
85 | USE_GCC8?= no | 84 | USE_GCC8?= no | |
86 | .if ${USE_GCC8} == "yes" | 85 | .if ${USE_GCC8} == "yes" | |
87 | # CC is set further down in this file | 86 | # CC is set further down in this file | |
88 | COPTS+= -Wno-attributes # for abs and labs | 87 | COPTS+= -Wno-attributes # for abs and labs | |
89 | COPTS.arch.c+= -Wno-error=format-truncation | 88 | COPTS.arch.c+= -Wno-error=format-truncation | |
90 | COPTS.dir.c+= -Wno-error=format-truncation | 89 | COPTS.dir.c+= -Wno-error=format-truncation | |
91 | COPTS.main.c+= -Wno-error=format-truncation | 90 | COPTS.main.c+= -Wno-error=format-truncation | |
92 | COPTS.meta.c+= -Wno-error=format-truncation | 91 | COPTS.meta.c+= -Wno-error=format-truncation | |
93 | .endif | 92 | .endif | |
94 | 93 | |||
95 | USE_META?= yes | 94 | USE_META?= yes | |
96 | .if ${USE_META:tl} != "no" | 95 | .if ${USE_META:tl} != "no" | |
97 | 96 | |||
98 | SRCS+= meta.c | 97 | SRCS+= meta.c | |
99 | CPPFLAGS+= -DUSE_META | 98 | CPPFLAGS+= -DUSE_META | |
100 | 99 | |||
101 | USE_FILEMON?= ktrace | 100 | USE_FILEMON?= ktrace | |
102 | . if ${USE_FILEMON:tl} != "no" | 101 | . if ${USE_FILEMON:tl} != "no" | |
103 | 102 | |||
104 | .PATH: ${.CURDIR}/filemon | 103 | .PATH: ${.CURDIR}/filemon | |
105 | SRCS+= filemon_${USE_FILEMON}.c | 104 | SRCS+= filemon_${USE_FILEMON}.c | |
106 | CPPFLAGS+= -DUSE_FILEMON | 105 | CPPFLAGS+= -DUSE_FILEMON | |
107 | CPPFLAGS+= -DUSE_FILEMON_${USE_FILEMON:tu} | 106 | CPPFLAGS+= -DUSE_FILEMON_${USE_FILEMON:tu} | |
108 | 107 | |||
109 | . if ${USE_FILEMON} == "dev" | 108 | . if ${USE_FILEMON} == "dev" | |
110 | FILEMON_H?= /usr/include/dev/filemon/filemon.h | 109 | FILEMON_H?= /usr/include/dev/filemon/filemon.h | |
111 | . if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h" | 110 | . if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h" | |
112 | COPTS.filemon_dev.c+= \ | 111 | COPTS.filemon_dev.c+= \ | |
113 | -DHAVE_FILEMON_H -I${FILEMON_H:H} | 112 | -DHAVE_FILEMON_H -I${FILEMON_H:H} | |
114 | . endif | 113 | . endif | |
115 | . endif | 114 | . endif | |
116 | . endif | 115 | . endif | |
117 | .endif | 116 | .endif | |
118 | 117 | |||
119 | SUBDIR.roff+= PSD.doc | 118 | SUBDIR.roff+= PSD.doc | |
120 | .if make(obj) || make(clean) | 119 | .if make(obj) || make(clean) | |
121 | SUBDIR+= unit-tests | 120 | SUBDIR+= unit-tests | |
122 | .endif | 121 | .endif | |
123 | 122 | |||
124 | ${SRCS:M*.c:.c=.o}: ${HDRS} | 123 | ${SRCS:M*.c:.c=.o}: ${HDRS} | |
125 | 124 | |||
126 | .include <bsd.prog.mk> | 125 | .include <bsd.prog.mk> | |
127 | .include <bsd.subdir.mk> | 126 | .include <bsd.subdir.mk> | |
128 | 127 | |||
129 | CPPFLAGS+= -DMAKE_NATIVE | 128 | CPPFLAGS+= -DMAKE_NATIVE | |
130 | COPTS.job.c+= -Wno-format-nonliteral | 129 | COPTS.job.c+= -Wno-format-nonliteral | |
131 | COPTS.parse.c+= -Wno-format-nonliteral | 130 | COPTS.parse.c+= -Wno-format-nonliteral | |
132 | COPTS.var.c+= -Wno-format-nonliteral | 131 | COPTS.var.c+= -Wno-format-nonliteral | |
133 | 132 | |||
134 | .if ${USE_GCC10} == "yes" | 133 | .if ${USE_GCC10} == "yes" | |
135 | GCC9BASE?= /usr/pkg/gcc10 | 134 | GCC9BASE?= /usr/pkg/gcc10 | |
136 | CC= ${GCC10BASE}/bin/gcc | 135 | CC= ${GCC10BASE}/bin/gcc | |
137 | GCOV= ${GCC10BASE}/bin/gcov | 136 | GCOV= ${GCC10BASE}/bin/gcov | |
138 | .endif | 137 | .endif | |
139 | 138 | |||
140 | .if ${USE_GCC9} == "yes" | 139 | .if ${USE_GCC9} == "yes" | |
141 | GCC9BASE?= /usr/pkg/gcc9 | 140 | GCC9BASE?= /usr/pkg/gcc9 | |
142 | CC= ${GCC9BASE}/bin/gcc | 141 | CC= ${GCC9BASE}/bin/gcc | |
143 | GCOV= ${GCC9BASE}/bin/gcov | 142 | GCOV= ${GCC9BASE}/bin/gcov | |
144 | .endif | 143 | .endif | |
145 | 144 | |||
146 | .if ${USE_GCC8} == "yes" | 145 | .if ${USE_GCC8} == "yes" | |
147 | GCC8BASE?= /usr/pkg/gcc8 | 146 | GCC8BASE?= /usr/pkg/gcc8 | |
148 | CC= ${GCC8BASE}/bin/gcc | 147 | CC= ${GCC8BASE}/bin/gcc | |
149 | GCOV= ${GCC8BASE}/bin/gcov | 148 | GCOV= ${GCC8BASE}/bin/gcov | |
150 | .endif | 149 | .endif | |
151 | 150 | |||
152 | .if defined(TOOLDIR) | 151 | .if defined(TOOLDIR) | |
153 | # This is a native NetBSD build, use libutil rather than the local emalloc etc. | 152 | # This is a native NetBSD build, use libutil rather than the local emalloc etc. | |
154 | CPPFLAGS+= -DUSE_EMALLOC | 153 | CPPFLAGS+= -DUSE_EMALLOC | |
155 | LDADD+= -lutil | 154 | LDADD+= -lutil | |
156 | DPADD+= ${LIBUTIL} | 155 | DPADD+= ${LIBUTIL} | |
157 | .endif | 156 | .endif | |
158 | 157 | |||
159 | COPTS.arch.c+= ${GCC_NO_FORMAT_TRUNCATION} | 158 | COPTS.arch.c+= ${GCC_NO_FORMAT_TRUNCATION} | |
160 | COPTS.dir.c+= ${GCC_NO_FORMAT_TRUNCATION} | 159 | COPTS.dir.c+= ${GCC_NO_FORMAT_TRUNCATION} | |
161 | COPTS.main.c+= ${GCC_NO_FORMAT_TRUNCATION} ${GCC_NO_STRINGOP_TRUNCATION} | 160 | COPTS.main.c+= ${GCC_NO_FORMAT_TRUNCATION} ${GCC_NO_STRINGOP_TRUNCATION} | |
162 | COPTS.meta.c+= ${GCC_NO_FORMAT_TRUNCATION} | 161 | COPTS.meta.c+= ${GCC_NO_FORMAT_TRUNCATION} | |
163 | COPTS.parse.c+= ${GCC_NO_FORMAT_TRUNCATION} | 162 | COPTS.parse.c+= ${GCC_NO_FORMAT_TRUNCATION} | |
164 | 163 | |||
165 | COPTS+= -Wdeclaration-after-statement | 164 | COPTS+= -Wdeclaration-after-statement | |
166 | 165 | |||
167 | # For -DCLEANUP and similar feature toggles. | 166 | # For -DCLEANUP and similar feature toggles. | |
168 | CPPFLAGS+= ${USER_CPPFLAGS} | 167 | CPPFLAGS+= ${USER_CPPFLAGS} | |
169 | # For overriding -std=gnu99 or similar options. | 168 | # For overriding -std=gnu99 or similar options. | |
170 | CFLAGS+= ${USER_CFLAGS} | 169 | CFLAGS+= ${USER_CFLAGS} | |
171 | 170 | |||
172 | # A simple unit-test driver to help catch regressions | 171 | # A simple unit-test driver to help catch regressions | |
173 | TEST_MAKE ?= ${.OBJDIR}/${PROG:T} | 172 | TEST_MAKE ?= ${.OBJDIR}/${PROG:T} | |
174 | test: .MAKE | 173 | test: .MAKE | |
175 | cd ${.CURDIR}/unit-tests \ | 174 | cd ${.CURDIR}/unit-tests \ | |
176 | && MAKEFLAGS= ${TEST_MAKE} -r -m / TEST_MAKE=${TEST_MAKE} ${TESTS:DTESTS=${TESTS:Q}} ${.TARGET} | 175 | && MAKEFLAGS= ${TEST_MAKE} -r -m / TEST_MAKE=${TEST_MAKE} ${TESTS:DTESTS=${TESTS:Q}} ${.TARGET} | |
177 | .if ${USE_COVERAGE} == yes | 176 | .if ${USE_COVERAGE} == yes | |
178 | ${GCOV} ${GCOV_OPTS} ${SRCS} | 177 | ${GCOV} ${GCOV_OPTS} ${SRCS} | |
179 | sed -i 's,^\([^:]*\): *[0-9]*:,\1: ,' *.gcov | 178 | sed -i 's,^\([^:]*\): *[0-9]*:,\1: ,' *.gcov | |
180 | .endif | 179 | .endif | |
181 | 180 | |||
182 | accept sync-mi: .MAKE | 181 | accept sync-mi: .MAKE | |
183 | cd ${.CURDIR}/unit-tests && ${.MAKE} ${.TARGET} | 182 | cd ${.CURDIR}/unit-tests && ${.MAKE} ${.TARGET} | |
184 | 183 | |||
185 | retest: | 184 | retest: | |
186 | ${.MAKE} -C ${.CURDIR}/unit-tests cleandir | 185 | ${.MAKE} -C ${.CURDIR}/unit-tests cleandir | |
187 | .if ${USE_COVERAGE} == yes | 186 | .if ${USE_COVERAGE} == yes | |
188 | rm -f *.gcov *.gcda | 187 | rm -f *.gcov *.gcda | |
189 | .endif | 188 | .endif | |
190 | ${.MAKE} test | 189 | ${.MAKE} test |
--- src/usr.bin/make/hash.c 2020/08/01 14:47:49 1.26
+++ src/usr.bin/make/hash.c 2020/08/26 23:00:47 1.27
@@ -1,522 +1,520 @@ | @@ -1,522 +1,520 @@ | |||
1 | /* $NetBSD: hash.c,v 1.26 2020/08/01 14:47:49 rillig Exp $ */ | 1 | /* $NetBSD: hash.c,v 1.27 2020/08/26 23:00:47 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | 4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | |
5 | * All rights reserved. | 5 | * 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) 1988, 1989 by Adam de Boor | 36 | * Copyright (c) 1988, 1989 by Adam de Boor | |
37 | * Copyright (c) 1989 by Berkeley Softworks | 37 | * Copyright (c) 1989 by Berkeley Softworks | |
38 | * All rights reserved. | 38 | * All rights reserved. | |
39 | * | 39 | * | |
40 | * This code is derived from software contributed to Berkeley by | 40 | * This code is derived from software contributed to Berkeley by | |
41 | * Adam de Boor. | 41 | * Adam de Boor. | |
42 | * | 42 | * | |
43 | * Redistribution and use in source and binary forms, with or without | 43 | * Redistribution and use in source and binary forms, with or without | |
44 | * modification, are permitted provided that the following conditions | 44 | * modification, are permitted provided that the following conditions | |
45 | * are met: | 45 | * are met: | |
46 | * 1. Redistributions of source code must retain the above copyright | 46 | * 1. Redistributions of source code must retain the above copyright | |
47 | * notice, this list of conditions and the following disclaimer. | 47 | * notice, this list of conditions and the following disclaimer. | |
48 | * 2. Redistributions in binary form must reproduce the above copyright | 48 | * 2. Redistributions in binary form must reproduce the above copyright | |
49 | * notice, this list of conditions and the following disclaimer in the | 49 | * notice, this list of conditions and the following disclaimer in the | |
50 | * documentation and/or other materials provided with the distribution. | 50 | * documentation and/or other materials provided with the distribution. | |
51 | * 3. All advertising materials mentioning features or use of this software | 51 | * 3. All advertising materials mentioning features or use of this software | |
52 | * must display the following acknowledgement: | 52 | * must display the following acknowledgement: | |
53 | * This product includes software developed by the University of | 53 | * This product includes software developed by the University of | |
54 | * California, Berkeley and its contributors. | 54 | * California, Berkeley and its contributors. | |
55 | * 4. Neither the name of the University nor the names of its contributors | 55 | * 4. Neither the name of the University nor the names of its contributors | |
56 | * may be used to endorse or promote products derived from this software | 56 | * may be used to endorse or promote products derived from this software | |
57 | * without specific prior written permission. | 57 | * without specific prior written permission. | |
58 | * | 58 | * | |
59 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 59 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
60 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 60 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
61 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 61 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
62 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 62 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
63 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 63 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
64 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 64 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
65 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 65 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
66 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 66 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
67 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 67 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
68 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 68 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
69 | * SUCH DAMAGE. | 69 | * SUCH DAMAGE. | |
70 | */ | 70 | */ | |
71 | 71 | |||
72 | #ifndef MAKE_NATIVE | 72 | #ifndef MAKE_NATIVE | |
73 | static char rcsid[] = "$NetBSD: hash.c,v 1.26 2020/08/01 14:47:49 rillig Exp $"; | 73 | static char rcsid[] = "$NetBSD: hash.c,v 1.27 2020/08/26 23:00:47 rillig Exp $"; | |
74 | #else | 74 | #else | |
75 | #include <sys/cdefs.h> | 75 | #include <sys/cdefs.h> | |
76 | #ifndef lint | 76 | #ifndef lint | |
77 | #if 0 | 77 | #if 0 | |
78 | static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93"; | 78 | static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93"; | |
79 | #else | 79 | #else | |
80 | __RCSID("$NetBSD: hash.c,v 1.26 2020/08/01 14:47:49 rillig Exp $"); | 80 | __RCSID("$NetBSD: hash.c,v 1.27 2020/08/26 23:00:47 rillig Exp $"); | |
81 | #endif | 81 | #endif | |
82 | #endif /* not lint */ | 82 | #endif /* not lint */ | |
83 | #endif | 83 | #endif | |
84 | 84 | |||
85 | /* hash.c -- | 85 | /* hash.c -- | |
86 | * | 86 | * | |
87 | * This module contains routines to manipulate a hash table. | 87 | * This module contains routines to manipulate a hash table. | |
88 | * See hash.h for a definition of the structure of the hash | 88 | * See hash.h for a definition of the structure of the hash | |
89 | * table. Hash tables grow automatically as the amount of | 89 | * table. Hash tables grow automatically as the amount of | |
90 | * information increases. | 90 | * information increases. | |
91 | */ | 91 | */ | |
92 | #include "sprite.h" | |||
93 | #include "make.h" | 92 | #include "make.h" | |
94 | #include "hash.h" | |||
95 | 93 | |||
96 | /* | 94 | /* | |
97 | * Forward references to local procedures that are used before they're | 95 | * Forward references to local procedures that are used before they're | |
98 | * defined: | 96 | * defined: | |
99 | */ | 97 | */ | |
100 | 98 | |||
101 | static void RebuildTable(Hash_Table *); | 99 | static void RebuildTable(Hash_Table *); | |
102 | 100 | |||
103 | /* | 101 | /* | |
104 | * The following defines the ratio of # entries to # buckets | 102 | * The following defines the ratio of # entries to # buckets | |
105 | * at which we rebuild the table to make it larger. | 103 | * at which we rebuild the table to make it larger. | |
106 | */ | 104 | */ | |
107 | 105 | |||
108 | #define rebuildLimit 3 | 106 | #define rebuildLimit 3 | |
109 | 107 | |||
110 | /* The hash function(s) */ | 108 | /* The hash function(s) */ | |
111 | 109 | |||
112 | #ifndef HASH | 110 | #ifndef HASH | |
113 | /* The default: this one matches Gosling's emacs */ | 111 | /* The default: this one matches Gosling's emacs */ | |
114 | #define HASH(h, key, p) do { \ | 112 | #define HASH(h, key, p) do { \ | |
115 | for (h = 0, p = key; *p;) \ | 113 | for (h = 0, p = key; *p;) \ | |
116 | h = (h << 5) - h + *p++; \ | 114 | h = (h << 5) - h + *p++; \ | |
117 | } while (0) | 115 | } while (0) | |
118 | 116 | |||
119 | #endif | 117 | #endif | |
120 | 118 | |||
121 | /* | 119 | /* | |
122 | *--------------------------------------------------------- | 120 | *--------------------------------------------------------- | |
123 | * | 121 | * | |
124 | * Hash_InitTable -- | 122 | * Hash_InitTable -- | |
125 | * | 123 | * | |
126 | * This routine just sets up the hash table. | 124 | * This routine just sets up the hash table. | |
127 | * | 125 | * | |
128 | * Input: | 126 | * Input: | |
129 | * t Structure to to hold table. | 127 | * t Structure to to hold table. | |
130 | * numBuckets How many buckets to create for starters. This | 128 | * numBuckets How many buckets to create for starters. This | |
131 | * number is rounded up to a power of two. If | 129 | * number is rounded up to a power of two. If | |
132 | * <= 0, a reasonable default is chosen. The | 130 | * <= 0, a reasonable default is chosen. The | |
133 | * table will grow in size later as needed. | 131 | * table will grow in size later as needed. | |
134 | * | 132 | * | |
135 | * Results: | 133 | * Results: | |
136 | * None. | 134 | * None. | |
137 | * | 135 | * | |
138 | * Side Effects: | 136 | * Side Effects: | |
139 | * Memory is allocated for the initial bucket area. | 137 | * Memory is allocated for the initial bucket area. | |
140 | * | 138 | * | |
141 | *--------------------------------------------------------- | 139 | *--------------------------------------------------------- | |
142 | */ | 140 | */ | |
143 | 141 | |||
144 | void | 142 | void | |
145 | Hash_InitTable(Hash_Table *t, int numBuckets) | 143 | Hash_InitTable(Hash_Table *t, int numBuckets) | |
146 | { | 144 | { | |
147 | int i; | 145 | int i; | |
148 | struct Hash_Entry **hp; | 146 | struct Hash_Entry **hp; | |
149 | 147 | |||
150 | /* | 148 | /* | |
151 | * Round up the size to a power of two. | 149 | * Round up the size to a power of two. | |
152 | */ | 150 | */ | |
153 | if (numBuckets <= 0) | 151 | if (numBuckets <= 0) | |
154 | i = 16; | 152 | i = 16; | |
155 | else { | 153 | else { | |
156 | for (i = 2; i < numBuckets; i <<= 1) | 154 | for (i = 2; i < numBuckets; i <<= 1) | |
157 | continue; | 155 | continue; | |
158 | } | 156 | } | |
159 | t->numEntries = 0; | 157 | t->numEntries = 0; | |
160 | t->maxchain = 0; | 158 | t->maxchain = 0; | |
161 | t->size = i; | 159 | t->size = i; | |
162 | t->mask = i - 1; | 160 | t->mask = i - 1; | |
163 | t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); | 161 | t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); | |
164 | while (--i >= 0) | 162 | while (--i >= 0) | |
165 | *hp++ = NULL; | 163 | *hp++ = NULL; | |
166 | } | 164 | } | |
167 | 165 | |||
168 | /* | 166 | /* | |
169 | *--------------------------------------------------------- | 167 | *--------------------------------------------------------- | |
170 | * | 168 | * | |
171 | * Hash_DeleteTable -- | 169 | * Hash_DeleteTable -- | |
172 | * | 170 | * | |
173 | * This routine removes everything from a hash table | 171 | * This routine removes everything from a hash table | |
174 | * and frees up the memory space it occupied (except for | 172 | * and frees up the memory space it occupied (except for | |
175 | * the space in the Hash_Table structure). | 173 | * the space in the Hash_Table structure). | |
176 | * | 174 | * | |
177 | * Results: | 175 | * Results: | |
178 | * None. | 176 | * None. | |
179 | * | 177 | * | |
180 | * Side Effects: | 178 | * Side Effects: | |
181 | * Lots of memory is freed up. | 179 | * Lots of memory is freed up. | |
182 | * | 180 | * | |
183 | *--------------------------------------------------------- | 181 | *--------------------------------------------------------- | |
184 | */ | 182 | */ | |
185 | 183 | |||
186 | void | 184 | void | |
187 | Hash_DeleteTable(Hash_Table *t) | 185 | Hash_DeleteTable(Hash_Table *t) | |
188 | { | 186 | { | |
189 | struct Hash_Entry **hp, *h, *nexth = NULL; | 187 | struct Hash_Entry **hp, *h, *nexth = NULL; | |
190 | int i; | 188 | int i; | |
191 | 189 | |||
192 | for (hp = t->bucketPtr, i = t->size; --i >= 0;) { | 190 | for (hp = t->bucketPtr, i = t->size; --i >= 0;) { | |
193 | for (h = *hp++; h != NULL; h = nexth) { | 191 | for (h = *hp++; h != NULL; h = nexth) { | |
194 | nexth = h->next; | 192 | nexth = h->next; | |
195 | free(h); | 193 | free(h); | |
196 | } | 194 | } | |
197 | } | 195 | } | |
198 | free(t->bucketPtr); | 196 | free(t->bucketPtr); | |
199 | 197 | |||
200 | /* | 198 | /* | |
201 | * Set up the hash table to cause memory faults on any future access | 199 | * Set up the hash table to cause memory faults on any future access | |
202 | * attempts until re-initialization. | 200 | * attempts until re-initialization. | |
203 | */ | 201 | */ | |
204 | t->bucketPtr = NULL; | 202 | t->bucketPtr = NULL; | |
205 | } | 203 | } | |
206 | 204 | |||
207 | /* | 205 | /* | |
208 | *--------------------------------------------------------- | 206 | *--------------------------------------------------------- | |
209 | * | 207 | * | |
210 | * Hash_FindEntry -- | 208 | * Hash_FindEntry -- | |
211 | * | 209 | * | |
212 | * Searches a hash table for an entry corresponding to key. | 210 | * Searches a hash table for an entry corresponding to key. | |
213 | * | 211 | * | |
214 | * Input: | 212 | * Input: | |
215 | * t Hash table to search. | 213 | * t Hash table to search. | |
216 | * key A hash key. | 214 | * key A hash key. | |
217 | * | 215 | * | |
218 | * Results: | 216 | * Results: | |
219 | * The return value is a pointer to the entry for key, | 217 | * The return value is a pointer to the entry for key, | |
220 | * if key was present in the table. If key was not | 218 | * if key was present in the table. If key was not | |
221 | * present, NULL is returned. | 219 | * present, NULL is returned. | |
222 | * | 220 | * | |
223 | * Side Effects: | 221 | * Side Effects: | |
224 | * None. | 222 | * None. | |
225 | * | 223 | * | |
226 | *--------------------------------------------------------- | 224 | *--------------------------------------------------------- | |
227 | */ | 225 | */ | |
228 | 226 | |||
229 | Hash_Entry * | 227 | Hash_Entry * | |
230 | Hash_FindEntry(Hash_Table *t, const char *key) | 228 | Hash_FindEntry(Hash_Table *t, const char *key) | |
231 | { | 229 | { | |
232 | Hash_Entry *e; | 230 | Hash_Entry *e; | |
233 | unsigned h; | 231 | unsigned h; | |
234 | const char *p; | 232 | const char *p; | |
235 | int chainlen; | 233 | int chainlen; | |
236 | 234 | |||
237 | if (t == NULL || t->bucketPtr == NULL) { | 235 | if (t == NULL || t->bucketPtr == NULL) { | |
238 | return NULL; | 236 | return NULL; | |
239 | } | 237 | } | |
240 | HASH(h, key, p); | 238 | HASH(h, key, p); | |
241 | p = key; | 239 | p = key; | |
242 | chainlen = 0; | 240 | chainlen = 0; | |
243 | #ifdef DEBUG_HASH_LOOKUP | 241 | #ifdef DEBUG_HASH_LOOKUP | |
244 | if (DEBUG(HASH)) | 242 | if (DEBUG(HASH)) | |
245 | fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__, | 243 | fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__, | |
246 | t, h, key); | 244 | t, h, key); | |
247 | #endif | 245 | #endif | |
248 | for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) { | 246 | for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) { | |
249 | chainlen++; | 247 | chainlen++; | |
250 | if (e->namehash == h && strcmp(e->name, p) == 0) | 248 | if (e->namehash == h && strcmp(e->name, p) == 0) | |
251 | break; | 249 | break; | |
252 | } | 250 | } | |
253 | if (chainlen > t->maxchain) | 251 | if (chainlen > t->maxchain) | |
254 | t->maxchain = chainlen; | 252 | t->maxchain = chainlen; | |
255 | return e; | 253 | return e; | |
256 | } | 254 | } | |
257 | 255 | |||
258 | /* | 256 | /* | |
259 | *--------------------------------------------------------- | 257 | *--------------------------------------------------------- | |
260 | * | 258 | * | |
261 | * Hash_CreateEntry -- | 259 | * Hash_CreateEntry -- | |
262 | * | 260 | * | |
263 | * Searches a hash table for an entry corresponding to | 261 | * Searches a hash table for an entry corresponding to | |
264 | * key. If no entry is found, then one is created. | 262 | * key. If no entry is found, then one is created. | |
265 | * | 263 | * | |
266 | * Input: | 264 | * Input: | |
267 | * t Hash table to search. | 265 | * t Hash table to search. | |
268 | * key A hash key. | 266 | * key A hash key. | |
269 | * newPtr Filled in with TRUE if new entry created, | 267 | * newPtr Filled in with TRUE if new entry created, | |
270 | * FALSE otherwise. | 268 | * FALSE otherwise. | |
271 | * | 269 | * | |
272 | * Results: | 270 | * Results: | |
273 | * The return value is a pointer to the entry. If *newPtr | 271 | * The return value is a pointer to the entry. If *newPtr | |
274 | * isn't NULL, then *newPtr is filled in with TRUE if a | 272 | * isn't NULL, then *newPtr is filled in with TRUE if a | |
275 | * new entry was created, and FALSE if an entry already existed | 273 | * new entry was created, and FALSE if an entry already existed | |
276 | * with the given key. | 274 | * with the given key. | |
277 | * | 275 | * | |
278 | * Side Effects: | 276 | * Side Effects: | |
279 | * Memory may be allocated, and the hash buckets may be modified. | 277 | * Memory may be allocated, and the hash buckets may be modified. | |
280 | *--------------------------------------------------------- | 278 | *--------------------------------------------------------- | |
281 | */ | 279 | */ | |
282 | 280 | |||
283 | Hash_Entry * | 281 | Hash_Entry * | |
284 | Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr) | 282 | Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr) | |
285 | { | 283 | { | |
286 | Hash_Entry *e; | 284 | Hash_Entry *e; | |
287 | unsigned h; | 285 | unsigned h; | |
288 | const char *p; | 286 | const char *p; | |
289 | int keylen; | 287 | int keylen; | |
290 | int chainlen; | 288 | int chainlen; | |
291 | struct Hash_Entry **hp; | 289 | struct Hash_Entry **hp; | |
292 | 290 | |||
293 | /* | 291 | /* | |
294 | * Hash the key. As a side effect, save the length (strlen) of the | 292 | * Hash the key. As a side effect, save the length (strlen) of the | |
295 | * key in case we need to create the entry. | 293 | * key in case we need to create the entry. | |
296 | */ | 294 | */ | |
297 | HASH(h, key, p); | 295 | HASH(h, key, p); | |
298 | keylen = p - key; | 296 | keylen = p - key; | |
299 | p = key; | 297 | p = key; | |
300 | chainlen = 0; | 298 | chainlen = 0; | |
301 | #ifdef DEBUG_HASH_LOOKUP | 299 | #ifdef DEBUG_HASH_LOOKUP | |
302 | if (DEBUG(HASH)) | 300 | if (DEBUG(HASH)) | |
303 | fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__, | 301 | fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__, | |
304 | t, h, key); | 302 | t, h, key); | |
305 | #endif | 303 | #endif | |
306 | for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) { | 304 | for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) { | |
307 | chainlen++; | 305 | chainlen++; | |
308 | if (e->namehash == h && strcmp(e->name, p) == 0) { | 306 | if (e->namehash == h && strcmp(e->name, p) == 0) { | |
309 | if (newPtr != NULL) | 307 | if (newPtr != NULL) | |
310 | *newPtr = FALSE; | 308 | *newPtr = FALSE; | |
311 | break; | 309 | break; | |
312 | } | 310 | } | |
313 | } | 311 | } | |
314 | if (chainlen > t->maxchain) | 312 | if (chainlen > t->maxchain) | |
315 | t->maxchain = chainlen; | 313 | t->maxchain = chainlen; | |
316 | if (e) | 314 | if (e) | |
317 | return e; | 315 | return e; | |
318 | 316 | |||
319 | /* | 317 | /* | |
320 | * The desired entry isn't there. Before allocating a new entry, | 318 | * The desired entry isn't there. Before allocating a new entry, | |
321 | * expand the table if necessary (and this changes the resulting | 319 | * expand the table if necessary (and this changes the resulting | |
322 | * bucket chain). | 320 | * bucket chain). | |
323 | */ | 321 | */ | |
324 | if (t->numEntries >= rebuildLimit * t->size) | 322 | if (t->numEntries >= rebuildLimit * t->size) | |
325 | RebuildTable(t); | 323 | RebuildTable(t); | |
326 | e = bmake_malloc(sizeof(*e) + keylen); | 324 | e = bmake_malloc(sizeof(*e) + keylen); | |
327 | hp = &t->bucketPtr[h & t->mask]; | 325 | hp = &t->bucketPtr[h & t->mask]; | |
328 | e->next = *hp; | 326 | e->next = *hp; | |
329 | *hp = e; | 327 | *hp = e; | |
330 | Hash_SetValue(e, NULL); | 328 | Hash_SetValue(e, NULL); | |
331 | e->namehash = h; | 329 | e->namehash = h; | |
332 | (void)strcpy(e->name, p); | 330 | (void)strcpy(e->name, p); | |
333 | t->numEntries++; | 331 | t->numEntries++; | |
334 | 332 | |||
335 | if (newPtr != NULL) | 333 | if (newPtr != NULL) | |
336 | *newPtr = TRUE; | 334 | *newPtr = TRUE; | |
337 | return e; | 335 | return e; | |
338 | } | 336 | } | |
339 | 337 | |||
340 | /* | 338 | /* | |
341 | *--------------------------------------------------------- | 339 | *--------------------------------------------------------- | |
342 | * | 340 | * | |
343 | * Hash_DeleteEntry -- | 341 | * Hash_DeleteEntry -- | |
344 | * | 342 | * | |
345 | * Delete the given hash table entry and free memory associated with | 343 | * Delete the given hash table entry and free memory associated with | |
346 | * it. | 344 | * it. | |
347 | * | 345 | * | |
348 | * Results: | 346 | * Results: | |
349 | * None. | 347 | * None. | |
350 | * | 348 | * | |
351 | * Side Effects: | 349 | * Side Effects: | |
352 | * Hash chain that entry lives in is modified and memory is freed. | 350 | * Hash chain that entry lives in is modified and memory is freed. | |
353 | * | 351 | * | |
354 | *--------------------------------------------------------- | 352 | *--------------------------------------------------------- | |
355 | */ | 353 | */ | |
356 | 354 | |||
357 | void | 355 | void | |
358 | Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e) | 356 | Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e) | |
359 | { | 357 | { | |
360 | Hash_Entry **hp, *p; | 358 | Hash_Entry **hp, *p; | |
361 | 359 | |||
362 | if (e == NULL) | 360 | if (e == NULL) | |
363 | return; | 361 | return; | |
364 | for (hp = &t->bucketPtr[e->namehash & t->mask]; | 362 | for (hp = &t->bucketPtr[e->namehash & t->mask]; | |
365 | (p = *hp) != NULL; hp = &p->next) { | 363 | (p = *hp) != NULL; hp = &p->next) { | |
366 | if (p == e) { | 364 | if (p == e) { | |
367 | *hp = p->next; | 365 | *hp = p->next; | |
368 | free(p); | 366 | free(p); | |
369 | t->numEntries--; | 367 | t->numEntries--; | |
370 | return; | 368 | return; | |
371 | } | 369 | } | |
372 | } | 370 | } | |
373 | (void)write(2, "bad call to Hash_DeleteEntry\n", 29); | 371 | (void)write(2, "bad call to Hash_DeleteEntry\n", 29); | |
374 | abort(); | 372 | abort(); | |
375 | } | 373 | } | |
376 | 374 | |||
377 | /* | 375 | /* | |
378 | *--------------------------------------------------------- | 376 | *--------------------------------------------------------- | |
379 | * | 377 | * | |
380 | * Hash_EnumFirst -- | 378 | * Hash_EnumFirst -- | |
381 | * This procedure sets things up for a complete search | 379 | * This procedure sets things up for a complete search | |
382 | * of all entries recorded in the hash table. | 380 | * of all entries recorded in the hash table. | |
383 | * | 381 | * | |
384 | * Input: | 382 | * Input: | |
385 | * t Table to be searched. | 383 | * t Table to be searched. | |
386 | * searchPtr Area in which to keep state about search. | 384 | * searchPtr Area in which to keep state about search. | |
387 | * | 385 | * | |
388 | * Results: | 386 | * Results: | |
389 | * The return value is the address of the first entry in | 387 | * The return value is the address of the first entry in | |
390 | * the hash table, or NULL if the table is empty. | 388 | * the hash table, or NULL if the table is empty. | |
391 | * | 389 | * | |
392 | * Side Effects: | 390 | * Side Effects: | |
393 | * The information in searchPtr is initialized so that successive | 391 | * The information in searchPtr is initialized so that successive | |
394 | * calls to Hash_Next will return successive HashEntry's | 392 | * calls to Hash_Next will return successive HashEntry's | |
395 | * from the table. | 393 | * from the table. | |
396 | * | 394 | * | |
397 | *--------------------------------------------------------- | 395 | *--------------------------------------------------------- | |
398 | */ | 396 | */ | |
399 | 397 | |||
400 | Hash_Entry * | 398 | Hash_Entry * | |
401 | Hash_EnumFirst(Hash_Table *t, Hash_Search *searchPtr) | 399 | Hash_EnumFirst(Hash_Table *t, Hash_Search *searchPtr) | |
402 | { | 400 | { | |
403 | searchPtr->tablePtr = t; | 401 | searchPtr->tablePtr = t; | |
404 | searchPtr->nextIndex = 0; | 402 | searchPtr->nextIndex = 0; | |
405 | searchPtr->hashEntryPtr = NULL; | 403 | searchPtr->hashEntryPtr = NULL; | |
406 | return Hash_EnumNext(searchPtr); | 404 | return Hash_EnumNext(searchPtr); | |
407 | } | 405 | } | |
408 | 406 | |||
409 | /* | 407 | /* | |
410 | *--------------------------------------------------------- | 408 | *--------------------------------------------------------- | |
411 | * | 409 | * | |
412 | * Hash_EnumNext -- | 410 | * Hash_EnumNext -- | |
413 | * This procedure returns successive entries in the hash table. | 411 | * This procedure returns successive entries in the hash table. | |
414 | * | 412 | * | |
415 | * Input: | 413 | * Input: | |
416 | * searchPtr Area used to keep state about search. | 414 | * searchPtr Area used to keep state about search. | |
417 | * | 415 | * | |
418 | * Results: | 416 | * Results: | |
419 | * The return value is a pointer to the next HashEntry | 417 | * The return value is a pointer to the next HashEntry | |
420 | * in the table, or NULL when the end of the table is | 418 | * in the table, or NULL when the end of the table is | |
421 | * reached. | 419 | * reached. | |
422 | * | 420 | * | |
423 | * Side Effects: | 421 | * Side Effects: | |
424 | * The information in searchPtr is modified to advance to the | 422 | * The information in searchPtr is modified to advance to the | |
425 | * next entry. | 423 | * next entry. | |
426 | * | 424 | * | |
427 | *--------------------------------------------------------- | 425 | *--------------------------------------------------------- | |
428 | */ | 426 | */ | |
429 | 427 | |||
430 | Hash_Entry * | 428 | Hash_Entry * | |
431 | Hash_EnumNext(Hash_Search *searchPtr) | 429 | Hash_EnumNext(Hash_Search *searchPtr) | |
432 | { | 430 | { | |
433 | Hash_Entry *e; | 431 | Hash_Entry *e; | |
434 | Hash_Table *t = searchPtr->tablePtr; | 432 | Hash_Table *t = searchPtr->tablePtr; | |
435 | 433 | |||
436 | /* | 434 | /* | |
437 | * The hashEntryPtr field points to the most recently returned | 435 | * The hashEntryPtr field points to the most recently returned | |
438 | * entry, or is nil if we are starting up. If not nil, we have | 436 | * entry, or is nil if we are starting up. If not nil, we have | |
439 | * to start at the next one in the chain. | 437 | * to start at the next one in the chain. | |
440 | */ | 438 | */ | |
441 | e = searchPtr->hashEntryPtr; | 439 | e = searchPtr->hashEntryPtr; | |
442 | if (e != NULL) | 440 | if (e != NULL) | |
443 | e = e->next; | 441 | e = e->next; | |
444 | /* | 442 | /* | |
445 | * If the chain ran out, or if we are starting up, we need to | 443 | * If the chain ran out, or if we are starting up, we need to | |
446 | * find the next nonempty chain. | 444 | * find the next nonempty chain. | |
447 | */ | 445 | */ | |
448 | while (e == NULL) { | 446 | while (e == NULL) { | |
449 | if (searchPtr->nextIndex >= t->size) | 447 | if (searchPtr->nextIndex >= t->size) | |
450 | return NULL; | 448 | return NULL; | |
451 | e = t->bucketPtr[searchPtr->nextIndex++]; | 449 | e = t->bucketPtr[searchPtr->nextIndex++]; | |
452 | } | 450 | } | |
453 | searchPtr->hashEntryPtr = e; | 451 | searchPtr->hashEntryPtr = e; | |
454 | return e; | 452 | return e; | |
455 | } | 453 | } | |
456 | 454 | |||
457 | /* | 455 | /* | |
458 | *--------------------------------------------------------- | 456 | *--------------------------------------------------------- | |
459 | * | 457 | * | |
460 | * RebuildTable -- | 458 | * RebuildTable -- | |
461 | * This local routine makes a new hash table that | 459 | * This local routine makes a new hash table that | |
462 | * is larger than the old one. | 460 | * is larger than the old one. | |
463 | * | 461 | * | |
464 | * Results: | 462 | * Results: | |
465 | * None. | 463 | * None. | |
466 | * | 464 | * | |
467 | * Side Effects: | 465 | * Side Effects: | |
468 | * The entire hash table is moved, so any bucket numbers | 466 | * The entire hash table is moved, so any bucket numbers | |
469 | * from the old table are invalid. | 467 | * from the old table are invalid. | |
470 | * | 468 | * | |
471 | *--------------------------------------------------------- | 469 | *--------------------------------------------------------- | |
472 | */ | 470 | */ | |
473 | 471 | |||
474 | static void | 472 | static void | |
475 | RebuildTable(Hash_Table *t) | 473 | RebuildTable(Hash_Table *t) | |
476 | { | 474 | { | |
477 | Hash_Entry *e, *next = NULL, **hp, **xp; | 475 | Hash_Entry *e, *next = NULL, **hp, **xp; | |
478 | int i, mask; | 476 | int i, mask; | |
479 | Hash_Entry **oldhp; | 477 | Hash_Entry **oldhp; | |
480 | int oldsize; | 478 | int oldsize; | |
481 | 479 | |||
482 | oldhp = t->bucketPtr; | 480 | oldhp = t->bucketPtr; | |
483 | oldsize = i = t->size; | 481 | oldsize = i = t->size; | |
484 | i <<= 1; | 482 | i <<= 1; | |
485 | t->size = i; | 483 | t->size = i; | |
486 | t->mask = mask = i - 1; | 484 | t->mask = mask = i - 1; | |
487 | t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); | 485 | t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); | |
488 | while (--i >= 0) | 486 | while (--i >= 0) | |
489 | *hp++ = NULL; | 487 | *hp++ = NULL; | |
490 | for (hp = oldhp, i = oldsize; --i >= 0;) { | 488 | for (hp = oldhp, i = oldsize; --i >= 0;) { | |
491 | for (e = *hp++; e != NULL; e = next) { | 489 | for (e = *hp++; e != NULL; e = next) { | |
492 | next = e->next; | 490 | next = e->next; | |
493 | xp = &t->bucketPtr[e->namehash & mask]; | 491 | xp = &t->bucketPtr[e->namehash & mask]; | |
494 | e->next = *xp; | 492 | e->next = *xp; | |
495 | *xp = e; | 493 | *xp = e; | |
496 | } | 494 | } | |
497 | } | 495 | } | |
498 | free(oldhp); | 496 | free(oldhp); | |
499 | if (DEBUG(HASH)) | 497 | if (DEBUG(HASH)) | |
500 | fprintf(debug_file, "%s: %p size=%d entries=%d maxchain=%d\n", | 498 | fprintf(debug_file, "%s: %p size=%d entries=%d maxchain=%d\n", | |
501 | __func__, t, t->size, t->numEntries, t->maxchain); | 499 | __func__, t, t->size, t->numEntries, t->maxchain); | |
502 | t->maxchain = 0; | 500 | t->maxchain = 0; | |
503 | } | 501 | } | |
504 | 502 | |||
505 | void Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data) | 503 | void Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data) | |
506 | { | 504 | { | |
507 | Hash_Search search; | 505 | Hash_Search search; | |
508 | Hash_Entry *e; | 506 | Hash_Entry *e; | |
509 | 507 | |||
510 | for (e = Hash_EnumFirst(t, &search); | 508 | for (e = Hash_EnumFirst(t, &search); | |
511 | e != NULL; | 509 | e != NULL; | |
512 | e = Hash_EnumNext(&search)) | 510 | e = Hash_EnumNext(&search)) | |
513 | action(Hash_GetValue(e), data); | 511 | action(Hash_GetValue(e), data); | |
514 | } | 512 | } | |
515 | 513 | |||
516 | void | 514 | void | |
517 | Hash_DebugStats(Hash_Table *t, const char *name) | 515 | Hash_DebugStats(Hash_Table *t, const char *name) | |
518 | { | 516 | { | |
519 | if (DEBUG(HASH)) | 517 | if (DEBUG(HASH)) | |
520 | fprintf(debug_file, "Hash_Table %s: size=%d numEntries=%d maxchain=%d\n", | 518 | fprintf(debug_file, "Hash_Table %s: size=%d numEntries=%d maxchain=%d\n", | |
521 | name, t->size, t->numEntries, t->maxchain); | 519 | name, t->size, t->numEntries, t->maxchain); | |
522 | } | 520 | } |
--- src/usr.bin/make/lst.h 2020/08/26 22:55:46 1.44
+++ src/usr.bin/make/lst.h 2020/08/26 23:00:47 1.45
@@ -1,191 +1,189 @@ | @@ -1,191 +1,189 @@ | |||
1 | /* $NetBSD: lst.h,v 1.44 2020/08/26 22:55:46 rillig Exp $ */ | 1 | /* $NetBSD: lst.h,v 1.45 2020/08/26 23:00:47 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | 4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | |
5 | * All rights reserved. | 5 | * 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: @(#)lst.h 8.1 (Berkeley) 6/6/93 | 34 | * from: @(#)lst.h 8.1 (Berkeley) 6/6/93 | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | /* | 37 | /* | |
38 | * Copyright (c) 1988, 1989 by Adam de Boor | 38 | * Copyright (c) 1988, 1989 by Adam de Boor | |
39 | * Copyright (c) 1989 by Berkeley Softworks | 39 | * Copyright (c) 1989 by Berkeley Softworks | |
40 | * All rights reserved. | 40 | * All rights reserved. | |
41 | * | 41 | * | |
42 | * This code is derived from software contributed to Berkeley by | 42 | * This code is derived from software contributed to Berkeley by | |
43 | * Adam de Boor. | 43 | * Adam de Boor. | |
44 | * | 44 | * | |
45 | * Redistribution and use in source and binary forms, with or without | 45 | * Redistribution and use in source and binary forms, with or without | |
46 | * modification, are permitted provided that the following conditions | 46 | * modification, are permitted provided that the following conditions | |
47 | * are met: | 47 | * are met: | |
48 | * 1. Redistributions of source code must retain the above copyright | 48 | * 1. Redistributions of source code must retain the above copyright | |
49 | * notice, this list of conditions and the following disclaimer. | 49 | * notice, this list of conditions and the following disclaimer. | |
50 | * 2. Redistributions in binary form must reproduce the above copyright | 50 | * 2. Redistributions in binary form must reproduce the above copyright | |
51 | * notice, this list of conditions and the following disclaimer in the | 51 | * notice, this list of conditions and the following disclaimer in the | |
52 | * documentation and/or other materials provided with the distribution. | 52 | * documentation and/or other materials provided with the distribution. | |
53 | * 3. All advertising materials mentioning features or use of this software | 53 | * 3. All advertising materials mentioning features or use of this software | |
54 | * must display the following acknowledgement: | 54 | * must display the following acknowledgement: | |
55 | * This product includes software developed by the University of | 55 | * This product includes software developed by the University of | |
56 | * California, Berkeley and its contributors. | 56 | * California, Berkeley and its contributors. | |
57 | * 4. Neither the name of the University nor the names of its contributors | 57 | * 4. Neither the name of the University nor the names of its contributors | |
58 | * may be used to endorse or promote products derived from this software | 58 | * may be used to endorse or promote products derived from this software | |
59 | * without specific prior written permission. | 59 | * without specific prior written permission. | |
60 | * | 60 | * | |
61 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 61 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
62 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 62 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
63 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 63 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
64 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 64 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
65 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 65 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
66 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 66 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
67 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 67 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
68 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 68 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
69 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 69 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
70 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 70 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
71 | * SUCH DAMAGE. | 71 | * SUCH DAMAGE. | |
72 | * | 72 | * | |
73 | * from: @(#)lst.h 8.1 (Berkeley) 6/6/93 | 73 | * from: @(#)lst.h 8.1 (Berkeley) 6/6/93 | |
74 | */ | 74 | */ | |
75 | 75 | |||
76 | /*- | 76 | /*- | |
77 | * lst.h -- | 77 | * lst.h -- | |
78 | * Header for using the list library | 78 | * Header for using the list library | |
79 | */ | 79 | */ | |
80 | #ifndef MAKE_LST_H | 80 | #ifndef MAKE_LST_H | |
81 | #define MAKE_LST_H | 81 | #define MAKE_LST_H | |
82 | 82 | |||
83 | #include <sys/param.h> | 83 | #include <sys/param.h> | |
84 | #include <stdlib.h> | 84 | #include <stdlib.h> | |
85 | 85 | |||
86 | #include "sprite.h" | |||
87 | ||||
88 | /* | 86 | /* | |
89 | * basic typedef. This is what the Lst_ functions handle | 87 | * basic typedef. This is what the Lst_ functions handle | |
90 | */ | 88 | */ | |
91 | 89 | |||
92 | typedef struct List *Lst; | 90 | typedef struct List *Lst; | |
93 | typedef struct ListNode *LstNode; | 91 | typedef struct ListNode *LstNode; | |
94 | 92 | |||
95 | typedef void *LstCopyProc(void *); | 93 | typedef void *LstCopyProc(void *); | |
96 | typedef void LstFreeProc(void *); | 94 | typedef void LstFreeProc(void *); | |
97 | typedef int LstFindProc(const void *, const void *); | 95 | typedef int LstFindProc(const void *, const void *); | |
98 | typedef int LstActionProc(void *, void *); | 96 | typedef int LstActionProc(void *, void *); | |
99 | 97 | |||
100 | /* | 98 | /* | |
101 | * Creation/destruction functions | 99 | * Creation/destruction functions | |
102 | */ | 100 | */ | |
103 | /* Create a new list */ | 101 | /* Create a new list */ | |
104 | Lst Lst_Init(void); | 102 | Lst Lst_Init(void); | |
105 | /* Duplicate an existing list */ | 103 | /* Duplicate an existing list */ | |
106 | Lst Lst_CopyS(Lst, LstCopyProc); | 104 | Lst Lst_CopyS(Lst, LstCopyProc); | |
107 | /* Destroy an old one */ | 105 | /* Destroy an old one */ | |
108 | void Lst_FreeS(Lst); | 106 | void Lst_FreeS(Lst); | |
109 | void Lst_DestroyS(Lst, LstFreeProc); | 107 | void Lst_DestroyS(Lst, LstFreeProc); | |
110 | /* True if list is empty */ | 108 | /* True if list is empty */ | |
111 | Boolean Lst_IsEmpty(Lst); | 109 | Boolean Lst_IsEmpty(Lst); | |
112 | Boolean Lst_IsEmptyS(Lst); | 110 | Boolean Lst_IsEmptyS(Lst); | |
113 | 111 | |||
114 | /* | 112 | /* | |
115 | * Functions to modify a list | 113 | * Functions to modify a list | |
116 | */ | 114 | */ | |
117 | /* Insert an element before another */ | 115 | /* Insert an element before another */ | |
118 | void Lst_InsertBeforeS(Lst, LstNode, void *); | 116 | void Lst_InsertBeforeS(Lst, LstNode, void *); | |
119 | /* Place an element at the front of a lst. */ | 117 | /* Place an element at the front of a lst. */ | |
120 | void Lst_PrependS(Lst, void *); | 118 | void Lst_PrependS(Lst, void *); | |
121 | /* Place an element at the end of a lst. */ | 119 | /* Place an element at the end of a lst. */ | |
122 | void Lst_AppendS(Lst, void *); | 120 | void Lst_AppendS(Lst, void *); | |
123 | /* Remove an element */ | 121 | /* Remove an element */ | |
124 | void Lst_RemoveS(Lst, LstNode); | 122 | void Lst_RemoveS(Lst, LstNode); | |
125 | /* Replace a node with a new value */ | 123 | /* Replace a node with a new value */ | |
126 | void LstNode_SetS(LstNode, void *); | 124 | void LstNode_SetS(LstNode, void *); | |
127 | void LstNode_SetNullS(LstNode); | 125 | void LstNode_SetNullS(LstNode); | |
128 | 126 | |||
129 | void Lst_PrependAllS(Lst, Lst); | 127 | void Lst_PrependAllS(Lst, Lst); | |
130 | void Lst_AppendAllS(Lst, Lst); | 128 | void Lst_AppendAllS(Lst, Lst); | |
131 | void Lst_MoveAllS(Lst, Lst); | 129 | void Lst_MoveAllS(Lst, Lst); | |
132 | 130 | |||
133 | /* | 131 | /* | |
134 | * Node-specific functions | 132 | * Node-specific functions | |
135 | */ | 133 | */ | |
136 | /* Return first element in list */ | 134 | /* Return first element in list */ | |
137 | LstNode Lst_First(Lst); | 135 | LstNode Lst_First(Lst); | |
138 | LstNode Lst_FirstS(Lst); | 136 | LstNode Lst_FirstS(Lst); | |
139 | /* Return last element in list */ | 137 | /* Return last element in list */ | |
140 | LstNode Lst_Last(Lst); | 138 | LstNode Lst_Last(Lst); | |
141 | LstNode Lst_LastS(Lst); | 139 | LstNode Lst_LastS(Lst); | |
142 | /* Return successor to given element */ | 140 | /* Return successor to given element */ | |
143 | LstNode Lst_Succ(LstNode); | 141 | LstNode Lst_Succ(LstNode); | |
144 | LstNode Lst_SuccS(LstNode); | 142 | LstNode Lst_SuccS(LstNode); | |
145 | /* Return predecessor to given element */ | 143 | /* Return predecessor to given element */ | |
146 | LstNode Lst_PrevS(LstNode); | 144 | LstNode Lst_PrevS(LstNode); | |
147 | /* Get datum from LstNode */ | 145 | /* Get datum from LstNode */ | |
148 | void *Lst_DatumS(LstNode); | 146 | void *Lst_DatumS(LstNode); | |
149 | 147 | |||
150 | /* | 148 | /* | |
151 | * Functions for entire lists | 149 | * Functions for entire lists | |
152 | */ | 150 | */ | |
153 | /* Find an element in a list */ | 151 | /* Find an element in a list */ | |
154 | LstNode Lst_Find(Lst, LstFindProc, const void *); | 152 | LstNode Lst_Find(Lst, LstFindProc, const void *); | |
155 | LstNode Lst_FindS(Lst, LstFindProc, const void *); | 153 | LstNode Lst_FindS(Lst, LstFindProc, const void *); | |
156 | /* Find an element starting from somewhere */ | 154 | /* Find an element starting from somewhere */ | |
157 | LstNode Lst_FindFrom(Lst, LstNode, LstFindProc, const void *); | 155 | LstNode Lst_FindFrom(Lst, LstNode, LstFindProc, const void *); | |
158 | LstNode Lst_FindFromS(Lst, LstNode, LstFindProc, const void *); | 156 | LstNode Lst_FindFromS(Lst, LstNode, LstFindProc, const void *); | |
159 | /* | 157 | /* | |
160 | * See if the given datum is on the list. Returns the LstNode containing | 158 | * See if the given datum is on the list. Returns the LstNode containing | |
161 | * the datum | 159 | * the datum | |
162 | */ | 160 | */ | |
163 | LstNode Lst_MemberS(Lst, void *); | 161 | LstNode Lst_MemberS(Lst, void *); | |
164 | /* Apply a function to all elements of a lst */ | 162 | /* Apply a function to all elements of a lst */ | |
165 | int Lst_ForEach(Lst, LstActionProc, void *); | 163 | int Lst_ForEach(Lst, LstActionProc, void *); | |
166 | int Lst_ForEachS(Lst, LstActionProc, void *); | 164 | int Lst_ForEachS(Lst, LstActionProc, void *); | |
167 | /* Apply a function to all elements of a lst starting from a certain point. */ | 165 | /* Apply a function to all elements of a lst starting from a certain point. */ | |
168 | int Lst_ForEachFrom(Lst, LstNode, LstActionProc, void *); | 166 | int Lst_ForEachFrom(Lst, LstNode, LstActionProc, void *); | |
169 | int Lst_ForEachFromS(Lst, LstNode, LstActionProc, void *); | 167 | int Lst_ForEachFromS(Lst, LstNode, LstActionProc, void *); | |
170 | /* | 168 | /* | |
171 | * these functions are for dealing with a list as a table, of sorts. | 169 | * these functions are for dealing with a list as a table, of sorts. | |
172 | * An idea of the "current element" is kept and used by all the functions | 170 | * An idea of the "current element" is kept and used by all the functions | |
173 | * between Lst_Open() and Lst_Close(). | 171 | * between Lst_Open() and Lst_Close(). | |
174 | */ | 172 | */ | |
175 | /* Open the list */ | 173 | /* Open the list */ | |
176 | ReturnStatus Lst_Open(Lst); | 174 | ReturnStatus Lst_Open(Lst); | |
177 | void Lst_OpenS(Lst); | 175 | void Lst_OpenS(Lst); | |
178 | /* Next element please, or NULL */ | 176 | /* Next element please, or NULL */ | |
179 | LstNode Lst_NextS(Lst); | 177 | LstNode Lst_NextS(Lst); | |
180 | /* Finish table access */ | 178 | /* Finish table access */ | |
181 | void Lst_CloseS(Lst); | 179 | void Lst_CloseS(Lst); | |
182 | 180 | |||
183 | /* | 181 | /* | |
184 | * for using the list as a queue | 182 | * for using the list as a queue | |
185 | */ | 183 | */ | |
186 | /* Place an element at tail of queue */ | 184 | /* Place an element at tail of queue */ | |
187 | void Lst_EnqueueS(Lst, void *); | 185 | void Lst_EnqueueS(Lst, void *); | |
188 | /* Remove an element from head of queue */ | 186 | /* Remove an element from head of queue */ | |
189 | void *Lst_DequeueS(Lst); | 187 | void *Lst_DequeueS(Lst); | |
190 | 188 | |||
191 | #endif /* MAKE_LST_H */ | 189 | #endif /* MAKE_LST_H */ |
--- src/usr.bin/make/make.h 2020/08/24 20:15:51 1.126
+++ src/usr.bin/make/make.h 2020/08/26 23:00:47 1.127
@@ -1,551 +1,581 @@ | @@ -1,551 +1,581 @@ | |||
1 | /* $NetBSD: make.h,v 1.126 2020/08/24 20:15:51 rillig Exp $ */ | 1 | /* $NetBSD: make.h,v 1.127 2020/08/26 23:00:47 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 | #include "sprite.h" | 131 | /* | |
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. | |||
134 | */ | |||
135 | ||||
136 | typedef int Boolean; | |||
137 | #ifndef TRUE | |||
138 | #define TRUE 1 | |||
139 | #endif /* TRUE */ | |||
140 | #ifndef FALSE | |||
141 | #define FALSE 0 | |||
142 | #endif /* FALSE */ | |||
143 | ||||
144 | /* | |||
145 | * Functions that must return a status can return a ReturnStatus to | |||
146 | * indicate success or type of failure. | |||
147 | */ | |||
148 | ||||
149 | typedef int ReturnStatus; | |||
150 | ||||
151 | /* | |||
152 | * The following statuses overlap with the first 2 generic statuses | |||
153 | * defined in status.h: | |||
154 | * | |||
155 | * SUCCESS There was no error. | |||
156 | * FAILURE There was a general error. | |||
157 | */ | |||
158 | ||||
159 | #define SUCCESS 0x00000000 | |||
160 | #define FAILURE 0x00000001 | |||
161 | ||||
132 | #include "lst.h" | 162 | #include "lst.h" | |
133 | #include "hash.h" | 163 | #include "hash.h" | |
134 | #include "config.h" | 164 | #include "config.h" | |
135 | #include "buf.h" | 165 | #include "buf.h" | |
136 | #include "make_malloc.h" | 166 | #include "make_malloc.h" | |
137 | 167 | |||
138 | typedef enum { | 168 | typedef enum { | |
139 | UNMADE, /* Not examined yet */ | 169 | UNMADE, /* Not examined yet */ | |
140 | DEFERRED, /* Examined once (building child) */ | 170 | DEFERRED, /* Examined once (building child) */ | |
141 | REQUESTED, /* on toBeMade list */ | 171 | REQUESTED, /* on toBeMade list */ | |
142 | BEINGMADE, /* Target is already being made. | 172 | BEINGMADE, /* Target is already being made. | |
143 | * Indicates a cycle in the graph. */ | 173 | * Indicates a cycle in the graph. */ | |
144 | MADE, /* Was out-of-date and has been made */ | 174 | MADE, /* Was out-of-date and has been made */ | |
145 | UPTODATE, /* Was already up-to-date */ | 175 | UPTODATE, /* Was already up-to-date */ | |
146 | ERROR, /* An error occurred while it was being | 176 | ERROR, /* An error occurred while it was being | |
147 | * made (used only in compat mode) */ | 177 | * made (used only in compat mode) */ | |
148 | ABORTED /* The target was aborted due to an error | 178 | ABORTED /* The target was aborted due to an error | |
149 | * making an inferior (compat). */ | 179 | * making an inferior (compat). */ | |
150 | } GNodeMade; | 180 | } GNodeMade; | |
151 | 181 | |||
152 | /* The OP_ constants are used when parsing a dependency line as a way of | 182 | /* The OP_ constants are used when parsing a dependency line as a way of | |
153 | * communicating to other parts of the program the way in which a target | 183 | * communicating to other parts of the program the way in which a target | |
154 | * should be made. | 184 | * should be made. | |
155 | * | 185 | * | |
156 | * These constants are bitwise-OR'ed together and placed in the 'type' field | 186 | * These constants are bitwise-OR'ed together and placed in the 'type' field | |
157 | * of each node. Any node that has a 'type' field which satisfies the OP_NOP | 187 | * of each node. Any node that has a 'type' field which satisfies the OP_NOP | |
158 | * function was never never on the left-hand side of an operator, though it | 188 | * function was never never on the left-hand side of an operator, though it | |
159 | * may have been on the right-hand side... */ | 189 | * may have been on the right-hand side... */ | |
160 | typedef enum { | 190 | typedef enum { | |
161 | /* Execution of commands depends on children (:) */ | 191 | /* Execution of commands depends on children (:) */ | |
162 | OP_DEPENDS = 1 << 0, | 192 | OP_DEPENDS = 1 << 0, | |
163 | /* Always execute commands (!) */ | 193 | /* Always execute commands (!) */ | |
164 | OP_FORCE = 1 << 1, | 194 | OP_FORCE = 1 << 1, | |
165 | /* Execution of commands depends on children per line (::) */ | 195 | /* Execution of commands depends on children per line (::) */ | |
166 | OP_DOUBLEDEP = 1 << 2, | 196 | OP_DOUBLEDEP = 1 << 2, | |
167 | 197 | |||
168 | OP_OPMASK = OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP, | 198 | OP_OPMASK = OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP, | |
169 | 199 | |||
170 | /* Don't care if the target doesn't exist and can't be created */ | 200 | /* Don't care if the target doesn't exist and can't be created */ | |
171 | OP_OPTIONAL = 1 << 3, | 201 | OP_OPTIONAL = 1 << 3, | |
172 | /* Use associated commands for parents */ | 202 | /* Use associated commands for parents */ | |
173 | OP_USE = 1 << 4, | 203 | OP_USE = 1 << 4, | |
174 | /* Target is never out of date, but always execute commands anyway. | 204 | /* Target is never out of date, but always execute commands anyway. | |
175 | * Its time doesn't matter, so it has none...sort of */ | 205 | * Its time doesn't matter, so it has none...sort of */ | |
176 | OP_EXEC = 1 << 5, | 206 | OP_EXEC = 1 << 5, | |
177 | /* Ignore errors when creating the node */ | 207 | /* Ignore errors when creating the node */ | |
178 | OP_IGNORE = 1 << 6, | 208 | OP_IGNORE = 1 << 6, | |
179 | /* Don't remove the target when interrupted */ | 209 | /* Don't remove the target when interrupted */ | |
180 | OP_PRECIOUS = 1 << 7, | 210 | OP_PRECIOUS = 1 << 7, | |
181 | /* Don't echo commands when executed */ | 211 | /* Don't echo commands when executed */ | |
182 | OP_SILENT = 1 << 8, | 212 | OP_SILENT = 1 << 8, | |
183 | /* Target is a recursive make so its commands should always be executed | 213 | /* Target is a recursive make so its commands should always be executed | |
184 | * when it is out of date, regardless of the state of the -n or -t flags */ | 214 | * when it is out of date, regardless of the state of the -n or -t flags */ | |
185 | OP_MAKE = 1 << 9, | 215 | OP_MAKE = 1 << 9, | |
186 | /* Target is out-of-date only if any of its children was out-of-date */ | 216 | /* Target is out-of-date only if any of its children was out-of-date */ | |
187 | OP_JOIN = 1 << 10, | 217 | OP_JOIN = 1 << 10, | |
188 | /* Assume the children of the node have been already made */ | 218 | /* Assume the children of the node have been already made */ | |
189 | OP_MADE = 1 << 11, | 219 | OP_MADE = 1 << 11, | |
190 | /* Special .BEGIN, .END, .INTERRUPT */ | 220 | /* Special .BEGIN, .END, .INTERRUPT */ | |
191 | OP_SPECIAL = 1 << 12, | 221 | OP_SPECIAL = 1 << 12, | |
192 | /* Like .USE, only prepend commands */ | 222 | /* Like .USE, only prepend commands */ | |
193 | OP_USEBEFORE = 1 << 13, | 223 | OP_USEBEFORE = 1 << 13, | |
194 | /* The node is invisible to its parents. I.e. it doesn't show up in the | 224 | /* The node is invisible to its parents. I.e. it doesn't show up in the | |
195 | * parents' local variables. */ | 225 | * parents' local variables. */ | |
196 | OP_INVISIBLE = 1 << 14, | 226 | OP_INVISIBLE = 1 << 14, | |
197 | /* The node is exempt from normal 'main target' processing in parse.c */ | 227 | /* The node is exempt from normal 'main target' processing in parse.c */ | |
198 | OP_NOTMAIN = 1 << 15, | 228 | OP_NOTMAIN = 1 << 15, | |
199 | /* Not a file target; run always */ | 229 | /* Not a file target; run always */ | |
200 | OP_PHONY = 1 << 16, | 230 | OP_PHONY = 1 << 16, | |
201 | /* Don't search for file in the path */ | 231 | /* Don't search for file in the path */ | |
202 | OP_NOPATH = 1 << 17, | 232 | OP_NOPATH = 1 << 17, | |
203 | /* .WAIT phony node */ | 233 | /* .WAIT phony node */ | |
204 | OP_WAIT = 1 << 18, | 234 | OP_WAIT = 1 << 18, | |
205 | /* .NOMETA do not create a .meta file */ | 235 | /* .NOMETA do not create a .meta file */ | |
206 | OP_NOMETA = 1 << 19, | 236 | OP_NOMETA = 1 << 19, | |
207 | /* .META we _do_ want a .meta file */ | 237 | /* .META we _do_ want a .meta file */ | |
208 | OP_META = 1 << 20, | 238 | OP_META = 1 << 20, | |
209 | /* Do not compare commands in .meta file */ | 239 | /* Do not compare commands in .meta file */ | |
210 | OP_NOMETA_CMP = 1 << 21, | 240 | OP_NOMETA_CMP = 1 << 21, | |
211 | /* Possibly a submake node */ | 241 | /* Possibly a submake node */ | |
212 | OP_SUBMAKE = 1 << 22, | 242 | OP_SUBMAKE = 1 << 22, | |
213 | 243 | |||
214 | /* Attributes applied by PMake */ | 244 | /* Attributes applied by PMake */ | |
215 | 245 | |||
216 | /* The node is a transformation rule */ | 246 | /* The node is a transformation rule */ | |
217 | OP_TRANSFORM = 1 << 31, | 247 | OP_TRANSFORM = 1 << 31, | |
218 | /* Target is a member of an archive */ | 248 | /* Target is a member of an archive */ | |
219 | OP_MEMBER = 1 << 30, | 249 | OP_MEMBER = 1 << 30, | |
220 | /* Target is a library */ | 250 | /* Target is a library */ | |
221 | OP_LIB = 1 << 29, | 251 | OP_LIB = 1 << 29, | |
222 | /* Target is an archive construct */ | 252 | /* Target is an archive construct */ | |
223 | OP_ARCHV = 1 << 28, | 253 | OP_ARCHV = 1 << 28, | |
224 | /* Target has all the commands it should. Used when parsing to catch | 254 | /* Target has all the commands it should. Used when parsing to catch | |
225 | * multiple commands for a target. */ | 255 | * multiple commands for a target. */ | |
226 | OP_HAS_COMMANDS = 1 << 27, | 256 | OP_HAS_COMMANDS = 1 << 27, | |
227 | /* Saving commands on .END (Compat) */ | 257 | /* Saving commands on .END (Compat) */ | |
228 | OP_SAVE_CMDS = 1 << 26, | 258 | OP_SAVE_CMDS = 1 << 26, | |
229 | /* Already processed by Suff_FindDeps */ | 259 | /* Already processed by Suff_FindDeps */ | |
230 | OP_DEPS_FOUND = 1 << 25, | 260 | OP_DEPS_FOUND = 1 << 25, | |
231 | /* Node found while expanding .ALLSRC */ | 261 | /* Node found while expanding .ALLSRC */ | |
232 | OP_MARK = 1 << 24 | 262 | OP_MARK = 1 << 24 | |
233 | } GNodeType; | 263 | } GNodeType; | |
234 | 264 | |||
235 | typedef enum { | 265 | typedef enum { | |
236 | REMAKE = 0x0001, /* this target needs to be (re)made */ | 266 | REMAKE = 0x0001, /* this target needs to be (re)made */ | |
237 | CHILDMADE = 0x0002, /* children of this target were made */ | 267 | CHILDMADE = 0x0002, /* children of this target were made */ | |
238 | FORCE = 0x0004, /* children don't exist, and we pretend made */ | 268 | FORCE = 0x0004, /* children don't exist, and we pretend made */ | |
239 | DONE_WAIT = 0x0008, /* Set by Make_ProcessWait() */ | 269 | DONE_WAIT = 0x0008, /* Set by Make_ProcessWait() */ | |
240 | DONE_ORDER = 0x0010, /* Build requested by .ORDER processing */ | 270 | DONE_ORDER = 0x0010, /* Build requested by .ORDER processing */ | |
241 | FROM_DEPEND = 0x0020, /* Node created from .depend */ | 271 | FROM_DEPEND = 0x0020, /* Node created from .depend */ | |
242 | DONE_ALLSRC = 0x0040, /* We do it once only */ | 272 | DONE_ALLSRC = 0x0040, /* We do it once only */ | |
243 | CYCLE = 0x1000, /* Used by MakePrintStatus */ | 273 | CYCLE = 0x1000, /* Used by MakePrintStatus */ | |
244 | DONECYCLE = 0x2000, /* Used by MakePrintStatus */ | 274 | DONECYCLE = 0x2000, /* Used by MakePrintStatus */ | |
245 | INTERNAL = 0x4000 /* Internal use only */ | 275 | INTERNAL = 0x4000 /* Internal use only */ | |
246 | } GNodeFlags; | 276 | } GNodeFlags; | |
247 | 277 | |||
248 | /* A graph node represents a target that can possibly be made, including its | 278 | /* A graph node represents a target that can possibly be made, including its | |
249 | * relation to other targets and a lot of other details. */ | 279 | * relation to other targets and a lot of other details. */ | |
250 | typedef struct GNode { | 280 | typedef struct GNode { | |
251 | /* The target's name, such as "clean" or "make.c" */ | 281 | /* The target's name, such as "clean" or "make.c" */ | |
252 | char *name; | 282 | char *name; | |
253 | /* The unexpanded name of a .USE node */ | 283 | /* The unexpanded name of a .USE node */ | |
254 | char *uname; | 284 | char *uname; | |
255 | /* The full pathname of the file belonging to the target. | 285 | /* The full pathname of the file belonging to the target. | |
256 | * XXX: What about .PHONY targets? These don't have an associated path. */ | 286 | * XXX: What about .PHONY targets? These don't have an associated path. */ | |
257 | char *path; | 287 | char *path; | |
258 | 288 | |||
259 | /* The type of operator used to define the sources (see the OP flags below). | 289 | /* The type of operator used to define the sources (see the OP flags below). | |
260 | * XXX: This looks like a wild mixture of type and flags. */ | 290 | * XXX: This looks like a wild mixture of type and flags. */ | |
261 | GNodeType type; | 291 | GNodeType type; | |
262 | /* whether it is involved in this invocation of make */ | 292 | /* whether it is involved in this invocation of make */ | |
263 | GNodeFlags flags; | 293 | GNodeFlags flags; | |
264 | 294 | |||
265 | /* The state of processing on this node */ | 295 | /* The state of processing on this node */ | |
266 | GNodeMade made; | 296 | GNodeMade made; | |
267 | int unmade; /* The number of unmade children */ | 297 | int unmade; /* The number of unmade children */ | |
268 | 298 | |||
269 | time_t mtime; /* Its modification time */ | 299 | time_t mtime; /* Its modification time */ | |
270 | struct GNode *cmgn; /* The youngest child */ | 300 | struct GNode *cmgn; /* The youngest child */ | |
271 | 301 | |||
272 | /* Links to parents for which this is an implied source. May be empty. | 302 | /* Links to parents for which this is an implied source. May be empty. | |
273 | * Nodes that depend on this, as gleaned from the transformation rules. */ | 303 | * Nodes that depend on this, as gleaned from the transformation rules. */ | |
274 | Lst iParents; | 304 | Lst iParents; | |
275 | 305 | |||
276 | /* Other nodes of the same name for the :: operator. */ | 306 | /* Other nodes of the same name for the :: operator. */ | |
277 | Lst cohorts; | 307 | Lst cohorts; | |
278 | 308 | |||
279 | /* The nodes that depend on this one, or in other words, the nodes for | 309 | /* The nodes that depend on this one, or in other words, the nodes for | |
280 | * which this is a source. */ | 310 | * which this is a source. */ | |
281 | Lst parents; | 311 | Lst parents; | |
282 | /* The nodes on which this one depends. */ | 312 | /* The nodes on which this one depends. */ | |
283 | Lst children; | 313 | Lst children; | |
284 | 314 | |||
285 | /* .ORDER nodes we need made. The nodes that must be made (if they're | 315 | /* .ORDER nodes we need made. The nodes that must be made (if they're | |
286 | * made) before this node can be made, but that do not enter into the | 316 | * made) before this node can be made, but that do not enter into the | |
287 | * datedness of this node. */ | 317 | * datedness of this node. */ | |
288 | Lst order_pred; | 318 | Lst order_pred; | |
289 | /* .ORDER nodes who need us. The nodes that must be made (if they're made | 319 | /* .ORDER nodes who need us. The nodes that must be made (if they're made | |
290 | * at all) after this node is made, but that do not depend on this node, | 320 | * at all) after this node is made, but that do not depend on this node, | |
291 | * in the normal sense. */ | 321 | * in the normal sense. */ | |
292 | Lst order_succ; | 322 | Lst order_succ; | |
293 | 323 | |||
294 | /* #n for this cohort */ | 324 | /* #n for this cohort */ | |
295 | char cohort_num[8]; | 325 | char cohort_num[8]; | |
296 | /* The number of unmade instances on the cohorts list */ | 326 | /* The number of unmade instances on the cohorts list */ | |
297 | int unmade_cohorts; | 327 | int unmade_cohorts; | |
298 | /* Pointer to the first instance of a :: node; only set when on a cohorts | 328 | /* Pointer to the first instance of a :: node; only set when on a cohorts | |
299 | * list */ | 329 | * list */ | |
300 | struct GNode *centurion; | 330 | struct GNode *centurion; | |
301 | 331 | |||
302 | /* Last time (sequence number) we tried to make this node */ | 332 | /* Last time (sequence number) we tried to make this node */ | |
303 | unsigned int checked; | 333 | unsigned int checked; | |
304 | 334 | |||
305 | /* The "local" variables that are specific to this target and this target | 335 | /* The "local" variables that are specific to this target and this target | |
306 | * only, such as $@, $<, $?. */ | 336 | * only, such as $@, $<, $?. */ | |
307 | Hash_Table context; | 337 | Hash_Table context; | |
308 | 338 | |||
309 | /* The commands to be given to a shell to create this target. */ | 339 | /* The commands to be given to a shell to create this target. */ | |
310 | Lst commands; | 340 | Lst commands; | |
311 | 341 | |||
312 | /* Suffix for the node (determined by Suff_FindDeps and opaque to everyone | 342 | /* Suffix for the node (determined by Suff_FindDeps and opaque to everyone | |
313 | * but the Suff module) */ | 343 | * but the Suff module) */ | |
314 | struct Suff *suffix; | 344 | struct Suff *suffix; | |
315 | 345 | |||
316 | /* filename where the GNode got defined */ | 346 | /* filename where the GNode got defined */ | |
317 | const char *fname; | 347 | const char *fname; | |
318 | /* line number where the GNode got defined */ | 348 | /* line number where the GNode got defined */ | |
319 | int lineno; | 349 | int lineno; | |
320 | } GNode; | 350 | } GNode; | |
321 | 351 | |||
322 | #define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute) | 352 | #define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute) | |
323 | /* | 353 | /* | |
324 | * OP_NOP will return TRUE if the node with the given type was not the | 354 | * OP_NOP will return TRUE if the node with the given type was not the | |
325 | * object of a dependency operator | 355 | * object of a dependency operator | |
326 | */ | 356 | */ | |
327 | #define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000) | 357 | #define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000) | |
328 | 358 | |||
329 | #define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM) | 359 | #define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM) | |
330 | 360 | |||
331 | /* | 361 | /* | |
332 | * The TARG_ constants are used when calling the Targ_FindNode and | 362 | * The TARG_ constants are used when calling the Targ_FindNode and | |
333 | * Targ_FindList functions in targ.c. They simply tell the functions what to | 363 | * Targ_FindList functions in targ.c. They simply tell the functions what to | |
334 | * do if the desired node(s) is (are) not found. If the TARG_CREATE constant | 364 | * do if the desired node(s) is (are) not found. If the TARG_CREATE constant | |
335 | * is given, a new, empty node will be created for the target, placed in the | 365 | * is given, a new, empty node will be created for the target, placed in the | |
336 | * table of all targets and its address returned. If TARG_NOCREATE is given, | 366 | * table of all targets and its address returned. If TARG_NOCREATE is given, | |
337 | * a NULL pointer will be returned. | 367 | * a NULL pointer will be returned. | |
338 | */ | 368 | */ | |
339 | #define TARG_NOCREATE 0x00 /* don't create it */ | 369 | #define TARG_NOCREATE 0x00 /* don't create it */ | |
340 | #define TARG_CREATE 0x01 /* create node if not found */ | 370 | #define TARG_CREATE 0x01 /* create node if not found */ | |
341 | #define TARG_NOHASH 0x02 /* don't look in/add to hash table */ | 371 | #define TARG_NOHASH 0x02 /* don't look in/add to hash table */ | |
342 | 372 | |||
343 | /* | 373 | /* | |
344 | * Error levels for parsing. PARSE_FATAL means the process cannot continue | 374 | * Error levels for parsing. PARSE_FATAL means the process cannot continue | |
345 | * once the makefile has been parsed. PARSE_WARNING means it can. Passed | 375 | * once the makefile has been parsed. PARSE_WARNING means it can. Passed | |
346 | * as the first argument to Parse_Error. | 376 | * as the first argument to Parse_Error. | |
347 | */ | 377 | */ | |
348 | #define PARSE_INFO 3 | 378 | #define PARSE_INFO 3 | |
349 | #define PARSE_WARNING 2 | 379 | #define PARSE_WARNING 2 | |
350 | #define PARSE_FATAL 1 | 380 | #define PARSE_FATAL 1 | |
351 | 381 | |||
352 | /* | 382 | /* | |
353 | * Values returned by Cond_Eval. | 383 | * Values returned by Cond_Eval. | |
354 | */ | 384 | */ | |
355 | typedef enum { | 385 | typedef enum { | |
356 | COND_PARSE, /* Parse the next lines */ | 386 | COND_PARSE, /* Parse the next lines */ | |
357 | COND_SKIP, /* Skip the next lines */ | 387 | COND_SKIP, /* Skip the next lines */ | |
358 | COND_INVALID /* Not a conditional statement */ | 388 | COND_INVALID /* Not a conditional statement */ | |
359 | } CondEvalResult; | 389 | } CondEvalResult; | |
360 | 390 | |||
361 | /* | 391 | /* | |
362 | * Definitions for the "local" variables. Used only for clarity. | 392 | * Definitions for the "local" variables. Used only for clarity. | |
363 | */ | 393 | */ | |
364 | #define TARGET "@" /* Target of dependency */ | 394 | #define TARGET "@" /* Target of dependency */ | |
365 | #define OODATE "?" /* All out-of-date sources */ | 395 | #define OODATE "?" /* All out-of-date sources */ | |
366 | #define ALLSRC ">" /* All sources */ | 396 | #define ALLSRC ">" /* All sources */ | |
367 | #define IMPSRC "<" /* Source implied by transformation */ | 397 | #define IMPSRC "<" /* Source implied by transformation */ | |
368 | #define PREFIX "*" /* Common prefix */ | 398 | #define PREFIX "*" /* Common prefix */ | |
369 | #define ARCHIVE "!" /* Archive in "archive(member)" syntax */ | 399 | #define ARCHIVE "!" /* Archive in "archive(member)" syntax */ | |
370 | #define MEMBER "%" /* Member in "archive(member)" syntax */ | 400 | #define MEMBER "%" /* Member in "archive(member)" syntax */ | |
371 | 401 | |||
372 | #define FTARGET "@F" /* file part of TARGET */ | 402 | #define FTARGET "@F" /* file part of TARGET */ | |
373 | #define DTARGET "@D" /* directory part of TARGET */ | 403 | #define DTARGET "@D" /* directory part of TARGET */ | |
374 | #define FIMPSRC "<F" /* file part of IMPSRC */ | 404 | #define FIMPSRC "<F" /* file part of IMPSRC */ | |
375 | #define DIMPSRC "<D" /* directory part of IMPSRC */ | 405 | #define DIMPSRC "<D" /* directory part of IMPSRC */ | |
376 | #define FPREFIX "*F" /* file part of PREFIX */ | 406 | #define FPREFIX "*F" /* file part of PREFIX */ | |
377 | #define DPREFIX "*D" /* directory part of PREFIX */ | 407 | #define DPREFIX "*D" /* directory part of PREFIX */ | |
378 | 408 | |||
379 | /* | 409 | /* | |
380 | * Global Variables | 410 | * Global Variables | |
381 | */ | 411 | */ | |
382 | extern Lst create; /* The list of target names specified on the | 412 | extern Lst create; /* The list of target names specified on the | |
383 | * command line. used to resolve #if | 413 | * command line. used to resolve #if | |
384 | * make(...) statements */ | 414 | * make(...) statements */ | |
385 | extern Lst dirSearchPath; /* The list of directories to search when | 415 | extern Lst dirSearchPath; /* The list of directories to search when | |
386 | * looking for targets */ | 416 | * looking for targets */ | |
387 | 417 | |||
388 | extern Boolean compatMake; /* True if we are make compatible */ | 418 | extern Boolean compatMake; /* True if we are make compatible */ | |
389 | extern Boolean ignoreErrors; /* True if should ignore all errors */ | 419 | extern Boolean ignoreErrors; /* True if should ignore all errors */ | |
390 | extern Boolean beSilent; /* True if should print no commands */ | 420 | extern Boolean beSilent; /* True if should print no commands */ | |
391 | extern Boolean noExecute; /* True if should execute nothing */ | 421 | extern Boolean noExecute; /* True if should execute nothing */ | |
392 | extern Boolean noRecursiveExecute; /* True if should execute nothing */ | 422 | extern Boolean noRecursiveExecute; /* True if should execute nothing */ | |
393 | extern Boolean allPrecious; /* True if every target is precious */ | 423 | extern Boolean allPrecious; /* True if every target is precious */ | |
394 | extern Boolean deleteOnError; /* True if failed targets should be deleted */ | 424 | extern Boolean deleteOnError; /* True if failed targets should be deleted */ | |
395 | extern Boolean keepgoing; /* True if should continue on unaffected | 425 | extern Boolean keepgoing; /* True if should continue on unaffected | |
396 | * portions of the graph when have an error | 426 | * portions of the graph when have an error | |
397 | * in one portion */ | 427 | * in one portion */ | |
398 | extern Boolean touchFlag; /* TRUE if targets should just be 'touched' | 428 | extern Boolean touchFlag; /* TRUE if targets should just be 'touched' | |
399 | * if out of date. Set by the -t flag */ | 429 | * if out of date. Set by the -t flag */ | |
400 | extern Boolean queryFlag; /* TRUE if we aren't supposed to really make | 430 | extern Boolean queryFlag; /* TRUE if we aren't supposed to really make | |
401 | * anything, just see if the targets are out- | 431 | * anything, just see if the targets are out- | |
402 | * of-date */ | 432 | * of-date */ | |
403 | extern Boolean doing_depend; /* TRUE if processing .depend */ | 433 | extern Boolean doing_depend; /* TRUE if processing .depend */ | |
404 | 434 | |||
405 | extern Boolean checkEnvFirst; /* TRUE if environment should be searched for | 435 | extern Boolean checkEnvFirst; /* TRUE if environment should be searched for | |
406 | * variables before the global context */ | 436 | * variables before the global context */ | |
407 | 437 | |||
408 | extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are | 438 | extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are | |
409 | * treated as errors */ | 439 | * treated as errors */ | |
410 | 440 | |||
411 | extern Boolean varNoExportEnv; /* TRUE if we should not export variables | 441 | extern Boolean varNoExportEnv; /* TRUE if we should not export variables | |
412 | * set on the command line to the env. */ | 442 | * set on the command line to the env. */ | |
413 | 443 | |||
414 | extern GNode *DEFAULT; /* .DEFAULT rule */ | 444 | extern GNode *DEFAULT; /* .DEFAULT rule */ | |
415 | 445 | |||
416 | extern GNode *VAR_INTERNAL; /* Variables defined internally by make | 446 | extern GNode *VAR_INTERNAL; /* Variables defined internally by make | |
417 | * which should not override those set by | 447 | * which should not override those set by | |
418 | * makefiles. | 448 | * makefiles. | |
419 | */ | 449 | */ | |
420 | extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g | 450 | extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g | |
421 | * in the Makefile itself */ | 451 | * in the Makefile itself */ | |
422 | extern GNode *VAR_CMD; /* Variables defined on the command line */ | 452 | extern GNode *VAR_CMD; /* Variables defined on the command line */ | |
423 | extern char var_Error[]; /* Value returned by Var_Parse when an error | 453 | extern char var_Error[]; /* Value returned by Var_Parse when an error | |
424 | * is encountered. It actually points to | 454 | * is encountered. It actually points to | |
425 | * an empty string, so naive callers needn't | 455 | * an empty string, so naive callers needn't | |
426 | * worry about it. */ | 456 | * worry about it. */ | |
427 | 457 | |||
428 | extern time_t now; /* The time at the start of this whole | 458 | extern time_t now; /* The time at the start of this whole | |
429 | * process */ | 459 | * process */ | |
430 | 460 | |||
431 | extern Boolean oldVars; /* Do old-style variable substitution */ | 461 | extern Boolean oldVars; /* Do old-style variable substitution */ | |
432 | 462 | |||
433 | extern Lst sysIncPath; /* The system include path. */ | 463 | extern Lst sysIncPath; /* The system include path. */ | |
434 | extern Lst defIncPath; /* The default include path. */ | 464 | extern Lst defIncPath; /* The default include path. */ | |
435 | 465 | |||
436 | extern char curdir[]; /* Startup directory */ | 466 | extern char curdir[]; /* Startup directory */ | |
437 | extern char *progname; /* The program name */ | 467 | extern char *progname; /* The program name */ | |
438 | extern char *makeDependfile; /* .depend */ | 468 | extern char *makeDependfile; /* .depend */ | |
439 | extern char **savedEnv; /* if we replaced environ this will be non-NULL */ | 469 | extern char **savedEnv; /* if we replaced environ this will be non-NULL */ | |
440 | 470 | |||
441 | extern int makelevel; | 471 | extern int makelevel; | |
442 | 472 | |||
443 | /* | 473 | /* | |
444 | * We cannot vfork() in a child of vfork(). | 474 | * We cannot vfork() in a child of vfork(). | |
445 | * Most systems do not enforce this but some do. | 475 | * Most systems do not enforce this but some do. | |
446 | */ | 476 | */ | |
447 | #define vFork() ((getpid() == myPid) ? vfork() : fork()) | 477 | #define vFork() ((getpid() == myPid) ? vfork() : fork()) | |
448 | extern pid_t myPid; | 478 | extern pid_t myPid; | |
449 | 479 | |||
450 | #define MAKEFLAGS ".MAKEFLAGS" | 480 | #define MAKEFLAGS ".MAKEFLAGS" | |
451 | #define MAKEOVERRIDES ".MAKEOVERRIDES" | 481 | #define MAKEOVERRIDES ".MAKEOVERRIDES" | |
452 | #define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */ | 482 | #define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */ | |
453 | #define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */ | 483 | #define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */ | |
454 | #define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */ | 484 | #define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */ | |
455 | #define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */ | 485 | #define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */ | |
456 | #define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE" | 486 | #define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE" | |
457 | #define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */ | 487 | #define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */ | |
458 | #define MAKE_MODE ".MAKE.MODE" | 488 | #define MAKE_MODE ".MAKE.MODE" | |
459 | #ifndef MAKE_LEVEL_ENV | 489 | #ifndef MAKE_LEVEL_ENV | |
460 | # define MAKE_LEVEL_ENV "MAKELEVEL" | 490 | # define MAKE_LEVEL_ENV "MAKELEVEL" | |
461 | #endif | 491 | #endif | |
462 | 492 | |||
463 | /* | 493 | /* | |
464 | * debug control: | 494 | * debug control: | |
465 | * There is one bit per module. It is up to the module what debug | 495 | * There is one bit per module. It is up to the module what debug | |
466 | * information to print. | 496 | * information to print. | |
467 | */ | 497 | */ | |
468 | extern FILE *debug_file; /* Output is written here - default stderr */ | 498 | extern FILE *debug_file; /* Output is written here - default stderr */ | |
469 | extern int debug; | 499 | extern int debug; | |
470 | #define DEBUG_ARCH 0x00001 | 500 | #define DEBUG_ARCH 0x00001 | |
471 | #define DEBUG_COND 0x00002 | 501 | #define DEBUG_COND 0x00002 | |
472 | #define DEBUG_DIR 0x00004 | 502 | #define DEBUG_DIR 0x00004 | |
473 | #define DEBUG_GRAPH1 0x00008 | 503 | #define DEBUG_GRAPH1 0x00008 | |
474 | #define DEBUG_GRAPH2 0x00010 | 504 | #define DEBUG_GRAPH2 0x00010 | |
475 | #define DEBUG_JOB 0x00020 | 505 | #define DEBUG_JOB 0x00020 | |
476 | #define DEBUG_MAKE 0x00040 | 506 | #define DEBUG_MAKE 0x00040 | |
477 | #define DEBUG_SUFF 0x00080 | 507 | #define DEBUG_SUFF 0x00080 | |
478 | #define DEBUG_TARG 0x00100 | 508 | #define DEBUG_TARG 0x00100 | |
479 | #define DEBUG_VAR 0x00200 | 509 | #define DEBUG_VAR 0x00200 | |
480 | #define DEBUG_FOR 0x00400 | 510 | #define DEBUG_FOR 0x00400 | |
481 | #define DEBUG_SHELL 0x00800 | 511 | #define DEBUG_SHELL 0x00800 | |
482 | #define DEBUG_ERROR 0x01000 | 512 | #define DEBUG_ERROR 0x01000 | |
483 | #define DEBUG_LOUD 0x02000 | 513 | #define DEBUG_LOUD 0x02000 | |
484 | #define DEBUG_META 0x04000 | 514 | #define DEBUG_META 0x04000 | |
485 | #define DEBUG_HASH 0x08000 | 515 | #define DEBUG_HASH 0x08000 | |
486 | 516 | |||
487 | #define DEBUG_GRAPH3 0x10000 | 517 | #define DEBUG_GRAPH3 0x10000 | |
488 | #define DEBUG_SCRIPT 0x20000 | 518 | #define DEBUG_SCRIPT 0x20000 | |
489 | #define DEBUG_PARSE 0x40000 | 519 | #define DEBUG_PARSE 0x40000 | |
490 | #define DEBUG_CWD 0x80000 | 520 | #define DEBUG_CWD 0x80000 | |
491 | 521 | |||
492 | #define DEBUG_LINT 0x100000 | 522 | #define DEBUG_LINT 0x100000 | |
493 | 523 | |||
494 | #define CONCAT(a,b) a##b | 524 | #define CONCAT(a,b) a##b | |
495 | 525 | |||
496 | #define DEBUG(module) (debug & CONCAT(DEBUG_,module)) | 526 | #define DEBUG(module) (debug & CONCAT(DEBUG_,module)) | |
497 | 527 | |||
498 | #include "nonints.h" | 528 | #include "nonints.h" | |
499 | 529 | |||
500 | int Make_TimeStamp(GNode *, GNode *); | 530 | int Make_TimeStamp(GNode *, GNode *); | |
501 | Boolean Make_OODate(GNode *); | 531 | Boolean Make_OODate(GNode *); | |
502 | void Make_ExpandUse(Lst); | 532 | void Make_ExpandUse(Lst); | |
503 | time_t Make_Recheck(GNode *); | 533 | time_t Make_Recheck(GNode *); | |
504 | void Make_HandleUse(GNode *, GNode *); | 534 | void Make_HandleUse(GNode *, GNode *); | |
505 | void Make_Update(GNode *); | 535 | void Make_Update(GNode *); | |
506 | void Make_DoAllVar(GNode *); | 536 | void Make_DoAllVar(GNode *); | |
507 | Boolean Make_Run(Lst); | 537 | Boolean Make_Run(Lst); | |
508 | int dieQuietly(GNode *, int); | 538 | int dieQuietly(GNode *, int); | |
509 | void PrintOnError(GNode *, const char *); | 539 | void PrintOnError(GNode *, const char *); | |
510 | void Main_ExportMAKEFLAGS(Boolean); | 540 | void Main_ExportMAKEFLAGS(Boolean); | |
511 | Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); | 541 | Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); | |
512 | int mkTempFile(const char *, char **); | 542 | int mkTempFile(const char *, char **); | |
513 | int str2Lst_Append(Lst, char *, const char *); | 543 | int str2Lst_Append(Lst, char *, const char *); | |
514 | int cached_lstat(const char *, void *); | 544 | int cached_lstat(const char *, void *); | |
515 | int cached_stat(const char *, void *); | 545 | int cached_stat(const char *, void *); | |
516 | void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *); | 546 | void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *); | |
517 | 547 | |||
518 | #ifdef __GNUC__ | 548 | #ifdef __GNUC__ | |
519 | #define UNCONST(ptr) ({ \ | 549 | #define UNCONST(ptr) ({ \ | |
520 | union __unconst { \ | 550 | union __unconst { \ | |
521 | const void *__cp; \ | 551 | const void *__cp; \ | |
522 | void *__p; \ | 552 | void *__p; \ | |
523 | } __d; \ | 553 | } __d; \ | |
524 | __d.__cp = ptr, __d.__p; }) | 554 | __d.__cp = ptr, __d.__p; }) | |
525 | #else | 555 | #else | |
526 | #define UNCONST(ptr) (void *)(ptr) | 556 | #define UNCONST(ptr) (void *)(ptr) | |
527 | #endif | 557 | #endif | |
528 | 558 | |||
529 | #ifndef MIN | 559 | #ifndef MIN | |
530 | #define MIN(a, b) ((a < b) ? a : b) | 560 | #define MIN(a, b) ((a < b) ? a : b) | |
531 | #endif | 561 | #endif | |
532 | #ifndef MAX | 562 | #ifndef MAX | |
533 | #define MAX(a, b) ((a > b) ? a : b) | 563 | #define MAX(a, b) ((a > b) ? a : b) | |
534 | #endif | 564 | #endif | |
535 | 565 | |||
536 | /* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */ | 566 | /* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */ | |
537 | #include <limits.h> | 567 | #include <limits.h> | |
538 | #ifndef MAXPATHLEN | 568 | #ifndef MAXPATHLEN | |
539 | #define MAXPATHLEN 4096 | 569 | #define MAXPATHLEN 4096 | |
540 | #endif | 570 | #endif | |
541 | #ifndef PATH_MAX | 571 | #ifndef PATH_MAX | |
542 | #define PATH_MAX MAXPATHLEN | 572 | #define PATH_MAX MAXPATHLEN | |
543 | #endif | 573 | #endif | |
544 | 574 | |||
545 | #if defined(SYSV) | 575 | #if defined(SYSV) | |
546 | #define KILLPG(pid, sig) kill(-(pid), (sig)) | 576 | #define KILLPG(pid, sig) kill(-(pid), (sig)) | |
547 | #else | 577 | #else | |
548 | #define KILLPG(pid, sig) killpg((pid), (sig)) | 578 | #define KILLPG(pid, sig) killpg((pid), (sig)) | |
549 | #endif | 579 | #endif | |
550 | 580 | |||
551 | #endif /* MAKE_MAKE_H */ | 581 | #endif /* MAKE_MAKE_H */ |