Sun Jun 18 19:16:51 2023 UTC ()
tests/make: extend test for multiple-inclusion guards


(rillig)
diff -r1.1 -r1.2 src/usr.bin/make/unit-tests/directive-include-guard.exp
diff -r1.1 -r1.2 src/usr.bin/make/unit-tests/directive-include-guard.mk

cvs diff -r1.1 -r1.2 src/usr.bin/make/unit-tests/directive-include-guard.exp (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/directive-include-guard.exp 2023/06/16 09:25:13 1.1
+++ src/usr.bin/make/unit-tests/directive-include-guard.exp 2023/06/18 19:16:51 1.2
@@ -12,14 +12,24 @@ Parse_PushInput: file directive-include- @@ -12,14 +12,24 @@ Parse_PushInput: file directive-include-
12Parse_PushInput: file directive-include-guard-varname-indirect.tmp, line 1 12Parse_PushInput: file directive-include-guard-varname-indirect.tmp, line 1
13Parse_PushInput: file directive-include-guard-late-assignment.tmp, line 1 13Parse_PushInput: file directive-include-guard-late-assignment.tmp, line 1
14Parse_PushInput: file directive-include-guard-late-assignment.tmp, line 1 14Parse_PushInput: file directive-include-guard-late-assignment.tmp, line 1
15Parse_PushInput: file directive-include-guard-two-conditions.tmp, line 1 15Parse_PushInput: file directive-include-guard-two-conditions.tmp, line 1
16Parse_PushInput: file directive-include-guard-two-conditions.tmp, line 1 16Parse_PushInput: file directive-include-guard-two-conditions.tmp, line 1
17Parse_PushInput: file directive-include-guard-already-set.tmp, line 1 17Parse_PushInput: file directive-include-guard-already-set.tmp, line 1
18Parse_PushInput: file directive-include-guard-already-set.tmp, line 1 18Parse_PushInput: file directive-include-guard-already-set.tmp, line 1
19Parse_PushInput: file directive-include-guard-twice.tmp, line 1 19Parse_PushInput: file directive-include-guard-twice.tmp, line 1
20Parse_PushInput: file directive-include-guard-twice.tmp, line 1 20Parse_PushInput: file directive-include-guard-twice.tmp, line 1
21Parse_PushInput: file directive-include-guard-reuse.tmp, line 1 21Parse_PushInput: file directive-include-guard-reuse.tmp, line 1
22Parse_PushInput: file directive-include-guard-reuse.tmp, line 1 22Parse_PushInput: file directive-include-guard-reuse.tmp, line 1
23Parse_PushInput: file directive-include-guard-swapped.tmp, line 1 23Parse_PushInput: file directive-include-guard-swapped.tmp, line 1
24Parse_PushInput: file directive-include-guard-swapped.tmp, line 1 24Parse_PushInput: file directive-include-guard-swapped.tmp, line 1
 25Parse_PushInput: file directive-include-guard-undef-between.tmp, line 1
 26Parse_PushInput: file directive-include-guard-undef-between.tmp, line 1
 27Parse_PushInput: file directive-include-guard-undef-inside.tmp, line 1
 28Parse_PushInput: file directive-include-guard-undef-inside.tmp, line 1
 29Parse_PushInput: file directive-include-guard-if-elif.tmp, line 1
 30Parse_PushInput: file directive-include-guard-if-elif.tmp, line 1
 31Parse_PushInput: file directive-include-guard-if-else.tmp, line 1
 32Parse_PushInput: file directive-include-guard-if-else.tmp, line 1
 33Parse_PushInput: file directive-include-guard-inner-if-elif-else.tmp, line 1
 34Parse_PushInput: file directive-include-guard-inner-if-elif-else.tmp, line 1
25exit status 0 35exit status 0

cvs diff -r1.1 -r1.2 src/usr.bin/make/unit-tests/directive-include-guard.mk (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/directive-include-guard.mk 2023/06/16 09:25:13 1.1
+++ src/usr.bin/make/unit-tests/directive-include-guard.mk 2023/06/18 19:16:51 1.2
@@ -1,27 +1,30 @@ @@ -1,27 +1,30 @@
1# $NetBSD: directive-include-guard.mk,v 1.1 2023/06/16 09:25:13 rillig Exp $ 1# $NetBSD: directive-include-guard.mk,v 1.2 2023/06/18 19:16:51 rillig Exp $
2# 2#
3# Tests for multiple-inclusion guards in makefiles. 3# Tests for multiple-inclusion guards in makefiles.
4# 4#
5# A file that is guarded by a multiple-inclusion guard has the following form: 5# A file that is guarded by a multiple-inclusion guard has the following form:
6# 6#
7# .ifndef GUARD_NAME 7# .ifndef GUARD_NAME
8# GUARD_NAME= # any value 8# GUARD_NAME= # any value
9# ... 9# ...
10# .endif 10# .endif
11# 11#
12# When such a file is included for the second time, it has no effect as all 12# When such a file is included for the second time, it has no effect, as all
13# its content is skipped. 13# its content is skipped.
14# 14#
 15# See also:
 16# https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
 17#
15# TODO: In these cases, do not include the file, to increase performance. 18# TODO: In these cases, do not include the file, to increase performance.
16 19
17 20
18# This is the canonical form of a multiple-inclusion guard. 21# This is the canonical form of a multiple-inclusion guard.
19INCS+= guarded-ifndef 22INCS+= guarded-ifndef
20LINES.guarded-ifndef= \ 23LINES.guarded-ifndef= \
21 '.ifndef GUARDED_IFNDEF' \ 24 '.ifndef GUARDED_IFNDEF' \
22 'GUARDED_IFNDEF=' \ 25 'GUARDED_IFNDEF=' \
23 '.endif' 26 '.endif'
24 27
25# Comments and empty lines have no influence on the multiple-inclusion guard. 28# Comments and empty lines have no influence on the multiple-inclusion guard.
26INCS+= comments 29INCS+= comments
27LINES.comments= \ 30LINES.comments= \
@@ -56,39 +59,44 @@ LINES.varname-mismatch= \ @@ -56,39 +59,44 @@ LINES.varname-mismatch= \
56 'OTHER_NAME=' \ 59 'OTHER_NAME=' \
57 '.endif' 60 '.endif'
58 61
59# The variable name in the assignment must only contain alphanumeric 62# The variable name in the assignment must only contain alphanumeric
60# characters and underscores, in particular, it must not be a dynamically 63# characters and underscores, in particular, it must not be a dynamically
61# computed name. 64# computed name.
62INCS+= varname-indirect 65INCS+= varname-indirect
63LINES.varname-indirect= \ 66LINES.varname-indirect= \
64 '.ifndef VARNAME_INDIRECT' \ 67 '.ifndef VARNAME_INDIRECT' \
65 'VARNAME_$${:UINDIRECT}=' \ 68 'VARNAME_$${:UINDIRECT}=' \
66 '.endif' 69 '.endif'
67 70
68# The variable assignment for the guard must directly follow the conditional. 71# The variable assignment for the guard must directly follow the conditional.
 72#
 73# This requirement may be dropped entirely later, as the guard variable could
 74# also be undefined while reading the file or at a later point, and as long as
 75# the implementation checks the guard variable before skipping the file, the
 76# optimization is still valid.
69INCS+= late-assignment 77INCS+= late-assignment
70LINES.late-assignment= \ 78LINES.late-assignment= \
71 '.ifndef LATE_ASSIGNMENT' \ 79 '.ifndef LATE_ASSIGNMENT' \
72 'OTHER=' \ 80 'OTHER=' \
73 'LATE_ASSIGNMENT=' \ 81 'LATE_ASSIGNMENT=' \
74 '.endif' 82 '.endif'
75 83
76# There must be no other condition between the guard condition and the 84# There must be no other condition between the guard condition and the
77# variable assignment. 85# variable assignment.
78INCS+= two-conditions 86INCS+= two-conditions
79LINES.two-conditions= \ 87LINES.two-conditions= \
80 '.ifndef TWO_CONDITIONS' \ 88 '.ifndef TWO_CONDITIONS' \
81 '. if 0' \ 89 '. if 1' \
82 'TWO_CONDITIONS=' \ 90 'TWO_CONDITIONS=' \
83 '. endif' \ 91 '. endif' \
84 '.endif' 92 '.endif'
85 93
86# If the guard variable is already set before the file is included for the 94# If the guard variable is already set before the file is included for the
87# first time, that file is not considered to be guarded. It's a situation 95# first time, that file is not considered to be guarded. It's a situation
88# that is uncommon in practice. 96# that is uncommon in practice.
89INCS+= already-set 97INCS+= already-set
90LINES.already-set= \ 98LINES.already-set= \
91 '.ifndef ALREADY_SET' \ 99 '.ifndef ALREADY_SET' \
92 'ALREADY_SET=' \ 100 'ALREADY_SET=' \
93 '.endif' 101 '.endif'
94ALREADY_SET= 102ALREADY_SET=
@@ -109,32 +117,84 @@ LINES.twice= \ @@ -109,32 +117,84 @@ LINES.twice= \
109# variable names. Typical choices are ${PROJECT}_${DIR}_${FILE}_MK. 117# variable names. Typical choices are ${PROJECT}_${DIR}_${FILE}_MK.
110INCS+= reuse 118INCS+= reuse
111LINES.reuse= \ 119LINES.reuse= \
112 ${LINES.guarded-if} 120 ${LINES.guarded-if}
113 121
114# The conditional must come before the assignment, otherwise the conditional 122# The conditional must come before the assignment, otherwise the conditional
115# is useless, as it always evaluates to false. 123# is useless, as it always evaluates to false.
116INCS+= swapped 124INCS+= swapped
117LINES.swapped= \ 125LINES.swapped= \
118 'SWAPPED=' \ 126 'SWAPPED=' \
119 '.ifndef SWAPPED' \ 127 '.ifndef SWAPPED' \
120 '.endif' 128 '.endif'
121 129
 130# If the guard variable is undefined at some later point, the guarded file is
 131# included again.
 132INCS+= undef-between
 133LINES.undef-between= \
 134 '.ifndef UNDEF_BETWEEN' \
 135 'UNDEF_BETWEEN=' \
 136 '.endif'
 137
 138# If the guarded file undefines the guard variable, the guarded file is
 139# included again.
 140INCS+= undef-inside
 141LINES.undef-inside= \
 142 '.ifndef UNDEF_INSIDE' \
 143 'UNDEF_INSIDE=' \
 144 '.undef UNDEF_INSIDE' \
 145 '.endif'
 146
 147# The outermost '.if' must not have an '.elif' branch.
 148INCS+= if-elif
 149LINES.if-elif = \
 150 '.ifndef IF_ELIF' \
 151 'IF_ELIF=' \
 152 '.elif 1' \
 153 '.endif'
 154
 155# The outermost '.if' must not have an '.else' branch.
 156INCS+= if-else
 157LINES.if-else = \
 158 '.ifndef IF_ELSE' \
 159 'IF_ELSE=' \
 160 '.else' \
 161 '.endif'
 162
 163# The inner '.if' directives may have an '.elif' or '.else'.
 164INCS+= inner-if-elif-else
 165LINES.inner-if-elif-else = \
 166 '.ifndef INNER_IF_ELIF_ELSE' \
 167 'INNER_IF_ELIF_ELSE=' \
 168 '. if 0' \
 169 '. elif 0' \
 170 '. else' \
 171 '. endif' \
 172 '. if 0' \
 173 '. elif 1' \
 174 '. else' \
 175 '. endif' \
 176 '. if 1' \
 177 '. elif 1' \
 178 '. else' \
 179 '. endif' \
 180 '.endif'
122 181
123# Include each of the files twice. The directive-include-guard.exp file 182# Include each of the files twice. The directive-include-guard.exp file
124# contains a single entry for the files whose multiple-inclusion guard works, 183# contains a single entry for the files whose multiple-inclusion guard works,
125# and two entries for the files that are not protected against multiple 184# and two entries for the files that are not protected against multiple
126# inclusion. 185# inclusion.
127# 186#
128# Some debug output lines are suppressed in the .exp file, see ./Makefile. 187# Some debug output lines are suppressed in the .exp file, see ./Makefile.
129.for i in ${INCS} 188.for i in ${INCS}
130. for fname in directive-include-guard-$i.tmp 189. for fname in directive-include-guard-$i.tmp
131_!= printf '%s\n' ${LINES.$i} > ${fname} 190_!= printf '%s\n' ${LINES.$i} > ${fname}
132.MAKEFLAGS: -dp 191.MAKEFLAGS: -dp
133.include "${.CURDIR}/${fname}" 192.include "${.CURDIR}/${fname}"
 193.undef ${i:Mundef-between:%=UNDEF_BETWEEN}
134.include "${.CURDIR}/${fname}" 194.include "${.CURDIR}/${fname}"
135.MAKEFLAGS: -d0 195.MAKEFLAGS: -d0
136_!= rm ${fname} 196_!= rm ${fname}
137. endfor 197. endfor
138.endfor 198.endfor
139 199
140all: 200all: