make(1): in debug mode, print GNode details in symbols A string like OP_DEPENDS|OP_OPTIONAL|OP_PRECIOUS is much easier to read and understand than the bit pattern 00000089. The implementation in enum.h looks really bloated and ugly, but using this API is as simple and natural as possible. That's the trade-off. In enum.h, I thought about choosing the numbers in the macros such that it is always possible to combine two of them in order to reach an arbitrary number, because of the "part1, part2" in the ENUM__SPEC macro. The powers of 2 are not these numbers, as 7 cannot be expressed as the sum of two of them. Neither are the fibonacci numbers since 12 cannot be expressed as the sum of 2 fibonacci numbers. I tried to find a general pattern to generate these minimal 2-sum numbers, but failed.diff -r1.3 -r1.4 src/usr.bin/make/enum.c
(rillig)
--- src/usr.bin/make/Attic/enum.c 2020/08/09 09:44:14 1.3
+++ src/usr.bin/make/Attic/enum.c 2020/08/24 20:15:51 1.4
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: enum.c,v 1.3 2020/08/09 09:44:14 rillig Exp $ */ | 1 | /* $NetBSD: enum.c,v 1.4 2020/08/24 20:15:51 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | Copyright (c) 2020 Roland Illig <rillig@NetBSD.org> | 4 | Copyright (c) 2020 Roland Illig <rillig@NetBSD.org> | |
5 | All rights reserved. | 5 | All rights reserved. | |
6 | 6 | |||
7 | Redistribution and use in source and binary forms, with or without | 7 | Redistribution and use in source and binary forms, with or without | |
8 | modification, are permitted provided that the following conditions | 8 | modification, are permitted provided that the following conditions | |
9 | are met: | 9 | are met: | |
10 | 10 | |||
11 | 1. Redistributions of source code must retain the above copyright | 11 | 1. Redistributions of source code must retain the above copyright | |
12 | notice, this list of conditions and the following disclaimer. | 12 | notice, this list of conditions and the following disclaimer. | |
13 | 2. Redistributions in binary form must reproduce the above copyright | 13 | 2. Redistributions in binary form must reproduce the above copyright | |
14 | notice, this list of conditions and the following disclaimer in the | 14 | notice, this list of conditions and the following disclaimer in the | |
@@ -18,44 +18,44 @@ | @@ -18,44 +18,44 @@ | |||
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
20 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS | 20 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS | |
21 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 21 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 | POSSIBILITY OF SUCH DAMAGE. | 27 | POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #ifndef MAKE_NATIVE | 30 | #ifndef MAKE_NATIVE | |
31 | static char rcsid[] = "$NetBSD: enum.c,v 1.3 2020/08/09 09:44:14 rillig Exp $"; | 31 | static char rcsid[] = "$NetBSD: enum.c,v 1.4 2020/08/24 20:15:51 rillig Exp $"; | |
32 | #else | 32 | #else | |
33 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
34 | #ifndef lint | 34 | #ifndef lint | |
35 | __RCSID("$NetBSD: enum.c,v 1.3 2020/08/09 09:44:14 rillig Exp $"); | 35 | __RCSID("$NetBSD: enum.c,v 1.4 2020/08/24 20:15:51 rillig Exp $"); | |
36 | #endif | 36 | #endif | |
37 | #endif | 37 | #endif | |
38 | 38 | |||
39 | #include <assert.h> | 39 | #include <assert.h> | |
40 | #include <string.h> | 40 | #include <string.h> | |
41 | 41 | |||
42 | #include "enum.h" | 42 | #include "enum.h" | |
43 | 43 | |||
44 | /* Convert a bitset into a string representation showing the names of the | 44 | /* Convert a bitset into a string representation showing the names of the | |
45 | * individual bits, or optionally shortcuts for groups of bits. */ | 45 | * individual bits, or optionally shortcuts for groups of bits. */ | |
46 | const char * | 46 | const char * | |
47 | Enum_ToString(char *buf, size_t buf_size, int value, | 47 | Enum_FlagsToString(char *buf, size_t buf_size, | |
48 | const EnumToStringSpec *spec) | 48 | int value, const EnumToStringSpec *spec) | |
49 | { | 49 | { | |
50 | const char *buf_start = buf; | 50 | const char *buf_start = buf; | |
51 | const char *sep = ""; | 51 | const char *sep = ""; | |
52 | size_t sep_len = 0; | 52 | size_t sep_len = 0; | |
53 | 53 | |||
54 | for (; spec->es_value != 0; spec++) { | 54 | for (; spec->es_value != 0; spec++) { | |
55 | size_t name_len; | 55 | size_t name_len; | |
56 | 56 | |||
57 | if ((value & spec->es_value) != spec->es_value) | 57 | if ((value & spec->es_value) != spec->es_value) | |
58 | continue; | 58 | continue; | |
59 | value &= ~spec->es_value; | 59 | value &= ~spec->es_value; | |
60 | 60 | |||
61 | assert(buf_size >= sep_len + 1); | 61 | assert(buf_size >= sep_len + 1); | |
@@ -71,13 +71,24 @@ Enum_ToString(char *buf, size_t buf_size | @@ -71,13 +71,24 @@ Enum_ToString(char *buf, size_t buf_size | |||
71 | 71 | |||
72 | sep = ENUM__SEP; | 72 | sep = ENUM__SEP; | |
73 | sep_len = sizeof ENUM__SEP - 1; | 73 | sep_len = sizeof ENUM__SEP - 1; | |
74 | } | 74 | } | |
75 | assert(value == 0); | 75 | assert(value == 0); | |
76 | 76 | |||
77 | if (buf == buf_start) | 77 | if (buf == buf_start) | |
78 | return "none"; | 78 | return "none"; | |
79 | 79 | |||
80 | assert(buf_size >= 1); | 80 | assert(buf_size >= 1); | |
81 | buf[0] = '\0'; | 81 | buf[0] = '\0'; | |
82 | return buf_start; | 82 | return buf_start; | |
83 | } | 83 | } | |
84 | ||||
85 | /* Convert a fixed-value enum into a string representation. */ | |||
86 | const char * | |||
87 | Enum_ValueToString(int value, const EnumToStringSpec *spec) | |||
88 | { | |||
89 | for (; spec->es_name[0] != '\0'; spec++) { | |||
90 | if (value == spec->es_value) | |||
91 | return spec->es_name; | |||
92 | } | |||
93 | assert(!"unknown enum value"); | |||
94 | } |
--- src/usr.bin/make/Attic/enum.h 2020/08/23 09:28:52 1.6
+++ src/usr.bin/make/Attic/enum.h 2020/08/24 20:15:51 1.7
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: enum.h,v 1.6 2020/08/23 09:28:52 rillig Exp $ */ | 1 | /* $NetBSD: enum.h,v 1.7 2020/08/24 20:15:51 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | Copyright (c) 2020 Roland Illig <rillig@NetBSD.org> | 4 | Copyright (c) 2020 Roland Illig <rillig@NetBSD.org> | |
5 | All rights reserved. | 5 | All rights reserved. | |
6 | 6 | |||
7 | Redistribution and use in source and binary forms, with or without | 7 | Redistribution and use in source and binary forms, with or without | |
8 | modification, are permitted provided that the following conditions | 8 | modification, are permitted provided that the following conditions | |
9 | are met: | 9 | are met: | |
10 | 10 | |||
11 | 1. Redistributions of source code must retain the above copyright | 11 | 1. Redistributions of source code must retain the above copyright | |
12 | notice, this list of conditions and the following disclaimer. | 12 | notice, this list of conditions and the following disclaimer. | |
13 | 2. Redistributions in binary form must reproduce the above copyright | 13 | 2. Redistributions in binary form must reproduce the above copyright | |
14 | notice, this list of conditions and the following disclaimer in the | 14 | notice, this list of conditions and the following disclaimer in the | |
@@ -31,68 +31,105 @@ | @@ -31,68 +31,105 @@ | |||
31 | #define MAKE_ENUM_H | 31 | #define MAKE_ENUM_H | |
32 | 32 | |||
33 | /* | 33 | /* | |
34 | * Generate string representation for bitmasks. | 34 | * Generate string representation for bitmasks. | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | #include <stddef.h> | 37 | #include <stddef.h> | |
38 | 38 | |||
39 | typedef struct { | 39 | typedef struct { | |
40 | int es_value; | 40 | int es_value; | |
41 | const char *es_name; | 41 | const char *es_name; | |
42 | } EnumToStringSpec; | 42 | } EnumToStringSpec; | |
43 | 43 | |||
44 | const char *Enum_ToString(char *, size_t, int, const EnumToStringSpec *); | 44 | const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *); | |
45 | const char *Enum_ValueToString(int, const EnumToStringSpec *); | |||
45 | 46 | |||
46 | #define ENUM__SEP "|" | 47 | #define ENUM__SEP "|" | |
47 | 48 | |||
48 | #define ENUM__JOIN_1(v1) \ | 49 | #define ENUM__JOIN_1(v1) \ | |
49 | #v1 | 50 | #v1 | |
50 | #define ENUM__JOIN_2(v1, v2) \ | 51 | #define ENUM__JOIN_2(v1, v2) \ | |
51 | #v1 ENUM__SEP ENUM__JOIN_1(v2) | 52 | #v1 ENUM__SEP #v2 | |
52 | #define ENUM__JOIN_3(v1, v2, v3) \ | |||
53 | #v1 ENUM__SEP ENUM__JOIN_2(v2, v3) | |||
54 | #define ENUM__JOIN_4(v1, v2, v3, v4) \ | 53 | #define ENUM__JOIN_4(v1, v2, v3, v4) \ | |
55 | #v1 ENUM__SEP ENUM__JOIN_3(v2, v3, v4) | 54 | ENUM__JOIN_2(v1, v2) ENUM__SEP ENUM__JOIN_2(v3, v4) | |
56 | #define ENUM__JOIN_5(v1, v2, v3, v4, v5) \ | |||
57 | #v1 ENUM__SEP ENUM__JOIN_4(v2, v3, v4, v5) | |||
58 | #define ENUM__JOIN_6(v1, v2, v3, v4, v5, v6) \ | |||
59 | #v1 ENUM__SEP ENUM__JOIN_5(v2, v3, v4, v5, v6) | |||
60 | #define ENUM__JOIN_7(v1, v2, v3, v4, v5, v6, v7) \ | |||
61 | #v1 ENUM__SEP ENUM__JOIN_6(v2, v3, v4, v5, v6, v7) | |||
62 | #define ENUM__JOIN_8(v1, v2, v3, v4, v5, v6, v7, v8) \ | 55 | #define ENUM__JOIN_8(v1, v2, v3, v4, v5, v6, v7, v8) \ | |
63 | #v1 ENUM__SEP ENUM__JOIN_7(v2, v3, v4, v5, v6, v7, v8) | 56 | ENUM__JOIN_4(v1, v2, v3, v4) ENUM__SEP ENUM__JOIN_4(v5, v6, v7, v8) | |
57 | #define ENUM__JOIN_16(v01, v02, v03, v04, v05, v06, v07, v08, \ | |||
58 | v09, v10, v11, v12, v13, v14, v15, v16) \ | |||
59 | ENUM__JOIN_8(v01, v02, v03, v04, v05, v06, v07, v08) ENUM__SEP \ | |||
60 | ENUM__JOIN_8(v09, v10, v11, v12, v13, v14, v15, v16) | |||
61 | #define ENUM__JOIN_32(v01, v02, v03, v04, v05, v06, v07, v08, \ | |||
62 | v09, v10, v11, v12, v13, v14, v15, v16, \ | |||
63 | v17, v18, v19, v20, v21, v22, v23, v24, \ | |||
64 | v25, v26, v27, v28, v29, v30, v31, v32) \ | |||
65 | ENUM__JOIN_16(v01, v02, v03, v04, v05, v06, v07, v08, \ | |||
66 | v09, v10, v11, v12, v13, v14, v15, v16) ENUM__SEP \ | |||
67 | ENUM__JOIN_16(v17, v18, v19, v20, v21, v22, v23, v24, \ | |||
68 | v25, v26, v27, v28, v29, v30, v31, v32) | |||
69 | #define ENUM__JOIN(part1, part2) \ | |||
70 | part1 ENUM__SEP part2 | |||
64 | 71 | |||
65 | #define ENUM__RTTI(typnam, specs, joined) \ | 72 | #define ENUM__RTTI(typnam, specs, joined) \ | |
66 | static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \ | 73 | static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \ | |
67 | enum { typnam ## _ ## ToStringSize = sizeof joined } | 74 | enum { typnam ## _ ## ToStringSize = sizeof joined } | |
68 | 75 | |||
69 | #define ENUM__SPEC(v) { v, #v } | 76 | #define ENUM__SPEC_1(v1) { v1, #v1 } | |
70 | 77 | #define ENUM__SPEC_2(v1, v2) \ | ||
71 | #define ENUM__SPEC_3(v1, v2, v3) { \ | 78 | ENUM__SPEC_1(v1), \ | |
72 | ENUM__SPEC(v1), \ | 79 | ENUM__SPEC_1(v2) | |
73 | ENUM__SPEC(v2), \ | 80 | #define ENUM__SPEC_4(v1, v2, v3, v4) \ | |
74 | ENUM__SPEC(v3), \ | 81 | ENUM__SPEC_2(v1, v2), \ | |
75 | { 0, "" } } | 82 | ENUM__SPEC_2(v3, v4) | |
76 | 83 | #define ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8) \ | ||
77 | #define ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8) { \ | 84 | ENUM__SPEC_4(v1, v2, v3, v4), \ | |
78 | ENUM__SPEC(v1), \ | 85 | ENUM__SPEC_4(v5, v6, v7, v8) | |
79 | ENUM__SPEC(v2), \ | 86 | #define ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \ | |
80 | ENUM__SPEC(v3), \ | 87 | v09, v10, v11, v12, v13, v14, v15, v16) \ | |
81 | ENUM__SPEC(v4), \ | 88 | ENUM__SPEC_8(v01, v02, v03, v04, v05, v06, v07, v08), \ | |
82 | ENUM__SPEC(v5), \ | 89 | ENUM__SPEC_8(v09, v10, v11, v12, v13, v14, v15, v16) | |
83 | ENUM__SPEC(v6), \ | 90 | #define ENUM__SPEC(part1, part2) \ | |
84 | ENUM__SPEC(v7), \ | 91 | { part1, part2, { 0, "" } } | |
85 | ENUM__SPEC(v8), \ | |||
86 | { 0, "" } } | |||
87 | 92 | |||
88 | #define ENUM_RTTI_3(typnam, v1, v2, v3) \ | 93 | #define ENUM_RTTI_3(typnam, v1, v2, v3) \ | |
89 | ENUM__RTTI(typnam, \ | 94 | ENUM__RTTI(typnam, \ | |
90 | ENUM__SPEC_3(v1, v2, v3), \ | 95 | ENUM__SPEC(ENUM__SPEC_2(v1, v2), ENUM__SPEC_1(v3)), \ | |
91 | ENUM__JOIN_3(v1, v2, v3)) | 96 | ENUM__JOIN_2(ENUM__JOIN_2(v1, v2), ENUM__JOIN_1(v3))) | |
92 | 97 | |||
93 | #define ENUM_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \ | 98 | #define ENUM_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \ | |
94 | ENUM__RTTI(typnam, \ | 99 | ENUM__RTTI(typnam, \ | |
95 | ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8), \ | 100 | ENUM__SPEC( \ | |
96 | ENUM__JOIN_8(v1, v2, v3, v4, v5, v6, v7, v8)) | 101 | ENUM__SPEC_4(v1, v2, v3, v4), \ | |
102 | ENUM__SPEC_4(v5, v6, v7, v8)), \ | |||
103 | ENUM__JOIN( \ | |||
104 | ENUM__JOIN_4(v1, v2, v3, v4), \ | |||
105 | ENUM__JOIN_4(v5, v6, v7, v8))) | |||
106 | ||||
107 | #define ENUM_RTTI_10(typnam, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) \ | |||
108 | ENUM__RTTI(typnam, \ | |||
109 | ENUM__SPEC( \ | |||
110 | ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8), \ | |||
111 | ENUM__SPEC_2(v9, v10)), \ | |||
112 | ENUM__JOIN( \ | |||
113 | ENUM__JOIN_8(v1, v2, v3, v4, v5, v6, v7, v8), \ | |||
114 | ENUM__JOIN_2(v9, v10))) | |||
115 | ||||
116 | #define ENUM_RTTI_32( \ | |||
117 | typnam, \ | |||
118 | v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, \ | |||
119 | v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, \ | |||
120 | v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, \ | |||
121 | v31, v32) \ | |||
122 | ENUM__RTTI( \ | |||
123 | typnam, \ | |||
124 | ENUM__SPEC( \ | |||
125 | ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \ | |||
126 | v09, v10, v11, v12, v13, v14, v15, v16), \ | |||
127 | ENUM__SPEC_16(v17, v18, v19, v20, v21, v22, v23, v24, \ | |||
128 | v25, v26, v27, v28, v29, v30, v31, v32)), \ | |||
129 | ENUM__JOIN_32( \ | |||
130 | v01, v02, v03, v04, v05, v06, v07, v08, \ | |||
131 | v09, v10, v11, v12, v13, v14, v15, v16, \ | |||
132 | v17, v18, v19, v20, v21, v22, v23, v24, \ | |||
133 | v25, v26, v27, v28, v29, v30, v31, v32)) | |||
97 | 134 | |||
98 | #endif | 135 | #endif |
--- src/usr.bin/make/make.c 2020/08/22 22:57:53 1.121
+++ src/usr.bin/make/make.c 2020/08/24 20:15:51 1.122
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: make.c,v 1.121 2020/08/22 22:57:53 rillig Exp $ */ | 1 | /* $NetBSD: make.c,v 1.122 2020/08/24 20:15:51 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | 4 | * Copyright (c) 1988, 1989, 1990, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Adam de Boor. | 8 | * Adam de Boor. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -59,34 +59,34 @@ | @@ -59,34 +59,34 @@ | |||
59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
68 | * SUCH DAMAGE. | 68 | * SUCH DAMAGE. | |
69 | */ | 69 | */ | |
70 | 70 | |||
71 | #ifndef MAKE_NATIVE | 71 | #ifndef MAKE_NATIVE | |
72 | static char rcsid[] = "$NetBSD: make.c,v 1.121 2020/08/22 22:57:53 rillig Exp $"; | 72 | static char rcsid[] = "$NetBSD: make.c,v 1.122 2020/08/24 20:15:51 rillig Exp $"; | |
73 | #else | 73 | #else | |
74 | #include <sys/cdefs.h> | 74 | #include <sys/cdefs.h> | |
75 | #ifndef lint | 75 | #ifndef lint | |
76 | #if 0 | 76 | #if 0 | |
77 | static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93"; | 77 | static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93"; | |
78 | #else | 78 | #else | |
79 | __RCSID("$NetBSD: make.c,v 1.121 2020/08/22 22:57:53 rillig Exp $"); | 79 | __RCSID("$NetBSD: make.c,v 1.122 2020/08/24 20:15:51 rillig Exp $"); | |
80 | #endif | 80 | #endif | |
81 | #endif /* not lint */ | 81 | #endif /* not lint */ | |
82 | #endif | 82 | #endif | |
83 | 83 | |||
84 | /*- | 84 | /*- | |
85 | * make.c -- | 85 | * make.c -- | |
86 | * The functions which perform the examination of targets and | 86 | * The functions which perform the examination of targets and | |
87 | * their suitability for creation | 87 | * their suitability for creation | |
88 | * | 88 | * | |
89 | * Interface: | 89 | * Interface: | |
90 | * Make_Run Initialize things for the module and recreate | 90 | * Make_Run Initialize things for the module and recreate | |
91 | * whatever needs recreating. Returns TRUE if | 91 | * whatever needs recreating. Returns TRUE if | |
92 | * work was (or would have been) done and FALSE | 92 | * work was (or would have been) done and FALSE | |
@@ -106,27 +106,27 @@ __RCSID("$NetBSD: make.c,v 1.121 2020/08 | @@ -106,27 +106,27 @@ __RCSID("$NetBSD: make.c,v 1.121 2020/08 | |||
106 | * target, including the .ALLSRC variable, making | 106 | * target, including the .ALLSRC variable, making | |
107 | * sure that any variable that needs to exist | 107 | * sure that any variable that needs to exist | |
108 | * at the very least has the empty value. | 108 | * at the very least has the empty value. | |
109 | * | 109 | * | |
110 | * Make_OODate Determine if a target is out-of-date. | 110 | * Make_OODate Determine if a target is out-of-date. | |
111 | * | 111 | * | |
112 | * Make_HandleUse See if a child is a .USE node for a parent | 112 | * Make_HandleUse See if a child is a .USE node for a parent | |
113 | * and perform the .USE actions if so. | 113 | * and perform the .USE actions if so. | |
114 | * | 114 | * | |
115 | * Make_ExpandUse Expand .USE nodes | 115 | * Make_ExpandUse Expand .USE nodes | |
116 | */ | 116 | */ | |
117 | 117 | |||
118 | #include "make.h" | 118 | #include "make.h" | |
119 | #include "hash.h" | 119 | #include "enum.h" | |
120 | #include "dir.h" | 120 | #include "dir.h" | |
121 | #include "job.h" | 121 | #include "job.h" | |
122 | 122 | |||
123 | static unsigned int checked = 1;/* Sequence # to detect recursion */ | 123 | static unsigned int checked = 1;/* Sequence # to detect recursion */ | |
124 | static Lst toBeMade; /* The current fringe of the graph. These | 124 | static Lst toBeMade; /* The current fringe of the graph. These | |
125 | * are nodes which await examination by | 125 | * are nodes which await examination by | |
126 | * MakeOODate. It is added to by | 126 | * MakeOODate. It is added to by | |
127 | * Make_Update and subtracted from by | 127 | * Make_Update and subtracted from by | |
128 | * MakeStartJobs */ | 128 | * MakeStartJobs */ | |
129 | 129 | |||
130 | static int MakeAddChild(void *, void *); | 130 | static int MakeAddChild(void *, void *); | |
131 | static int MakeFindChild(void *, void *); | 131 | static int MakeFindChild(void *, void *); | |
132 | static int MakeUnmark(void *, void *); | 132 | static int MakeUnmark(void *, void *); | |
@@ -141,26 +141,62 @@ static int MakeBuildParent(void *, void | @@ -141,26 +141,62 @@ static int MakeBuildParent(void *, void | |||
141 | 141 | |||
142 | MAKE_ATTR_DEAD static void | 142 | MAKE_ATTR_DEAD static void | |
143 | make_abort(GNode *gn, int line) | 143 | make_abort(GNode *gn, int line) | |
144 | { | 144 | { | |
145 | static int two = 2; | 145 | static int two = 2; | |
146 | 146 | |||
147 | fprintf(debug_file, "make_abort from line %d\n", line); | 147 | fprintf(debug_file, "make_abort from line %d\n", line); | |
148 | Targ_PrintNode(gn, &two); | 148 | Targ_PrintNode(gn, &two); | |
149 | Lst_ForEach(toBeMade, Targ_PrintNode, &two); | 149 | Lst_ForEach(toBeMade, Targ_PrintNode, &two); | |
150 | Targ_PrintGraph(3); | 150 | Targ_PrintGraph(3); | |
151 | abort(); | 151 | abort(); | |
152 | } | 152 | } | |
153 | 153 | |||
154 | ENUM_RTTI_8(GNodeMade, | |||
155 | UNMADE, DEFERRED, REQUESTED, BEINGMADE, | |||
156 | MADE, UPTODATE, ERROR, ABORTED); | |||
157 | ||||
158 | ENUM_RTTI_32(GNodeType, | |||
159 | OP_DEPENDS, OP_FORCE, OP_DOUBLEDEP, OP_OPMASK, | |||
160 | OP_OPTIONAL, OP_USE, OP_EXEC, OP_IGNORE, | |||
161 | OP_PRECIOUS, OP_SILENT, OP_MAKE, OP_JOIN, | |||
162 | OP_MADE, OP_SPECIAL, OP_USEBEFORE, OP_INVISIBLE, | |||
163 | OP_NOTMAIN, OP_PHONY, OP_NOPATH, OP_WAIT, | |||
164 | OP_NOMETA, OP_META, OP_NOMETA_CMP, OP_SUBMAKE, | |||
165 | OP_TRANSFORM, OP_MEMBER, OP_LIB, OP_ARCHV, | |||
166 | OP_HAS_COMMANDS, OP_SAVE_CMDS, OP_DEPS_FOUND, OP_MARK); | |||
167 | ||||
168 | ENUM_RTTI_10(GNodeFlags, | |||
169 | REMAKE, CHILDMADE, FORCE, DONE_WAIT, | |||
170 | DONE_ORDER, FROM_DEPEND, DONE_ALLSRC, CYCLE, | |||
171 | DONECYCLE, INTERNAL); | |||
172 | ||||
173 | void | |||
174 | GNode_FprintDetails(FILE *f, const char *prefix, const GNode *gn, | |||
175 | const char *suffix) | |||
176 | { | |||
177 | char type_buf[GNodeType_ToStringSize]; | |||
178 | char flags_buf[GNodeFlags_ToStringSize]; | |||
179 | ||||
180 | fprintf(f, "%smade %s, type %s, flags %s%s", | |||
181 | prefix, | |||
182 | Enum_ValueToString(gn->made, GNodeMade_ToStringSpecs), | |||
183 | Enum_FlagsToString(type_buf, sizeof type_buf, | |||
184 | gn->type, GNodeType_ToStringSpecs), | |||
185 | Enum_FlagsToString(flags_buf, sizeof flags_buf, | |||
186 | gn->flags, GNodeFlags_ToStringSpecs), | |||
187 | suffix); | |||
188 | } | |||
189 | ||||
154 | /*- | 190 | /*- | |
155 | *----------------------------------------------------------------------- | 191 | *----------------------------------------------------------------------- | |
156 | * Make_TimeStamp -- | 192 | * Make_TimeStamp -- | |
157 | * Set the cmgn field of a parent node based on the mtime stamp in its | 193 | * Set the cmgn field of a parent node based on the mtime stamp in its | |
158 | * child. Called from MakeOODate via Lst_ForEach. | 194 | * child. Called from MakeOODate via Lst_ForEach. | |
159 | * | 195 | * | |
160 | * Input: | 196 | * Input: | |
161 | * pgn the current parent | 197 | * pgn the current parent | |
162 | * cgn the child we've just examined | 198 | * cgn the child we've just examined | |
163 | * | 199 | * | |
164 | * Results: | 200 | * Results: | |
165 | * Always returns 0. | 201 | * Always returns 0. | |
166 | * | 202 | * | |
@@ -1146,67 +1182,68 @@ MakeStartJobs(void) | @@ -1146,67 +1182,68 @@ MakeStartJobs(void) | |||
1146 | * | 1182 | * | |
1147 | *----------------------------------------------------------------------- | 1183 | *----------------------------------------------------------------------- | |
1148 | */ | 1184 | */ | |
1149 | static int | 1185 | static int | |
1150 | MakePrintStatusOrder(void *ognp, void *gnp) | 1186 | MakePrintStatusOrder(void *ognp, void *gnp) | |
1151 | { | 1187 | { | |
1152 | GNode *ogn = ognp; | 1188 | GNode *ogn = ognp; | |
1153 | GNode *gn = gnp; | 1189 | GNode *gn = gnp; | |
1154 | 1190 | |||
1155 | if (!(ogn->flags & REMAKE) || ogn->made > REQUESTED) | 1191 | if (!(ogn->flags & REMAKE) || ogn->made > REQUESTED) | |
1156 | /* not waiting for this one */ | 1192 | /* not waiting for this one */ | |
1157 | return 0; | 1193 | return 0; | |
1158 | 1194 | |||
1159 | printf(" `%s%s' has .ORDER dependency against %s%s " | 1195 | printf(" `%s%s' has .ORDER dependency against %s%s ", | |
1160 | "(made %d, flags %x, type %x)\n", | 1196 | gn->name, gn->cohort_num, ogn->name, ogn->cohort_num); | |
1161 | gn->name, gn->cohort_num, | 1197 | GNode_FprintDetails(stdout, "(", ogn, ")\n"); | |
1162 | ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type); | 1198 | ||
1163 | if (DEBUG(MAKE) && debug_file != stdout) | 1199 | if (DEBUG(MAKE) && debug_file != stdout) { | |
1164 | fprintf(debug_file, " `%s%s' has .ORDER dependency against %s%s " | 1200 | fprintf(debug_file, " `%s%s' has .ORDER dependency against %s%s ", | |
1165 | "(made %d, flags %x, type %x)\n", | 1201 | gn->name, gn->cohort_num, ogn->name, ogn->cohort_num); | |
1166 | gn->name, gn->cohort_num, | 1202 | GNode_FprintDetails(debug_file, "(", ogn, ")\n"); | |
1167 | ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type); | 1203 | } | |
1168 | return 0; | 1204 | return 0; | |
1169 | } | 1205 | } | |
1170 | 1206 | |||
1171 | static int | 1207 | static int | |
1172 | MakePrintStatus(void *gnp, void *v_errors) | 1208 | MakePrintStatus(void *gnp, void *v_errors) | |
1173 | { | 1209 | { | |
1174 | GNode *gn = (GNode *)gnp; | 1210 | GNode *gn = (GNode *)gnp; | |
1175 | int *errors = v_errors; | 1211 | int *errors = v_errors; | |
1176 | 1212 | |||
1177 | if (gn->flags & DONECYCLE) | 1213 | if (gn->flags & DONECYCLE) | |
1178 | /* We've completely processed this node before, don't do it again. */ | 1214 | /* We've completely processed this node before, don't do it again. */ | |
1179 | return 0; | 1215 | return 0; | |
1180 | 1216 | |||
1181 | if (gn->unmade == 0) { | 1217 | if (gn->unmade == 0) { | |
1182 | gn->flags |= DONECYCLE; | 1218 | gn->flags |= DONECYCLE; | |
1183 | switch (gn->made) { | 1219 | switch (gn->made) { | |
1184 | case UPTODATE: | 1220 | case UPTODATE: | |
1185 | printf("`%s%s' is up to date.\n", gn->name, gn->cohort_num); | 1221 | printf("`%s%s' is up to date.\n", gn->name, gn->cohort_num); | |
1186 | break; | 1222 | break; | |
1187 | case MADE: | 1223 | case MADE: | |
1188 | break; | 1224 | break; | |
1189 | case UNMADE: | 1225 | case UNMADE: | |
1190 | case DEFERRED: | 1226 | case DEFERRED: | |
1191 | case REQUESTED: | 1227 | case REQUESTED: | |
1192 | case BEINGMADE: | 1228 | case BEINGMADE: | |
1193 | (*errors)++; | 1229 | (*errors)++; | |
1194 | printf("`%s%s' was not built (made %d, flags %x, type %x)!\n", | 1230 | printf("`%s%s' was not built", gn->name, gn->cohort_num); | |
1195 | gn->name, gn->cohort_num, gn->made, gn->flags, gn->type); | 1231 | GNode_FprintDetails(stdout, " (", gn, ")!\n"); | |
1196 | if (DEBUG(MAKE) && debug_file != stdout) | 1232 | if (DEBUG(MAKE) && debug_file != stdout) { | |
1197 | fprintf(debug_file, | 1233 | fprintf(debug_file, "`%s%s' was not built", | |
1198 | "`%s%s' was not built (made %d, flags %x, type %x)!\n", | 1234 | gn->name, gn->cohort_num); | |
1199 | gn->name, gn->cohort_num, gn->made, gn->flags, gn->type); | 1235 | GNode_FprintDetails(debug_file, " (", gn, ")!\n"); | |
1236 | } | |||
1200 | /* Most likely problem is actually caused by .ORDER */ | 1237 | /* Most likely problem is actually caused by .ORDER */ | |
1201 | Lst_ForEach(gn->order_pred, MakePrintStatusOrder, gn); | 1238 | Lst_ForEach(gn->order_pred, MakePrintStatusOrder, gn); | |
1202 | break; | 1239 | break; | |
1203 | default: | 1240 | default: | |
1204 | /* Errors - already counted */ | 1241 | /* Errors - already counted */ | |
1205 | printf("`%s%s' not remade because of errors.\n", | 1242 | printf("`%s%s' not remade because of errors.\n", | |
1206 | gn->name, gn->cohort_num); | 1243 | gn->name, gn->cohort_num); | |
1207 | if (DEBUG(MAKE) && debug_file != stdout) | 1244 | if (DEBUG(MAKE) && debug_file != stdout) | |
1208 | fprintf(debug_file, "`%s%s' not remade because of errors.\n", | 1245 | fprintf(debug_file, "`%s%s' not remade because of errors.\n", | |
1209 | gn->name, gn->cohort_num); | 1246 | gn->name, gn->cohort_num); | |
1210 | break; | 1247 | break; | |
1211 | } | 1248 | } | |
1212 | return 0; | 1249 | return 0; |
--- src/usr.bin/make/make.h 2020/08/23 17:04:21 1.125
+++ src/usr.bin/make/make.h 2020/08/24 20:15:51 1.126
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: make.h,v 1.125 2020/08/23 17:04:21 rillig Exp $ */ | 1 | /* $NetBSD: make.h,v 1.126 2020/08/24 20:15:51 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. | |
@@ -503,26 +503,27 @@ void Make_ExpandUse(Lst); | @@ -503,26 +503,27 @@ void Make_ExpandUse(Lst); | |||
503 | time_t Make_Recheck(GNode *); | 503 | time_t Make_Recheck(GNode *); | |
504 | void Make_HandleUse(GNode *, GNode *); | 504 | void Make_HandleUse(GNode *, GNode *); | |
505 | void Make_Update(GNode *); | 505 | void Make_Update(GNode *); | |
506 | void Make_DoAllVar(GNode *); | 506 | void Make_DoAllVar(GNode *); | |
507 | Boolean Make_Run(Lst); | 507 | Boolean Make_Run(Lst); | |
508 | int dieQuietly(GNode *, int); | 508 | int dieQuietly(GNode *, int); | |
509 | void PrintOnError(GNode *, const char *); | 509 | void PrintOnError(GNode *, const char *); | |
510 | void Main_ExportMAKEFLAGS(Boolean); | 510 | void Main_ExportMAKEFLAGS(Boolean); | |
511 | Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); | 511 | Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); | |
512 | int mkTempFile(const char *, char **); | 512 | int mkTempFile(const char *, char **); | |
513 | int str2Lst_Append(Lst, char *, const char *); | 513 | int str2Lst_Append(Lst, char *, const char *); | |
514 | int cached_lstat(const char *, void *); | 514 | int cached_lstat(const char *, void *); | |
515 | int cached_stat(const char *, void *); | 515 | int cached_stat(const char *, void *); | |
516 | void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *); | |||
516 | 517 | |||
517 | #ifdef __GNUC__ | 518 | #ifdef __GNUC__ | |
518 | #define UNCONST(ptr) ({ \ | 519 | #define UNCONST(ptr) ({ \ | |
519 | union __unconst { \ | 520 | union __unconst { \ | |
520 | const void *__cp; \ | 521 | const void *__cp; \ | |
521 | void *__p; \ | 522 | void *__p; \ | |
522 | } __d; \ | 523 | } __d; \ | |
523 | __d.__cp = ptr, __d.__p; }) | 524 | __d.__cp = ptr, __d.__p; }) | |
524 | #else | 525 | #else | |
525 | #define UNCONST(ptr) (void *)(ptr) | 526 | #define UNCONST(ptr) (void *)(ptr) | |
526 | #endif | 527 | #endif | |
527 | 528 | |||
528 | #ifndef MIN | 529 | #ifndef MIN |
--- src/usr.bin/make/targ.c 2020/08/22 18:20:31 1.71
+++ src/usr.bin/make/targ.c 2020/08/24 20:15:51 1.72
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: targ.c,v 1.71 2020/08/22 18:20:31 rillig Exp $ */ | 1 | /* $NetBSD: targ.c,v 1.72 2020/08/24 20:15:51 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | 4 | * Copyright (c) 1988, 1989, 1990, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Adam de Boor. | 8 | * Adam de Boor. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -59,34 +59,34 @@ | @@ -59,34 +59,34 @@ | |||
59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
68 | * SUCH DAMAGE. | 68 | * SUCH DAMAGE. | |
69 | */ | 69 | */ | |
70 | 70 | |||
71 | #ifndef MAKE_NATIVE | 71 | #ifndef MAKE_NATIVE | |
72 | static char rcsid[] = "$NetBSD: targ.c,v 1.71 2020/08/22 18:20:31 rillig Exp $"; | 72 | static char rcsid[] = "$NetBSD: targ.c,v 1.72 2020/08/24 20:15:51 rillig Exp $"; | |
73 | #else | 73 | #else | |
74 | #include <sys/cdefs.h> | 74 | #include <sys/cdefs.h> | |
75 | #ifndef lint | 75 | #ifndef lint | |
76 | #if 0 | 76 | #if 0 | |
77 | static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; | 77 | static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; | |
78 | #else | 78 | #else | |
79 | __RCSID("$NetBSD: targ.c,v 1.71 2020/08/22 18:20:31 rillig Exp $"); | 79 | __RCSID("$NetBSD: targ.c,v 1.72 2020/08/24 20:15:51 rillig Exp $"); | |
80 | #endif | 80 | #endif | |
81 | #endif /* not lint */ | 81 | #endif /* not lint */ | |
82 | #endif | 82 | #endif | |
83 | 83 | |||
84 | /*- | 84 | /*- | |
85 | * targ.c -- | 85 | * targ.c -- | |
86 | * Functions for maintaining the Lst allTargets. Target nodes are | 86 | * Functions for maintaining the Lst allTargets. Target nodes are | |
87 | * kept in two structures: a Lst, maintained by the list library, and a | 87 | * kept in two structures: a Lst, maintained by the list library, and a | |
88 | * hash table, maintained by the hash library. | 88 | * hash table, maintained by the hash library. | |
89 | * | 89 | * | |
90 | * Interface: | 90 | * Interface: | |
91 | * Targ_Init Initialization procedure. | 91 | * Targ_Init Initialization procedure. | |
92 | * | 92 | * | |
@@ -622,28 +622,28 @@ made_name(GNodeMade made) | @@ -622,28 +622,28 @@ made_name(GNodeMade made) | |||
622 | 622 | |||
623 | /*- | 623 | /*- | |
624 | *----------------------------------------------------------------------- | 624 | *----------------------------------------------------------------------- | |
625 | * TargPrintNode -- | 625 | * TargPrintNode -- | |
626 | * print the contents of a node | 626 | * print the contents of a node | |
627 | *----------------------------------------------------------------------- | 627 | *----------------------------------------------------------------------- | |
628 | */ | 628 | */ | |
629 | int | 629 | int | |
630 | Targ_PrintNode(void *gnp, void *passp) | 630 | Targ_PrintNode(void *gnp, void *passp) | |
631 | { | 631 | { | |
632 | GNode *gn = (GNode *)gnp; | 632 | GNode *gn = (GNode *)gnp; | |
633 | int pass = passp ? *(int *)passp : 0; | 633 | int pass = passp ? *(int *)passp : 0; | |
634 | 634 | |||
635 | fprintf(debug_file, "# %s%s, flags %x, type %x, made %d\n", | 635 | fprintf(debug_file, "# %s%s", gn->name, gn->cohort_num); | |
636 | gn->name, gn->cohort_num, gn->flags, gn->type, gn->made); | 636 | GNode_FprintDetails(debug_file, ", ", gn, "\n"); | |
637 | if (gn->flags == 0) | 637 | if (gn->flags == 0) | |
638 | return 0; | 638 | return 0; | |
639 | 639 | |||
640 | if (!OP_NOP(gn->type)) { | 640 | if (!OP_NOP(gn->type)) { | |
641 | fprintf(debug_file, "#\n"); | 641 | fprintf(debug_file, "#\n"); | |
642 | if (gn == mainTarg) { | 642 | if (gn == mainTarg) { | |
643 | fprintf(debug_file, "# *** MAIN TARGET ***\n"); | 643 | fprintf(debug_file, "# *** MAIN TARGET ***\n"); | |
644 | } | 644 | } | |
645 | if (pass >= 2) { | 645 | if (pass >= 2) { | |
646 | if (gn->unmade) { | 646 | if (gn->unmade) { | |
647 | fprintf(debug_file, "# %d unmade children\n", gn->unmade); | 647 | fprintf(debug_file, "# %d unmade children\n", gn->unmade); | |
648 | } else { | 648 | } else { | |
649 | fprintf(debug_file, "# No unmade children\n"); | 649 | fprintf(debug_file, "# No unmade children\n"); |
--- src/usr.bin/make/var.c 2020/08/23 22:49:45 1.469
+++ src/usr.bin/make/var.c 2020/08/24 20:15:51 1.470
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: var.c,v 1.469 2020/08/23 22:49:45 rillig Exp $ */ | 1 | /* $NetBSD: var.c,v 1.470 2020/08/24 20:15:51 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | 4 | * Copyright (c) 1988, 1989, 1990, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Adam de Boor. | 8 | * Adam de Boor. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -59,34 +59,34 @@ | @@ -59,34 +59,34 @@ | |||
59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
68 | * SUCH DAMAGE. | 68 | * SUCH DAMAGE. | |
69 | */ | 69 | */ | |
70 | 70 | |||
71 | #ifndef MAKE_NATIVE | 71 | #ifndef MAKE_NATIVE | |
72 | static char rcsid[] = "$NetBSD: var.c,v 1.469 2020/08/23 22:49:45 rillig Exp $"; | 72 | static char rcsid[] = "$NetBSD: var.c,v 1.470 2020/08/24 20:15:51 rillig Exp $"; | |
73 | #else | 73 | #else | |
74 | #include <sys/cdefs.h> | 74 | #include <sys/cdefs.h> | |
75 | #ifndef lint | 75 | #ifndef lint | |
76 | #if 0 | 76 | #if 0 | |
77 | static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; | 77 | static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; | |
78 | #else | 78 | #else | |
79 | __RCSID("$NetBSD: var.c,v 1.469 2020/08/23 22:49:45 rillig Exp $"); | 79 | __RCSID("$NetBSD: var.c,v 1.470 2020/08/24 20:15:51 rillig Exp $"); | |
80 | #endif | 80 | #endif | |
81 | #endif /* not lint */ | 81 | #endif /* not lint */ | |
82 | #endif | 82 | #endif | |
83 | 83 | |||
84 | /*- | 84 | /*- | |
85 | * var.c -- | 85 | * var.c -- | |
86 | * Variable-handling functions | 86 | * Variable-handling functions | |
87 | * | 87 | * | |
88 | * Interface: | 88 | * Interface: | |
89 | * Var_Set Set the value of a variable in the given | 89 | * Var_Set Set the value of a variable in the given | |
90 | * context. The variable is created if it doesn't | 90 | * context. The variable is created if it doesn't | |
91 | * yet exist. | 91 | * yet exist. | |
92 | * | 92 | * | |
@@ -3120,30 +3120,30 @@ ApplyModifiers( | @@ -3120,30 +3120,30 @@ ApplyModifiers( | |||
3120 | mod = p; | 3120 | mod = p; | |
3121 | 3121 | |||
3122 | if (DEBUG(VAR)) { | 3122 | if (DEBUG(VAR)) { | |
3123 | char eflags_str[VarEvalFlags_ToStringSize]; | 3123 | char eflags_str[VarEvalFlags_ToStringSize]; | |
3124 | char vflags_str[VarFlags_ToStringSize]; | 3124 | char vflags_str[VarFlags_ToStringSize]; | |
3125 | Boolean is_single_char = mod[0] != '\0' && | 3125 | Boolean is_single_char = mod[0] != '\0' && | |
3126 | (mod[1] == endc || mod[1] == ':'); | 3126 | (mod[1] == endc || mod[1] == ':'); | |
3127 | 3127 | |||
3128 | /* At this point, only the first character of the modifier can | 3128 | /* At this point, only the first character of the modifier can | |
3129 | * be used since the end of the modifier is not yet known. */ | 3129 | * be used since the end of the modifier is not yet known. */ | |
3130 | VAR_DEBUG("Applying ${%s:%c%s} to \"%s\" " | 3130 | VAR_DEBUG("Applying ${%s:%c%s} to \"%s\" " | |
3131 | "(eflags = %s, vflags = %s)\n", | 3131 | "(eflags = %s, vflags = %s)\n", | |
3132 | st.v->name, mod[0], is_single_char ? "" : "...", st.val, | 3132 | st.v->name, mod[0], is_single_char ? "" : "...", st.val, | |
3133 | Enum_ToString(eflags_str, sizeof eflags_str, st.eflags, | 3133 | Enum_FlagsToString(eflags_str, sizeof eflags_str, | |
3134 | VarEvalFlags_ToStringSpecs), | 3134 | st.eflags, VarEvalFlags_ToStringSpecs), | |
3135 | Enum_ToString(vflags_str, sizeof vflags_str, st.v->flags, | 3135 | Enum_FlagsToString(vflags_str, sizeof vflags_str, | |
3136 | VarFlags_ToStringSpecs)); | 3136 | st.v->flags, VarFlags_ToStringSpecs)); | |
3137 | } | 3137 | } | |
3138 | 3138 | |||
3139 | switch (*mod) { | 3139 | switch (*mod) { | |
3140 | case ':': | 3140 | case ':': | |
3141 | res = ApplyModifier_Assign(&p, &st); | 3141 | res = ApplyModifier_Assign(&p, &st); | |
3142 | break; | 3142 | break; | |
3143 | case '@': | 3143 | case '@': | |
3144 | res = ApplyModifier_Loop(&p, &st); | 3144 | res = ApplyModifier_Loop(&p, &st); | |
3145 | break; | 3145 | break; | |
3146 | case '_': | 3146 | case '_': | |
3147 | res = ApplyModifier_Remember(&p, &st); | 3147 | res = ApplyModifier_Remember(&p, &st); | |
3148 | break; | 3148 | break; | |
3149 | case 'D': | 3149 | case 'D': | |
@@ -3265,30 +3265,30 @@ ApplyModifiers( | @@ -3265,30 +3265,30 @@ ApplyModifiers( | |||
3265 | goto cleanup; | 3265 | goto cleanup; | |
3266 | if (res == AMR_BAD) | 3266 | if (res == AMR_BAD) | |
3267 | goto bad_modifier; | 3267 | goto bad_modifier; | |
3268 | 3268 | |||
3269 | if (DEBUG(VAR)) { | 3269 | if (DEBUG(VAR)) { | |
3270 | char eflags_str[VarEvalFlags_ToStringSize]; | 3270 | char eflags_str[VarEvalFlags_ToStringSize]; | |
3271 | char vflags_str[VarFlags_ToStringSize]; | 3271 | char vflags_str[VarFlags_ToStringSize]; | |
3272 | const char *quot = st.newVal == var_Error ? "" : "\""; | 3272 | const char *quot = st.newVal == var_Error ? "" : "\""; | |
3273 | const char *newVal = st.newVal == var_Error ? "error" : st.newVal; | 3273 | const char *newVal = st.newVal == var_Error ? "error" : st.newVal; | |
3274 | 3274 | |||
3275 | VAR_DEBUG("Result of ${%s:%.*s} is %s%s%s " | 3275 | VAR_DEBUG("Result of ${%s:%.*s} is %s%s%s " | |
3276 | "(eflags = %s, vflags = %s)\n", | 3276 | "(eflags = %s, vflags = %s)\n", | |
3277 | st.v->name, (int)(p - mod), mod, quot, newVal, quot, | 3277 | st.v->name, (int)(p - mod), mod, quot, newVal, quot, | |
3278 | Enum_ToString(eflags_str, sizeof eflags_str, st.eflags, | 3278 | Enum_FlagsToString(eflags_str, sizeof eflags_str, | |
3279 | VarEvalFlags_ToStringSpecs), | 3279 | st.eflags, VarEvalFlags_ToStringSpecs), | |
3280 | Enum_ToString(vflags_str, sizeof vflags_str, st.v->flags, | 3280 | Enum_FlagsToString(vflags_str, sizeof vflags_str, | |
3281 | VarFlags_ToStringSpecs)); | 3281 | st.v->flags, VarFlags_ToStringSpecs)); | |
3282 | } | 3282 | } | |
3283 | 3283 | |||
3284 | if (st.newVal != st.val) { | 3284 | if (st.newVal != st.val) { | |
3285 | if (*freePtr) { | 3285 | if (*freePtr) { | |
3286 | free(st.val); | 3286 | free(st.val); | |
3287 | *freePtr = NULL; | 3287 | *freePtr = NULL; | |
3288 | } | 3288 | } | |
3289 | st.val = st.newVal; | 3289 | st.val = st.newVal; | |
3290 | if (st.val != var_Error && st.val != varNoError) { | 3290 | if (st.val != var_Error && st.val != varNoError) { | |
3291 | *freePtr = st.val; | 3291 | *freePtr = st.val; | |
3292 | } | 3292 | } | |
3293 | } | 3293 | } | |
3294 | if (*p == '\0' && st.endc != '\0') { | 3294 | if (*p == '\0' && st.endc != '\0') { | |
@@ -3400,28 +3400,28 @@ Var_Parse(const char * const str, GNode | @@ -3400,28 +3400,28 @@ Var_Parse(const char * const str, GNode | |||
3400 | * or braces */ | 3400 | * or braces */ | |
3401 | char endc; /* Ending character if variable in parens | 3401 | char endc; /* Ending character if variable in parens | |
3402 | * or braces */ | 3402 | * or braces */ | |
3403 | Boolean dynamic; /* TRUE if the variable is local and we're | 3403 | Boolean dynamic; /* TRUE if the variable is local and we're | |
3404 | * expanding it in a non-local context. This | 3404 | * expanding it in a non-local context. This | |
3405 | * is done to support dynamic sources. The | 3405 | * is done to support dynamic sources. The | |
3406 | * result is just the invocation, unaltered */ | 3406 | * result is just the invocation, unaltered */ | |
3407 | const char *extramodifiers; | 3407 | const char *extramodifiers; | |
3408 | Var *v; | 3408 | Var *v; | |
3409 | char *nstr; | 3409 | char *nstr; | |
3410 | char eflags_str[VarEvalFlags_ToStringSize]; | 3410 | char eflags_str[VarEvalFlags_ToStringSize]; | |
3411 | 3411 | |||
3412 | VAR_DEBUG("%s: %s with %s\n", __func__, str, | 3412 | VAR_DEBUG("%s: %s with %s\n", __func__, str, | |
3413 | Enum_ToString(eflags_str, sizeof eflags_str, eflags, | 3413 | Enum_FlagsToString(eflags_str, sizeof eflags_str, eflags, | |
3414 | VarEvalFlags_ToStringSpecs)); | 3414 | VarEvalFlags_ToStringSpecs)); | |
3415 | 3415 | |||
3416 | *freePtr = NULL; | 3416 | *freePtr = NULL; | |
3417 | extramodifiers = NULL; /* extra modifiers to apply first */ | 3417 | extramodifiers = NULL; /* extra modifiers to apply first */ | |
3418 | dynamic = FALSE; | 3418 | dynamic = FALSE; | |
3419 | 3419 | |||
3420 | startc = str[1]; | 3420 | startc = str[1]; | |
3421 | if (startc != PROPEN && startc != BROPEN) { | 3421 | if (startc != PROPEN && startc != BROPEN) { | |
3422 | char name[2]; | 3422 | char name[2]; | |
3423 | 3423 | |||
3424 | /* | 3424 | /* | |
3425 | * If it's not bounded by braces of some sort, life is much simpler. | 3425 | * If it's not bounded by braces of some sort, life is much simpler. | |
3426 | * We just need to check for the first character and return the | 3426 | * We just need to check for the first character and return the | |
3427 | * value if it exists. | 3427 | * value if it exists. |