diff options
Diffstat (limited to 'devel/bmake/files/unit-tests')
34 files changed, 756 insertions, 30 deletions
diff --git a/devel/bmake/files/unit-tests/Makefile b/devel/bmake/files/unit-tests/Makefile new file mode 100644 index 00000000000..4c91e6697c8 --- /dev/null +++ b/devel/bmake/files/unit-tests/Makefile @@ -0,0 +1,155 @@ +# $Id: Makefile,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ +# +# $NetBSD: Makefile,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ +# +# Unit tests for make(1) +# The main targets are: +# +# all: run all the tests +# test: run 'all', and compare to expected results +# accept: move generated output to expected results +# +# Adding a test case. +# Each feature should get its own set of tests in its own suitably +# named makefile (*.mk), with its own set of expected results (*.exp), +# and it should be added to the TESTNAMES list. +# + +.MAIN: all + +.-include "Makefile.config" + +UNIT_TESTS:= ${.PARSEDIR} +.PATH: ${UNIT_TESTS} + +# Each test is in a sub-makefile. +# Keep the list sorted. +TESTNAMES= \ + comment \ + cond-late \ + cond1 \ + cond2 \ + dollar \ + doterror \ + dotwait \ + error \ + export \ + export-all \ + export-env \ + forloop \ + forsubst \ + hash \ + include-main \ + misc \ + moderrs \ + modmatch \ + modmisc \ + modorder \ + modts \ + modword \ + order \ + posix \ + qequals \ + sunshcmd \ + sysv \ + ternary \ + unexport \ + unexport-env \ + varcmd \ + varmisc \ + varmod-edge \ + varquote \ + varshell + +# these tests were broken by referting POSIX chanegs +STRICT_POSIX_TESTS = \ + escape \ + impsrc \ + phony-end \ + posix1 \ + suffixes + +# Override make flags for certain tests +flags.doterror= +flags.order=-j1 + +OUTFILES= ${TESTNAMES:S/$/.out/} + +all: ${OUTFILES} + +CLEANFILES += *.rawout *.out *.status *.tmp *.core *.tmp +CLEANFILES += obj*.[och] lib*.a # posix1.mk +CLEANFILES += issue* .[ab]* # suffixes.mk +CLEANRECURSIVE += dir dummy # posix1.mk + +clean: + rm -f ${CLEANFILES} +.if !empty(CLEANRECURSIVE) + rm -rf ${CLEANRECURSIVE} +.endif + +TEST_MAKE?= ${.MAKE} +TOOL_SED?= sed +TOOL_TR?= tr +TOOL_DIFF?= diff + +.if defined(.PARSEDIR) +# ensure consistent results from sort(1) +LC_ALL= C +LANG= C +.export LANG LC_ALL +.endif + +# some tests need extra post-processing +SED_CMDS.varshell = -e 's,^[a-z]*sh: ,,' \ + -e '/command/s,No such.*,not found,' + +# the tests are actually done with sub-makes. +.SUFFIXES: .mk .rawout .out +.mk.rawout: + @echo ${TEST_MAKE} ${flags.${.TARGET:R}:U-k} -f ${.IMPSRC} + -@cd ${.OBJDIR} && \ + { ${TEST_MAKE} ${flags.${.TARGET:R}:U-k} -f ${.IMPSRC} \ + 2>&1 ; echo $$? >${.TARGET:R}.status ; } > ${.TARGET}.tmp + @mv ${.TARGET}.tmp ${.TARGET} + +# We always pretend .MAKE was called 'make' +# and strip ${.CURDIR}/ from the output +# and replace anything after 'stopped in' with unit-tests +# so the results can be compared. +.rawout.out: + @echo postprocess ${.TARGET} + @${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}[][0-9]*:,make:,' \ + -e 's,${TEST_MAKE:C/\./\\\./g},make,' \ + -e '/stopped/s, /.*, unit-tests,' \ + -e 's,${.CURDIR:C/\./\\\./g}/,,g' \ + -e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' ${SED_CMDS.${.TARGET:T:R}} \ + < ${.IMPSRC} > ${.TARGET}.tmp + @echo "exit status `cat ${.TARGET:R}.status`" >> ${.TARGET}.tmp + @mv ${.TARGET}.tmp ${.TARGET} + +# Compare all output files +test: ${OUTFILES} .PHONY + @failed= ; \ + for test in ${TESTNAMES}; do \ + ${TOOL_DIFF} ${DIFF_FLAGS} ${UNIT_TESTS}/$${test}.exp $${test}.out \ + || failed="$${failed}$${failed:+ }$${test}" ; \ + done ; \ + if [ -n "$${failed}" ]; then \ + echo "Failed tests: $${failed}" ; false ; \ + else \ + echo "All tests passed" ; \ + fi + +accept: + @for test in ${TESTNAMES}; do \ + cmp -s ${UNIT_TESTS}/$${test}.exp $${test}.out \ + || { echo "Replacing $${test}.exp" ; \ + cp $${test}.out ${UNIT_TESTS}/$${test}.exp ; } \ + done + +.if exists(${TEST_MAKE}) +${TESTNAMES:S/$/.rawout/}: ${TEST_MAKE} +.endif + +.-include <obj.mk> diff --git a/devel/bmake/files/unit-tests/Makefile.config.in b/devel/bmake/files/unit-tests/Makefile.config.in new file mode 100644 index 00000000000..0993ab0a224 --- /dev/null +++ b/devel/bmake/files/unit-tests/Makefile.config.in @@ -0,0 +1,4 @@ +# $Id: Makefile.config.in,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ + +srcdir= @srcdir@ +DIFF_FLAGS?= @diff_u@ diff --git a/devel/bmake/files/unit-tests/cond-late.exp b/devel/bmake/files/unit-tests/cond-late.exp new file mode 100644 index 00000000000..3717b088c64 --- /dev/null +++ b/devel/bmake/files/unit-tests/cond-late.exp @@ -0,0 +1,3 @@ +yes +no +exit status 0 diff --git a/devel/bmake/files/unit-tests/cond-late.mk b/devel/bmake/files/unit-tests/cond-late.mk new file mode 100644 index 00000000000..efc6f829133 --- /dev/null +++ b/devel/bmake/files/unit-tests/cond-late.mk @@ -0,0 +1,23 @@ +# $NetBSD: cond-late.mk,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ +# +# Using the :? modifier, variable expressions can contain conditional +# expressions that are evaluated late. Any variables appearing in these +# conditions are expanded before parsing the condition. This is +# different from many other places. +# +# Because of this, variables that are used in these lazy conditions +# should not contain double-quotes, or the parser will probably fail. +# +# They should also not contain operators like == or <, since these are +# actually interpreted as these operators. This is demonstrated below. +# +# If the order of evaluation were to change to first parse the condition +# and then expand the variables, the output would change from the +# current "yes no" to "yes yes", since both variables are non-empty. + +COND.true= "yes" == "yes" +COND.false= "yes" != "yes" + +all: + @echo ${ ${COND.true} :?yes:no} + @echo ${ ${COND.false} :?yes:no} diff --git a/devel/bmake/files/unit-tests/cond2.mk b/devel/bmake/files/unit-tests/cond2.mk index e396fc308e7..1d6125af4a0 100644 --- a/devel/bmake/files/unit-tests/cond2.mk +++ b/devel/bmake/files/unit-tests/cond2.mk @@ -1,4 +1,4 @@ -# $Id: cond2.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $ +# $Id: cond2.mk,v 1.1.1.2 2020/05/24 05:35:53 nia Exp $ TEST_UNAME_S= NetBSD @@ -21,5 +21,9 @@ Y!= echo TEST_NOT_SET is empty or not defined >&2; echo Y= oops .endif +.if defined(.NDEF) && ${.NDEF} > 0 +Z= yes +.endif + all: @echo $@ diff --git a/devel/bmake/files/unit-tests/dollar.exp b/devel/bmake/files/unit-tests/dollar.exp new file mode 100644 index 00000000000..496adc02f15 --- /dev/null +++ b/devel/bmake/files/unit-tests/dollar.exp @@ -0,0 +1,51 @@ + +Printing dollar from literals and variables + +To survive the parser, a dollar character must be doubled. + 1 dollar literal => <single-quote-var-value> + 1 dollar literal eol => <> + 2 dollar literal => <$> + 4 dollar literal => <$$> +Some hungry part of make eats all the dollars after a :U modifier. + 1 dollar default => <> + 2 dollar default => <> + 4 dollar default => <> +This works as expected. + 1 dollar variable => <> + 2 dollar variable => <$> + 4 dollar variable => <$$> +Some hungry part of make eats all the dollars after a :U modifier. + 1 dollar var-default => <> + 2 dollar var-default => <$> + 4 dollar var-default => <$$> + +Dollar in :S pattern + + S,$,word, => <$XYword> + S,$X,word, => <$XY> + S,$$X,word, => <$XY> + S,$$$X,word, => <$XY> + S,$X,replaced, => <replaced> + S,$$X,replaced, => <replaced> + S,$$$X,replaced, => <replaced> + +Dollar in :C character class + +The A is replaced because the $$ is reduced to a single $, +which is then resolved to the variable X with the value VAR_X. +The effective character class becomes [VAR_XY]. + C,[$$XY],<&>,g => <$<A><X><Y>> + +Dollar in :C pattern + +For some reason, multiple dollars are folded into one. + C,$,dollar,g => <> + C,$$,dollar,g => <> + +Dollar in :S replacement + +For some reason, multiple dollars are folded into one. + S,word,a$Xo, => <aVAR_Xo> + S,word,a$$Xo, => <aVAR_Xo> + S,word,a$$$Xo, => <aVAR_Xo> +exit status 0 diff --git a/devel/bmake/files/unit-tests/dollar.mk b/devel/bmake/files/unit-tests/dollar.mk new file mode 100644 index 00000000000..faa8e622802 --- /dev/null +++ b/devel/bmake/files/unit-tests/dollar.mk @@ -0,0 +1,81 @@ +# $NetBSD: dollar.mk,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ +# +# Test the various places where a dollar character can appear and +# see what happens. There are lots of surprises here. +# + +LIST= plain 'single' "double" 'mix'"ed" back\ slashed +WORD= word + +DOLLAR1= $ +DOLLAR2= $$ +DOLLAR4= $$$$ + +X= VAR_X +DOLLAR_XY= $$XY +DOLLAR_AXY= $$AXY + +H= @header() { printf '\n%s\n\n' "$$*"; }; header +T= @testcase() { printf '%23s => <%s>\n' "$$@"; }; testcase +C= @comment() { printf '%s\n' "$$*"; }; comment + +# These variable values are not accessed. +# The trailing dollar in the '1 dollar literal eol' test case accesses +# the empty variable instead, which is always guaranteed to be empty. +${:U }= space-var-value +${:U${.newline}}= newline-var-value +# But this one is accessed. +${:U'}= single-quote-var-value' + +all: + $H 'Printing dollar from literals and variables' + + $C 'To survive the parser, a dollar character must be doubled.' + $T '1 dollar literal' '$' + $T '1 dollar literal eol' ''$ + $T '2 dollar literal' '$$' + $T '4 dollar literal' '$$$$' + + $C 'Some hungry part of make eats all the dollars after a :U modifier.' + $T '1 dollar default' ''${:U$:Q} + $T '2 dollar default' ''${:U$$:Q} + $T '4 dollar default' ''${:U$$$$:Q} + + $C 'This works as expected.' + $T '1 dollar variable' ''${DOLLAR1:Q} + $T '2 dollar variable' ''${DOLLAR2:Q} + $T '4 dollar variable' ''${DOLLAR4:Q} + + $C 'Some hungry part of make eats all the dollars after a :U modifier.' + $T '1 dollar var-default' ''${:U${DOLLAR1}:Q} + $T '2 dollar var-default' ''${:U${DOLLAR2}:Q} + $T '4 dollar var-default' ''${:U${DOLLAR4}:Q} + + $H 'Dollar in :S pattern' + + $T 'S,$$,word,' ''${DOLLAR_XY:S,$,word,:Q} + $T 'S,$$X,word,' ''${DOLLAR_XY:S,$X,word,:Q} + $T 'S,$$$$X,word,' ''${DOLLAR_XY:S,$$X,word,:Q} + $T 'S,$$$$$$X,word,' ''${DOLLAR_XY:S,$$$X,word,:Q} + + $T 'S,$$X,replaced,' ''${X:S,$X,replaced,:Q} + $T 'S,$$$$X,replaced,' ''${X:S,$$X,replaced,:Q} + $T 'S,$$$$$$X,replaced,' ''${X:S,$$$X,replaced,:Q} + + $H 'Dollar in :C character class' + + $C 'The A is replaced because the $$$$ is reduced to a single $$,' + $C 'which is then resolved to the variable X with the value VAR_X.' + $C 'The effective character class becomes [VAR_XY].' + $T 'C,[$$$$XY],<&>,g' ''${DOLLAR_AXY:C,[$$XY],<&>,g:Q} + + $H 'Dollar in :C pattern' + $C 'For some reason, multiple dollars are folded into one.' + $T 'C,$$,dollar,g' ''${DOLLAR:C,$,dollar,g:Q} + $T 'C,$$$$,dollar,g' ''${DOLLAR:C,$$,dollar,g:Q} + + $H 'Dollar in :S replacement' + $C 'For some reason, multiple dollars are folded into one.' + $T 'S,word,a$$Xo,' ''${WORD:S,word,a$Xo,:Q} + $T 'S,word,a$$$$Xo,' ''${WORD:S,word,a$$Xo,:Q} + $T 'S,word,a$$$$$$Xo,' ''${WORD:S,word,a$$$Xo,:Q} diff --git a/devel/bmake/files/unit-tests/doterror.exp b/devel/bmake/files/unit-tests/doterror.exp index 0447a519344..5655644c32e 100644 --- a/devel/bmake/files/unit-tests/doterror.exp +++ b/devel/bmake/files/unit-tests/doterror.exp @@ -1,9 +1,9 @@ At first, I am happy and now: sad -.ERROR: Looks like 'sad' is upset. *** Error code 1 Stop. make: stopped in unit-tests +.ERROR: Looks like 'sad' is upset. exit status 1 diff --git a/devel/bmake/files/unit-tests/dotwait.exp b/devel/bmake/files/unit-tests/dotwait.exp index 6bf96e301c1..bdc0a0eb150 100644 --- a/devel/bmake/files/unit-tests/dotwait.exp +++ b/devel/bmake/files/unit-tests/dotwait.exp @@ -22,9 +22,9 @@ shared.2.1 shared.2.1 shared.2.99 shared.2.99 +cycle.1.99 +cycle.1.99 make: Graph cycles through `cycle.2.99' make: Graph cycles through `cycle.2.98' make: Graph cycles through `cycle.2.97' -cycle.1.99 -cycle.1.99 exit status 0 diff --git a/devel/bmake/files/unit-tests/dotwait.mk b/devel/bmake/files/unit-tests/dotwait.mk index b6cde7d31de..463d30625f8 100644 --- a/devel/bmake/files/unit-tests/dotwait.mk +++ b/devel/bmake/files/unit-tests/dotwait.mk @@ -1,4 +1,4 @@ -# $NetBSD: dotwait.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $ +# $NetBSD: dotwait.mk,v 1.1.1.2 2020/05/24 05:35:53 nia Exp $ THISMAKEFILE:= ${.PARSEDIR}/${.PARSEFILE} @@ -11,7 +11,7 @@ PAUSE= sleep 1 # Ignore "--- target ---" lines printed by parallel make. all: .for t in ${TESTS} - @${.MAKE} -f ${THISMAKEFILE} -j4 $t | grep -v "^--- " + @${.MAKE} -f ${THISMAKEFILE} -j4 $t 2>&1 | grep -v "^--- " .endfor # diff --git a/devel/bmake/files/unit-tests/escape.mk b/devel/bmake/files/unit-tests/escape.mk index ede9d9e7254..a48ea29f8be 100644 --- a/devel/bmake/files/unit-tests/escape.mk +++ b/devel/bmake/files/unit-tests/escape.mk @@ -1,4 +1,4 @@ -# $Id: escape.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $ +# $Id: escape.mk,v 1.1.1.2 2020/05/24 05:35:53 nia Exp $ # # Test backslash escaping. @@ -35,8 +35,8 @@ # Also, our practice is that an even number of backslashes before a # newline in a variable assignment simply stores the backslashes as part # of the value, and treats the newline as though it was not escaped. -# Similarly, ann even number of backslashes before a newline in a -# command simply uses the backslashes as part of the command test, but +# Similarly, an even number of backslashes before a newline in a +# command simply uses the backslashes as part of the command, but # does not escape the newline. This is compatible with GNU make. all: .PHONY diff --git a/devel/bmake/files/unit-tests/export-env.exp b/devel/bmake/files/unit-tests/export-env.exp index 6221232a2a1..8a779e6aff0 100644 --- a/devel/bmake/files/unit-tests/export-env.exp +++ b/devel/bmake/files/unit-tests/export-env.exp @@ -2,8 +2,10 @@ make: UT_TEST=export-env.mk UT_ENV=not-exported UT_EXP=not-exported +UT_LIT=literal export-env.mk env: UT_TEST=export-env.mk UT_ENV=exported UT_EXP=exported +UT_LIT=literal ${UT_TEST} exit status 0 diff --git a/devel/bmake/files/unit-tests/export-env.mk b/devel/bmake/files/unit-tests/export-env.mk index 3832e2a2e27..aedcc7b38a3 100644 --- a/devel/bmake/files/unit-tests/export-env.mk +++ b/devel/bmake/files/unit-tests/export-env.mk @@ -1,4 +1,4 @@ -# $Id: export-env.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $ +# $Id: export-env.mk,v 1.1.1.2 2020/05/24 05:35:53 nia Exp $ # our normal .export, subsequent changes affect the environment UT_TEST=this @@ -15,9 +15,12 @@ UT_EXP=before-export export UT_EXP=exported UT_EXP=not-exported +UT_LIT= literal ${UT_TEST} +.export-literal UT_LIT + all: - @echo make:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=${$v};@} - @echo env:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=$${$v};@} + @echo make:; ${UT_TEST UT_ENV UT_EXP UT_LIT:L:@v@echo $v=${$v};@} + @echo env:; ${UT_TEST UT_ENV UT_EXP UT_LIT:L:@v@echo $v=$${$v};@} diff --git a/devel/bmake/files/unit-tests/forloop.exp b/devel/bmake/files/unit-tests/forloop.exp index df14b751224..99845619073 100644 --- a/devel/bmake/files/unit-tests/forloop.exp +++ b/devel/bmake/files/unit-tests/forloop.exp @@ -7,12 +7,13 @@ x=-I"This or that" x=-Ithat x="-DTHIS=\"this and that\"" cfl=-I/this -I"This or that" -Ithat "-DTHIS=\"this and that\"" +newline-item=(a) a=one b="two and three" a=four b="five" a=ONE b="TWO AND THREE" a=FOUR b="FIVE" We expect an error next: -make: "forloop.mk" line 38: Wrong number of words (9) in .for substitution list with 2 vars +make: "forloop.mk" line 46: Wrong number of words (9) in .for substitution list with 2 vars make: Fatal errors encountered -- cannot continue make: stopped in unit-tests OK diff --git a/devel/bmake/files/unit-tests/forloop.mk b/devel/bmake/files/unit-tests/forloop.mk index ae693438b94..985ccaf964b 100644 --- a/devel/bmake/files/unit-tests/forloop.mk +++ b/devel/bmake/files/unit-tests/forloop.mk @@ -1,4 +1,4 @@ -# $Id: forloop.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $ +# $Id: forloop.mk,v 1.1.1.2 2020/05/24 05:35:53 nia Exp $ all: for-loop @@ -33,7 +33,15 @@ X!= echo 'cfl=${cfl}' >&2; echo .for a b in ${EMPTY} X!= echo 'a=$a b=$b' >&2; echo .endfor -.endif + +# Since at least 1993, iteration stops at the first newline. +# Back then, the .newline variable didn't exist, therefore it was unlikely +# that a newline ever occured. +.for var in a${.newline}b${.newline}c +X!= echo 'newline-item=('${var:Q}')' 1>&2; echo +.endfor + +.endif # for-fail .for a b in ${LIST} ${LIST:tu} ${XTRA_LIST} X!= echo 'a=$a b=$b' >&2; echo diff --git a/devel/bmake/files/unit-tests/include-main.exp b/devel/bmake/files/unit-tests/include-main.exp new file mode 100644 index 00000000000..7a55c6e97dc --- /dev/null +++ b/devel/bmake/files/unit-tests/include-main.exp @@ -0,0 +1,6 @@ +main-before-ok +sub-before-ok +subsub-ok +sub-after-fail(include-sub.mk) +main-after-fail(include-sub.mk) +exit status 0 diff --git a/devel/bmake/files/unit-tests/include-main.mk b/devel/bmake/files/unit-tests/include-main.mk new file mode 100644 index 00000000000..cb333ef5211 --- /dev/null +++ b/devel/bmake/files/unit-tests/include-main.mk @@ -0,0 +1,30 @@ +# $NetBSD: include-main.mk,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ +# +# Demonstrates that the .INCLUDEDFROMFILE magic variable does not behave +# as described in the manual page. +# +# The manual page says that it is the "filename of the file this Makefile +# was included from", while in reality it is the "filename in which the +# latest .include happened". +# + +.if !defined(.INCLUDEDFROMFILE) +LOG+= main-before-ok +.else +. for f in ${.INCLUDEDFROMFILE} +LOG+= main-before-fail\(${f:Q}\) +. endfor +.endif + +.include "include-sub.mk" + +.if !defined(.INCLUDEDFROMFILE) +LOG+= main-after-ok +.else +. for f in ${.INCLUDEDFROMFILE} +LOG+= main-after-fail\(${f:Q}\) +. endfor +.endif + +all: + @printf '%s\n' ${LOG} diff --git a/devel/bmake/files/unit-tests/include-sub.mk b/devel/bmake/files/unit-tests/include-sub.mk new file mode 100644 index 00000000000..2bed3465966 --- /dev/null +++ b/devel/bmake/files/unit-tests/include-sub.mk @@ -0,0 +1,17 @@ +# $NetBSD: include-sub.mk,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ + +.if ${.INCLUDEDFROMFILE} == "include-main.mk" +LOG+= sub-before-ok +.else +LOG+= sub-before-fail +.endif + +.include "include-subsub.mk" + +.if ${.INCLUDEDFROMFILE} == "include-main.mk" +LOG+= sub-after-ok +.else +. for f in ${.INCLUDEDFROMFILE} +LOG+= sub-after-fail\(${f:Q}\) +. endfor +.endif diff --git a/devel/bmake/files/unit-tests/include-subsub.mk b/devel/bmake/files/unit-tests/include-subsub.mk new file mode 100644 index 00000000000..87d3e371366 --- /dev/null +++ b/devel/bmake/files/unit-tests/include-subsub.mk @@ -0,0 +1,7 @@ +# $NetBSD: include-subsub.mk,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ + +.if ${.INCLUDEDFROMFILE:T} == "include-sub.mk" +LOG+= subsub-ok +.else +LOG+= subsub-fail +.endif diff --git a/devel/bmake/files/unit-tests/modmatch.exp b/devel/bmake/files/unit-tests/modmatch.exp index fcaf6c02ed6..a7bf8b748f5 100644 --- a/devel/bmake/files/unit-tests/modmatch.exp +++ b/devel/bmake/files/unit-tests/modmatch.exp @@ -14,4 +14,7 @@ LIB=e X_LIBS:M${LIB${LIB:tu}} is "/tmp/libe.a" LIB=e X_LIBS:M*/lib${LIB}.a is "/tmp/libe.a" LIB=e X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBE.A" Mscanner=OK +Upper=One Two Three Four +Lower=five six seven +nose=One Three five exit status 0 diff --git a/devel/bmake/files/unit-tests/modmatch.mk b/devel/bmake/files/unit-tests/modmatch.mk index 48a1befb58b..45199287acd 100644 --- a/devel/bmake/files/unit-tests/modmatch.mk +++ b/devel/bmake/files/unit-tests/modmatch.mk @@ -15,7 +15,9 @@ res = no res = OK .endif -all: +all: show-libs check-cclass + +show-libs: @for x in $X; do ${.MAKE} -f ${MAKEFILE} show LIB=$$x; done @echo "Mscanner=${res}" @@ -23,3 +25,10 @@ show: @echo 'LIB=${LIB} X_LIBS:M$${LIB$${LIB:tu}} is "${X_LIBS:M${LIB${LIB:tu}}}"' @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a is "${X_LIBS:M*/lib${LIB}.a}"' @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a:tu is "${X_LIBS:M*/lib${LIB}.a:tu}"' + +LIST= One Two Three Four five six seven + +check-cclass: + @echo Upper=${LIST:M[A-Z]*} + @echo Lower=${LIST:M[^A-Z]*} + @echo nose=${LIST:M[^s]*[ex]} diff --git a/devel/bmake/files/unit-tests/modorder.mk b/devel/bmake/files/unit-tests/modorder.mk index 441a3da5ad2..3070d340e1a 100644 --- a/devel/bmake/files/unit-tests/modorder.mk +++ b/devel/bmake/files/unit-tests/modorder.mk @@ -1,4 +1,4 @@ -# $NetBSD: modorder.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $ +# $NetBSD: modorder.mk,v 1.1.1.2 2020/05/24 05:35:53 nia Exp $ LIST= one two three four five six seven eight nine ten LISTX= ${LIST:Ox} @@ -12,8 +12,9 @@ all: @echo "LIST:O = ${LIST:O}" # Note that 1 in every 10! trials two independently generated # randomized orderings will be the same. The test framework doesn't - # support checking probabilistic output, so we accept that the test - # will incorrectly fail with probability 2.8E-7. + # support checking probabilistic output, so we accept that each of the + # 3 :Ox tests will incorrectly fail with probability 2.756E-7, which + # lets the whole test fail once in 1.209.600 runs, on average. @echo "LIST:Ox = `test '${LIST:Ox}' != '${LIST:Ox}' ${TEST_RESULT}`" @echo "LIST:O:Ox = `test '${LIST:O:Ox}' != '${LIST:O:Ox}' ${TEST_RESULT}`" @echo "LISTX = `test '${LISTX}' != '${LISTX}' ${TEST_RESULT}`" diff --git a/devel/bmake/files/unit-tests/modts.exp b/devel/bmake/files/unit-tests/modts.exp index cf3c91d43c0..338964963a8 100644 --- a/devel/bmake/files/unit-tests/modts.exp +++ b/devel/bmake/files/unit-tests/modts.exp @@ -23,10 +23,16 @@ THREE FOUR FIVE SIX" +LIST:ts/xa:tu="ONE +TWO +THREE +FOUR +FIVE +SIX" make: Bad modifier `:tx' for LIST LIST:tx="}" -make: Bad modifier `:ts\x' for LIST -LIST:ts/x:tu="\x:tu}" +make: Bad modifier `:ts\X' for LIST +LIST:ts/x:tu="\X:tu}" FU_mod-ts="a/b/cool" FU_mod-ts:ts:T="cool" == cool? B.${AAA:ts}="Baaa" == Baaa? diff --git a/devel/bmake/files/unit-tests/modts.mk b/devel/bmake/files/unit-tests/modts.mk index 616bd8944f2..e66dc25a2a0 100644 --- a/devel/bmake/files/unit-tests/modts.mk +++ b/devel/bmake/files/unit-tests/modts.mk @@ -12,9 +12,9 @@ all: mod-ts # Use print or printf iff they are builtin. # XXX note that this causes problems, when make decides # there is no need to use a shell, so avoid where possible. -.if ${type print 2> /dev/null || echo:L:sh:Mbuiltin} != "" +.if ${(type print) 2> /dev/null || echo:L:sh:Mbuiltin} != "" PRINT= print -r -- -.elif ${type printf 2> /dev/null || echo:L:sh:Mbuiltin} != "" +.elif ${(type printf) 2> /dev/null || echo:L:sh:Mbuiltin} != "" PRINT= printf '%s\n' .else PRINT= echo @@ -36,8 +36,9 @@ mod-ts: @${PRINT} 'LIST:ts/n="${LIST:ts\n}"' @${PRINT} 'LIST:ts/t="${LIST:ts\t}"' @${PRINT} 'LIST:ts/012:tu="${LIST:ts\012:tu}"' + @${PRINT} 'LIST:ts/xa:tu="${LIST:ts\xa:tu}"' @${PRINT} 'LIST:tx="${LIST:tx}"' - @${PRINT} 'LIST:ts/x:tu="${LIST:ts\x:tu}"' + @${PRINT} 'LIST:ts/x:tu="${LIST:ts\X:tu}"' @${PRINT} 'FU_$@="${FU_${@:ts}:ts}"' @${PRINT} 'FU_$@:ts:T="${FU_${@:ts}:ts:T}" == cool?' @${PRINT} 'B.$${AAA:ts}="${B.${AAA:ts}}" == Baaa?' diff --git a/devel/bmake/files/unit-tests/sysv.exp b/devel/bmake/files/unit-tests/sysv.exp index 4cce2de3191..610f97c39e8 100644 --- a/devel/bmake/files/unit-tests/sysv.exp +++ b/devel/bmake/files/unit-tests/sysv.exp @@ -4,4 +4,12 @@ fun fun fun In the Sun +acme +aam.d +sam.c +a%.c +asam.c.c +asam.c +a.c.c + exit status 0 diff --git a/devel/bmake/files/unit-tests/sysv.mk b/devel/bmake/files/unit-tests/sysv.mk index 0eb780f91e9..99a9f4a3bc9 100644 --- a/devel/bmake/files/unit-tests/sysv.mk +++ b/devel/bmake/files/unit-tests/sysv.mk @@ -1,4 +1,4 @@ -# $Id: sysv.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $ +# $Id: sysv.mk,v 1.1.1.2 2020/05/24 05:35:53 nia Exp $ FOO ?= FOOBAR = ${FOO:=bar} @@ -11,7 +11,7 @@ FUN = ${B}${S}fun SUN = the Sun # we expect nothing when FOO is empty -all: foo fun +all: foo fun sam bla foo: @echo FOOBAR = ${FOOBAR} @@ -24,3 +24,20 @@ fun: @echo ${FUN:${B}${S}fun=fun} @echo ${FUN:${B}${S}%=%} @echo ${In:L:%=% ${SUN}} + + +SAM=sam.c + +sam: + @echo ${SAM:s%.c=acme} + @echo ${SAM:s%.c=a%.d} + @echo ${SAM:s.c=a%.d} + @echo ${SAM:sam.c=a%.c} + @echo ${SAM:%=a%.c} + @echo ${SAM:%.c=a%.c} + @echo ${SAM:sam%=a%.c} + +BLA= + +bla: + @echo $(BLA:%=foo/%x) diff --git a/devel/bmake/files/unit-tests/varcmd.exp b/devel/bmake/files/unit-tests/varcmd.exp index 34dd637f93e..7803c2b4299 100644 --- a/devel/bmake/files/unit-tests/varcmd.exp +++ b/devel/bmake/files/unit-tests/varcmd.exp @@ -1,5 +1,7 @@ default FU=<v>fu</v> FOO=<v>foo</v> VAR=<v></v> two FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v> +immutable FU='bar' +immutable FOO='goo' three FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v> four FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v> five FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v> diff --git a/devel/bmake/files/unit-tests/varcmd.mk b/devel/bmake/files/unit-tests/varcmd.mk index b107a7ccec8..1d6e75c7fb2 100644 --- a/devel/bmake/files/unit-tests/varcmd.mk +++ b/devel/bmake/files/unit-tests/varcmd.mk @@ -1,4 +1,4 @@ -# $Id: varcmd.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $ +# $Id: varcmd.mk,v 1.1.1.2 2020/05/24 05:35:53 nia Exp $ # # Test behaviour of recursive make and vars set on command line. @@ -15,7 +15,7 @@ show: @echo "${TAG} FU=<v>${FU}</v> FOO=<v>${FOO}</v> VAR=<v>${VAR}</v>" one: show - @${.MAKE} -f ${MAKEFILE} FU=bar FOO=goo two + @${.MAKE} -f ${MAKEFILE} FU=bar FOO+=goo two two: show @${.MAKE} -f ${MAKEFILE} three @@ -24,6 +24,17 @@ three: show @${.MAKE} -f ${MAKEFILE} four +.ifmake two +# this should not work +FU+= oops +FOO+= oops +_FU:= ${FU} +_FOO:= ${FOO} +two: immutable +immutable: + @echo "$@ FU='${_FU}'" + @echo "$@ FOO='${_FOO}'" +.endif .ifmake four VAR=Internal .MAKEOVERRIDES+= VAR diff --git a/devel/bmake/files/unit-tests/varmisc.exp b/devel/bmake/files/unit-tests/varmisc.exp index 1636aafc11e..ffe8f8b867c 100644 --- a/devel/bmake/files/unit-tests/varmisc.exp +++ b/devel/bmake/files/unit-tests/varmisc.exp @@ -1,2 +1,25 @@ +:D expanded when var set +true +TRUE +:U expanded when var undef +true +TRUE +:D skipped if var undef + +:U skipped when var set +is set +:? only lhs when value true +true +TRUE +:? only rhs when value false +false +FALSE +do not evaluate or expand :? if discarding +is set +year=2016 month=04 day=01 +date=20160401 +Version=123.456.789 == 123456789 +Literal=3.4.5 == 3004005 +We have target specific vars exit status 0 diff --git a/devel/bmake/files/unit-tests/varmisc.mk b/devel/bmake/files/unit-tests/varmisc.mk index 47da97329ad..8f23dfec588 100644 --- a/devel/bmake/files/unit-tests/varmisc.mk +++ b/devel/bmake/files/unit-tests/varmisc.mk @@ -1,8 +1,62 @@ -# $Id: varmisc.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $ +# $Id: varmisc.mk,v 1.1.1.2 2020/05/24 05:35:53 nia Exp $ # # Miscellaneous variable tests. -all: unmatched_var_paren +all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none \ + strftime cmpv unmatched_var_paren: @echo ${foo::=foo-text} + +True = ${echo true >&2:L:sh}TRUE +False= ${echo false >&2:L:sh}FALSE + +VSET= is set +.undef UNDEF + +U_false: + @echo :U skipped when var set + @echo ${VSET:U${False}} + +D_false: + @echo :D skipped if var undef + @echo ${UNDEF:D${False}} + +U_true: + @echo :U expanded when var undef + @echo ${UNDEF:U${True}} + +D_true: + @echo :D expanded when var set + @echo ${VSET:D${True}} + +Q_lhs: + @echo :? only lhs when value true + @echo ${1:L:?${True}:${False}} + +Q_rhs: + @echo :? only rhs when value false + @echo ${0:L:?${True}:${False}} + +NQ_none: + @echo do not evaluate or expand :? if discarding + @echo ${VSET:U${1:L:?${True}:${False}}} + +April1= 1459494000 + +# slightly contorted syntax to use utc via variable +strftime: + @echo ${year=%Y month=%m day=%d:L:gmtime=1459494000} + @echo date=${%Y%m%d:L:${gmtime=${April1}:L}} + +# big jumps to handle 3 digits per step +M_cmpv.units = 1 1000 1000000 +M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh + +Version = 123.456.789 +cmpv.only = target specific vars + +cmpv: + @echo Version=${Version} == ${Version:${M_cmpv}} + @echo Literal=3.4.5 == ${3.4.5:L:${M_cmpv}} + @echo We have ${${.TARGET:T}.only} diff --git a/devel/bmake/files/unit-tests/varmod-edge.exp b/devel/bmake/files/unit-tests/varmod-edge.exp new file mode 100644 index 00000000000..b3b2e3a92f9 --- /dev/null +++ b/devel/bmake/files/unit-tests/varmod-edge.exp @@ -0,0 +1,17 @@ +make: Unclosed variable specification (expecting '}') for "" (value "*)") modifier U +make: Unclosed substitution for INP.eq-esc (= missing) +ok M-paren +ok M-mixed +ok M-unescape +ok M-nest-mix +ok M-nest-brk +ok M-pat-err +ok M-bsbs +ok M-bs1-par +ok M-bs2-par +ok M-128 +ok eq-ext +ok eq-q +ok eq-bs +ok eq-esc +exit status 0 diff --git a/devel/bmake/files/unit-tests/varmod-edge.mk b/devel/bmake/files/unit-tests/varmod-edge.mk new file mode 100644 index 00000000000..587f5bd6d94 --- /dev/null +++ b/devel/bmake/files/unit-tests/varmod-edge.mk @@ -0,0 +1,162 @@ +# $NetBSD: varmod-edge.mk,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ +# +# Tests for edge cases in variable modifiers. +# +# These tests demonstrate the current implementation in small examples. +# They may contain surprising behavior. +# +# Each test consists of: +# - INP, the input to the test +# - MOD, the expression for testing the modifier +# - EXP, the expected output + +TESTS+= M-paren +INP.M-paren= (parentheses) {braces} (opening closing) () +MOD.M-paren= ${INP.M-paren:M(*)} +EXP.M-paren= (parentheses) () + +# The first closing brace matches the opening parenthesis. +# The second closing brace actually ends the variable expression. +# +# XXX: This is unexpected but rarely occurs in practice. +TESTS+= M-mixed +INP.M-mixed= (paren-brace} ( +MOD.M-mixed= ${INP.M-mixed:M(*}} +EXP.M-mixed= (paren-brace} + +# After the :M modifier has parsed the pattern, only the closing brace +# and the colon are unescaped. The other characters are left as-is. +# To actually see this effect, the backslashes in the :M modifier need +# to be doubled since single backslashes would simply be unescaped by +# Str_Match. +# +# XXX: This is unexpected. The opening brace should also be unescaped. +TESTS+= M-unescape +INP.M-unescape= ({}): \(\{\}\)\: \(\{}\): +MOD.M-unescape= ${INP.M-unescape:M\\(\\{\\}\\)\\:} +EXP.M-unescape= \(\{}\): + +# When the :M and :N modifiers are parsed, the pattern finishes as soon +# as open_parens + open_braces == closing_parens + closing_braces. This +# means that ( and } form a matching pair. +# +# Nested variable expressions are not parsed as such. Instead, only the +# parentheses and braces are counted. This leads to a parse error since +# the nested expression is not "${:U*)}" but only "${:U*)", which is +# missing the closing brace. The expression is evaluated anyway. +# The final brace in the output comes from the end of M.nest-mix. +# +# XXX: This is unexpected but rarely occurs in practice. +TESTS+= M-nest-mix +INP.M-nest-mix= (parentheses) +MOD.M-nest-mix= ${INP.M-nest-mix:M${:U*)}} +EXP.M-nest-mix= (parentheses)} +# make: Unclosed variable specification (expecting '}') for "" (value "*)") modifier U + +# In contrast to parentheses and braces, the brackets are not counted +# when the :M modifier is parsed since Makefile variables only take the +# ${VAR} or $(VAR) forms, but not $[VAR]. +# +# The final ] in the pattern is needed to close the character class. +TESTS+= M-nest-brk +INP.M-nest-brk= [ [[ [[[ +MOD.M-nest-brk= ${INP.M-nest-brk:M${:U[[[[[]}} +EXP.M-nest-brk= [ + +# The pattern in the nested variable has an unclosed character class. +# No error is reported though, and the pattern is closed implicitly. +# +# XXX: It is unexpected that no error is reported. +# See str.c, function Str_Match. +# +# Before 2019-12-02, this test case triggered an out-of-bounds read +# in Str_Match. +TESTS+= M-pat-err +INP.M-pat-err= [ [[ [[[ +MOD.M-pat-err= ${INP.M-pat-err:M${:U[[}} +EXP.M-pat-err= [ + +# The first backslash does not escape the second backslash. +# Therefore, the second backslash escapes the parenthesis. +# This means that the pattern ends there. +# The final } in the output comes from the end of MOD.M-bsbs. +# +# If the first backslash were to escape the second backslash, the first +# closing brace would match the opening parenthesis (see M-mixed), and +# the second closing brace would be needed to close the variable. +# After that, the remaining backslash would escape the parenthesis in +# the pattern, therefore (} would match. +TESTS+= M-bsbs +INP.M-bsbs= (} \( \(} +MOD.M-bsbs= ${INP.M-bsbs:M\\(}} +EXP.M-bsbs= \(} +#EXP.M-bsbs= (} # If the first backslash were to escape ... + +# The backslash in \( does not escape the parenthesis, therefore it +# counts for the nesting level and matches with the first closing brace. +# The second closing brace closes the variable, and the third is copied +# literally. +# +# The second :M in the pattern is nested between ( and }, therefore it +# does not start a new modifier. +TESTS+= M-bs1-par +INP.M-bs1-par= ( (:M (:M} \( \(:M \(:M} +MOD.M-bs1-par= ${INP.M-bs1-par:M\(:M*}}} +EXP.M-bs1-par= (:M}} + +# The double backslash is passed verbatim to the pattern matcher. +# The Str_Match pattern is \\(:M*}, and there the backslash is unescaped. +# Again, the ( takes place in the nesting level, and there is no way to +# prevent this, no matter how many backslashes are used. +TESTS+= M-bs2-par +INP.M-bs2-par= ( (:M (:M} \( \(:M \(:M} +MOD.M-bs2-par= ${INP.M-bs2-par:M\\(:M*}}} +EXP.M-bs2-par= \(:M}} + +# Str_Match uses a recursive algorithm for matching the * patterns. +# Make sure that it survives patterns with 128 asterisks. +# That should be enough for all practical purposes. +# To produce a stack overflow, just add more :Qs below. +TESTS+= M-128 +INP.M-128= ${:U\\:Q:Q:Q:Q:Q:Q:Q:S,\\,x,g} +PAT.M-128= ${:U\\:Q:Q:Q:Q:Q:Q:Q:S,\\,*,g} +MOD.M-128= ${INP.M-128:M${PAT.M-128}} +EXP.M-128= ${INP.M-128} + +# This is the normal SysV substitution. Nothing surprising here. +TESTS+= eq-ext +INP.eq-ext= file.c file.cc +MOD.eq-ext= ${INP.eq-ext:%.c=%.o} +EXP.eq-ext= file.o file.cc + +# The SysV := modifier is greedy and consumes all the modifier text +# up until the closing brace or parenthesis. The :Q may look like a +# modifier, but it really isn't, that's why it appears in the output. +TESTS+= eq-q +INP.eq-q= file.c file.cc +MOD.eq-q= ${INP.eq-q:%.c=%.o:Q} +EXP.eq-q= file.o:Q file.cc + +# The = in the := modifier can be escaped. +TESTS+= eq-bs +INP.eq-bs= file.c file.c=%.o +MOD.eq-bs= ${INP.eq-bs:%.c\=%.o=%.ext} +EXP.eq-bs= file.c file.ext + +# Having only an escaped = results in a parse error. +# The call to "pattern.lhs = VarGetPattern" fails. +TESTS+= eq-esc +INP.eq-esc= file.c file... +MOD.eq-esc= ${INP.eq-esc:a\=b} +EXP.eq-esc= # empty +# make: Unclosed substitution for INP.eq-esc (= missing) + +all: +.for test in ${TESTS} +. if ${MOD.${test}} == ${EXP.${test}} + @printf 'ok %s\n' ${test:Q}'' +. else + @printf 'error in %s: expected %s, got %s\n' \ + ${test:Q}'' ${EXP.${test}:Q}'' ${MOD.${test}:Q}'' +. endif +.endfor diff --git a/devel/bmake/files/unit-tests/varquote.exp b/devel/bmake/files/unit-tests/varquote.exp new file mode 100644 index 00000000000..63107bfd34f --- /dev/null +++ b/devel/bmake/files/unit-tests/varquote.exp @@ -0,0 +1,3 @@ +-fdebug-prefix-map=$NETBSDSRCDIR=/usr/src -fdebug-regex-map=/usr/src/(.*)/obj$=/usr/obj/\1 +-fdebug-prefix-map=$NETBSDSRCDIR=/usr/src -fdebug-regex-map=/usr/src/(.*)/obj$=/usr/obj/\1 +exit status 0 diff --git a/devel/bmake/files/unit-tests/varquote.mk b/devel/bmake/files/unit-tests/varquote.mk new file mode 100644 index 00000000000..45fc119c831 --- /dev/null +++ b/devel/bmake/files/unit-tests/varquote.mk @@ -0,0 +1,14 @@ +# $NetBSD: varquote.mk,v 1.1.1.1 2020/05/24 05:35:53 nia Exp $ +# +# Test VAR:q modifier + +.if !defined(REPROFLAGS) +REPROFLAGS+= -fdebug-prefix-map=\$$NETBSDSRCDIR=/usr/src +REPROFLAGS+= -fdebug-regex-map='/usr/src/(.*)/obj$$=/usr/obj/\1' +all: + @${MAKE} -f ${MAKEFILE} REPROFLAGS=${REPROFLAGS:S/\$/&&/g:Q} + @${MAKE} -f ${MAKEFILE} REPROFLAGS=${REPROFLAGS:q} +.else +all: + @printf "%s %s\n" ${REPROFLAGS} +.endif |