shithub: mc

Download patch

ref: 49ea47caf3cb37e0fe667d3ed833d12d670bae68
parent: c2a04cf2cb447ffb3c24d91e7978ef170460bf46
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Jun 14 22:02:23 EDT 2015

Update libregex tests to run in mbld.

    Drop the hacky shell.

--- a/libregex/bld.sub
+++ b/libregex/bld.sub
@@ -17,3 +17,5 @@
 gen ranges.myr {durable} =
 	mkchartab -a -p_ranges UnicodeData.txt -o ranges.myr
 ;;
+
+sub = test ;;
--- a/libregex/test/Makefile
+++ /dev/null
@@ -1,20 +1,0 @@
-# don't build anything for 'all'
-all: 
-	$(MAKE) -C ..
-
-check:
-	./runtest.sh
-
-.PHONY: %
-%:
-	./runtest.sh $@
-
-.PHONY: clean
-clean:
-	rm -f testmatch.use testmatch.o
-	@for i in `awk '/^[A-Z]/{print $$2}' tests`; do \
-	    echo rm -f $$i; \
-	    rm -f $$i; \
-	done
-
-install:
--- a/libregex/test/basic.myr
+++ b/libregex/test/basic.myr
@@ -19,13 +19,21 @@
 		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
 		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
 	][:], "")
-	testmatch(".*bc", "Abc")
-	testmatch("(a*)*", "a")
-	testmatch("(aa|aab?)*", s)
+	testmatch(".*bc", "Abc", `std.Some [][:])
+	testmatch("(a*)*", "a", `std.Some ["a"][:])
+	testmatch("(aa|aab?)*", s, `std.Some ["aa"][:])
         /* greedy matches */
-        testmatch("(<.*>).*", "<a foo> blah <bar>")
-        testmatch("(<.+>).*", "<a foo> blah <bar>")
+	testmatch("(<.*>).*", "<a foo> blah <bar>", `std.Some [
+			"<a foo> blah <bar>",
+		][:])
+	testmatch("(<.+>).*", "<a foo> blah <bar>", `std.Some [
+			"<a foo> blah <bar>",
+		][:])
         /* reluctant matches */
-        testmatch("(<.*?>).*", "<a foo> blah <bar>")
-        testmatch("(<.+?>).*", "<a foo> blah <bar>")
+	testmatch("(<.*?>).*", "<a foo> blah <bar>", `std.Some [
+			"<a foo>",
+		][:])
+	testmatch("(<.+?>).*", "<a foo> blah <bar>", `std.Some [
+			"<a foo>",
+		][:])
 }
--- /dev/null
+++ b/libregex/test/bld.sub
@@ -1,0 +1,7 @@
+test basic = basic.myr testmatch.myr;;
+test boundaries = boundaries.myr testmatch.myr;;
+test capture = capture.myr testmatch.myr;;
+test class = class.myr testmatch.myr;;
+test failmatch = failmatch.myr testmatch.myr;;
+test negclass = negclass.myr testmatch.myr;;
+test unicode = unicode.myr testmatch.myr;;
--- a/libregex/test/boundaries.myr
+++ b/libregex/test/boundaries.myr
@@ -1,17 +1,36 @@
+use std
 use "testmatch.use"
 
 const main = {
 	/* expected matches */
-	testmatch("\\<([a-z]*)\\>", "abcdef")	/* whole word */
-	testmatch(".*(\\<.*\\>).*", "!m!")	/* single char word in midstring */
-	testmatch(".*(\\<.*\\>).*", "!m")	/* single char word at end of string */
-	testmatch(".*(\\<.*\\>).*", "m!")	/* single char word at start of string */
-	testmatch(".*(\\<.*\\>).*", "!@#!!matches!!%!")	/* word in midstring */
-	testmatch(".*(\\<.*\\>).*", "matches!!%!")	/* word at start of string */
-	testmatch(".*(\\<.*\\>).*", "!@#!!matches")	/* word at end of string */
-	testmatch(".*(\\<.*\\>).*", "!@#!!matches!!%!foo")	/* matches last word in string */
-	testmatch(".*(\\<.*\\>).*", "123")	/* numbers are also word bounds */
+	testmatch("\\<([a-z]*)\\>", "abcdef", `std.Some [
+		"abcdef",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!m!", `std.Some [	/* single char word in midstring */
+		"m",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!m", `std.Some [	/* single char word at end of string */
+		"m",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "m!", `std.Some [	/* single char word at start of string */
+		"m",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!@#!!matches!!%!", `std.Some [	/* word in midstring */
+		"matches",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "matches!!%!", `std.Some [	/* word at start of string */
+		"matches",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!@#!!matches", `std.Some [	/* word at end of string */
+		"matches",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "!@#!!matches!!%!foo", `std.Some [	/* matches last word in string */
+		"foo",
+	][:])
+	testmatch(".*(\\<.*\\>).*", "123", `std.Some [	/* numbers are also word bounds */
+		"123",
+	][:])
 	
 	/* nonmatches */
-	testmatch("\\<([a-z]*)\\>foo", "abcdefoo")	/* word boundary needed in midstring */
+	testmatch("\\<([a-z]*)\\>foo", "abcdefoo", `std.None)	/* word boundary needed in midstring */
 }
--- a/libregex/test/capture.myr
+++ b/libregex/test/capture.myr
@@ -1,9 +1,17 @@
+use std
 use "testmatch.use"
 
 const main = {
-	testmatch("A(.*)", "Abc")
-	testmatch("A(.*)e", "Abcde")
-	testmatch("(a|b)+", "abab")
-	testmatch("A(b(.*)d)e", "Abcde")
-	testmatch("(a?)(a*)(a?)", "aaaa")
+	testmatch("A(.*)", "Abc", `std.Some ["bc"][:])
+	testmatch("A(.*)e", "Abcde", `std.Some ["bcd"][:])
+	testmatch("(a|b)+", "abab", `std.Some ["b"][:])
+	testmatch("A(b(.*)d)e", "Abcde", `std.Some [
+		"bcd",
+		"c"
+	][:])
+	testmatch("(a?)(a*)(a?)", "aaaa", `std.Some [
+		"a",
+		"aaa",
+		""
+	][:])
 }
--- a/libregex/test/class.myr
+++ b/libregex/test/class.myr
@@ -15,53 +15,53 @@
 
 const asciiclass = {
 	/* \d success */
-	testmatch("\\d", "1")
-	testmatch("\\d\\d", "13")
-	testmatch("\\d+", "13688")
+	testmatch("\\d", "1", `std.Some [][:])
+	testmatch("\\d\\d", "13", `std.Some [][:])
+	testmatch("\\d+", "13688", `std.Some [][:])
 	/* \d fail */
-	testmatch("\\d", "x")
-	testmatch("\\d\\d", "x3")
-	testmatch("\\d+", "1368f")
+	testmatch("\\d", "x", `std.None)
+	testmatch("\\d\\d", "x3", `std.None)
+	testmatch("\\d+", "1368f", `std.None)
 
 	/* \x success */
-	testmatch("\\x", "a")
-	testmatch("\\x\\x", "1F")
-	testmatch("\\x+", "13b8cDEf")
+	testmatch("\\x", "a", `std.Some [][:])
+	testmatch("\\x\\x", "1F", `std.Some [][:])
+	testmatch("\\x+", "13b8cDEf", `std.Some [][:])
 	/* \x fail */
-	testmatch("\\x", "Z")
-	testmatch("\\x\\x", "fg")
-	testmatch("\\x+", "13b8cg")
+	testmatch("\\x", "Z", `std.None)
+	testmatch("\\x\\x", "fg", `std.None)
+	testmatch("\\x+", "13b8cg", `std.None)
 
 	/* \s success */
-	testmatch("\\s", " ")
-	testmatch("\\s\\s", "\t\n")
-	testmatch("\\s+", "\t\n\r \t")
+	testmatch("\\s", " ", `std.Some [][:])
+	testmatch("\\s\\s", "\t\n", `std.Some [][:])
+	testmatch("\\s+", "\t\n\r \t", `std.Some [][:])
 	/* \s fail */
-	testmatch("\\s", "a")
-	testmatch("\\s\\s", "i\n")
-	testmatch("\\s+", "\t\n\r.\t")
+	testmatch("\\s", "a", `std.None)
+	testmatch("\\s\\s", "i\n", `std.None)
+	testmatch("\\s+", "\t\n\r.\t", `std.None)
 
 	/* word success */
-	testmatch("\\w+", "abcABC0123_")
+	testmatch("\\w+", "abcABC0123_", `std.Some [][:])
 	/* word fail */
-	testmatch("\\w+", "abcABC0123_.")
+	testmatch("\\w+", "abcABC0123_.", `std.None)
 
 	/* \h success */
-	testmatch("\\h", " ")
-	testmatch("\\h\\h", "\t ")
-	testmatch("\\h+", "\t \t ")
+	testmatch("\\h", " ", `std.Some [][:])
+	testmatch("\\h\\h", "\t ", `std.Some [][:])
+	testmatch("\\h+", "\t \t ", `std.Some [][:])
 	/* \h fail */
-	testmatch("\\h", "\n")
-	testmatch("\\h\\h", "\t\r")
-	testmatch("\\h+", "\t \t.")
+	testmatch("\\h", "\n", `std.None)
+	testmatch("\\h\\h", "\t\r", `std.None)
+	testmatch("\\h+", "\t \t.", `std.None)
 }
 
 const set = {
 	/* ranges */
-	testmatch("[a-z]*", "abcd")
-	testmatch("[a-zA-Z]*", "abCD")
-	testmatch("[a-zA-Z0-9_]*", "_abCD018")
+	testmatch("[a-z]*", "abcd", `std.Some [][:])
+	testmatch("[a-zA-Z]*", "abCD", `std.Some [][:])
+	testmatch("[a-zA-Z0-9_]*", "_abCD018", `std.Some [][:])
 
-	testmatch("[abc]*", "abba")
-	testmatch("[a-zABC]*", "abBa")
+	testmatch("[abc]*", "abba", `std.Some [][:])
+	testmatch("[a-zABC]*", "abBa", `std.Some [][:])
 }
--- a/libregex/test/data/basic-expected
+++ /dev/null
@@ -1,20 +1,0 @@
-Matched Abc via .*bc : 1
-	match 0: Abc
-Matched a via (a*)* : 2
-	match 0: a
-	match 1: a
-Matched aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa via (aa|aab?)* : 2
-	match 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-	match 1: aa
-Matched <a foo> blah <bar> via (<.*>).* : 2
-	match 0: <a foo> blah <bar>
-	match 1: <a foo> blah <bar>
-Matched <a foo> blah <bar> via (<.+>).* : 2
-	match 0: <a foo> blah <bar>
-	match 1: <a foo> blah <bar>
-Matched <a foo> blah <bar> via (<.*?>).* : 2
-	match 0: <a foo> blah <bar>
-	match 1: <a foo>
-Matched <a foo> blah <bar> via (<.+?>).* : 2
-	match 0: <a foo> blah <bar>
-	match 1: <a foo>
--- a/libregex/test/data/boundaries-expected
+++ /dev/null
@@ -1,28 +1,0 @@
-Matched abcdef via \<([a-z]*)\> : 2
-	match 0: abcdef
-	match 1: abcdef
-Matched !m! via .*(\<.*\>).* : 2
-	match 0: !m!
-	match 1: m
-Matched !m via .*(\<.*\>).* : 2
-	match 0: !m
-	match 1: m
-Matched m! via .*(\<.*\>).* : 2
-	match 0: m!
-	match 1: m
-Matched !@#!!matches!!%! via .*(\<.*\>).* : 2
-	match 0: !@#!!matches!!%!
-	match 1: matches
-Matched matches!!%! via .*(\<.*\>).* : 2
-	match 0: matches!!%!
-	match 1: matches
-Matched !@#!!matches via .*(\<.*\>).* : 2
-	match 0: !@#!!matches
-	match 1: matches
-Matched !@#!!matches!!%!foo via .*(\<.*\>).* : 2
-	match 0: !@#!!matches!!%!foo
-	match 1: foo
-Matched 123 via .*(\<.*\>).* : 2
-	match 0: 123
-	match 1: 123
-No match of abcdefoo via \<([a-z]*)\>foo
--- a/libregex/test/data/capture-expected
+++ /dev/null
@@ -1,18 +1,0 @@
-Matched Abc via A(.*) : 2
-	match 0: Abc
-	match 1: bc
-Matched Abcde via A(.*)e : 2
-	match 0: Abcde
-	match 1: bcd
-Matched abab via (a|b)+ : 2
-	match 0: abab
-	match 1: b
-Matched Abcde via A(b(.*)d)e : 3
-	match 0: Abcde
-	match 1: c
-	match 2: bcd
-Matched aaaa via (a?)(a*)(a?) : 4
-	match 0: aaaa
-	match 1: a
-	match 2: aaa
-	match 3: 
--- a/libregex/test/data/class-expected
+++ /dev/null
@@ -1,56 +1,0 @@
-Matched 1 via \d : 1
-	match 0: 1
-Matched 13 via \d\d : 1
-	match 0: 13
-Matched 13688 via \d+ : 1
-	match 0: 13688
-No match of x via \d
-No match of x3 via \d\d
-No match of 1368f via \d+
-Matched a via \x : 1
-	match 0: a
-Matched 1F via \x\x : 1
-	match 0: 1F
-Matched 13b8cDEf via \x+ : 1
-	match 0: 13b8cDEf
-No match of Z via \x
-No match of fg via \x\x
-No match of 13b8cg via \x+
-Matched   via \s : 1
-	match 0:  
-Matched 	
- via \s\s : 1
-	match 0: 	
-
-Matched 	
-
 	 via \s+ : 1
-	match 0: 	
-
 	
-No match of a via \s
-No match of i
- via \s\s
-No match of 	
-
.	 via \s+
-Matched abcABC0123_ via \w+ : 1
-	match 0: abcABC0123_
-No match of abcABC0123_. via \w+
-Matched   via \h : 1
-	match 0:  
-Matched 	  via \h\h : 1
-	match 0: 	 
-Matched 	 	  via \h+ : 1
-	match 0: 	 	 
-No match of 
- via \h
-No match of 	
 via \h\h
-No match of 	 	. via \h+
-Matched abcd via [a-z]* : 1
-	match 0: abcd
-Matched abCD via [a-zA-Z]* : 1
-	match 0: abCD
-Matched _abCD018 via [a-zA-Z0-9_]* : 1
-	match 0: _abCD018
-Matched abba via [abc]* : 1
-	match 0: abba
-Matched abBa via [a-zABC]* : 1
-	match 0: abBa
--- a/libregex/test/data/failmatch-expected
+++ /dev/null
@@ -1,1 +1,0 @@
-No match of Abc via .*bcd
--- a/libregex/test/data/negclass-expected
+++ /dev/null
@@ -1,54 +1,0 @@
-Matched x via \D : 1
-	match 0: x
-Matched xa!#^cs via \D+ : 1
-	match 0: xa!#^cs
-No match of 0 via \D
-No match of 9 via \D
-No match of a35x via \D+
-No match of 13688 via \D+
-Matched Z via \X : 1
-	match 0: Z
-Matched gg via \X\X : 1
-	match 0: gg
-No match of a via \X
-No match of zz13b8cDEf via \X+
-Matched a via \S : 1
-	match 0: a
-Matched i% via \S\S : 1
-	match 0: i%
-Matched alskd690!#!! via \S+ : 1
-	match 0: alskd690!#!!
-No match of   via \S
-No match of 	
- via \S\S
-No match of 	 
-kait via \S+
-Matched !%!^^@@!^ via \W+ : 1
-	match 0: !%!^^@@!^
-No match of a^#$bcABC0123_ via \W+
-Matched 
- via \H : 1
-	match 0: 
-
-Matched 
-
 via \H\H : 1
-	match 0: 
-
-No match of 	 	. via \H+
-No match of 	  via \H\H
-No match of 	a35 	  via \H+
-Matched ABCD via [^a-z]* : 1
-	match 0: ABCD
-Matched 1234 via [^a-zA-Z]* : 1
-	match 0: 1234
-Matched -^^- via [^a-zA-Z0-9_]* : 1
-	match 0: -^^-
-Matched d6d via [^abc]* : 1
-	match 0: d6d
-Matched !^!!))# via [^a-zABC]* : 1
-	match 0: !^!!))#
-No match of abcd via [^a-z]*
-No match of abCD via [^a-zA-Z]*
-No match of _abCD018 via [^a-zA-Z0-9_]*
-No match of abba via [^abc]*
-No match of abBa via [^a-zABC]*
--- a/libregex/test/data/unicode-expected
+++ /dev/null
@@ -1,13 +1,0 @@
-Matched Abæc via .*bæc : 1
-	match 0: Abæc
-Matched Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! via (\p{L}*)bæc\P{L}* : 2
-	match 0: Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	match 1: Aa
-Matched Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! via (\pL*)bæc\PL* : 2
-	match 0: Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	match 1: Aa
-Matched Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! via (\p{Letter}*)bæc\P{Uppercase_Letter}* : 2
-	match 0: Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	match 1: Aa
-Matched æ via . : 1
-	match 0: æ
--- a/libregex/test/failmatch.myr
+++ b/libregex/test/failmatch.myr
@@ -1,8 +1,7 @@
 use std
-use regex
 
 use "testmatch.use"
 
 const main = {
-	testmatch(".*bcd", "Abc")
+	testmatch(".*bcd", "Abc", `std.None)
 }
--- a/libregex/test/negclass.myr
+++ b/libregex/test/negclass.myr
@@ -15,58 +15,58 @@
 
 const asciiclass = {
 	/* \D success */
-	testmatch("\\D", "x")
-	testmatch("\\D+", "xa!#^cs")
+	testmatch("\\D", "x", `std.Some [][:])
+	testmatch("\\D+", "xa!#^cs", `std.Some [][:])
 
 	/* \D fail: end of ranges chars */
-	testmatch("\\D", "0")
-	testmatch("\\D", "9")
-	testmatch("\\D+", "a35x")
-	testmatch("\\D+", "13688")
+	testmatch("\\D", "0", `std.None)
+	testmatch("\\D", "9", `std.None)
+	testmatch("\\D+", "a35x", `std.None)
+	testmatch("\\D+", "13688", `std.None)
 
 	/* \X success */
-	testmatch("\\X", "Z")
-	testmatch("\\X\\X", "gg")
+	testmatch("\\X", "Z", `std.Some [][:])
+	testmatch("\\X\\X", "gg", `std.Some [][:])
 	/* \X fail */
-	testmatch("\\X", "a")
-	testmatch("\\X+", "zz13b8cDEf")
+	testmatch("\\X", "a", `std.None)
+	testmatch("\\X+", "zz13b8cDEf", `std.None)
 
 	/* \S success */
-	testmatch("\\S", "a")
-	testmatch("\\S\\S", "i%")
-	testmatch("\\S+", "alskd690!#!!")
+	testmatch("\\S", "a", `std.Some [][:])
+	testmatch("\\S\\S", "i%", `std.Some [][:])
+	testmatch("\\S+", "alskd690!#!!", `std.Some [][:])
 
 	/* \S fail */
-	testmatch("\\S", " ")
-	testmatch("\\S\\S", "\t\n")
-	testmatch("\\S+", "\t \nkait")
+	testmatch("\\S", " ", `std.None)
+	testmatch("\\S\\S", "\t\n", `std.None)
+	testmatch("\\S+", "\t \nkait", `std.None)
 
 	/* word success */
-	testmatch("\\W+", "!%!^^@@!^")
+	testmatch("\\W+", "!%!^^@@!^", `std.Some [][:])
 	/* word fail */
-	testmatch("\\W+", "a^#$bcABC0123_")
+	testmatch("\\W+", "a^#$bcABC0123_", `std.None)
 
 	/* \H success */
-	testmatch("\\H", "\n")
-	testmatch("\\H\\H", "\n\r")
+	testmatch("\\H", "\n", `std.Some [][:])
+	testmatch("\\H\\H", "\n\r", `std.Some [][:])
 	/* \H fail */
-	testmatch("\\H+", "\t \t.")
-	testmatch("\\H\\H", "\t ")
-	testmatch("\\H+", "\ta35 \t ")
+	testmatch("\\H+", "\t \t.", `std.None)
+	testmatch("\\H\\H", "\t ", `std.None)
+	testmatch("\\H+", "\ta35 \t ", `std.None)
 }
 
 const set = {
 	/* ranges: should succeed */
-	testmatch("[^a-z]*", "ABCD")
-	testmatch("[^a-zA-Z]*", "1234")
-	testmatch("[^a-zA-Z0-9_]*", "-^^-")
-	testmatch("[^abc]*", "d6d")
-	testmatch("[^a-zABC]*", "!^!!))#")
+	testmatch("[^a-z]*", "ABCD", `std.Some [][:])
+	testmatch("[^a-zA-Z]*", "1234", `std.Some [][:])
+	testmatch("[^a-zA-Z0-9_]*", "-^^-", `std.Some [][:])
+	testmatch("[^abc]*", "d6d", `std.Some [][:])
+	testmatch("[^a-zABC]*", "!^!!))#", `std.Some [][:])
 
 	/* ranges: should fail */
-	testmatch("[^a-z]*", "abcd")
-	testmatch("[^a-zA-Z]*", "abCD")
-	testmatch("[^a-zA-Z0-9_]*", "_abCD018")
-	testmatch("[^abc]*", "abba")
-	testmatch("[^a-zABC]*", "abBa")
+	testmatch("[^a-z]*", "abcd", `std.None)
+	testmatch("[^a-zA-Z]*", "abCD", `std.None)
+	testmatch("[^a-zA-Z0-9_]*", "_abCD018", `std.None)
+	testmatch("[^abc]*", "abba", `std.None)
+	testmatch("[^a-zABC]*", "abBa", `std.None)
 }
--- a/libregex/test/testmatch.myr
+++ b/libregex/test/testmatch.myr
@@ -2,33 +2,57 @@
 use regex
 
 pkg =
-	const testmatch	: (pat : byte[:], text : byte[:] -> void)
-	const dbgmatch	: (pat : byte[:], text : byte[:] -> void)
+	const testmatch	: (pat : byte[:], text : byte[:], expected : std.option(byte[:][:]) -> void)
+	const dbgmatch	: (pat : byte[:], text : byte[:], expected : std.option(byte[:][:]) -> void)
 ;;
 
-const testmatch = {pat, text
-	run(regex.compile(pat), pat, text)
+const testmatch = {pat, text, expected
+	run(regex.compile(pat), pat, text, expected)
 }
 
-const dbgmatch = {pat, text
-	run(regex.dbgcompile(pat), pat, text)
+const dbgmatch = {pat, text, expected
+	run(regex.dbgcompile(pat), pat, text, expected)
 }
 
-const run = {regex, pat, text
-	var i
-	match regex
-	| `std.Ok re:
-		match regex.exec(re, text)
-		| `std.Some m:
-			std.put("Matched %s via %s : %i\n", text, pat, m.len)
-			for i = 0; i < m.len; i++
-				std.put("\tmatch %i: %s\n", i, m[i])
-			;;
+const run = {regex, pat, text, expected
+	var i, re
+
+	re = std.try(regex)
+	match regex.exec(re, text)
+	| `std.Some res:
+		match expected
 		| `std.None:
-			std.put("No match of %s via %s\n", text, pat)
+			std.fatal("expected no match, got:")
+			for i = 0; i < res.len; i++
+				std.put("\t{}: {}\n", i, res[i])
+			;;
+		| `std.Some exp:
+			if !std.sleq(res[0], text)
+				std.put("whole match does not match text!\n")
+				std.fatal("failed matching {} over {}\n", pat, text)
+			;;
+			res = res[1:]
+			if res.len != exp.len
+				std.put("mismatch: expected {} matches, got {}\n",  exp.len, res.len)
+				std.fatal("failed matching {} over {}\n", pat, text)
+			;;
+			for i = 0; i < exp.len; i++
+				if !std.sleq(res[i], exp[i])
+					std.put("mismatch on {}: expected {}, got {}\n", i, exp[i], res[i])
+					std.fatal("failed matching {} over {}\n", pat, text)
+				;;
+			;;
 		;;
-		regex.free(re)
-	| `std.Fail err:
-		std.put("failed to compile regex")
+	| `std.None:
+		match expected
+		| `std.None:	/* : expected failure */
+		| `std.Some matches:
+			std.put("expected matches:\n")
+			for i = 0; i < matches.len; i++
+				std.put("\t{}: {}\n", i, matches[i])
+			;;
+			std.fatal("no match found\n")
+		;;
 	;;
+	regex.free(re)
 }
--- a/libregex/test/unicode.myr
+++ b/libregex/test/unicode.myr
@@ -4,10 +4,16 @@
 use "testmatch.use"
 
 const main = {
-	testmatch(".*bæc", "Abæc")
-	testmatch("(\\p{L}*)bæc\\P{L}*", "Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+	testmatch(".*bæc", "Abæc", `std.Some [][:])
+	testmatch("(\\p{L}*)bæc\\P{L}*", \
+		"Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", \
+		`std.Some ["Aa"][:])
         /* test various syntaxen */
-	testmatch("(\\pL*)bæc\\PL*", "Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-	testmatch("(\\p{Letter}*)bæc\\P{Uppercase_Letter}*", "Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-	testmatch(".", "æ")
+	testmatch("(\\pL*)bæc\\PL*", \
+		"Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", \
+		`std.Some ["Aa"][:])
+	testmatch("(\\p{Letter}*)bæc\\P{Uppercase_Letter}*", \
+		"Aabæc%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", \
+		`std.Some ["Aa"][:])
+	testmatch(".", "æ", `std.Some [][:])
 }
--- a/mbld/parse.myr
+++ b/mbld/parse.myr
@@ -33,30 +33,29 @@
 
 const loadall = {b, path, dir
 	var p : parser#
-	var subpath, subbld, subproj, ok
+	var subbld, subproj, ok
 	var curbase
 
 	p = mkparser(path, dir, b.basedir)
 	ok = bld.parse(b, p, "")
-	for s in p.subdirs
-		subpath = std.pathcat(p.fdir, s)
-		subbld = std.pathcat(subpath, "bld.sub")
-		subproj = std.pathcat(subpath, "bld.proj")
+	for sub in p.subdirs
+		subbld = std.pathcat(sub, "bld.sub")
+		subproj = std.pathcat(sub, "bld.proj")
 		/*
 		bld.sub is a subbuild. It doesn't change the
 		build root.
 		*/
 		if std.fexists(subbld)
-			loadall(b, subbld, subpath)
+			loadall(b, subbld, sub)
 		/*
 		bld.proj reroots the project -- @/
 		is relative to the most recent bld.proj
 		in the heirarchy.
 		*/
-		elif std.fexists(subproj)
+		elif std.fexists(sub)
 			curbase = b.basedir
-			b.basedir = subpath
-			loadall(b, subproj, subpath)
+			b.basedir = sub
+			loadall(b, subproj, sub)
 			b.basedir = curbase
 		else
 			std.fatal("could not open {} or {} \n", subbld, subproj)
@@ -63,7 +62,6 @@
 		;;
 		std.slfree(subbld)
 		std.slfree(subproj)
-		std.slfree(subpath)
 	;;
 	freeparser(p)
 	-> ok