Mon Aug 24 20:15:51 2020 UTC ()
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.


(rillig)
diff -r1.3 -r1.4 src/usr.bin/make/enum.c
diff -r1.6 -r1.7 src/usr.bin/make/enum.h
diff -r1.121 -r1.122 src/usr.bin/make/make.c
diff -r1.125 -r1.126 src/usr.bin/make/make.h
diff -r1.71 -r1.72 src/usr.bin/make/targ.c
diff -r1.469 -r1.470 src/usr.bin/make/var.c

cvs diff -r1.3 -r1.4 src/usr.bin/make/Attic/enum.c (expand / switch to unified diff)

--- 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
31static char rcsid[] = "$NetBSD: enum.c,v 1.3 2020/08/09 09:44:14 rillig Exp $"; 31static 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. */
46const char * 46const char *
47Enum_ToString(char *buf, size_t buf_size, int value, 47Enum_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. */
 86const char *
 87Enum_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}

cvs diff -r1.6 -r1.7 src/usr.bin/make/Attic/enum.h (expand / switch to unified diff)

--- 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
39typedef struct { 39typedef 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
44const char *Enum_ToString(char *, size_t, int, const EnumToStringSpec *); 44const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
 45const 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

cvs diff -r1.121 -r1.122 src/usr.bin/make/make.c (expand / switch to unified diff)

--- 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
72static char rcsid[] = "$NetBSD: make.c,v 1.121 2020/08/22 22:57:53 rillig Exp $"; 72static 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
77static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93"; 77static 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
123static unsigned int checked = 1;/* Sequence # to detect recursion */ 123static unsigned int checked = 1;/* Sequence # to detect recursion */
124static Lst toBeMade; /* The current fringe of the graph. These 124static 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
130static int MakeAddChild(void *, void *); 130static int MakeAddChild(void *, void *);
131static int MakeFindChild(void *, void *); 131static int MakeFindChild(void *, void *);
132static int MakeUnmark(void *, void *); 132static int MakeUnmark(void *, void *);
@@ -141,26 +141,62 @@ static int MakeBuildParent(void *, void  @@ -141,26 +141,62 @@ static int MakeBuildParent(void *, void
141 141
142MAKE_ATTR_DEAD static void 142MAKE_ATTR_DEAD static void
143make_abort(GNode *gn, int line) 143make_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
 154ENUM_RTTI_8(GNodeMade,
 155 UNMADE, DEFERRED, REQUESTED, BEINGMADE,
 156 MADE, UPTODATE, ERROR, ABORTED);
 157
 158ENUM_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
 168ENUM_RTTI_10(GNodeFlags,
 169 REMAKE, CHILDMADE, FORCE, DONE_WAIT,
 170 DONE_ORDER, FROM_DEPEND, DONE_ALLSRC, CYCLE,
 171 DONECYCLE, INTERNAL);
 172
 173void
 174GNode_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 */
1149static int 1185static int
1150MakePrintStatusOrder(void *ognp, void *gnp) 1186MakePrintStatusOrder(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
1171static int 1207static int
1172MakePrintStatus(void *gnp, void *v_errors) 1208MakePrintStatus(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;

cvs diff -r1.125 -r1.126 src/usr.bin/make/make.h (expand / switch to unified diff)

--- 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);
503time_t Make_Recheck(GNode *); 503time_t Make_Recheck(GNode *);
504void Make_HandleUse(GNode *, GNode *); 504void Make_HandleUse(GNode *, GNode *);
505void Make_Update(GNode *); 505void Make_Update(GNode *);
506void Make_DoAllVar(GNode *); 506void Make_DoAllVar(GNode *);
507Boolean Make_Run(Lst); 507Boolean Make_Run(Lst);
508int dieQuietly(GNode *, int); 508int dieQuietly(GNode *, int);
509void PrintOnError(GNode *, const char *); 509void PrintOnError(GNode *, const char *);
510void Main_ExportMAKEFLAGS(Boolean); 510void Main_ExportMAKEFLAGS(Boolean);
511Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); 511Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
512int mkTempFile(const char *, char **); 512int mkTempFile(const char *, char **);
513int str2Lst_Append(Lst, char *, const char *); 513int str2Lst_Append(Lst, char *, const char *);
514int cached_lstat(const char *, void *); 514int cached_lstat(const char *, void *);
515int cached_stat(const char *, void *); 515int cached_stat(const char *, void *);
 516void 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

cvs diff -r1.71 -r1.72 src/usr.bin/make/targ.c (expand / switch to unified diff)

--- 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
72static char rcsid[] = "$NetBSD: targ.c,v 1.71 2020/08/22 18:20:31 rillig Exp $"; 72static 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
77static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; 77static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
78#else 78#else
79__RCSID("$NetBSD: targ.c,v 1.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 */
629int 629int
630Targ_PrintNode(void *gnp, void *passp) 630Targ_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");

cvs diff -r1.469 -r1.470 src/usr.bin/make/var.c (expand / switch to unified diff)

--- 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
72static char rcsid[] = "$NetBSD: var.c,v 1.469 2020/08/23 22:49:45 rillig Exp $"; 72static 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
77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 77static 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.