Module Name:    src
Committed By:   apb
Date:           Thu Aug 21 13:44:52 UTC 2014

Modified Files:
        src/usr.bin/make/unit-tests: Makefile
Added Files:
        src/usr.bin/make/unit-tests: comment.exp comment.mk cond1.exp cond1.mk
            doterror.exp doterror.mk dotwait.exp dotwait.mk error.exp error.mk
            export-all.exp export-all.mk export-env.exp export-env.mk
            export.exp export.mk forloop.exp forloop.mk forsubst.exp
            forsubst.mk hash.exp hash.mk misc.exp misc.mk moderrs.exp
            moderrs.mk modmatch.exp modmatch.mk modmisc.exp modmisc.mk
            modorder.exp modorder.mk modts.exp modts.mk modword.exp modword.mk
            order.exp order.mk phony-end.exp phony-end.mk posix.exp posix.mk
            qequals.exp qequals.mk sunshcmd.exp sunshcmd.mk sysv.exp sysv.mk
            ternary.exp ternary.mk unexport-env.exp unexport-env.mk
            unexport.exp unexport.mk varcmd.exp varcmd.mk varshell.exp
            varshell.mk
Removed Files:
        src/usr.bin/make/unit-tests: comment cond1 doterror dotwait error
            export export-all export-env forloop forsubst hash misc moderrs
            modmatch modmisc modorder modts modword order phony-end posix
            qequals sunshcmd sysv ternary test.exp unexport unexport-env varcmd
            varshell

Log Message:
Give each group of tests its own output file.

* Rename each sub-makefile to *.mk;
* Add a *.exp file of expected output for each sub-makefile;
* Remove test.exp, which is replaced by all the other *.exp files.
* Use suffix rules to generate *.rawout and *.out files for
  each test case.
* Rewrite the test and accept targets to adapt to the new way.

The old (now removed) test.exp file is almost identical to the
concatenation (in the correct order) of all the new *.exp files.  There
are expected differences in makefile names embedded in the output, and
the new "exit status" lines.  Some old "*** Error code 1 (ignored)"
lines are also removed (replaced by new "exit status 1" lines).


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/usr.bin/make/unit-tests/Makefile
cvs rdiff -u -r1.3 -r0 src/usr.bin/make/unit-tests/comment \
    src/usr.bin/make/unit-tests/varcmd
cvs rdiff -u -r0 -r1.1 src/usr.bin/make/unit-tests/comment.exp \
    src/usr.bin/make/unit-tests/comment.mk \
    src/usr.bin/make/unit-tests/cond1.exp \
    src/usr.bin/make/unit-tests/cond1.mk \
    src/usr.bin/make/unit-tests/doterror.exp \
    src/usr.bin/make/unit-tests/doterror.mk \
    src/usr.bin/make/unit-tests/dotwait.exp \
    src/usr.bin/make/unit-tests/dotwait.mk \
    src/usr.bin/make/unit-tests/error.exp \
    src/usr.bin/make/unit-tests/error.mk \
    src/usr.bin/make/unit-tests/export-all.exp \
    src/usr.bin/make/unit-tests/export-all.mk \
    src/usr.bin/make/unit-tests/export-env.exp \
    src/usr.bin/make/unit-tests/export-env.mk \
    src/usr.bin/make/unit-tests/export.exp \
    src/usr.bin/make/unit-tests/export.mk \
    src/usr.bin/make/unit-tests/forloop.exp \
    src/usr.bin/make/unit-tests/forloop.mk \
    src/usr.bin/make/unit-tests/forsubst.exp \
    src/usr.bin/make/unit-tests/forsubst.mk \
    src/usr.bin/make/unit-tests/hash.exp src/usr.bin/make/unit-tests/hash.mk \
    src/usr.bin/make/unit-tests/misc.exp src/usr.bin/make/unit-tests/misc.mk \
    src/usr.bin/make/unit-tests/moderrs.exp \
    src/usr.bin/make/unit-tests/moderrs.mk \
    src/usr.bin/make/unit-tests/modmatch.exp \
    src/usr.bin/make/unit-tests/modmatch.mk \
    src/usr.bin/make/unit-tests/modmisc.exp \
    src/usr.bin/make/unit-tests/modmisc.mk \
    src/usr.bin/make/unit-tests/modorder.exp \
    src/usr.bin/make/unit-tests/modorder.mk \
    src/usr.bin/make/unit-tests/modts.exp \
    src/usr.bin/make/unit-tests/modts.mk \
    src/usr.bin/make/unit-tests/modword.exp \
    src/usr.bin/make/unit-tests/modword.mk \
    src/usr.bin/make/unit-tests/order.exp \
    src/usr.bin/make/unit-tests/order.mk \
    src/usr.bin/make/unit-tests/phony-end.exp \
    src/usr.bin/make/unit-tests/phony-end.mk \
    src/usr.bin/make/unit-tests/posix.exp \
    src/usr.bin/make/unit-tests/posix.mk \
    src/usr.bin/make/unit-tests/qequals.exp \
    src/usr.bin/make/unit-tests/qequals.mk \
    src/usr.bin/make/unit-tests/sunshcmd.exp \
    src/usr.bin/make/unit-tests/sunshcmd.mk \
    src/usr.bin/make/unit-tests/sysv.exp src/usr.bin/make/unit-tests/sysv.mk \
    src/usr.bin/make/unit-tests/ternary.exp \
    src/usr.bin/make/unit-tests/ternary.mk \
    src/usr.bin/make/unit-tests/unexport-env.exp \
    src/usr.bin/make/unit-tests/unexport-env.mk \
    src/usr.bin/make/unit-tests/unexport.exp \
    src/usr.bin/make/unit-tests/unexport.mk \
    src/usr.bin/make/unit-tests/varcmd.exp \
    src/usr.bin/make/unit-tests/varcmd.mk \
    src/usr.bin/make/unit-tests/varshell.exp \
    src/usr.bin/make/unit-tests/varshell.mk
cvs rdiff -u -r1.5 -r0 src/usr.bin/make/unit-tests/cond1
cvs rdiff -u -r1.1 -r0 src/usr.bin/make/unit-tests/doterror \
    src/usr.bin/make/unit-tests/dotwait src/usr.bin/make/unit-tests/export \
    src/usr.bin/make/unit-tests/export-env \
    src/usr.bin/make/unit-tests/forloop src/usr.bin/make/unit-tests/forsubst \
    src/usr.bin/make/unit-tests/hash src/usr.bin/make/unit-tests/misc \
    src/usr.bin/make/unit-tests/modword src/usr.bin/make/unit-tests/order \
    src/usr.bin/make/unit-tests/phony-end src/usr.bin/make/unit-tests/posix \
    src/usr.bin/make/unit-tests/qequals src/usr.bin/make/unit-tests/sunshcmd \
    src/usr.bin/make/unit-tests/unexport \
    src/usr.bin/make/unit-tests/unexport-env \
    src/usr.bin/make/unit-tests/varshell
cvs rdiff -u -r1.2 -r0 src/usr.bin/make/unit-tests/error \
    src/usr.bin/make/unit-tests/export-all \
    src/usr.bin/make/unit-tests/moderrs src/usr.bin/make/unit-tests/modmatch \
    src/usr.bin/make/unit-tests/modorder src/usr.bin/make/unit-tests/modts \
    src/usr.bin/make/unit-tests/sysv src/usr.bin/make/unit-tests/ternary
cvs rdiff -u -r1.7 -r0 src/usr.bin/make/unit-tests/modmisc
cvs rdiff -u -r1.44 -r0 src/usr.bin/make/unit-tests/test.exp

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

Modified files:

Index: src/usr.bin/make/unit-tests/Makefile
diff -u src/usr.bin/make/unit-tests/Makefile:1.41 src/usr.bin/make/unit-tests/Makefile:1.42
--- src/usr.bin/make/unit-tests/Makefile:1.41	Thu Aug 21 13:31:52 2014
+++ src/usr.bin/make/unit-tests/Makefile	Thu Aug 21 13:44:51 2014
@@ -1,24 +1,25 @@
-# $NetBSD: Makefile,v 1.41 2014/08/21 13:31:52 apb Exp $
+# $NetBSD: Makefile,v 1.42 2014/08/21 13:44:51 apb Exp $
 #
 # Unit tests for make(1)
 # The main targets are:
 # 
 # all:	run all the tests
-# test:	run 'all', capture output and compare to expected results
+# 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 which should be added to SUBFILES to hook it in.
+# named makefile (*.mk), with its own set of expected results (*.exp),
+# and it should be added to the TESTNAMES list.
 # 
 
 .MAIN: all
 
 UNIT_TESTS:= ${.PARSEDIR}
 
-# Simple sub-makefiles - we run them as a black box
-# keep the list sorted.
-SUBFILES= \
+# Each test is in a sub-makefile.
+# Keep the list sorted.
+TESTNAMES= \
 	comment \
 	cond1 \
 	error \
@@ -49,21 +50,16 @@ SUBFILES= \
 	varcmd \
 	varshell
 
-all: ${SUBFILES}
-
+# Override make flags for certain tests
 flags.doterror=
 flags.order=-j1
 
-# the tests are actually done with sub-makes.
-.PHONY: ${SUBFILES}
-.PRECIOUS: ${SUBFILES}
-${SUBFILES}:
-	-@${.MAKE} ${flags.$@:U-k} -f ${UNIT_TESTS}/$@
+OUTFILES= ${TESTNAMES:S/$/.out/}
 
-clean:
-	rm -f *.out *.fail *.core
+all: ${OUTFILES}
 
-.-include <bsd.obj.mk>
+clean:
+	rm -f *.rawout *.out *.status *.tmp *.core *.tmp
 
 TEST_MAKE?= ${.MAKE}
 TOOL_SED?= sed
@@ -73,22 +69,48 @@ LC_ALL= C
 LANG= C
 .export LANG LC_ALL
 
-# The driver.
+# 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.
-test:
-	@echo "${TEST_MAKE} -f ${MAKEFILE} > ${.TARGET}.out 2>&1"
-	cd ${.OBJDIR} && ${TEST_MAKE} -f ${MAKEFILE} 2>&1 | \
-	${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' > ${.TARGET}.out || { \
-	tail ${.TARGET}.out; mv ${.TARGET}.out ${.TARGET}.fail; exit 1; }
-	diff -u ${UNIT_TESTS}/${.TARGET}.exp ${.TARGET}.out
+.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' \
+	  < ${.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 \
+	  diff -u ${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:
-	mv test.out ${.CURDIR}/test.exp
+	@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
 
+.-include <bsd.obj.mk>

Added files:

Index: src/usr.bin/make/unit-tests/comment.exp
diff -u /dev/null src/usr.bin/make/unit-tests/comment.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/comment.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,5 @@
+comment testing start
+this is foo
+This is how a comment looks: # comment
+comment testing done
+exit status 0
Index: src/usr.bin/make/unit-tests/comment.mk
diff -u /dev/null src/usr.bin/make/unit-tests/comment.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/comment.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,31 @@
+# This is a comment
+.if ${MACHINE_ARCH} == something
+FOO=bar
+.endif
+
+#\
+	Multiline comment
+
+BAR=# defined
+FOOBAR= # defined 
+
+# This is an escaped comment \
+that keeps going until the end of this line
+
+# Another escaped comment \
+that \
+goes \
+on
+
+# This is NOT an escaped comment due to the double backslashes \\
+all: hi foo bar
+	@echo comment testing done
+
+hi:
+	@echo comment testing start
+
+foo:
+	@echo this is $@
+
+bar:
+	@echo This is how a comment looks: '# comment'
Index: src/usr.bin/make/unit-tests/cond1.exp
diff -u /dev/null src/usr.bin/make/unit-tests/cond1.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/cond1.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,23 @@
+make: "cond1.mk" line 75: warning: extra else
+make: "cond1.mk" line 85: warning: extra else
+2 is  prime
+A='other' B='unknown' C='clever' o='no,no'
+Passed:
+ var
+ ("var")
+ (var != var)
+ var != var
+ !((var != var) && defined(name))
+ var == quoted
+
+1 is not prime
+2 is  prime
+3 is  prime
+4 is not prime
+5 is  prime
+
+make: warning: String comparison operator should be either == or !=
+make: Bad conditional expression `"0" > 0' in "0" > 0?OK:No
+
+OK
+exit status 0
Index: src/usr.bin/make/unit-tests/cond1.mk
diff -u /dev/null src/usr.bin/make/unit-tests/cond1.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/cond1.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,109 @@
+# $Id: cond1.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+# hard code these!
+TEST_UNAME_S= NetBSD
+TEST_UNAME_M= sparc
+TEST_MACHINE= i386
+
+.if ${TEST_UNAME_S}
+Ok=var,
+.endif
+.if ("${TEST_UNAME_S}")
+Ok+=(\"var\"),
+.endif
+.if (${TEST_UNAME_M} != ${TEST_MACHINE})
+Ok+=(var != var),
+.endif
+.if ${TEST_UNAME_M} != ${TEST_MACHINE}
+Ok+= var != var,
+.endif
+.if !((${TEST_UNAME_M} != ${TEST_MACHINE}) && defined(X))
+Ok+= !((var != var) && defined(name)),
+.endif
+# from bsd.obj.mk
+MKOBJ?=no
+.if ${MKOBJ} == "no"
+o= no
+Ok+= var == "quoted",
+.else
+.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR)
+.if defined(notMAKEOBJDIRPREFIX)
+o=${MAKEOBJDIRPREFIX}${__curdir}
+.else
+o= ${MAKEOBJDIR}
+.endif
+.endif
+o= o
+.endif
+
+# repeat the above to check we get the same result
+.if ${MKOBJ} == "no"
+o2= no
+.else
+.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR)
+.if defined(notMAKEOBJDIRPREFIX)
+o2=${MAKEOBJDIRPREFIX}${__curdir}
+.else
+o2= ${MAKEOBJDIR}
+.endif
+.endif
+o2= o
+.endif
+
+PRIMES=2 3 5 7 11
+NUMBERS=1 2 3 4 5
+
+n=2
+.if ${PRIMES:M$n} == ""
+X=not
+.else
+X=
+.endif
+
+.if ${MACHINE_ARCH} == no-such
+A=one
+.else
+.if ${MACHINE_ARCH} == not-this
+.if ${MACHINE_ARCH} == something-else
+A=unlikely
+.else
+A=no
+.endif
+.endif
+A=other
+# We expect an extra else warning - we're not skipping here
+.else
+A=this should be an error
+.endif
+
+.if $X != ""
+.if $X == not
+B=one
+.else
+B=other
+# We expect an extra else warning - we are skipping here
+.else
+B=this should be an error
+.endif
+.else
+B=unknown
+.endif
+
+.if "quoted" == quoted
+C=clever
+.else
+C=dim
+.endif
+
+.if defined(nosuch) && ${nosuch:Mx} != ""
+# this should not happen
+.info nosuch is x
+.endif
+
+all:
+	@echo "$n is $X prime"
+	@echo "A='$A' B='$B' C='$C' o='$o,${o2}'"
+	@echo "Passed:${.newline} ${Ok:S/,/${.newline}/}"
+	@echo "${NUMBERS:@n@$n is ${("${PRIMES:M$n}" == ""):?not:} prime${.newline}@}"
+	@echo "${"${DoNotQuoteHere:U0}" > 0:?OK:No}"
+	@echo "${${NoSuchNumber:U42} > 0:?OK:No}"
Index: src/usr.bin/make/unit-tests/doterror.exp
diff -u /dev/null src/usr.bin/make/unit-tests/doterror.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/doterror.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +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
+exit status 1
Index: src/usr.bin/make/unit-tests/doterror.mk
diff -u /dev/null src/usr.bin/make/unit-tests/doterror.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/doterror.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,20 @@
+# $Id: doterror.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+
+.BEGIN:
+	@echo At first, I am
+
+.END:
+	@echo not reached
+
+.ERROR:
+	@echo "$@: Looks like '${.ERROR_TARGET}' is upset."
+
+all:	happy sad
+
+happy:
+	@echo $@
+
+sad:
+	@echo and now: $@; exit 1
+
Index: src/usr.bin/make/unit-tests/dotwait.exp
diff -u /dev/null src/usr.bin/make/unit-tests/dotwait.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/dotwait.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,30 @@
+simple.1
+simple.1
+simple.2
+simple.2
+recursive.1.1.*
+recursive.1.1.*
+recursive.1.1.*
+recursive.1.1.*
+recursive.1.99
+recursive.1.99
+recursive.2.1.*
+recursive.2.1.*
+recursive.2.1.*
+recursive.2.1.*
+recursive.2.99
+recursive.2.99
+shared.0
+shared.0
+shared.1.99
+shared.1.99
+shared.2.1
+shared.2.1
+shared.2.99
+shared.2.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
Index: src/usr.bin/make/unit-tests/dotwait.mk
diff -u /dev/null src/usr.bin/make/unit-tests/dotwait.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/dotwait.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,61 @@
+# $NetBSD: dotwait.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+THISMAKEFILE:= ${.PARSEDIR}/${.PARSEFILE}
+
+TESTS= simple recursive shared cycle
+PAUSE= sleep 1
+
+# Use a .for loop rather than dependencies here, to ensure
+# that the tests are run one by one, with parallelism
+# only within tests.
+# Ignore "--- target ---" lines printed by parallel make.
+all:
+.for t in ${TESTS}
+	@${.MAKE} -f ${THISMAKEFILE} -j4 $t | grep -v "^--- "
+.endfor
+
+#
+# Within each test, the names of the sub-targets follow these
+# conventions:
+# * If it's expected that two or more targets may be made in parallel,
+#   then the target names will differ only in an alphabetic component
+#   such as ".a" or ".b".
+# * If it's expected that two or more targets should be made in sequence
+#   then the target names will differ in numeric components, such that
+#   lexical ordering of the target names matches the expected order
+#   in which the targets should be made.
+#
+# Targets may echo ${PARALLEL_TARG} to print a modified version
+# of their own name, in which alphabetic components like ".a" or ".b"
+# are converted to ".*".  Two targets that are expected to
+# be made in parallel will thus print the same strings, so that the
+# output is independent of the order in which these targets are made.
+#
+PARALLEL_TARG= ${.TARGET:C/\.[a-z]/.*/g:Q}
+.DEFAULT:
+	@echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG}
+_ECHOUSE: .USE
+	@echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG}
+
+# simple: no recursion, no cycles
+simple: simple.1 .WAIT simple.2
+
+# recursive: all children of the left hand side of the .WAIT
+# must be made before any child of the right hand side.
+recursive: recursive.1.99 .WAIT recursive.2.99
+recursive.1.99: recursive.1.1.a recursive.1.1.b _ECHOUSE
+recursive.2.99: recursive.2.1.a recursive.2.1.b _ECHOUSE
+
+# shared: both shared.1.99 and shared.2.99 depend on shared.0.
+# shared.0 must be made first, even though it is a child of
+# the right hand side of the .WAIT.
+shared: shared.1.99 .WAIT shared.2.99
+shared.1.99: shared.0 _ECHOUSE
+shared.2.99: shared.2.1 shared.0 _ECHOUSE
+
+# cycle: the cyclic dependency must not cause infinite recursion
+# leading to stack overflow and a crash.
+cycle: cycle.1.99 .WAIT cycle.2.99
+cycle.2.99: cycle.2.98 _ECHOUSE
+cycle.2.98: cycle.2.97 _ECHOUSE
+cycle.2.97: cycle.2.99 _ECHOUSE
Index: src/usr.bin/make/unit-tests/error.exp
diff -u /dev/null src/usr.bin/make/unit-tests/error.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/error.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,4 @@
+make: "error.mk" line 3: just FYI
+make: "error.mk" line 4: warning: this could be serious
+make: "error.mk" line 5: this is fatal
+exit status 1
Index: src/usr.bin/make/unit-tests/error.mk
diff -u /dev/null src/usr.bin/make/unit-tests/error.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/error.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,10 @@
+# $Id: error.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+.info just FYI
+.warning this could be serious
+.error this is fatal
+
+all:
+
+.info.html:
+	@echo this should be ignored
Index: src/usr.bin/make/unit-tests/export-all.exp
diff -u /dev/null src/usr.bin/make/unit-tests/export-all.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/export-all.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,4 @@
+make: "export-all.mk" line 20: Could not find export
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+exit status 1
Index: src/usr.bin/make/unit-tests/export-all.mk
diff -u /dev/null src/usr.bin/make/unit-tests/export-all.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/export-all.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,23 @@
+# $Id: export-all.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+UT_OK=good
+UT_F=fine
+
+# the old way to do :tA
+M_tAbad = C,.*,cd & \&\& 'pwd',:sh
+# the new
+M_tA = tA
+
+here := ${.PARSEDIR}
+
+# this will cause trouble (recursing if we let it)
+UT_BADDIR = ${${here}/../${here:T}:L:${M_tAbad}:T}
+# this will be ok
+UT_OKDIR = ${${here}/../${here:T}:L:${M_tA}:T}
+
+.export
+
+.include "export"
+
+UT_TEST=export-all
+UT_ALL=even this gets exported
Index: src/usr.bin/make/unit-tests/export-env.exp
diff -u /dev/null src/usr.bin/make/unit-tests/export-env.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/export-env.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,9 @@
+make:
+UT_TEST=export-env.mk
+UT_ENV=not-exported
+UT_EXP=not-exported
+env:
+UT_TEST=export-env.mk
+UT_ENV=exported
+UT_EXP=exported
+exit status 0
Index: src/usr.bin/make/unit-tests/export-env.mk
diff -u /dev/null src/usr.bin/make/unit-tests/export-env.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/export-env.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,24 @@
+# $Id: export-env.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+# our normal .export, subsequent changes affect the environment
+UT_TEST=this
+.export UT_TEST
+UT_TEST:= ${.PARSEFILE}
+
+# not so with .export-env
+UT_ENV=exported
+.export-env UT_ENV
+UT_ENV=not-exported
+
+# gmake style export goes further; affects nothing but the environment
+UT_EXP=before-export
+export UT_EXP=exported
+UT_EXP=not-exported
+
+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};@}
+
+
+
+
Index: src/usr.bin/make/unit-tests/export.exp
diff -u /dev/null src/usr.bin/make/unit-tests/export.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/export.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,6 @@
+UT_DOLLAR=This is $UT_FU
+UT_FOO=foobar is fubar
+UT_FU=fubar
+UT_TEST=export
+UT_ZOO=hoopie
+exit status 0
Index: src/usr.bin/make/unit-tests/export.mk
diff -u /dev/null src/usr.bin/make/unit-tests/export.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/export.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,22 @@
+# $Id: export.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+UT_TEST=export
+UT_FOO=foo${BAR}
+UT_FU=fubar
+UT_ZOO=hoopie
+UT_NO=all
+# belive it or not, we expect this one to come out with $UT_FU unexpanded.
+UT_DOLLAR= This is $$UT_FU
+
+.export UT_FU UT_FOO
+.export UT_DOLLAR
+# this one will be ignored
+.export .MAKE.PID
+
+BAR=bar is ${UT_FU}
+
+.MAKE.EXPORTED+= UT_ZOO UT_TEST
+
+all:
+	@env | grep '^UT_' | sort
+
Index: src/usr.bin/make/unit-tests/forloop.exp
diff -u /dev/null src/usr.bin/make/unit-tests/forloop.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/forloop.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,19 @@
+x=one
+x="two and three"
+x=four
+x="five"
+x=-I/this
+x=-I"This or that"
+x=-Ithat
+x="-DTHIS=\"this and that\""
+cfl=-I/this -I"This or that" -Ithat "-DTHIS=\"this and that\""
+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: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+OK
+exit status 0
Index: src/usr.bin/make/unit-tests/forloop.mk
diff -u /dev/null src/usr.bin/make/unit-tests/forloop.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/forloop.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,45 @@
+# $Id: forloop.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+all: for-loop
+
+LIST = one "two and three" four "five"
+
+.if make(for-fail)
+for-fail:
+
+XTRA_LIST = xtra
+.else
+
+.for x in ${LIST}
+X!= echo 'x=$x' >&2; echo
+.endfor
+
+CFL = -I/this -I"This or that" -Ithat "-DTHIS=\"this and that\""
+cfl=
+.for x in ${CFL}
+X!= echo 'x=$x' >&2; echo
+.if empty(cfl)
+cfl= $x
+.else
+cfl+= $x
+.endif
+.endfor
+X!= echo 'cfl=${cfl}' >&2; echo
+
+.if ${cfl} != ${CFL}
+.error ${.newline}'${cfl}' != ${.newline}'${CFL}'
+.endif
+
+.for a b in ${EMPTY}
+X!= echo 'a=$a b=$b' >&2; echo
+.endfor
+.endif
+
+.for a b in ${LIST} ${LIST:tu} ${XTRA_LIST}
+X!= echo 'a=$a b=$b' >&2; echo
+.endfor
+
+for-loop:
+	@echo We expect an error next:
+	@(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} for-fail) && \
+	{ echo "Oops that should have failed!"; exit 1; } || echo OK
Index: src/usr.bin/make/unit-tests/forsubst.exp
diff -u /dev/null src/usr.bin/make/unit-tests/forsubst.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/forsubst.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,2 @@
+.for with :S;... OK
+exit status 0
Index: src/usr.bin/make/unit-tests/forsubst.mk
diff -u /dev/null src/usr.bin/make/unit-tests/forsubst.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/forsubst.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,10 @@
+# $Id: forsubst.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+all: for-subst
+
+here := ${.PARSEDIR}
+# this should not run foul of the parser
+.for file in ${.PARSEFILE}
+for-subst:	  ${file:S;^;${here}/;g}
+	@echo ".for with :S;... OK"
+.endfor
Index: src/usr.bin/make/unit-tests/hash.exp
diff -u /dev/null src/usr.bin/make/unit-tests/hash.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/hash.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,9 @@
+b2af338b
+3360ac65
+7747f046
+9ca87054
+880fe816
+208fcbd3
+d5d376eb
+de41416c
+exit status 0
Index: src/usr.bin/make/unit-tests/hash.mk
diff -u /dev/null src/usr.bin/make/unit-tests/hash.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/hash.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,18 @@
+STR1=
+STR2=	a
+STR3=	ab
+STR4=	abc
+STR5=	abcd
+STR6=	abcde
+STR7=	abcdef
+STR8=	abcdefghijklmnopqrstuvwxyz
+
+all:
+	@echo ${STR1:hash}
+	@echo ${STR2:hash}
+	@echo ${STR3:hash}
+	@echo ${STR4:hash}
+	@echo ${STR5:hash}
+	@echo ${STR6:hash}
+	@echo ${STR7:hash}
+	@echo ${STR8:hash}
Index: src/usr.bin/make/unit-tests/misc.exp
diff -u /dev/null src/usr.bin/make/unit-tests/misc.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/misc.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1 @@
+exit status 0
Index: src/usr.bin/make/unit-tests/misc.mk
diff -u /dev/null src/usr.bin/make/unit-tests/misc.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/misc.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,16 @@
+# $Id: misc.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+.if !exists(${.CURDIR}/)
+.warning ${.CURDIR}/ doesn't exist ?
+.endif
+
+.if !exists(${.CURDIR}/.)
+.warning ${.CURDIR}/. doesn't exist ?
+.endif
+
+.if !exists(${.CURDIR}/..)
+.warning ${.CURDIR}/.. doesn't exist ?
+.endif
+
+all:
+	@: all is well
Index: src/usr.bin/make/unit-tests/moderrs.exp
diff -u /dev/null src/usr.bin/make/unit-tests/moderrs.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/moderrs.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,16 @@
+Expect: Unknown modifier 'Z'
+make: Unknown modifier 'Z'
+VAR:Z=
+Expect: Unknown modifier 'Z'
+make: Unknown modifier 'Z'
+VAR:Z=
+Expect: Unclosed variable specification for VAR
+make: Unclosed variable specification (expecting '}') for "VAR" (value "Thevariable") modifier S
+VAR:S,V,v,=Thevariable
+Expect: Unclosed variable specification for VAR
+make: Unclosed variable specification after complex modifier (expecting '}') for VAR
+VAR:S,V,v,=Thevariable
+Expect: Unclosed substitution for VAR (, missing)
+make: Unclosed substitution for VAR (, missing)
+VAR:S,V,v=
+exit status 0
Index: src/usr.bin/make/unit-tests/moderrs.mk
diff -u /dev/null src/usr.bin/make/unit-tests/moderrs.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/moderrs.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,31 @@
+# $Id: moderrs.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+#
+# various modifier error tests
+
+VAR=TheVariable
+# incase we have to change it ;-)
+MOD_UNKN=Z
+MOD_TERM=S,V,v
+MOD_S:= ${MOD_TERM},
+
+all:	modunkn modunknV varterm vartermV modtermV
+
+modunkn:
+	@echo "Expect: Unknown modifier 'Z'"
+	@echo "VAR:Z=${VAR:Z}"
+
+modunknV:
+	@echo "Expect: Unknown modifier 'Z'"
+	@echo "VAR:${MOD_UNKN}=${VAR:${MOD_UNKN}}"
+
+varterm:
+	@echo "Expect: Unclosed variable specification for VAR"
+	@echo VAR:S,V,v,=${VAR:S,V,v,
+
+vartermV:
+	@echo "Expect: Unclosed variable specification for VAR"
+	@echo VAR:${MOD_TERM},=${VAR:${MOD_S}
+
+modtermV:
+	@echo "Expect: Unclosed substitution for VAR (, missing)"
+	-@echo "VAR:${MOD_TERM}=${VAR:${MOD_TERM}}"
Index: src/usr.bin/make/unit-tests/modmatch.exp
diff -u /dev/null src/usr.bin/make/unit-tests/modmatch.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modmatch.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,17 @@
+LIB=a X_LIBS:M${LIB${LIB:tu}} is "/tmp/liba.a"
+LIB=a X_LIBS:M*/lib${LIB}.a is "/tmp/liba.a"
+LIB=a X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBA.A"
+LIB=b X_LIBS:M${LIB${LIB:tu}} is ""
+LIB=b X_LIBS:M*/lib${LIB}.a is ""
+LIB=b X_LIBS:M*/lib${LIB}.a:tu is ""
+LIB=c X_LIBS:M${LIB${LIB:tu}} is ""
+LIB=c X_LIBS:M*/lib${LIB}.a is ""
+LIB=c X_LIBS:M*/lib${LIB}.a:tu is ""
+LIB=d X_LIBS:M${LIB${LIB:tu}} is "/tmp/libd.a"
+LIB=d X_LIBS:M*/lib${LIB}.a is "/tmp/libd.a"
+LIB=d X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBD.A"
+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
+exit status 0
Index: src/usr.bin/make/unit-tests/modmatch.mk
diff -u /dev/null src/usr.bin/make/unit-tests/modmatch.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modmatch.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,25 @@
+
+X=a b c d e
+
+.for x in $X
+LIB${x:tu}=/tmp/lib$x.a
+.endfor
+
+X_LIBS= ${LIBA} ${LIBD} ${LIBE}
+
+LIB?=a
+
+var = head
+res = no
+.if !empty(var:M${:Uhead\:tail:C/:.*//})
+res = OK
+.endif
+
+all:
+	@for x in $X; do ${.MAKE} -f ${MAKEFILE} show LIB=$$x; done
+	@echo "Mscanner=${res}"
+
+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}"'
Index: src/usr.bin/make/unit-tests/modmisc.exp
diff -u /dev/null src/usr.bin/make/unit-tests/modmisc.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modmisc.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,10 @@
+path=':/bin:/tmp::/:.:/no/such/dir:.'
+path='/bin:/tmp:/:/no/such/dir'
+path='/bin:/tmp:/:/no/such/dir'
+path='/bin':'/tmp':'/':'/no/such/dir'
+path='/bin':'/tmp':'/':'/no/such/dir'
+path_/usr/xbin=/opt/xbin/
+paths=/bin /tmp / /no/such/dir /opt/xbin
+PATHS=/BIN /TMP / /NO/SUCH/DIR /OPT/XBIN
+The answer is 42
+exit status 0
Index: src/usr.bin/make/unit-tests/modmisc.mk
diff -u /dev/null src/usr.bin/make/unit-tests/modmisc.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modmisc.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,38 @@
+# $Id: modmisc.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+#
+# miscellaneous modifier tests
+
+# do not put any dirs in this list which exist on some
+# but not all target systems - an exists() check is below.
+path=:/bin:/tmp::/:.:/no/such/dir:.
+# strip cwd from path.
+MOD_NODOT=S/:/ /g:N.:ts:
+# and decorate, note that $'s need to be doubled. Also note that 
+# the modifier_variable can be used with other modifiers.
+MOD_NODOTX=S/:/ /g:N.:@d@'$$d'@
+# another mod - pretend it is more interesting
+MOD_HOMES=S,/home/,/homes/,
+MOD_OPT=@d@$${exists($$d):?$$d:$${d:S,/usr,/opt,}}@
+MOD_SEP=S,:, ,g
+
+all:	modvar modvarloop modsysv
+
+modsysv:
+	@echo "The answer is ${libfoo.a:L:libfoo.a=42}"
+
+modvar:
+	@echo "path='${path}'"
+	@echo "path='${path:${MOD_NODOT}}'"
+	@echo "path='${path:S,home,homes,:${MOD_NODOT}}'"
+	@echo "path=${path:${MOD_NODOTX}:ts:}"
+	@echo "path=${path:${MOD_HOMES}:${MOD_NODOTX}:ts:}"
+
+.for d in ${path:${MOD_SEP}:N.} /usr/xbin
+path_$d?= ${d:${MOD_OPT}:${MOD_HOMES}}/
+paths+= ${d:${MOD_OPT}:${MOD_HOMES}}
+.endfor
+
+modvarloop:
+	@echo "path_/usr/xbin=${path_/usr/xbin}"
+	@echo "paths=${paths}"
+	@echo "PATHS=${paths:tu}"
Index: src/usr.bin/make/unit-tests/modorder.exp
diff -u /dev/null src/usr.bin/make/unit-tests/modorder.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modorder.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,11 @@
+LIST      = one two three four five six seven eight nine ten
+LIST:O    = eight five four nine one seven six ten three two
+LIST:Ox   = Ok
+LIST:O:Ox = Ok
+LISTX     = Ok
+LISTSX    = Ok
+make: Bad modifier `:OX' for LIST
+BADMOD 1  = }
+make: Bad modifier `:OxXX' for LIST
+BADMOD 2  = XX}
+exit status 0
Index: src/usr.bin/make/unit-tests/modorder.mk
diff -u /dev/null src/usr.bin/make/unit-tests/modorder.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modorder.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,22 @@
+# $NetBSD: modorder.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+LIST=		one two three four five six seven eight nine ten
+LISTX=		${LIST:Ox}
+LISTSX:=	${LIST:Ox}
+TEST_RESULT= && echo Ok || echo Failed
+
+# unit-tests have to produce the same results on each run
+# so we cannot actually include :Ox output.
+all:
+	@echo "LIST      = ${LIST}"
+	@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.
+	@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}`"
+	@echo "LISTSX    = `test '${LISTSX}' = '${LISTSX}' ${TEST_RESULT}`"
+	@echo "BADMOD 1  = ${LIST:OX}"
+	@echo "BADMOD 2  = ${LIST:OxXX}"
Index: src/usr.bin/make/unit-tests/modts.exp
diff -u /dev/null src/usr.bin/make/unit-tests/modts.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modts.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,33 @@
+LIST="one two three four five six"
+LIST:ts,="one,two,three,four,five,six"
+LIST:ts/:tu="ONE/TWO/THREE/FOUR/FIVE/SIX"
+LIST:ts::tu="ONE:TWO:THREE:FOUR:FIVE:SIX"
+LIST:ts:tu="ONETWOTHREEFOURFIVESIX"
+LIST:tu:ts/="ONE/TWO/THREE/FOUR/FIVE/SIX"
+LIST:ts:="one:two:three:four:five:six"
+LIST:ts="onetwothreefourfivesix"
+LIST:ts:S/two/2/="one2threefourfivesix"
+LIST:S/two/2/:ts="one2threefourfivesix"
+LIST:ts/:S/two/2/="one/2/three/four/five/six"
+Pretend the '/' in '/n' etc. below are back-slashes.
+LIST:ts/n="one
+two
+three
+four
+five
+six"
+LIST:ts/t="one	two	three	four	five	six"
+LIST:ts/012: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}"
+FU_mod-ts="a/b/cool"
+FU_mod-ts:ts:T="cool" == cool?
+B.${AAA:ts}="Baaa" == Baaa?
+exit status 0
Index: src/usr.bin/make/unit-tests/modts.mk
diff -u /dev/null src/usr.bin/make/unit-tests/modts.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modts.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,43 @@
+
+LIST= one two three
+LIST+= four five six
+
+FU_mod-ts = a / b / cool
+
+AAA= a a a
+B.aaa= Baaa
+
+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} != ""
+PRINT= print -r --
+.elif ${type printf 2> /dev/null || echo:L:sh:Mbuiltin} != ""
+PRINT= printf '%s\n'
+.else
+PRINT= echo
+.endif
+
+mod-ts:
+	@echo 'LIST="${LIST}"'
+	@echo 'LIST:ts,="${LIST:ts,}"'
+	@echo 'LIST:ts/:tu="${LIST:ts/:tu}"'
+	@echo 'LIST:ts::tu="${LIST:ts::tu}"'
+	@echo 'LIST:ts:tu="${LIST:ts:tu}"'
+	@echo 'LIST:tu:ts/="${LIST:tu:ts/}"'
+	@echo 'LIST:ts:="${LIST:ts:}"'
+	@echo 'LIST:ts="${LIST:ts}"'
+	@echo 'LIST:ts:S/two/2/="${LIST:ts:S/two/2/}"'
+	@echo 'LIST:S/two/2/:ts="${LIST:S/two/2/:ts}"'
+	@echo 'LIST:ts/:S/two/2/="${LIST:ts/:S/two/2/}"'
+	@echo "Pretend the '/' in '/n' etc. below are back-slashes."
+	@${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:tx="${LIST:tx}"'
+	@${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?'
Index: src/usr.bin/make/unit-tests/modword.exp
diff -u /dev/null src/usr.bin/make/unit-tests/modword.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modword.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,122 @@
+make: Bad modifier `:[]' for LIST
+LIST:[]="" is an error
+LIST:[0]="one two three four five six"
+LIST:[0x0]="one two three four five six"
+LIST:[000]="one two three four five six"
+LIST:[*]="one two three four five six"
+LIST:[@]="one two three four five six"
+LIST:[0]:C/ /,/="one,two three four five six"
+LIST:[0]:C/ /,/g="one,two,three,four,five,six"
+LIST:[0]:C/ /,/1g="one,two,three,four,five,six"
+LIST:[*]:C/ /,/="one,two three four five six"
+LIST:[*]:C/ /,/g="one,two,three,four,five,six"
+LIST:[*]:C/ /,/1g="one,two,three,four,five,six"
+LIST:[@]:C/ /,/="one two three four five six"
+LIST:[@]:C/ /,/g="one two three four five six"
+LIST:[@]:C/ /,/1g="one two three four five six"
+LIST:[@]:[0]:C/ /,/="one,two three four five six"
+LIST:[0]:[@]:C/ /,/="one two three four five six"
+LIST:[@]:[*]:C/ /,/="one,two three four five six"
+LIST:[*]:[@]:C/ /,/="one two three four five six"
+EMPTY=""
+EMPTY:[#]="1" == 1 ?
+ESCAPEDSPACE="\ "
+ESCAPEDSPACE:[#]="1" == 1 ?
+REALLYSPACE=" "
+REALLYSPACE:[#]="1" == 1 ?
+LIST:[#]="6"
+LIST:[0]:[#]="1" == 1 ?
+LIST:[*]:[#]="1" == 1 ?
+LIST:[@]:[#]="6"
+LIST:[1]:[#]="1"
+LIST:[1..3]:[#]="3"
+EMPTY:[1]=""
+ESCAPEDSPACE="\ "
+ESCAPEDSPACE:[1]="\ "
+REALLYSPACE=" "
+REALLYSPACE:[1]="" == "" ?
+REALLYSPACE:[*]:[1]=" " == " " ?
+LIST:[1]="one"
+make: Bad modifier `:[1.]' for LIST
+LIST:[1.]="" is an error
+make: Bad modifier `:[1].' for LIST
+LIST:[1].="}" is an error
+LIST:[2]="two"
+LIST:[6]="six"
+LIST:[7]=""
+LIST:[999]=""
+make: Bad modifier `:[-]' for LIST
+LIST:[-]="" is an error
+make: Bad modifier `:[--]' for LIST
+LIST:[--]="" is an error
+LIST:[-1]="six"
+LIST:[-2]="five"
+LIST:[-6]="one"
+LIST:[-7]=""
+LIST:[-999]=""
+LONGLIST:[17]="17"
+LONGLIST:[0x11]="17"
+LONGLIST:[021]="17"
+LIST:[0]:[1]="one two three four five six"
+LIST:[*]:[1]="one two three four five six"
+LIST:[@]:[1]="one"
+LIST:[0]:[2]=""
+LIST:[*]:[2]=""
+LIST:[@]:[2]="two"
+LIST:[*]:C/ /,/:[2]=""
+LIST:[*]:C/ /,/:[*]:[2]=""
+LIST:[*]:C/ /,/:[@]:[2]="three"
+make: Bad modifier `:[1.]' for LIST
+LIST:[1.]="" is an error
+make: Bad modifier `:[1..]' for LIST
+LIST:[1..]="" is an error
+LIST:[1..1]="one"
+make: Bad modifier `:[1..1.]' for LIST
+LIST:[1..1.]="" is an error
+LIST:[1..2]="one two"
+LIST:[2..1]="two one"
+LIST:[3..-2]="three four five"
+LIST:[-4..4]="three four"
+make: Bad modifier `:[0..1]' for LIST
+LIST:[0..1]="" is an error
+make: Bad modifier `:[-1..0]' for LIST
+LIST:[-1..0]="" is an error
+LIST:[-1..1]="six five four three two one"
+LIST:[0..0]="one two three four five six"
+LIST:[3..99]="three four five six"
+LIST:[-3..-99]="four three two one"
+LIST:[-99..-3]="one two three four"
+HASH="#" == "#" ?
+LIST:[${HASH}]="6"
+LIST:[${ZERO}]="one two three four five six"
+LIST:[${ZERO}x${ONE}]="one"
+LIST:[${ONE}]="one"
+LIST:[${MINUSONE}]="six"
+LIST:[${STAR}]="one two three four five six"
+LIST:[${AT}]="one two three four five six"
+make: Bad modifier `:[${EMPTY' for LIST
+LIST:[${EMPTY}]="" is an error
+LIST:[${LONGLIST:[21]:S/2//}]="one"
+LIST:[${LIST:[#]}]="six"
+LIST:[${LIST:[${HASH}]}]="six"
+LIST:S/ /,/="one two three four five six"
+LIST:S/ /,/W="one,two three four five six"
+LIST:S/ /,/gW="one,two,three,four,five,six"
+EMPTY:S/^/,/=","
+EMPTY:S/^/,/W=","
+LIST:C/ /,/="one two three four five six"
+LIST:C/ /,/W="one,two three four five six"
+LIST:C/ /,/gW="one,two,three,four,five,six"
+EMPTY:C/^/,/=","
+EMPTY:C/^/,/W=","
+LIST:tW="one two three four five six"
+LIST:tw="one two three four five six"
+LIST:tW:C/ /,/="one,two three four five six"
+LIST:tW:C/ /,/g="one,two,three,four,five,six"
+LIST:tW:C/ /,/1g="one,two,three,four,five,six"
+LIST:tw:C/ /,/="one two three four five six"
+LIST:tw:C/ /,/g="one two three four five six"
+LIST:tw:C/ /,/1g="one two three four five six"
+LIST:tw:tW:C/ /,/="one,two three four five six"
+LIST:tW:tw:C/ /,/="one two three four five six"
+exit status 0
Index: src/usr.bin/make/unit-tests/modword.mk
diff -u /dev/null src/usr.bin/make/unit-tests/modword.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/modword.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,151 @@
+# $Id: modword.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+#
+# Test behaviour of new :[] modifier
+
+all: mod-squarebrackets mod-S-W mod-C-W mod-tW-tw
+
+LIST= one two three
+LIST+= four five six
+LONGLIST= 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+
+EMPTY= # the space should be ignored
+ESCAPEDSPACE=\ # escaped space before the '#'
+REALLYSPACE:=${EMPTY:C/^/ /W}
+HASH= \#
+AT= @
+STAR= *
+ZERO= 0
+ONE= 1
+MINUSONE= -1
+
+mod-squarebrackets: mod-squarebrackets-0-star-at \
+	mod-squarebrackets-hash \
+	mod-squarebrackets-n \
+	mod-squarebrackets-start-end \
+	mod-squarebrackets-nested
+
+mod-squarebrackets-0-star-at:
+	@echo 'LIST:[]="${LIST:[]}" is an error'
+	@echo 'LIST:[0]="${LIST:[0]}"'
+	@echo 'LIST:[0x0]="${LIST:[0x0]}"'
+	@echo 'LIST:[000]="${LIST:[000]}"'
+	@echo 'LIST:[*]="${LIST:[*]}"'
+	@echo 'LIST:[@]="${LIST:[@]}"'
+	@echo 'LIST:[0]:C/ /,/="${LIST:[0]:C/ /,/}"'
+	@echo 'LIST:[0]:C/ /,/g="${LIST:[0]:C/ /,/g}"'
+	@echo 'LIST:[0]:C/ /,/1g="${LIST:[0]:C/ /,/1g}"'
+	@echo 'LIST:[*]:C/ /,/="${LIST:[*]:C/ /,/}"'
+	@echo 'LIST:[*]:C/ /,/g="${LIST:[*]:C/ /,/g}"'
+	@echo 'LIST:[*]:C/ /,/1g="${LIST:[*]:C/ /,/1g}"'
+	@echo 'LIST:[@]:C/ /,/="${LIST:[@]:C/ /,/}"'
+	@echo 'LIST:[@]:C/ /,/g="${LIST:[@]:C/ /,/g}"'
+	@echo 'LIST:[@]:C/ /,/1g="${LIST:[@]:C/ /,/1g}"'
+	@echo 'LIST:[@]:[0]:C/ /,/="${LIST:[@]:[0]:C/ /,/}"'
+	@echo 'LIST:[0]:[@]:C/ /,/="${LIST:[0]:[@]:C/ /,/}"'
+	@echo 'LIST:[@]:[*]:C/ /,/="${LIST:[@]:[*]:C/ /,/}"'
+	@echo 'LIST:[*]:[@]:C/ /,/="${LIST:[*]:[@]:C/ /,/}"'
+
+mod-squarebrackets-hash:
+	@echo 'EMPTY="${EMPTY}"'
+	@echo 'EMPTY:[#]="${EMPTY:[#]}" == 1 ?'
+	@echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"'
+	@echo 'ESCAPEDSPACE:[#]="${ESCAPEDSPACE:[#]}" == 1 ?'
+	@echo 'REALLYSPACE="${REALLYSPACE}"'
+	@echo 'REALLYSPACE:[#]="${REALLYSPACE:[#]}" == 1 ?'
+	@echo 'LIST:[#]="${LIST:[#]}"'
+	@echo 'LIST:[0]:[#]="${LIST:[0]:[#]}" == 1 ?'
+	@echo 'LIST:[*]:[#]="${LIST:[*]:[#]}" == 1 ?'
+	@echo 'LIST:[@]:[#]="${LIST:[@]:[#]}"'
+	@echo 'LIST:[1]:[#]="${LIST:[1]:[#]}"'
+	@echo 'LIST:[1..3]:[#]="${LIST:[1..3]:[#]}"'
+
+mod-squarebrackets-n:
+	@echo 'EMPTY:[1]="${EMPTY:[1]}"'
+	@echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"'
+	@echo 'ESCAPEDSPACE:[1]="${ESCAPEDSPACE:[1]}"'
+	@echo 'REALLYSPACE="${REALLYSPACE}"'
+	@echo 'REALLYSPACE:[1]="${REALLYSPACE:[1]}" == "" ?'
+	@echo 'REALLYSPACE:[*]:[1]="${REALLYSPACE:[*]:[1]}" == " " ?'
+	@echo 'LIST:[1]="${LIST:[1]}"'
+	@echo 'LIST:[1.]="${LIST:[1.]}" is an error'
+	@echo 'LIST:[1].="${LIST:[1].}" is an error'
+	@echo 'LIST:[2]="${LIST:[2]}"'
+	@echo 'LIST:[6]="${LIST:[6]}"'
+	@echo 'LIST:[7]="${LIST:[7]}"'
+	@echo 'LIST:[999]="${LIST:[999]}"'
+	@echo 'LIST:[-]="${LIST:[-]}" is an error'
+	@echo 'LIST:[--]="${LIST:[--]}" is an error'
+	@echo 'LIST:[-1]="${LIST:[-1]}"'
+	@echo 'LIST:[-2]="${LIST:[-2]}"'
+	@echo 'LIST:[-6]="${LIST:[-6]}"'
+	@echo 'LIST:[-7]="${LIST:[-7]}"'
+	@echo 'LIST:[-999]="${LIST:[-999]}"'
+	@echo 'LONGLIST:[17]="${LONGLIST:[17]}"'
+	@echo 'LONGLIST:[0x11]="${LONGLIST:[0x11]}"'
+	@echo 'LONGLIST:[021]="${LONGLIST:[021]}"'
+	@echo 'LIST:[0]:[1]="${LIST:[0]:[1]}"'
+	@echo 'LIST:[*]:[1]="${LIST:[*]:[1]}"'
+	@echo 'LIST:[@]:[1]="${LIST:[@]:[1]}"'
+	@echo 'LIST:[0]:[2]="${LIST:[0]:[2]}"'
+	@echo 'LIST:[*]:[2]="${LIST:[*]:[2]}"'
+	@echo 'LIST:[@]:[2]="${LIST:[@]:[2]}"'
+	@echo 'LIST:[*]:C/ /,/:[2]="${LIST:[*]:C/ /,/:[2]}"'
+	@echo 'LIST:[*]:C/ /,/:[*]:[2]="${LIST:[*]:C/ /,/:[*]:[2]}"'
+	@echo 'LIST:[*]:C/ /,/:[@]:[2]="${LIST:[*]:C/ /,/:[@]:[2]}"'
+
+mod-squarebrackets-start-end:
+	@echo 'LIST:[1.]="${LIST:[1.]}" is an error'
+	@echo 'LIST:[1..]="${LIST:[1..]}" is an error'
+	@echo 'LIST:[1..1]="${LIST:[1..1]}"'
+	@echo 'LIST:[1..1.]="${LIST:[1..1.]}" is an error'
+	@echo 'LIST:[1..2]="${LIST:[1..2]}"'
+	@echo 'LIST:[2..1]="${LIST:[2..1]}"'
+	@echo 'LIST:[3..-2]="${LIST:[3..-2]}"'
+	@echo 'LIST:[-4..4]="${LIST:[-4..4]}"'
+	@echo 'LIST:[0..1]="${LIST:[0..1]}" is an error'
+	@echo 'LIST:[-1..0]="${LIST:[-1..0]}" is an error'
+	@echo 'LIST:[-1..1]="${LIST:[-1..1]}"'
+	@echo 'LIST:[0..0]="${LIST:[0..0]}"'
+	@echo 'LIST:[3..99]="${LIST:[3..99]}"'
+	@echo 'LIST:[-3..-99]="${LIST:[-3..-99]}"'
+	@echo 'LIST:[-99..-3]="${LIST:[-99..-3]}"'
+
+mod-squarebrackets-nested:
+	@echo 'HASH="${HASH}" == "#" ?'
+	@echo 'LIST:[$${HASH}]="${LIST:[${HASH}]}"'
+	@echo 'LIST:[$${ZERO}]="${LIST:[${ZERO}]}"'
+	@echo 'LIST:[$${ZERO}x$${ONE}]="${LIST:[${ZERO}x${ONE}]}"'
+	@echo 'LIST:[$${ONE}]="${LIST:[${ONE}]}"'
+	@echo 'LIST:[$${MINUSONE}]="${LIST:[${MINUSONE}]}"'
+	@echo 'LIST:[$${STAR}]="${LIST:[${STAR}]}"'
+	@echo 'LIST:[$${AT}]="${LIST:[${AT}]}"'
+	@echo 'LIST:[$${EMPTY}]="${LIST:[${EMPTY}]}" is an error'
+	@echo 'LIST:[$${LONGLIST:[21]:S/2//}]="${LIST:[${LONGLIST:[21]:S/2//}]}"'
+	@echo 'LIST:[$${LIST:[#]}]="${LIST:[${LIST:[#]}]}"'
+	@echo 'LIST:[$${LIST:[$${HASH}]}]="${LIST:[${LIST:[${HASH}]}]}"'
+
+mod-C-W:
+	@echo 'LIST:C/ /,/="${LIST:C/ /,/}"'
+	@echo 'LIST:C/ /,/W="${LIST:C/ /,/W}"'
+	@echo 'LIST:C/ /,/gW="${LIST:C/ /,/gW}"'
+	@echo 'EMPTY:C/^/,/="${EMPTY:C/^/,/}"'
+	@echo 'EMPTY:C/^/,/W="${EMPTY:C/^/,/W}"'
+
+mod-S-W:
+	@echo 'LIST:S/ /,/="${LIST:S/ /,/}"'
+	@echo 'LIST:S/ /,/W="${LIST:S/ /,/W}"'
+	@echo 'LIST:S/ /,/gW="${LIST:S/ /,/gW}"'
+	@echo 'EMPTY:S/^/,/="${EMPTY:S/^/,/}"'
+	@echo 'EMPTY:S/^/,/W="${EMPTY:S/^/,/W}"'
+
+mod-tW-tw:
+	@echo 'LIST:tW="${LIST:tW}"'
+	@echo 'LIST:tw="${LIST:tw}"'
+	@echo 'LIST:tW:C/ /,/="${LIST:tW:C/ /,/}"'
+	@echo 'LIST:tW:C/ /,/g="${LIST:tW:C/ /,/g}"'
+	@echo 'LIST:tW:C/ /,/1g="${LIST:tW:C/ /,/1g}"'
+	@echo 'LIST:tw:C/ /,/="${LIST:tw:C/ /,/}"'
+	@echo 'LIST:tw:C/ /,/g="${LIST:tw:C/ /,/g}"'
+	@echo 'LIST:tw:C/ /,/1g="${LIST:tw:C/ /,/1g}"'
+	@echo 'LIST:tw:tW:C/ /,/="${LIST:tw:tW:C/ /,/}"'
+	@echo 'LIST:tW:tw:C/ /,/="${LIST:tW:tw:C/ /,/}"'
Index: src/usr.bin/make/unit-tests/order.exp
diff -u /dev/null src/usr.bin/make/unit-tests/order.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/order.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,4 @@
+Making the.c
+Making the.h
+Making the.o from the.h the.c
+exit status 0
Index: src/usr.bin/make/unit-tests/order.mk
diff -u /dev/null src/usr.bin/make/unit-tests/order.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/order.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,20 @@
+# $NetBSD: order.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+# Test that .ORDER is handled correctly.
+# The explicit dependency the.o: the.h will make us examine the.h
+# the .ORDER will prevent us building it immediately,
+# we should then examine the.c rather than stop.
+
+all: the.o
+
+.ORDER: the.c the.h
+
+the.c the.h:
+	@echo Making $@
+
+.SUFFIXES: .o .c
+
+.c.o:
+	@echo Making $@ from $?
+
+the.o: the.h
Index: src/usr.bin/make/unit-tests/phony-end.exp
diff -u /dev/null src/usr.bin/make/unit-tests/phony-end.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/phony-end.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,6 @@
+.TARGET="phony" .PREFIX="phony" .IMPSRC=""
+.TARGET="all" .PREFIX="all" .IMPSRC=""
+.TARGET="ok" .PREFIX="ok" .IMPSRC=""
+.TARGET="also.ok" .PREFIX="also.ok" .IMPSRC=""
+.TARGET="bug" .PREFIX="bug" .IMPSRC=""
+exit status 0
Index: src/usr.bin/make/unit-tests/phony-end.mk
diff -u /dev/null src/usr.bin/make/unit-tests/phony-end.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/phony-end.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,9 @@
+# $Id: phony-end.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+all ok also.ok bug phony:
+	@echo '${.TARGET .PREFIX .IMPSRC:L:@v@$v="${$v}"@}'
+
+.END:	ok also.ok bug
+
+phony bug:	.PHONY
+all: phony
Index: src/usr.bin/make/unit-tests/posix.exp
diff -u /dev/null src/usr.bin/make/unit-tests/posix.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/posix.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,23 @@
+Posix says we should execute the command as if run by system(3)
+Expect 'Hello,' and 'World!'
+Hello,
+World!
+a command
+a command prefixed by '+' executes even with -n
+another command
+make -n
+echo a command
+echo "a command prefixed by '+' executes even with -n"
+a command prefixed by '+' executes even with -n
+echo another command
+make -n -j1
+{ echo a command 
+} || exit $?
+echo "a command prefixed by '+' executes even with -n"
+a command prefixed by '+' executes even with -n
+{ echo another command 
+} || exit $?
+Now we expect an error...
+*** Error code 1 (continuing)
+`all' not remade because of errors.
+exit status 0
Index: src/usr.bin/make/unit-tests/posix.mk
diff -u /dev/null src/usr.bin/make/unit-tests/posix.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/posix.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,24 @@
+# $Id: posix.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+all:	x plus subs err
+
+x:
+	@echo "Posix says we should execute the command as if run by system(3)"
+	@echo "Expect 'Hello,' and 'World!'"
+	@echo Hello,; false; echo "World!"
+
+plus:
+	@echo a command
+	+@echo "a command prefixed by '+' executes even with -n"
+	@echo another command
+
+subs:
+	@echo make -n
+	@${.MAKE} -f ${MAKEFILE} -n plus
+	@echo make -n -j1
+	@${.MAKE} -f ${MAKEFILE} -n -j1 plus
+
+err:
+	@(echo Now we expect an error...; exit 1)
+	@echo "Oops! you shouldn't see this!"
+
Index: src/usr.bin/make/unit-tests/qequals.exp
diff -u /dev/null src/usr.bin/make/unit-tests/qequals.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/qequals.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,2 @@
+V.i386 ?= OK
+exit status 0
Index: src/usr.bin/make/unit-tests/qequals.mk
diff -u /dev/null src/usr.bin/make/unit-tests/qequals.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/qequals.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,8 @@
+# $Id: qequals.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
+
+M= i386
+V.i386= OK
+V.$M ?= bug
+
+all:
+	@echo 'V.$M ?= ${V.$M}'
Index: src/usr.bin/make/unit-tests/sunshcmd.exp
diff -u /dev/null src/usr.bin/make/unit-tests/sunshcmd.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/sunshcmd.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,4 @@
+TEST1=hello
+TEST2=bye
+TEST3=later
+exit status 0
Index: src/usr.bin/make/unit-tests/sunshcmd.mk
diff -u /dev/null src/usr.bin/make/unit-tests/sunshcmd.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/sunshcmd.mk	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,10 @@
+BYECMD		= echo bye
+LATERCMD	= echo later
+TEST1 :sh	= echo hello
+TEST2 :sh	= ${BYECMD}
+TEST3		= ${LATERCMD:sh}
+
+all:
+	@echo "TEST1=${TEST1}"
+	@echo "TEST2=${TEST2}"
+	@echo "TEST3=${TEST3}"
Index: src/usr.bin/make/unit-tests/sysv.exp
diff -u /dev/null src/usr.bin/make/unit-tests/sysv.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/sysv.exp	Thu Aug 21 13:44:51 2014
@@ -0,0 +1,7 @@
+FOOBAR =
+FOOBAR = foobar fubar
+fun
+fun
+fun
+In the Sun
+exit status 0
Index: src/usr.bin/make/unit-tests/sysv.mk
diff -u /dev/null src/usr.bin/make/unit-tests/sysv.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/sysv.mk	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,26 @@
+# $Id: sysv.mk,v 1.1 2014/08/21 13:44:52 apb Exp $
+
+FOO ?=
+FOOBAR = $(FOO:=bar)
+
+_this := ${.PARSEDIR}/${.PARSEFILE}
+
+B = /b
+S = /
+FUN = ${B}${S}fun
+SUN = the Sun
+
+# we expect nothing when FOO is empty
+all: foo fun
+
+foo:
+	@echo FOOBAR = $(FOOBAR)
+.if empty(FOO)
+	@FOO="foo fu" ${.MAKE} -f ${_this} foo
+.endif
+
+fun:
+	@echo ${FUN:T}
+	@echo ${FUN:${B}${S}fun=fun}
+	@echo ${FUN:${B}${S}%=%}
+	@echo ${In:L:%=% ${SUN}}
Index: src/usr.bin/make/unit-tests/ternary.exp
diff -u /dev/null src/usr.bin/make/unit-tests/ternary.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/ternary.exp	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,10 @@
+The answer is unknown
+The answer is unknown
+The answer is empty
+The answer is known
+The answer is 
+The answer is empty
+The answer is known
+The answer is 42
+The answer is 42
+exit status 0
Index: src/usr.bin/make/unit-tests/ternary.mk
diff -u /dev/null src/usr.bin/make/unit-tests/ternary.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/ternary.mk	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,8 @@
+
+all:
+	@for x in "" A= A=42; do ${.MAKE} -f ${MAKEFILE} show $$x; done
+
+show:
+	@echo "The answer is ${A:?known:unknown}"
+	@echo "The answer is ${A:?$A:unknown}"
+	@echo "The answer is ${empty(A):?empty:$A}"
Index: src/usr.bin/make/unit-tests/unexport-env.exp
diff -u /dev/null src/usr.bin/make/unit-tests/unexport-env.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/unexport-env.exp	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,2 @@
+UT_TEST=unexport-env
+exit status 0
Index: src/usr.bin/make/unit-tests/unexport-env.mk
diff -u /dev/null src/usr.bin/make/unit-tests/unexport-env.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/unexport-env.mk	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,14 @@
+# $Id: unexport-env.mk,v 1.1 2014/08/21 13:44:52 apb Exp $
+
+# pick up a bunch of exported vars
+.include "export.mk"
+
+# an example of setting up a minimal environment.
+PATH = /bin:/usr/bin:/sbin:/usr/sbin
+
+# now clobber the environment to just PATH and UT_TEST
+UT_TEST = unexport-env
+
+# this removes everything
+.unexport-env
+.export PATH UT_TEST
Index: src/usr.bin/make/unit-tests/unexport.exp
diff -u /dev/null src/usr.bin/make/unit-tests/unexport.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/unexport.exp	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,4 @@
+UT_DOLLAR=This is $UT_FU
+UT_FU=fubar
+UT_TEST=unexport
+exit status 0
Index: src/usr.bin/make/unit-tests/unexport.mk
diff -u /dev/null src/usr.bin/make/unit-tests/unexport.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/unexport.mk	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,8 @@
+# $Id: unexport.mk,v 1.1 2014/08/21 13:44:52 apb Exp $
+
+# pick up a bunch of exported vars
+.include "export.mk"
+
+.unexport UT_ZOO UT_FOO
+
+UT_TEST = unexport
Index: src/usr.bin/make/unit-tests/varcmd.exp
diff -u /dev/null src/usr.bin/make/unit-tests/varcmd.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/varcmd.exp	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,9 @@
+default FU=<v>fu</v> FOO=<v>foo</v> VAR=<v></v>
+two FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v>
+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>
+five v=is x k=is x
+six v=is y k=is y
+show-v v=override k=override
+exit status 0
Index: src/usr.bin/make/unit-tests/varcmd.mk
diff -u /dev/null src/usr.bin/make/unit-tests/varcmd.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/varcmd.mk	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,49 @@
+# $Id: varcmd.mk,v 1.1 2014/08/21 13:44:52 apb Exp $
+#
+# Test behaviour of recursive make and vars set on command line.
+
+FU=fu
+FOO?=foo
+.if !empty(.TARGETS)
+TAG=${.TARGETS}
+.endif
+TAG?=default
+
+all:	one
+
+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
+
+two:	show
+	@${.MAKE} -f ${MAKEFILE} three
+
+three:	show
+	@${.MAKE} -f ${MAKEFILE} four
+
+
+.ifmake four
+VAR=Internal
+.MAKEOVERRIDES+= VAR
+.endif
+
+four:	show
+	@${.MAKE} -f ${MAKEFILE} five
+
+M = x
+V.y = is y
+V.x = is x
+V := ${V.$M}
+K := ${V}
+
+show-v:
+	@echo '${TAG} v=${V} k=${K}'
+
+five:	show show-v
+	@${.MAKE} -f ${MAKEFILE} M=y six
+
+six:	show-v
+	@${.MAKE} -f ${MAKEFILE} V=override show-v
+
Index: src/usr.bin/make/unit-tests/varshell.exp
diff -u /dev/null src/usr.bin/make/unit-tests/varshell.exp:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/varshell.exp	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,12 @@
+sh: /bin/no/such/command: not found
+make: "varshell.mk" line 5: warning: "/bin/no/such/command" returned non-zero status
+make: "varshell.mk" line 6: warning: "kill -ALRM $$" exited on a signal
+make: "varshell.mk" line 7: warning: "false" returned non-zero status
+make: "varshell.mk" line 8: warning: "echo "output before the error"; false" returned non-zero status
+EXEC_FAILED=''
+TERMINATED_BY_SIGNAL=''
+ERROR_NO_OUTPUT=''
+ERROR_WITH_OUTPUT='output before the error'
+NO_ERROR_NO_OUTPUT=''
+NO_ERROR_WITH_OUTPUT='this is good'
+exit status 0
Index: src/usr.bin/make/unit-tests/varshell.mk
diff -u /dev/null src/usr.bin/make/unit-tests/varshell.mk:1.1
--- /dev/null	Thu Aug 21 13:44:52 2014
+++ src/usr.bin/make/unit-tests/varshell.mk	Thu Aug 21 13:44:52 2014
@@ -0,0 +1,18 @@
+# $Id: varshell.mk,v 1.1 2014/08/21 13:44:52 apb Exp $
+#
+# Test VAR != shell command
+
+EXEC_FAILED		!= /bin/no/such/command
+TERMINATED_BY_SIGNAL	!= kill -ALRM $$$$
+ERROR_NO_OUTPUT		!= false
+ERROR_WITH_OUTPUT	!= echo "output before the error"; false
+NO_ERROR_NO_OUTPUT	!= true
+NO_ERROR_WITH_OUTPUT	!= echo "this is good"
+
+allvars= EXEC_FAILED TERMINATED_BY_SIGNAL ERROR_NO_OUTPUT ERROR_WITH_OUTPUT \
+	NO_ERROR_NO_OUTPUT NO_ERROR_WITH_OUTPUT
+
+all:
+.for v in ${allvars}
+	@echo ${v}=\'${${v}}\'
+.endfor

Reply via email to