Subject: fix for :ts
To: Alan Barrett <apb@cequrux.com>
From: Simon J. Gerraty <sjg@crufty.net>
List: tech-toolchain
Date: 07/28/2003 11:52:32
The patch to var.c below is from Alan, and fixes a parse error for
things like:  ${FU${BAR:ts}:T}

I've also added the start of a unit-test suite - to help ensure that
fixing make - doesn't break it.  A reach over makefile in
regress/usr.sbin/make should also be added - but the actual tests
should reside with make itself - so that 
a/ bmake can benefit ;-)
b/ within emacs one can easily run the tests after compiling make.

--sjg

Index: Makefile
===================================================================
RCS file: /cvsroot/src/usr.bin/make/Makefile,v
retrieving revision 1.28
diff -u -p -r1.28 Makefile
--- Makefile	2003/07/26 16:04:29	1.28
+++ Makefile	2003/07/28 18:45:24
@@ -27,3 +27,7 @@ CPPFLAGS_main.o:= "-DMAKE_VERSION=\"${MA
 CPPFLAGS+= ${CPPFLAGS_${.TARGET}}
 main.o:	${OBJS:Nmain.o} ${MAKEFILE}
 COPTS.var.c+= -Wno-cast-qual
+
+# A simple unit-test driver to help catch regressions
+accept test:
+	cd ${.CURDIR} && ${.MAKE} -f unit-tests MAKE=${TEST_MAKE:U./${PROG:T}} ${.TARGET}
Index: var.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/var.c,v
retrieving revision 1.75
diff -u -p -r1.75 var.c
--- var.c	2003/07/23 18:06:46	1.75
+++ var.c	2003/07/28 18:45:26
@@ -2261,7 +2261,8 @@ Var_Parse(const char *str, GNode *ctxt, 
 			     */
 			    VarPattern pattern;
 
-			    if (tstr[3] == endc || tstr[3] == ':') {
+			    if (tstr[2] != endc &&
+				(tstr[3] == endc || tstr[3] == ':')) {
 				varSpace = tstr[2];
 				cp = tstr + 3;
 			    } else if (tstr[2] == endc || tstr[2] == ':') {
--- /dev/null	Mon Jul 28 11:44:40 2003
+++ unit-tests	Mon Jul 28 11:43:29 2003
@@ -0,0 +1,58 @@
+# $Id$
+#
+# Unit tests for make(1)
+# The main targets are:
+# 
+# all:    run all the tests
+# test:   run 'all', capture output 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 which should be hooked
+# into the 'all' target.
+# 
+
+.MAIN: all
+
+all: mod-ts
+
+LIST= one two three
+LIST+= four five six
+
+FU_mod-ts = a / b / cool
+
+mod-ts:
+	@echo LIST='${LIST}'
+	@echo LIST:ts,='${LIST:ts,}'
+	@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 "LIST:ts\n='${LIST:ts\n}'"
+	@echo "LIST:ts\t='${LIST:ts\t}'"
+	@echo "LIST:ts\012:tu='${LIST:ts\012:tu}'"
+	@echo "LIST:tx='${LIST:tx}'"
+	@echo "LIST:ts\a:tu='${LIST:ts\a:tu}'"
+	@echo "FU_$@='${FU_${@:ts}:ts}'"
+	@echo "FU_$@:ts:T='${FU_${@:ts}:ts:T}' == cool?"
+
+
+.include <bsd.obj.mk>
+
+# here is the driver
+.NOPATH:  test.out
+test.out:	${MAKEFILE} test.exp
+	@echo "${MAKE} -f ${MAKEFILE} > ${.TARGET} 2>&1"
+	@${MAKE} -f ${MAKEFILE} > ${.TARGET} 2>&1 || { \
+	tail ${.TARGET}; mv ${.TARGET} ${.PREFIX}.fail; exit 1; }
+	@[ ! -f ${.CURDIR}/${.PREFIX}.exp ] || { \
+	echo diff -u ${.CURDIR}/${.PREFIX}.exp ${.TARGET}; \
+	diff -u ${.CURDIR}/${.PREFIX}.exp ${.TARGET}; }
+
+test:	test.out
+accept:	test.out
+	mv test.out ${.CURDIR}/test.exp
+