Module Name:    src
Committed By:   rillig
Date:           Fri Jun 16 09:25:13 UTC 2023

Modified Files:
        src/distrib/sets/lists/tests: mi
        src/usr.bin/make/unit-tests: Makefile
Added Files:
        src/usr.bin/make/unit-tests: directive-include-guard.exp
            directive-include-guard.mk

Log Message:
tests/make: add test for multiple-inclusion guards


To generate a diff of this commit:
cvs rdiff -u -r1.1268 -r1.1269 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.337 -r1.338 src/usr.bin/make/unit-tests/Makefile
cvs rdiff -u -r0 -r1.1 \
    src/usr.bin/make/unit-tests/directive-include-guard.exp \
    src/usr.bin/make/unit-tests/directive-include-guard.mk

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.1268 src/distrib/sets/lists/tests/mi:1.1269
--- src/distrib/sets/lists/tests/mi:1.1268	Fri Jun 16 07:20:45 2023
+++ src/distrib/sets/lists/tests/mi	Fri Jun 16 09:25:13 2023
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1268 2023/06/16 07:20:45 rillig Exp $
+# $NetBSD: mi,v 1.1269 2023/06/16 09:25:13 rillig Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -5779,6 +5779,8 @@
 ./usr/tests/usr.bin/make/unit-tests/directive-ifnmake.mk			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/directive-include-fatal.exp			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/directive-include-fatal.mk			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/directive-include-guard.exp			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/directive-include-guard.mk			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/directive-include.exp			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/directive-include.mk			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/make/unit-tests/directive-info.exp				tests-usr.bin-tests	compattestfile,atf

Index: src/usr.bin/make/unit-tests/Makefile
diff -u src/usr.bin/make/unit-tests/Makefile:1.337 src/usr.bin/make/unit-tests/Makefile:1.338
--- src/usr.bin/make/unit-tests/Makefile:1.337	Fri Jun 16 07:20:45 2023
+++ src/usr.bin/make/unit-tests/Makefile	Fri Jun 16 09:25:13 2023
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.337 2023/06/16 07:20:45 rillig Exp $
+# $NetBSD: Makefile,v 1.338 2023/06/16 09:25:13 rillig Exp $
 #
 # Unit tests for make(1)
 #
@@ -196,6 +196,7 @@ TESTS+=		directive-ifndef
 TESTS+=		directive-ifnmake
 TESTS+=		directive-include
 TESTS+=		directive-include-fatal
+TESTS+=		directive-include-guard
 TESTS+=		directive-info
 TESTS+=		directive-misspellings
 TESTS+=		directive-sinclude
@@ -504,6 +505,11 @@ FLAGS.varname-empty=		-dv '$${:U}=cmdlin
 # Some tests need extra postprocessing.
 SED_CMDS.deptgt-phony=	${STD_SED_CMDS.dd}
 SED_CMDS.dir=		${STD_SED_CMDS.dd}
+SED_CMDS.directive-include-guard= \
+	-e '/\.MAKEFLAGS/d' \
+	-e '/^Parsing line/d' \
+	-e '/^SetFilenameVars:/d' \
+	-e '/^ParseEOF:/d'
 SED_CMDS.export=	-e '/^[^=_A-Za-z0-9]*=/d'
 SED_CMDS.export-all=	${SED_CMDS.export}
 SED_CMDS.export-env=	${SED_CMDS.export}

Added files:

Index: src/usr.bin/make/unit-tests/directive-include-guard.exp
diff -u /dev/null src/usr.bin/make/unit-tests/directive-include-guard.exp:1.1
--- /dev/null	Fri Jun 16 09:25:13 2023
+++ src/usr.bin/make/unit-tests/directive-include-guard.exp	Fri Jun 16 09:25:13 2023
@@ -0,0 +1,25 @@
+Parse_PushInput: file directive-include-guard-guarded-ifndef.tmp, line 1
+Parse_PushInput: file directive-include-guard-guarded-ifndef.tmp, line 1
+Parse_PushInput: file directive-include-guard-comments.tmp, line 1
+Parse_PushInput: file directive-include-guard-comments.tmp, line 1
+Parse_PushInput: file directive-include-guard-guarded-if.tmp, line 1
+Parse_PushInput: file directive-include-guard-guarded-if.tmp, line 1
+Parse_PushInput: file directive-include-guard-triple-negation.tmp, line 1
+Parse_PushInput: file directive-include-guard-triple-negation.tmp, line 1
+Parse_PushInput: file directive-include-guard-varname-mismatch.tmp, line 1
+Parse_PushInput: file directive-include-guard-varname-mismatch.tmp, line 1
+Parse_PushInput: file directive-include-guard-varname-indirect.tmp, line 1
+Parse_PushInput: file directive-include-guard-varname-indirect.tmp, line 1
+Parse_PushInput: file directive-include-guard-late-assignment.tmp, line 1
+Parse_PushInput: file directive-include-guard-late-assignment.tmp, line 1
+Parse_PushInput: file directive-include-guard-two-conditions.tmp, line 1
+Parse_PushInput: file directive-include-guard-two-conditions.tmp, line 1
+Parse_PushInput: file directive-include-guard-already-set.tmp, line 1
+Parse_PushInput: file directive-include-guard-already-set.tmp, line 1
+Parse_PushInput: file directive-include-guard-twice.tmp, line 1
+Parse_PushInput: file directive-include-guard-twice.tmp, line 1
+Parse_PushInput: file directive-include-guard-reuse.tmp, line 1
+Parse_PushInput: file directive-include-guard-reuse.tmp, line 1
+Parse_PushInput: file directive-include-guard-swapped.tmp, line 1
+Parse_PushInput: file directive-include-guard-swapped.tmp, line 1
+exit status 0
Index: src/usr.bin/make/unit-tests/directive-include-guard.mk
diff -u /dev/null src/usr.bin/make/unit-tests/directive-include-guard.mk:1.1
--- /dev/null	Fri Jun 16 09:25:13 2023
+++ src/usr.bin/make/unit-tests/directive-include-guard.mk	Fri Jun 16 09:25:13 2023
@@ -0,0 +1,140 @@
+# $NetBSD: directive-include-guard.mk,v 1.1 2023/06/16 09:25:13 rillig Exp $
+#
+# Tests for multiple-inclusion guards in makefiles.
+#
+# A file that is guarded by a multiple-inclusion guard has the following form:
+#
+#	.ifndef GUARD_NAME
+#	GUARD_NAME=	# any value
+#	...
+#	.endif
+#
+# When such a file is included for the second time, it has no effect as all
+# its content is skipped.
+#
+# TODO: In these cases, do not include the file, to increase performance.
+
+
+# This is the canonical form of a multiple-inclusion guard.
+INCS+=	guarded-ifndef
+LINES.guarded-ifndef= \
+	'.ifndef GUARDED_IFNDEF' \
+	'GUARDED_IFNDEF=' \
+	'.endif'
+
+# Comments and empty lines have no influence on the multiple-inclusion guard.
+INCS+=	comments
+LINES.comments= \
+	'\# comment' \
+	'' \
+	'.ifndef GUARD' \
+	'\# comment' \
+	'GUARD=\#comment' \
+	'.endif' \
+	'\# comment'
+
+# 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=' \
+	'.endif'
+
+# Triple negation is so uncommon that it's not recognized.
+INCS+=	triple-negation
+LINES.triple-negation= \
+	'.if !!!defined(TRIPLE_NEGATION)' \
+	'TRIPLE_NEGATION=' \
+	'.endif'
+
+# The variable names in the '.if' and the assignment must be the same.
+INCS+=	varname-mismatch
+LINES.varname-mismatch= \
+	'.ifndef VARNAME_MISMATCH' \
+	'OTHER_NAME=' \
+	'.endif'
+
+# The variable name in the assignment must only contain alphanumeric
+# characters and underscores, in particular, it must not be a dynamically
+# computed name.
+INCS+=	varname-indirect
+LINES.varname-indirect= \
+	'.ifndef VARNAME_INDIRECT' \
+	'VARNAME_$${:UINDIRECT}=' \
+	'.endif'
+
+# The variable assignment for the guard must directly follow the conditional.
+INCS+=	late-assignment
+LINES.late-assignment= \
+	'.ifndef LATE_ASSIGNMENT' \
+	'OTHER=' \
+	'LATE_ASSIGNMENT=' \
+	'.endif'
+
+# There must be no other condition between the guard condition and the
+# variable assignment.
+INCS+=	two-conditions
+LINES.two-conditions= \
+	'.ifndef TWO_CONDITIONS' \
+	'.  if 0' \
+	'TWO_CONDITIONS=' \
+	'.  endif' \
+	'.endif'
+
+# If the guard variable is already set before the file is included for the
+# first time, that file is not considered to be guarded.  It's a situation
+# that is uncommon in practice.
+INCS+=	already-set
+LINES.already-set= \
+	'.ifndef ALREADY_SET' \
+	'ALREADY_SET=' \
+	'.endif'
+ALREADY_SET=
+
+# The whole file content must be guarded by a single '.if' conditional, not by
+# several, even if they have the same effect.
+INCS+=	twice
+LINES.twice= \
+	'.ifndef TWICE' \
+	'TWICE=' \
+	'.endif' \
+	'.ifndef TWICE' \
+	'TWICE=' \
+	'.endif'
+
+# When multiple files use the same guard variable name, they exclude each
+# other.  It's the responsibility of the makefile authors to choose suitable
+# variable names.  Typical choices are ${PROJECT}_${DIR}_${FILE}_MK.
+INCS+=	reuse
+LINES.reuse= \
+	${LINES.guarded-if}
+
+# The conditional must come before the assignment, otherwise the conditional
+# is useless, as it always evaluates to false.
+INCS+=	swapped
+LINES.swapped= \
+	'SWAPPED=' \
+	'.ifndef SWAPPED' \
+	'.endif'
+
+
+# Include each of the files twice.  The directive-include-guard.exp file
+# contains a single entry for the files whose multiple-inclusion guard works,
+# and two entries for the files that are not protected against multiple
+# inclusion.
+#
+# Some debug output lines are suppressed in the .exp file, see ./Makefile.
+.for i in ${INCS}
+.  for fname in directive-include-guard-$i.tmp
+_!=	printf '%s\n' ${LINES.$i} > ${fname}
+.MAKEFLAGS: -dp
+.include "${.CURDIR}/${fname}"
+.include "${.CURDIR}/${fname}"
+.MAKEFLAGS: -d0
+_!=	rm ${fname}
+.  endfor
+.endfor
+
+all:

Reply via email to