Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make/unit-tests tests/make: clean up and extend test...



details:   https://anonhg.NetBSD.org/src/rev/ba30720a364d
branches:  trunk
changeset: 376504:ba30720a364d
user:      rillig <rillig%NetBSD.org@localhost>
date:      Wed Jun 21 12:16:31 2023 +0000

description:
tests/make: clean up and extend tests for multiple-inclusion guards

Multiple-inclusion guards can be defined either as variables or as
targets.  Rename the variable tests so they include the word 'variable'.

Add tests to cover special characters in guard names (both variable and
target), just in case ParseVarnameGuard gets removed someday.

Document the pitfalls associated with choosing a naming scheme for
guards that leads to name clashes, such as with .PARSEFILE without
.PARSEDIR.

diffstat:

 usr.bin/make/unit-tests/directive-include-guard.exp |   93 ++-
 usr.bin/make/unit-tests/directive-include-guard.mk  |  477 +++++++++++++------
 2 files changed, 375 insertions(+), 195 deletions(-)

diffs (truncated from 755 to 300 lines):

diff -r 7f75396cc1f1 -r ba30720a364d usr.bin/make/unit-tests/directive-include-guard.exp
--- a/usr.bin/make/unit-tests/directive-include-guard.exp       Wed Jun 21 07:30:50 2023 +0000
+++ b/usr.bin/make/unit-tests/directive-include-guard.exp       Wed Jun 21 12:16:31 2023 +0000
@@ -1,41 +1,50 @@
-Parse_PushInput: file guarded-ifndef.tmp, line 1
-Skipping 'guarded-ifndef.tmp' because 'GUARDED_IFNDEF' is defined
+Parse_PushInput: file variable-ifndef.tmp, line 1
+Skipping 'variable-ifndef.tmp' because 'VARIABLE_IFNDEF' is defined
 Parse_PushInput: file comments.tmp, line 1
 Skipping 'comments.tmp' because 'COMMENTS' is defined
-Parse_PushInput: file guarded-if.tmp, line 1
-Skipping 'guarded-if.tmp' because 'GUARDED_IF' is defined
-Parse_PushInput: file triple-negation.tmp, line 1
-Parse_PushInput: file triple-negation.tmp, line 1
-Parse_PushInput: file ifdef-negated.tmp, line 1
-Parse_PushInput: file ifdef-negated.tmp, line 1
-Parse_PushInput: file varname-mismatch.tmp, line 1
-Parse_PushInput: file varname-mismatch.tmp, line 1
-Parse_PushInput: file ifndef-plus.tmp, line 1
-Parse_PushInput: file ifndef-plus.tmp, line 1
-Parse_PushInput: file if-plus.tmp, line 1
-Parse_PushInput: file if-plus.tmp, line 1
-Parse_PushInput: file ifndef-indirect.tmp, line 1
-Parse_PushInput: file ifndef-indirect.tmp, line 1
-Parse_PushInput: file if-indirect.tmp, line 1
-Parse_PushInput: file if-indirect.tmp, line 1
-Parse_PushInput: file varassign-indirect.tmp, line 1
-Skipping 'varassign-indirect.tmp' because 'VARASSIGN_INDIRECT' is defined
-Parse_PushInput: file late-assignment.tmp, line 1
-Skipping 'late-assignment.tmp' because 'LATE_ASSIGNMENT' is defined
-Parse_PushInput: file two-conditions.tmp, line 1
-Skipping 'two-conditions.tmp' because 'TWO_CONDITIONS' is defined
-Parse_PushInput: file already-set.tmp, line 1
-Parse_PushInput: file already-set.tmp, line 1
-Parse_PushInput: file twice.tmp, line 1
-Parse_PushInput: file twice.tmp, line 1
-Parse_PushInput: file reuse.tmp, line 1
-Parse_PushInput: file reuse.tmp, line 1
-Parse_PushInput: file swapped.tmp, line 1
-Parse_PushInput: file swapped.tmp, line 1
-Parse_PushInput: file undef-between.tmp, line 1
-Parse_PushInput: file undef-between.tmp, line 1
-Parse_PushInput: file undef-inside.tmp, line 1
-Parse_PushInput: file undef-inside.tmp, line 1
+Parse_PushInput: file variable-if.tmp, line 1
+Skipping 'variable-if.tmp' because 'VARIABLE_IF' is defined
+Parse_PushInput: file variable-if-triple-negation.tmp, line 1
+Parse_PushInput: file variable-if-triple-negation.tmp, line 1
+Parse_PushInput: file variable-ifdef-negated.tmp, line 1
+Parse_PushInput: file variable-ifdef-negated.tmp, line 1
+Parse_PushInput: file variable-name-mismatch.tmp, line 1
+Parse_PushInput: file variable-name-mismatch.tmp, line 1
+Parse_PushInput: file variable-name-exclamation.tmp, line 1
+Parse_PushInput: file variable-name-exclamation.tmp, line 1
+Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
+Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
+Parse_PushInput: file variable-name-parentheses.tmp, line 1
+Parse_PushInput: file variable-name-parentheses.tmp, line 1
+Parse_PushInput: file variable-ifndef-plus.tmp, line 1
+Parse_PushInput: file variable-ifndef-plus.tmp, line 1
+Parse_PushInput: file variable-if-plus.tmp, line 1
+Parse_PushInput: file variable-if-plus.tmp, line 1
+Parse_PushInput: file variable-ifndef-indirect.tmp, line 1
+Parse_PushInput: file variable-ifndef-indirect.tmp, line 1
+Parse_PushInput: file variable-if-indirect.tmp, line 1
+Parse_PushInput: file variable-if-indirect.tmp, line 1
+Parse_PushInput: file variable-assign-indirect.tmp, line 1
+Skipping 'variable-assign-indirect.tmp' because 'VARIABLE_ASSIGN_INDIRECT' is defined
+Parse_PushInput: file variable-assign-late.tmp, line 1
+Skipping 'variable-assign-late.tmp' because 'VARIABLE_ASSIGN_LATE' is defined
+Parse_PushInput: file variable-assign-nested.tmp, line 1
+Parse_PushInput: .for loop in variable-assign-nested.tmp, line 3
+Skipping 'variable-assign-nested.tmp' because 'VARIABLE_ASSIGN_NESTED' is defined
+Parse_PushInput: file variable-already-defined.tmp, line 1
+Parse_PushInput: file variable-already-defined.tmp, line 1
+Parse_PushInput: file variable-two-times.tmp, line 1
+Parse_PushInput: file variable-two-times.tmp, line 1
+Parse_PushInput: file variable-clash.tmp, line 1
+Parse_PushInput: file variable-clash.tmp, line 1
+Parse_PushInput: file variable-swapped.tmp, line 1
+Parse_PushInput: file variable-swapped.tmp, line 1
+Parse_PushInput: file variable-undef-between.tmp, line 1
+Parse_PushInput: file variable-undef-between.tmp, line 1
+Parse_PushInput: file variable-undef-inside.tmp, line 1
+Parse_PushInput: file variable-undef-inside.tmp, line 1
+Parse_PushInput: file variable-not-defined.tmp, line 1
+Parse_PushInput: file variable-not-defined.tmp, line 1
 Parse_PushInput: file if-elif.tmp, line 1
 Parse_PushInput: file if-elif.tmp, line 1
 Parse_PushInput: file if-else.tmp, line 1
@@ -52,12 +61,24 @@ Parse_PushInput: file target-indirect-PA
 Skipping 'target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
 Parse_PushInput: file target-indirect-PARSEFILE2.tmp, line 1
 Skipping 'target-indirect-PARSEFILE2.tmp' because '__target-indirect-PARSEFILE2.tmp__' is defined
+Parse_PushInput: file subdir/target-indirect-PARSEFILE.tmp, line 1
+Parse_PushInput: file subdir/target-indirect-PARSEFILE.tmp, line 1
 Parse_PushInput: file target-indirect-PARSEFILE-tA.tmp, line 1
 Skipping 'target-indirect-PARSEFILE-tA.tmp' because '__target-indirect-PARSEFILE-tA.tmp__' is defined
+Parse_PushInput: file subdir/target-indirect-PARSEFILE-tA.tmp, line 1
+Skipping 'subdir/target-indirect-PARSEFILE-tA.tmp' because '__target-indirect-PARSEFILE-tA.tmp__' is defined
+Parse_PushInput: file subdir2/target-indirect-PARSEFILE-tA.tmp, line 1
+Parse_PushInput: file subdir2/target-indirect-PARSEFILE-tA.tmp, line 1
+Parse_PushInput: file target-indirect-PARSEDIR-PARSEFILE.tmp, line 1
+Skipping 'target-indirect-PARSEDIR-PARSEFILE.tmp' because '__target-indirect-PARSEDIR-PARSEFILE.tmp__' is defined
+Parse_PushInput: file subdir/target-indirect-PARSEDIR-PARSEFILE.tmp, line 1
+Skipping 'subdir/target-indirect-PARSEDIR-PARSEFILE.tmp' because '__subdir/target-indirect-PARSEDIR-PARSEFILE.tmp__' is defined
 Parse_PushInput: file target-unguarded.tmp, line 1
 Parse_PushInput: file target-unguarded.tmp, line 1
 Parse_PushInput: file target-plus.tmp, line 1
 Parse_PushInput: file target-plus.tmp, line 1
 Parse_PushInput: file target-already-set.tmp, line 1
 Parse_PushInput: file target-already-set.tmp, line 1
+Parse_PushInput: file target-name-exclamation.tmp, line 1
+Parse_PushInput: file target-name-exclamation.tmp, line 1
 exit status 0
diff -r 7f75396cc1f1 -r ba30720a364d usr.bin/make/unit-tests/directive-include-guard.mk
--- a/usr.bin/make/unit-tests/directive-include-guard.mk        Wed Jun 21 07:30:50 2023 +0000
+++ b/usr.bin/make/unit-tests/directive-include-guard.mk        Wed Jun 21 12:16:31 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: directive-include-guard.mk,v 1.8 2023/06/21 04:20:21 sjg Exp $
+# $NetBSD: directive-include-guard.mk,v 1.9 2023/06/21 12:16:31 rillig Exp $
 #
 # Tests for multiple-inclusion guards in makefiles.
 #
@@ -21,17 +21,21 @@
 # See also:
 #      https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
 
+# Each of the following test cases creates a temporary file named after the
+# test case and writes some lines of text to that file.  That file is then
+# included twice, to see whether the second '.include' is skipped.
 
-# This is the canonical form of a multiple-inclusion guard.
-INCS+= guarded-ifndef
-LINES.guarded-ifndef= \
-       '.ifndef GUARDED_IFNDEF' \
-       'GUARDED_IFNDEF=' \
+
+# This is the canonical form of a variable-based multiple-inclusion guard.
+INCS+= variable-ifndef
+LINES.variable-ifndef= \
+       '.ifndef VARIABLE_IFNDEF' \
+       'VARIABLE_IFNDEF=' \
        '.endif'
-# expect: Parse_PushInput: file guarded-ifndef.tmp, line 1
-# expect: Skipping 'guarded-ifndef.tmp' because 'GUARDED_IFNDEF' is defined
+# expect: Parse_PushInput: file variable-ifndef.tmp, line 1
+# expect: Skipping 'variable-ifndef.tmp' because 'VARIABLE_IFNDEF' is defined
 
-# Comments and empty lines have no influence on the multiple-inclusion guard.
+# Comments and empty lines do not affect the multiple-inclusion guard.
 INCS+= comments
 LINES.comments= \
        '\# comment' \
@@ -45,183 +49,240 @@ LINES.comments= \
 # expect: Skipping 'comments.tmp' because 'COMMENTS' is defined
 
 # An alternative form uses the 'defined' function.  It is more verbose than
-# the canonical form.  There are other possible forms as well, such as with a
-# triple negation, but these are not recognized as they are not common.
-INCS+= guarded-if
-LINES.guarded-if= \
-       '.if !defined(GUARDED_IF)' \
-       'GUARDED_IF=' \
+# the canonical form but avoids the '.ifndef' directive, as that directive is
+# not commonly used.
+INCS+= variable-if
+LINES.variable-if= \
+       '.if !defined(VARIABLE_IF)' \
+       'VARIABLE_IF=' \
        '.endif'
-# expect: Parse_PushInput: file guarded-if.tmp, line 1
-# expect: Skipping 'guarded-if.tmp' because 'GUARDED_IF' is defined
+# expect: Parse_PushInput: file variable-if.tmp, line 1
+# expect: Skipping 'variable-if.tmp' because 'VARIABLE_IF' is defined
 
-# Triple negation is so uncommon that it's not recognized.
-INCS+= triple-negation
-LINES.triple-negation= \
-       '.if !!!defined(TRIPLE_NEGATION)' \
-       'TRIPLE_NEGATION=' \
+# Triple negation is so uncommon that it's not recognized, even though it has
+# the same effect as a single negation.
+INCS+= variable-if-triple-negation
+LINES.variable-if-triple-negation= \
+       '.if !!!defined(VARIABLE_IF_TRIPLE_NEGATION)' \
+       'VARIABLE_IF_TRIPLE_NEGATION=' \
        '.endif'
-# expect: Parse_PushInput: file triple-negation.tmp, line 1
-# expect: Parse_PushInput: file triple-negation.tmp, line 1
+# expect: Parse_PushInput: file variable-if-triple-negation.tmp, line 1
+# expect: Parse_PushInput: file variable-if-triple-negation.tmp, line 1
 
-# A conditional other than '.if' or '.ifndef' marks the file as non-guarded,
-# even if it would actually work as a multiple-inclusion guard.
-INCS+= ifdef-negated
-LINES.ifdef-negated= \
-       '.ifdef !IFDEF_NEGATED' \
-       'IFDEF_NEGATED=' \
+# A conditional other than '.if' or '.ifndef' does not guard the file, even if
+# it is otherwise equivalent to the above accepted forms.
+INCS+= variable-ifdef-negated
+LINES.variable-ifdef-negated= \
+       '.ifdef !VARIABLE_IFDEF_NEGATED' \
+       'VARIABLE_IFDEF_NEGATED=' \
        '.endif'
-# expect: Parse_PushInput: file ifdef-negated.tmp, line 1
-# expect: Parse_PushInput: file ifdef-negated.tmp, line 1
+# expect: Parse_PushInput: file variable-ifdef-negated.tmp, line 1
+# expect: Parse_PushInput: file variable-ifdef-negated.tmp, line 1
 
 # The variable names in the '.if' and the assignment must be the same.
-INCS+= varname-mismatch
-LINES.varname-mismatch= \
-       '.ifndef VARNAME_MISMATCH' \
-       'OTHER_NAME=' \
+INCS+= variable-name-mismatch
+LINES.variable-name-mismatch= \
+       '.ifndef VARIABLE_NAME_MISMATCH' \
+       'VARIABLE_NAME_DIFFERENT=' \
+       '.endif'
+# expect: Parse_PushInput: file variable-name-mismatch.tmp, line 1
+# expect: Parse_PushInput: file variable-name-mismatch.tmp, line 1
+
+# The variable name '!VARNAME' cannot be used in an '.ifndef' directive, as
+# the '!' would be a negation.  It is syntactically valid in a '.if !defined'
+# condition, but ignored there.  Furthermore, when defining the variable, the
+# character '!' has to be escaped, to prevent it from being interpreted as the
+# '!' dependency operator.
+INCS+= variable-name-exclamation
+LINES.variable-name-exclamation= \
+       '.if !defined(!VARIABLE_NAME_EXCLAMATION)' \
+       '${:U!}VARIABLE_NAME_EXCLAMATION=' \
        '.endif'
-# expect: Parse_PushInput: file varname-mismatch.tmp, line 1
-# expect: Parse_PushInput: file varname-mismatch.tmp, line 1
+# expect: Parse_PushInput: file variable-name-exclamation.tmp, line 1
+# expect: Parse_PushInput: file variable-name-exclamation.tmp, line 1
+
+# A variable name can contain a '!' in the middle, as that character is
+# interpreted as an ordinary character in conditions as well as on the left
+# side of a variable assignment.  For guard variable names, the '!' is not
+# supported in any place, though.
+INCS+= variable-name-exclamation-middle
+LINES.variable-name-exclamation-middle= \
+       '.ifndef VARIABLE_NAME!MIDDLE' \
+       'VARIABLE_NAME!MIDDLE=' \
+       '.endif'
+# expect: Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
+# expect: Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
+
+# A variable name can contain balanced parentheses, at least in conditions and
+# on the left side of a variable assignment.  There are enough places in make
+# where parentheses or braces are handled inconsistently to make this naming
+# choice a bad idea, therefore these characters are not allowed in guard
+# variable names.
+INCS+= variable-name-parentheses
+LINES.variable-name-parentheses= \
+       '.ifndef VARIABLE_NAME(&)PARENTHESES' \
+       'VARIABLE_NAME(&)PARENTHESES=' \
+       '.endif'
+# expect: Parse_PushInput: file variable-name-parentheses.tmp, line 1
+# expect: Parse_PushInput: file variable-name-parentheses.tmp, line 1
 
 # The guard condition must consist of only the guard variable, nothing else.
-INCS+= ifndef-plus
-LINES.ifndef-plus= \
-       '.ifndef IFNDEF_PLUS && IFNDEF_SECOND' \
-       'IFNDEF_PLUS=' \
-       'IFNDEF_SECOND=' \
+INCS+= variable-ifndef-plus
+LINES.variable-ifndef-plus= \
+       '.ifndef VARIABLE_IFNDEF_PLUS && VARIABLE_IFNDEF_SECOND' \
+       'VARIABLE_IFNDEF_PLUS=' \
+       'VARIABLE_IFNDEF_SECOND=' \
        '.endif'
-# expect: Parse_PushInput: file ifndef-plus.tmp, line 1
-# expect: Parse_PushInput: file ifndef-plus.tmp, line 1
+# expect: Parse_PushInput: file variable-ifndef-plus.tmp, line 1
+# expect: Parse_PushInput: file variable-ifndef-plus.tmp, line 1
 
 # The guard condition must consist of only the guard variable, nothing else.
-INCS+= if-plus
-LINES.if-plus= \
-       '.if !defined(IF_PLUS) && !defined(IF_SECOND)' \
-       'IF_PLUS=' \
-       'IF_SECOND=' \
+INCS+= variable-if-plus
+LINES.variable-if-plus= \
+       '.if !defined(VARIABLE_IF_PLUS) && !defined(VARIABLE_IF_SECOND)' \
+       'VARIABLE_IF_PLUS=' \
+       'VARIABLE_IF_SECOND=' \
        '.endif'
-# expect: Parse_PushInput: file if-plus.tmp, line 1
-# expect: Parse_PushInput: file if-plus.tmp, line 1
+# expect: Parse_PushInput: file variable-if-plus.tmp, line 1
+# expect: Parse_PushInput: file variable-if-plus.tmp, line 1
 
 # The variable name in an '.ifndef' guard must be given directly, it must not
 # contain any '$' expression.



Home | Main Index | Thread Index | Old Index