Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Sep 2011 18:07:19 +0000 (UTC)
From:      Gabor Kovesdan <gabor@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r225558 - in user/gabor/tre-integration/tools/test/regex: . att att/tests printheur
Message-ID:  <201109141807.p8EI7JuE037018@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gabor
Date: Wed Sep 14 18:07:18 2011
New Revision: 225558
URL: http://svn.freebsd.org/changeset/base/225558

Log:
  - Add AT&T regex regression test and integrate it to our test suite.
    It has a BSD-like license.

Added:
  user/gabor/tre-integration/tools/test/regex/att/
  user/gabor/tre-integration/tools/test/regex/att/Makefile   (contents, props changed)
  user/gabor/tre-integration/tools/test/regex/att/testregex.c   (contents, props changed)
  user/gabor/tre-integration/tools/test/regex/att/tests/
  user/gabor/tre-integration/tools/test/regex/att/tests/basic.dat
  user/gabor/tre-integration/tools/test/regex/att/tests/categorize.dat
  user/gabor/tre-integration/tools/test/regex/att/tests/forcedassoc.dat
  user/gabor/tre-integration/tools/test/regex/att/tests/leftassoc.dat
  user/gabor/tre-integration/tools/test/regex/att/tests/nullsubexpr.dat
  user/gabor/tre-integration/tools/test/regex/att/tests/repetition.dat
  user/gabor/tre-integration/tools/test/regex/att/tests/rightassoc.dat
Modified:
  user/gabor/tre-integration/tools/test/regex/Makefile
  user/gabor/tre-integration/tools/test/regex/printheur/printheur.c

Modified: user/gabor/tre-integration/tools/test/regex/Makefile
==============================================================================
--- user/gabor/tre-integration/tools/test/regex/Makefile	Wed Sep 14 15:47:18 2011	(r225557)
+++ user/gabor/tre-integration/tools/test/regex/Makefile	Wed Sep 14 18:07:18 2011	(r225558)
@@ -1,13 +1,17 @@
 # $FreeBSD$
 
-SUBDIR=	regmatch
+SUBDIR=	att
+SUBDIR+=regmatch
 
 TESTS=	bre.tests
 TESTS+=	ere.tests
 TESTS+=	bre.hu_HU.ISO8859-2.tests
 TESTS+= bre.es_ES.ISO8859-1.tests
 
-test: regmatch
+test-all: test-freebsd test-att
+
+test-freebsd: regmatch
+	@echo "===== Running FreeBSD regex tests ====="
 .for t in ${TESTS}
 	@echo "=== Running test ${t} ==="
 	@flags=`grep '# *FLAGS' tests/${t} | sed 's|# *FLAGS *||g'`; \
@@ -25,4 +29,19 @@ test: regmatch
 	done 
 .endfor
 
+ATT_TESTS= basic.dat
+ATT_TESTS+=categorize.dat
+ATT_TESTS+=nullsubexpr.dat
+ATT_TESTS+=leftassoc.dat
+ATT_TESTS+=rightassoc.dat
+ATT_TESTS+=forcedassoc.dat
+ATT_TESTS+=repetition.dat
+
+test-att: att
+	@echo "===== Running AT&T regex tests ====="
+.for t in ${ATT_TESTS}
+	@echo "=== Running test ${t} ==="
+	${.CURDIR}/att/testregex < ${.CURDIR}/att/tests/${t}
+.endfor
+
 .include <bsd.prog.mk>

Added: user/gabor/tre-integration/tools/test/regex/att/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/gabor/tre-integration/tools/test/regex/att/Makefile	Wed Sep 14 18:07:18 2011	(r225558)
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+PROG=	testregex
+NO_MAN=	yes
+
+.include <bsd.prog.mk>

Added: user/gabor/tre-integration/tools/test/regex/att/testregex.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/gabor/tre-integration/tools/test/regex/att/testregex.c	Wed Sep 14 18:07:18 2011	(r225558)
@@ -0,0 +1,2286 @@
+#pragma prototyped noticed
+
+/*
+ * regex(3) test harness
+ *
+ * build:	cc -o testregex testregex.c
+ * help:	testregex --man
+ * note:	REG_* features are detected by #ifdef; if REG_* are enums
+ *		then supply #define REG_foo REG_foo for each enum REG_foo
+ *
+ *	Glenn Fowler <gsf@research.att.com>
+ *	AT&T Research
+ *
+ * PLEASE: publish your tests so everyone can benefit
+ *
+ * The following license covers testregex.c and all associated test data.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of THIS SOFTWARE FILE (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following disclaimer:
+ *
+ * THIS SOFTWARE IS PROVIDED BY AT&T ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL AT&T BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+static const char id[] = "\n@(#)$Id: testregex (AT&T Research) 2010-06-10 $\0\n";
+
+#if _PACKAGE_ast
+#include <ast.h>
+#else
+#include <sys/types.h>
+#endif
+
+#include <stdio.h>
+#include <regex.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef	__STDC__
+#include <stdlib.h>
+#include <locale.h>
+#endif
+
+#ifndef RE_DUP_MAX
+#define RE_DUP_MAX	32767
+#endif
+
+#if !_PACKAGE_ast
+#undef	REG_DISCIPLINE
+#endif
+
+#ifndef REG_DELIMITED
+#undef	_REG_subcomp
+#endif
+
+#define TEST_ARE		0x00000001
+#define TEST_BRE		0x00000002
+#define TEST_ERE		0x00000004
+#define TEST_KRE		0x00000008
+#define TEST_LRE		0x00000010
+#define TEST_SRE		0x00000020
+
+#define TEST_EXPAND		0x00000100
+#define TEST_LENIENT		0x00000200
+
+#define TEST_QUERY		0x00000400
+#define TEST_SUB		0x00000800
+#define TEST_UNSPECIFIED	0x00001000
+#define TEST_VERIFY		0x00002000
+#define TEST_AND		0x00004000
+#define TEST_OR			0x00008000
+
+#define TEST_DELIMIT		0x00010000
+#define TEST_OK			0x00020000
+#define TEST_SAME		0x00040000
+
+#define TEST_ACTUAL		0x00100000
+#define TEST_BASELINE		0x00200000
+#define TEST_FAIL		0x00400000
+#define TEST_PASS		0x00800000
+#define TEST_SUMMARY		0x01000000
+
+#define TEST_IGNORE_ERROR	0x02000000
+#define TEST_IGNORE_OVER	0x04000000
+#define TEST_IGNORE_POSITION	0x08000000
+
+#define TEST_CATCH		0x10000000
+#define TEST_VERBOSE		0x20000000
+
+#define TEST_DECOMP		0x40000000
+
+#define TEST_GLOBAL		(TEST_ACTUAL|TEST_AND|TEST_BASELINE|TEST_CATCH|TEST_FAIL|TEST_IGNORE_ERROR|TEST_IGNORE_OVER|TEST_IGNORE_POSITION|TEST_OR|TEST_PASS|TEST_SUMMARY|TEST_VERBOSE)
+
+#ifdef REG_DISCIPLINE
+
+
+#include <stk.h>
+
+typedef struct Disc_s
+{
+	regdisc_t	disc;
+	int		ordinal;
+	Sfio_t*		sp;
+} Disc_t;
+
+static void*
+compf(const regex_t* re, const char* xstr, size_t xlen, regdisc_t* disc)
+{
+	Disc_t*		dp = (Disc_t*)disc;
+
+	return (void*)((char*)0 + ++dp->ordinal);
+}
+
+static int
+execf(const regex_t* re, void* data, const char* xstr, size_t xlen, const char* sstr, size_t slen, char** snxt, regdisc_t* disc)
+{
+	Disc_t*		dp = (Disc_t*)disc;
+
+	sfprintf(dp->sp, "{%-.*s}(%lu:%d)", xlen, xstr, (char*)data - (char*)0, slen);
+	return atoi(xstr);
+}
+
+static void*
+resizef(void* handle, void* data, size_t size)
+{
+	if (!size)
+		return 0;
+	return stkalloc((Sfio_t*)handle, size);
+}
+
+#endif
+
+#ifndef NiL
+#ifdef	__STDC__
+#define NiL		0
+#else
+#define NiL		(char*)0
+#endif
+#endif
+
+#define H(x)		do{if(html)fprintf(stderr,x);}while(0)
+#define T(x)		fprintf(stderr,x)
+
+static void
+help(int html)
+{
+H("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n");
+H("<HTML>\n");
+H("<HEAD>\n");
+H("<TITLE>testregex man document</TITLE>\n");
+H("</HEAD>\n");
+H("<BODY bgcolor=white>\n");
+H("<PRE>\n");
+T("NAME\n");
+T("  testregex - regex(3) test harness\n");
+T("\n");
+T("SYNOPSIS\n");
+T("  testregex [ options ]\n");
+T("\n");
+T("DESCRIPTION\n");
+T("  testregex reads regex(3) test specifications, one per line, from the\n");
+T("  standard input and writes one output line for each failed test. A\n");
+T("  summary line is written after all tests are done. Each successful\n");
+T("  test is run again with REG_NOSUB. Unsupported features are noted\n");
+T("  before the first test, and tests requiring these features are\n");
+T("  silently ignored.\n");
+T("\n");
+T("OPTIONS\n");
+T("  -c	catch signals and non-terminating calls\n");
+T("  -e	ignore error return mismatches\n");
+T("  -h	list help on standard error\n");
+T("  -n	do not repeat successful tests with regnexec()\n");
+T("  -o	ignore match[] overrun errors\n");
+T("  -p	ignore negative position mismatches\n");
+T("  -s	use stack instead of malloc\n");
+T("  -x	do not repeat successful tests with REG_NOSUB\n");
+T("  -v	list each test line\n");
+T("  -A	list failed test lines with actual answers\n");
+T("  -B	list all test lines with actual answers\n");
+T("  -F	list failed test lines\n");
+T("  -P	list passed test lines\n");
+T("  -S	output one summary line\n");
+T("\n");
+T("INPUT FORMAT\n");
+T("  Input lines may be blank, a comment beginning with #, or a test\n");
+T("  specification. A specification is five fields separated by one\n");
+T("  or more tabs. NULL denotes the empty string and NIL denotes the\n");
+T("  0 pointer.\n");
+T("\n");
+T("  Field 1: the regex(3) flags to apply, one character per REG_feature\n");
+T("  flag. The test is skipped if REG_feature is not supported by the\n");
+T("  implementation. If the first character is not [BEASKLP] then the\n");
+T("  specification is a global control line. One or more of [BEASKLP] may be\n");
+T("  specified; the test will be repeated for each mode.\n");
+T("\n");
+T("    B 	basic			BRE	(grep, ed, sed)\n");
+T("    E 	REG_EXTENDED		ERE	(egrep)\n");
+T("    A	REG_AUGMENTED		ARE	(egrep with negation)\n");
+T("    S	REG_SHELL		SRE	(sh glob)\n");
+T("    K	REG_SHELL|REG_AUGMENTED	KRE	(ksh glob)\n");
+T("    L	REG_LITERAL		LRE	(fgrep)\n");
+T("\n");
+T("    a	REG_LEFT|REG_RIGHT	implicit ^...$\n");
+T("    b	REG_NOTBOL		lhs does not match ^\n");
+T("    c	REG_COMMENT		ignore space and #...\\n\n");
+T("    d	REG_SHELL_DOT		explicit leading . match\n");
+T("    e	REG_NOTEOL		rhs does not match $\n");
+T("    f	REG_MULTIPLE		multiple \\n separated patterns\n");
+T("    g	FNM_LEADING_DIR		testfnmatch only -- match until /\n");
+T("    h	REG_MULTIREF		multiple digit backref\n");
+T("    i	REG_ICASE		ignore case\n");
+T("    j	REG_SPAN		. matches \\n\n");
+T("    k	REG_ESCAPE		\\ to ecape [...] delimiter\n");
+T("    l	REG_LEFT		implicit ^...\n");
+T("    m	REG_MINIMAL		minimal match\n");
+T("    n	REG_NEWLINE		explicit \\n match\n");
+T("    o	REG_ENCLOSED		(|&) magic inside [@|&](...)\n");
+T("    p	REG_SHELL_PATH		explicit / match\n");
+T("    q	REG_DELIMITED		delimited pattern\n");
+T("    r	REG_RIGHT		implicit ...$\n");
+T("    s	REG_SHELL_ESCAPED	\\ not special\n");
+T("    t	REG_MUSTDELIM		all delimiters must be specified\n");
+T("    u	standard unspecified behavior -- errors not counted\n");
+T("    v	REG_CLASS_ESCAPE	\\ special inside [...]\n");
+T("    w	REG_NOSUB		no subexpression match array\n");
+T("    x	REG_LENIENT		let some errors slide\n");
+T("    y	REG_LEFT		regexec() implicit ^...\n");
+T("    z	REG_NULL		NULL subexpressions ok\n");
+T("    $	                        expand C \\c escapes in fields 2 and 3\n");
+T("    /	                        field 2 is a regsubcomp() expression\n");
+T("    =	                        field 3 is a regdecomp() expression\n");
+T("\n");
+T("  Field 1 control lines:\n");
+T("\n");
+T("    C		set LC_COLLATE and LC_CTYPE to locale in field 2\n");
+T("\n");
+T("    ?test ...	output field 5 if passed and != EXPECTED, silent otherwise\n");
+T("    &test ...	output field 5 if current and previous passed\n");
+T("    |test ...	output field 5 if current passed and previous failed\n");
+T("    ; ...	output field 2 if previous failed\n");
+T("    {test ...	skip if failed until }\n");
+T("    }		end of skip\n");
+T("\n");
+T("    : comment		comment copied as output NOTE\n");
+T("    :comment:test	:comment: ignored\n");
+T("    N[OTE] comment	comment copied as output NOTE\n");
+T("    T[EST] comment	comment\n");
+T("\n");
+T("    number		use number for nmatch (20 by default)\n");
+T("\n");
+T("  Field 2: the regular expression pattern; SAME uses the pattern from\n");
+T("    the previous specification. RE_DUP_MAX inside {...} expands to the\n");
+T("    value from <limits.h>.\n");
+T("\n");
+T("  Field 3: the string to match. X...{RE_DUP_MAX} expands to RE_DUP_MAX\n");
+T("    copies of X.\n");
+T("\n");
+T("  Field 4: the test outcome. This is either one of the posix error\n");
+T("    codes (with REG_ omitted) or the match array, a list of (m,n)\n");
+T("    entries with m and n being first and last+1 positions in the\n");
+T("    field 3 string, or NULL if REG_NOSUB is in effect and success\n");
+T("    is expected. BADPAT is acceptable in place of any regcomp(3)\n");
+T("    error code. The match[] array is initialized to (-2,-2) before\n");
+T("    each test. All array elements from 0 to nmatch-1 must be specified\n");
+T("    in the outcome. Unspecified endpoints (offset -1) are denoted by ?.\n");
+T("    Unset endpoints (offset -2) are denoted by X. {x}(o:n) denotes a\n");
+T("    matched (?{...}) expression, where x is the text enclosed by {...},\n");
+T("    o is the expression ordinal counting from 1, and n is the length of\n");
+T("    the unmatched portion of the subject string. If x starts with a\n");
+T("    number then that is the return value of re_execf(), otherwise 0 is\n");
+T("    returned. RE_DUP_MAX[-+]N expands to the <limits.h> value -+N.\n");
+T("\n");
+T("  Field 5: optional comment appended to the report.\n");
+T("\n");
+T("CAVEAT\n");
+T("    If a regex implementation misbehaves with memory then all bets are off.\n");
+T("\n");
+T("CONTRIBUTORS\n");
+T("  Glenn Fowler    gsf@research.att.com        (ksh strmatch, regex extensions)\n");
+T("  David Korn      dgk@research.att.com        (ksh glob matcher)\n");
+T("  Doug McIlroy    mcilroy@dartmouth.edu       (ast regex/testre in C++)\n");
+T("  Tom Lord        lord@regexps.com            (rx tests)\n");
+T("  Henry Spencer   henry@zoo.toronto.edu       (original public regex)\n");
+T("  Andrew Hume     andrew@research.att.com     (gre tests)\n");
+T("  John Maddock    John_Maddock@compuserve.com (regex++ tests)\n");
+T("  Philip Hazel    ph10@cam.ac.uk              (pcre tests)\n");
+T("  Ville Laurikari vl@iki.fi                   (libtre tests)\n");
+H("</PRE>\n");
+H("</BODY>\n");
+H("</HTML>\n");
+}
+
+#ifndef elementsof
+#define elementsof(x)	(sizeof(x)/sizeof(x[0]))
+#endif
+
+#ifndef streq
+#define streq(a,b)	(*(a)==*(b)&&!strcmp(a,b))
+#endif
+
+#define HUNG		2
+#define NOTEST		(~0)
+
+#ifndef REG_TEST_DEFAULT
+#define REG_TEST_DEFAULT	0
+#endif
+
+#ifndef REG_EXEC_DEFAULT
+#define REG_EXEC_DEFAULT	0
+#endif
+
+static const char* unsupported[] =
+{
+	"BASIC",
+#ifndef REG_EXTENDED
+	"EXTENDED",
+#endif
+#ifndef REG_AUGMENTED
+	"AUGMENTED",
+#endif
+#ifndef REG_SHELL
+	"SHELL",
+#endif
+
+#ifndef REG_CLASS_ESCAPE
+	"CLASS_ESCAPE",
+#endif
+#ifndef REG_COMMENT
+	"COMMENT",
+#endif
+#ifndef REG_DELIMITED
+	"DELIMITED",
+#endif
+#ifndef REG_DISCIPLINE
+	"DISCIPLINE",
+#endif
+#ifndef REG_ESCAPE
+	"ESCAPE",
+#endif
+#ifndef REG_ICASE
+	"ICASE",
+#endif
+#ifndef REG_LEFT
+	"LEFT",
+#endif
+#ifndef REG_LENIENT
+	"LENIENT",
+#endif
+#ifndef REG_LITERAL
+	"LITERAL",
+#endif
+#ifndef REG_MINIMAL
+	"MINIMAL",
+#endif
+#ifndef REG_MULTIPLE
+	"MULTIPLE",
+#endif
+#ifndef REG_MULTIREF
+	"MULTIREF",
+#endif
+#ifndef REG_MUSTDELIM
+	"MUSTDELIM",
+#endif
+#ifndef REG_NEWLINE
+	"NEWLINE",
+#endif
+#ifndef REG_NOTBOL
+	"NOTBOL",
+#endif
+#ifndef REG_NOTEOL
+	"NOTEOL",
+#endif
+#ifndef REG_NULL
+	"NULL",
+#endif
+#ifndef REG_RIGHT
+	"RIGHT",
+#endif
+#ifndef REG_SHELL_DOT
+	"SHELL_DOT",
+#endif
+#ifndef REG_SHELL_ESCAPED
+	"SHELL_ESCAPED",
+#endif
+#ifndef REG_SHELL_GROUP
+	"SHELL_GROUP",
+#endif
+#ifndef REG_SHELL_PATH
+	"SHELL_PATH",
+#endif
+#ifndef REG_SPAN
+	"SPAN",
+#endif
+#if REG_NOSUB & REG_TEST_DEFAULT
+	"SUBMATCH",
+#endif
+#if !_REG_nexec
+	"regnexec",
+#endif
+#if !_REG_subcomp
+	"regsubcomp",
+#endif
+#if !_REG_decomp
+	"redecomp",
+#endif
+	0
+};
+
+#ifndef REG_CLASS_ESCAPE
+#define REG_CLASS_ESCAPE	NOTEST
+#endif
+#ifndef REG_COMMENT
+#define REG_COMMENT	NOTEST
+#endif
+#ifndef REG_DELIMITED
+#define REG_DELIMITED	NOTEST
+#endif
+#ifndef REG_ESCAPE
+#define REG_ESCAPE	NOTEST
+#endif
+#ifndef REG_ICASE
+#define REG_ICASE	NOTEST
+#endif
+#ifndef REG_LEFT
+#define REG_LEFT	NOTEST
+#endif
+#ifndef REG_LENIENT
+#define REG_LENIENT	0
+#endif
+#ifndef REG_MINIMAL
+#define REG_MINIMAL	NOTEST
+#endif
+#ifndef REG_MULTIPLE
+#define REG_MULTIPLE	NOTEST
+#endif
+#ifndef REG_MULTIREF
+#define REG_MULTIREF	NOTEST
+#endif
+#ifndef REG_MUSTDELIM
+#define REG_MUSTDELIM	NOTEST
+#endif
+#ifndef REG_NEWLINE
+#define REG_NEWLINE	NOTEST
+#endif
+#ifndef REG_NOTBOL
+#define REG_NOTBOL	NOTEST
+#endif
+#ifndef REG_NOTEOL
+#define REG_NOTEOL	NOTEST
+#endif
+#ifndef REG_NULL
+#define REG_NULL	NOTEST
+#endif
+#ifndef REG_RIGHT
+#define REG_RIGHT	NOTEST
+#endif
+#ifndef REG_SHELL_DOT
+#define REG_SHELL_DOT	NOTEST
+#endif
+#ifndef REG_SHELL_ESCAPED
+#define REG_SHELL_ESCAPED	NOTEST
+#endif
+#ifndef REG_SHELL_GROUP
+#define REG_SHELL_GROUP	NOTEST
+#endif
+#ifndef REG_SHELL_PATH
+#define REG_SHELL_PATH	NOTEST
+#endif
+#ifndef REG_SPAN
+#define REG_SPAN	NOTEST
+#endif
+
+#define REG_UNKNOWN	(-1)
+
+#ifndef REG_ENEWLINE
+#define REG_ENEWLINE	(REG_UNKNOWN-1)
+#endif
+#ifndef REG_ENULL
+#ifndef REG_EMPTY
+#define REG_ENULL	(REG_UNKNOWN-2)
+#else
+#define REG_ENULL	REG_EMPTY
+#endif
+#endif
+#ifndef REG_ECOUNT
+#define REG_ECOUNT	(REG_UNKNOWN-3)
+#endif
+#ifndef REG_BADESC
+#define REG_BADESC	(REG_UNKNOWN-4)
+#endif
+#ifndef REG_EMEM
+#define REG_EMEM	(REG_UNKNOWN-5)
+#endif
+#ifndef REG_EHUNG
+#define REG_EHUNG	(REG_UNKNOWN-6)
+#endif
+#ifndef REG_EBUS
+#define REG_EBUS	(REG_UNKNOWN-7)
+#endif
+#ifndef REG_EFAULT
+#define REG_EFAULT	(REG_UNKNOWN-8)
+#endif
+#ifndef REG_EFLAGS
+#define REG_EFLAGS	(REG_UNKNOWN-9)
+#endif
+#ifndef REG_EDELIM
+#define REG_EDELIM	(REG_UNKNOWN-9)
+#endif
+
+static const struct { int code; char* name; } codes[] =
+{
+	REG_UNKNOWN,	"UNKNOWN",
+	REG_NOMATCH,	"NOMATCH",
+	REG_BADPAT,	"BADPAT",
+	REG_ECOLLATE,	"ECOLLATE",
+	REG_ECTYPE,	"ECTYPE",
+	REG_EESCAPE,	"EESCAPE",
+	REG_ESUBREG,	"ESUBREG",
+	REG_EBRACK,	"EBRACK",
+	REG_EPAREN,	"EPAREN",
+	REG_EBRACE,	"EBRACE",
+	REG_BADBR,	"BADBR",
+	REG_ERANGE,	"ERANGE",
+	REG_ESPACE,	"ESPACE",
+	REG_BADRPT,	"BADRPT",
+	REG_ENEWLINE,	"ENEWLINE",
+	REG_ENULL,	"ENULL",
+	REG_ECOUNT,	"ECOUNT",
+	REG_BADESC,	"BADESC",
+	REG_EMEM,	"EMEM",
+	REG_EHUNG,	"EHUNG",
+	REG_EBUS,	"EBUS",
+	REG_EFAULT,	"EFAULT",
+	REG_EFLAGS,	"EFLAGS",
+	REG_EDELIM,	"EDELIM",
+};
+
+static struct
+{
+	regmatch_t	NOMATCH;
+	int		errors;
+	int		extracted;
+	int		ignored;
+	int		lineno;
+	int		passed;
+	int		signals;
+	int		unspecified;
+	int		verify;
+	int		warnings;
+	char*		file;
+	char*		stack;
+	char*		which;
+	jmp_buf		gotcha;
+#ifdef REG_DISCIPLINE
+	Disc_t		disc;
+#endif
+} state;
+
+static void
+quote(char* s, int len, unsigned long test)
+{
+	unsigned char*	u = (unsigned char*)s;
+	unsigned char*	e;
+	int		c;
+#ifdef MB_CUR_MAX
+	int		w;
+#endif
+
+	if (!u)
+		printf("NIL");
+	else if (!*u && len <= 1)
+		printf("NULL");
+	else if (test & TEST_EXPAND)
+	{
+		if (len < 0)
+			len = strlen((char*)u);
+		e = u + len;
+		if (test & TEST_DELIMIT)
+			printf("\"");
+		while (u < e)
+			switch (c = *u++)
+			{
+			case '\\':
+				printf("\\\\");
+				break;
+			case '"':
+				if (test & TEST_DELIMIT)
+					printf("\\\"");
+				else
+					printf("\"");
+				break;
+			case '\a':
+				printf("\\a");
+				break;
+			case '\b':
+				printf("\\b");
+				break;
+			case 033:
+				printf("\\e");
+				break;
+			case '\f':
+				printf("\\f");
+				break;
+			case '\n':
+				printf("\\n");
+				break;
+			case '\r':
+				printf("\\r");
+				break;
+			case '\t':
+				printf("\\t");
+				break;
+			case '\v':
+				printf("\\v");
+				break;
+			default:
+#ifdef MB_CUR_MAX
+				s = (char*)u - 1;
+				if ((w = mblen(s, (char*)e - s)) > 1)
+				{
+					u += w - 1;
+					fwrite(s, 1, w, stdout);
+				}
+				else
+#endif
+				if (!iscntrl(c) && isprint(c))
+					putchar(c);
+				else
+					printf("\\x%02x", c);
+				break;
+			}
+		if (test & TEST_DELIMIT)
+			printf("\"");
+	}
+	else
+		printf("%s", s);
+}
+
+static void
+report(char* comment, char* fun, char* re, char* s, int len, char* msg, int flags, unsigned long test)
+{
+	if (state.file)
+		printf("%s:", state.file);
+	printf("%d:", state.lineno);
+	if (re)
+	{
+		printf(" ");
+		quote(re, -1, test|TEST_DELIMIT);
+		if (s)
+		{
+			printf(" versus ");
+			quote(s, len, test|TEST_DELIMIT);
+		}
+	}
+	if (test & TEST_UNSPECIFIED)
+	{
+		state.unspecified++;
+		printf(" unspecified behavior");
+	}
+	else
+		state.errors++;
+	if (state.which)
+		printf(" %s", state.which);
+	if (flags & REG_NOSUB)
+		printf(" NOSUB");
+	if (fun)
+		printf(" %s", fun);
+	if (comment[strlen(comment)-1] == '\n')
+		printf(" %s", comment);
+	else
+	{
+		printf(" %s: ", comment);
+		if (msg)
+			printf("%s: ", msg);
+	}
+}
+
+static void
+error(regex_t* preg, int code)
+{
+	char*	msg;
+	char	buf[256];
+
+	switch (code)
+	{
+	case REG_EBUS:
+		msg = "bus error";
+		break;
+	case REG_EFAULT:
+		msg = "memory fault";
+		break;
+	case REG_EHUNG:
+		msg = "did not terminate";
+		break;
+	default:
+		regerror(code, preg, msg = buf, sizeof buf);
+		break;
+	}
+	printf("%s\n", msg);
+}
+
+static void
+bad(char* comment, char* re, char* s, int len, unsigned long test)
+{
+	printf("bad test case ");
+	report(comment, NiL, re, s, len, NiL, 0, test);
+	exit(1);
+}
+
+static int
+escape(char* s)
+{
+	char*	b;
+	char*	t;
+	char*	q;
+	char*	e;
+	int	c;
+
+	for (b = t = s; *t = *s; s++, t++)
+		if (*s == '\\')
+			switch (*++s)
+			{
+			case '\\':
+				break;
+			case 'a':
+				*t = '\a';
+				break;
+			case 'b':
+				*t = '\b';
+				break;
+			case 'c':
+				if (*t = *++s)
+					*t &= 037;
+				else
+					s--;
+				break;
+			case 'e':
+			case 'E':
+				*t = 033;
+				break;
+			case 'f':
+				*t = '\f';
+				break;
+			case 'n':
+				*t = '\n';
+				break;
+			case 'r':
+				*t = '\r';
+				break;
+			case 's':
+				*t = ' ';
+				break;
+			case 't':
+				*t = '\t';
+				break;
+			case 'v':
+				*t = '\v';
+				break;
+			case 'u':
+			case 'x':
+				c = 0;
+				q = c == 'u' ? (s + 5) : (char*)0;
+				e = s + 1;
+				while (!e || !q || s < q)
+				{
+					switch (*++s)
+					{
+					case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+						c = (c << 4) + *s - 'a' + 10;
+						continue;
+					case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+						c = (c << 4) + *s - 'A' + 10;
+						continue;
+					case '0': case '1': case '2': case '3': case '4':
+					case '5': case '6': case '7': case '8': case '9':
+						c = (c << 4) + *s - '0';
+						continue;
+					case '{':
+					case '[':
+						if (s != e)
+						{
+							s--;
+							break;
+						}
+						e = 0;
+						continue;
+					case '}':
+					case ']':
+						if (e)
+							s--;
+						break;
+					default:
+						s--;
+						break;
+					}
+					break;
+				}
+				*t = c;
+				break;
+			case '0': case '1': case '2': case '3':
+			case '4': case '5': case '6': case '7':
+				c = *s - '0';
+				q = s + 2;
+				while (s < q)
+				{
+					switch (*++s)
+					{
+					case '0': case '1': case '2': case '3':
+					case '4': case '5': case '6': case '7':
+						c = (c << 3) + *s - '0';
+						break;
+					default:
+						q = --s;
+						break;
+					}
+				}
+				*t = c;
+				break;
+			default:
+				*(s + 1) = 0;
+				bad("invalid C \\ escape\n", s - 1, NiL, 0, 0);
+			}
+	return t - b;
+}
+
+static void
+matchoffprint(int off)
+{
+	switch (off)
+	{
+	case -2:
+		printf("X");
+		break;
+	case -1:
+		printf("?");
+		break;
+	default:
+		printf("%d", off);
+		break;
+	}
+}
+
+static void
+matchprint(regmatch_t* match, int nmatch, int nsub, char* ans, unsigned long test)
+{
+	int	i;
+
+	for (; nmatch > nsub + 1; nmatch--)
+		if ((match[nmatch-1].rm_so != -1 || match[nmatch-1].rm_eo != -1) && (!(test & TEST_IGNORE_POSITION) || match[nmatch-1].rm_so >= 0 && match[nmatch-1].rm_eo >= 0))
+			break;
+	for (i = 0; i < nmatch; i++)
+	{
+		printf("(");
+		matchoffprint(match[i].rm_so);
+		printf(",");
+		matchoffprint(match[i].rm_eo);
+		printf(")");
+	}
+	if (!(test & (TEST_ACTUAL|TEST_BASELINE)))
+	{
+		if (ans)
+			printf(" expected: %s", ans);
+		printf("\n");
+	}
+}
+
+static int
+matchcheck(regmatch_t* match, int nmatch, int nsub, char* ans, char* re, char* s, int len, int flags, unsigned long test)
+{
+	char*	p;
+	int	i;
+	int	m;
+	int	n;
+
+	if (streq(ans, "OK"))
+		return test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY);
+	for (i = 0, p = ans; i < nmatch && *p; i++)
+	{
+		if (*p == '{')
+		{
+#ifdef REG_DISCIPLINE
+			char*	x;
+
+			if (!(x = sfstruse(state.disc.sp)))
+				bad("out of space [discipline string]\n", NiL, NiL, 0, 0);
+			if (strcmp(p, x))
+			{
+				if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
+					return 0;
+				report("callout failed", NiL, re, s, len, NiL, flags, test);
+				quote(p, -1, test);
+				printf(" expected, ");
+				quote(x, -1, test);
+				printf(" returned\n");
+			}
+#endif
+			break;
+		}
+		if (*p++ != '(')
+			bad("improper answer\n", re, s, -1, test);
+		if (*p == '?')
+		{
+			m = -1;
+			p++;
+		}
+		else if (*p == 'R' && !memcmp(p, "RE_DUP_MAX", 10))
+		{
+			m = RE_DUP_MAX;
+			p += 10;
+			if (*p == '+' || *p == '-')
+				m += strtol(p, &p, 10);
+		}
+		else
+			m = strtol(p, &p, 10);
+		if (*p++ != ',')
+			bad("improper answer\n", re, s, -1, test);
+		if (*p == '?')
+		{
+			n = -1;
+			p++;
+		}
+		else if (*p == 'R' && !memcmp(p, "RE_DUP_MAX", 10))
+		{
+			n = RE_DUP_MAX;
+			p += 10;
+			if (*p == '+' || *p == '-')
+				n += strtol(p, &p, 10);
+		}
+		else
+			n = strtol(p, &p, 10);
+		if (*p++ != ')')
+			bad("improper answer\n", re, s, -1, test);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201109141807.p8EI7JuE037018>