diff options
Diffstat (limited to 'test/regex/testregex.c')
-rw-r--r-- | test/regex/testregex.c | 2145 |
1 files changed, 0 insertions, 2145 deletions
diff --git a/test/regex/testregex.c b/test/regex/testregex.c deleted file mode 100644 index d18761dd3..000000000 --- a/test/regex/testregex.c +++ /dev/null @@ -1,2145 +0,0 @@ -/* - * 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 Labs Research - * - * PLEASE: publish your tests so everyone can benefit - * - * 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) 2005-05-20 $\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 - -#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 0x00000040 -#define TEST_LENIENT 0x00000080 - -#define TEST_QUERY 0x00000100 -#define TEST_SUB 0x00000200 -#define TEST_UNSPECIFIED 0x00000400 -#define TEST_VERIFY 0x00000800 -#define TEST_AND 0x00001000 -#define TEST_OR 0x00002000 - -#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_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*)++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}(%d:%d)", xlen, xstr, (int)data, 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 [BEASKL] then the\n"); -T(" specification is a global control line. One or more of [BEASKL] 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(" 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("\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.\n"); -T("\n"); -T(" Field 3: the string to match.\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.\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 5 -#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_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 - 0 -}; - -#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; - - 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: - 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; - - x = sfstruse(state.disc.sp); - 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 - m = strtol(p, &p, 10); - if (*p++ != ',') - bad("improper answer\n", re, s, -1, test); - if (*p == '?') - { - n = -1; - p++; - } - else - n = strtol(p, &p, 10); - if (*p++ != ')') - bad("improper answer\n", re, s, -1, test); - if (m!=match[i].rm_so || n!=match[i].rm_eo) - { - if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))) - { - report("failed: match was", NiL, re, s, len, NiL, flags, test); - matchprint(match, nmatch, nsub, ans, test); - } - return 0; - } - } - for (; i < nmatch; i++) - { - if (match[i].rm_so!=-1 || match[i].rm_eo!=-1) - { - if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_VERIFY))) - { - if ((test & TEST_IGNORE_POSITION) && (match[i].rm_so<0 || match[i].rm_eo<0)) - { - state.ignored++; - return 0; - } - if (!(test & TEST_SUMMARY)) - { - report("failed: match was", NiL, re, s, len, NiL, flags, test); - matchprint(match, nmatch, nsub, ans, test); - } - } - return 0; - } - } - if (!(test & TEST_IGNORE_OVER) && match[nmatch].rm_so != state.NOMATCH.rm_so) - { - if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))) - { - report("failed: overran match array", NiL, re, s, len, NiL, flags, test); - matchprint(match, nmatch + 1, nsub, NiL, test); - } - return 0; - } - return 1; -} - -static void -sigunblock(int s) -{ -#ifdef SIG_SETMASK - int op; - sigset_t mask; - - sigemptyset(&mask); - if (s) - { - sigaddset(&mask, s); - op = SIG_UNBLOCK; - } - else op = SIG_SETMASK; - sigprocmask(op, &mask, NiL); -#else -#ifdef sigmask - sigsetmask(s ? (sigsetmask(0L) & ~sigmask(s)) : 0L); -#endif -#endif -} - -static void -gotcha(int sig) -{ - int ret; - - signal(sig, gotcha); - alarm(0); - state.signals++; - switch (sig) - { - case SIGALRM: - ret = REG_EHUNG; - break; - case SIGBUS: - ret = REG_EBUS; - break; - default: - ret = REG_EFAULT; - break; - } - sigunblock(sig); - longjmp(state.gotcha, ret); -} - -static char* -my_getline(FILE* fp) -{ - static char buf[32 * 1024]; - - register char* s = buf; - register char* e = &buf[sizeof(buf)]; - register char* b; - - for (;;) - { - if (!(b = fgets(s, e - s, fp))) - return 0; - state.lineno++; - s += strlen(s); - if (s == b || *--s != '\n' || s == b || *(s - 1) != '\\') - { - *s = 0; - break; - } - s--; - } - return buf; -} - -static unsigned long -note(unsigned long level, char* msg, unsigned long skip, unsigned long test) -{ - if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)) && !skip) - { - printf("NOTE\t"); - if (msg) - printf("%s: ", msg); - printf("skipping lines %d", state.lineno); - } - return skip | level; -} - -#define TABS(n) &ts[7-((n)&7)] - -static char ts[] = "\t\t\t\t\t\t\t"; - -static unsigned long -extract(int* tabs, char* spec, char* re, char* s, char* ans, char* msg, char* accept, regmatch_t* match, int nmatch, int nsub, unsigned long skip, unsigned long level, unsigned long test) -{ - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_OK|TEST_PASS|TEST_SUMMARY)) - { - state.extracted = 1; - if (test & TEST_OK) - { - state.passed++; - if ((test & TEST_VERIFY) && !(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY))) - { - if (msg && strcmp(msg, "EXPECTED")) - printf("NOTE\t%s\n", msg); - return skip; - } - test &= ~(TEST_PASS|TEST_QUERY); - } - if (test & (TEST_QUERY|TEST_VERIFY)) - { - if (test & TEST_BASELINE) - test &= ~(TEST_BASELINE|TEST_PASS); - else - test |= TEST_PASS; - skip |= level; - } - if (!(test & TEST_OK)) - { - if (test & TEST_UNSPECIFIED) - state.unspecified++; - else - state.errors++; - } - if (test & (TEST_PASS|TEST_SUMMARY)) - return skip; - test &= ~TEST_DELIMIT; - printf("%s%s", spec, TABS(*tabs++)); - if ((test & (TEST_BASELINE|TEST_SAME)) == (TEST_BASELINE|TEST_SAME)) - printf("SAME"); - else - quote(re, -1, test); - printf("%s", TABS(*tabs++)); - quote(s, -1, test); - printf("%s", TABS(*tabs++)); - if (!(test & (TEST_ACTUAL|TEST_BASELINE)) || (!accept && !match)) - printf("%s", ans); - else if (accept) - printf("%s", accept); - else - matchprint(match, nmatch, nsub, NiL, test); - if (msg) - printf("%s%s", TABS(*tabs++), msg); - putchar('\n'); - } - else if (test & TEST_QUERY) - skip = note(level, msg, skip, test); - else if (test & TEST_VERIFY) - state.extracted = 1; - return skip; -} - -static int -catchfree(regex_t* preg, int flags, int* tabs, char* spec, char* re, char* s, char* ans, char* msg, char* accept, regmatch_t* match, int nmatch, int nsub, unsigned long skip, unsigned long level, unsigned long test) -{ - int eret; - - if (!(test & TEST_CATCH)) - { - regfree(preg); - eret = 0; - } - else if (!(eret = setjmp(state.gotcha))) - { - alarm(HUNG); - regfree(preg); - alarm(0); - } - else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - extract(tabs, spec, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test); - else - { - report("failed", "regfree", re, NiL, -1, msg, flags, test); - error(preg, eret); - } - return eret; -} - -int -old_main(int unused_param_argc, char** argv) -{ - int flags; - int cflags; - int eflags; - int nmatch; - int nexec; - int nstr; - int cret; - int eret; - int nsub; - int i; - int j; - int expected; - int got; - int locale; - int subunitlen = 0; - int testno; - unsigned long level; - unsigned long skip; - char* p; - char* line; - char* spec; - char* re; - char* s; - char* ans; - char* msg; - char* fun; - char* ppat = NULL; - char* subunit = NULL; - char* version; - char* field[6]; - char* delim[6]; - FILE* fp; - int tabs[6]; - char unit[64]; - regmatch_t match[100]; - regex_t preg; - - static char pat[32 * 1024]; - - int nonosub = REG_NOSUB == 0; - int nonexec = 0; - - unsigned long test = 0; - - static char* filter[] = { "-", 0 }; - - state.NOMATCH.rm_so = state.NOMATCH.rm_eo = -2; - p = unit; - version = (char*)id + 10; - while (p < &unit[sizeof(unit)-1] && (*p = *version++) && !isspace(*p)) - p++; - *p = 0; - while ((p = *++argv) && *p == '-') - for (;;) - { - switch (*++p) - { - case 0: - break; - case 'c': - test |= TEST_CATCH; - continue; - case 'e': - test |= TEST_IGNORE_ERROR; - continue; - case 'h': - case '?': - help(0); - return 2; - case '-': - help(p[1] == 'h'); - return 2; - case 'n': - nonexec = 1; - continue; - case 'o': - test |= TEST_IGNORE_OVER; - continue; - case 'p': - test |= TEST_IGNORE_POSITION; - continue; - case 's': -#ifdef REG_DISCIPLINE - if (!(state.stack = stkalloc(stkstd, 0))) - fprintf(stderr, "%s: out of space [stack]", unit); - state.disc.disc.re_resizef = resizef; - state.disc.disc.re_resizehandle = (void*)stkstd; -#endif - continue; - case 'x': - nonosub = 1; - continue; - case 'v': - test |= TEST_VERBOSE; - continue; - case 'A': - test |= TEST_ACTUAL; - continue; - case 'B': - test |= TEST_BASELINE; - continue; - case 'F': - test |= TEST_FAIL; - continue; - case 'P': - test |= TEST_PASS; - continue; - case 'S': - test |= TEST_SUMMARY; - continue; - default: - fprintf(stderr, "%s: %c: invalid option\n", unit, *p); - return 2; - } - break; - } - if (!*argv) - argv = filter; - locale = 0; - while ((state.file = *argv++)) - { - if (streq(state.file, "-") || streq(state.file, "/dev/stdin") || streq(state.file, "/dev/fd/0")) - { - state.file = 0; - fp = stdin; - } - else if (!(fp = fopen(state.file, "r"))) - { - fprintf(stderr, "%s: %s: cannot read\n", unit, state.file); - return 2; - } - testno = state.errors = state.ignored = state.lineno = state.passed = - state.signals = state.unspecified = state.warnings = 0; - skip = 0; - level = 1; - if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY))) - { - printf("TEST\t%s ", unit); - if ((s = state.file)) - { - subunit = p = 0; - for (;;) - { - switch (*s++) - { - case 0: - break; - case '/': - subunit = s; - continue; - case '.': - p = s - 1; - continue; - default: - continue; - } - break; - } - if (!subunit) - subunit = state.file; - if (p < subunit) - p = s - 1; - subunitlen = p - subunit; - printf("%-.*s ", subunitlen, subunit); - } - else - subunit = 0; - for (s = version; *s && (*s != ' ' || *(s + 1) != '$'); s++) - putchar(*s); - if (test & TEST_CATCH) - printf(", catch"); - if (test & TEST_IGNORE_ERROR) - printf(", ignore error code mismatches"); - if (test & TEST_IGNORE_POSITION) - printf(", ignore negative position mismatches"); -#ifdef REG_DISCIPLINE - if (state.stack) - printf(", stack"); -#endif - if (test & TEST_VERBOSE) - printf(", verbose"); - printf("\n"); -#ifdef REG_VERSIONID - if (regerror(REG_VERSIONID, NiL, pat, sizeof(pat)) > 0) - s = pat; - else -#endif -#ifdef REG_TEST_VERSION - s = REG_TEST_VERSION; -#else - s = "regex"; -#endif - printf("NOTE\t%s\n", s); - if (elementsof(unsupported) > 1) - { -#if (REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL)) || !defined(REG_EXTENDED) - i = 0; -#else - i = REG_EXTENDED != 0; -#endif - for (got = 0; i < elementsof(unsupported) - 1; i++) - { - if (!got) - { - got = 1; - printf("NOTE\tunsupported: %s", unsupported[i]); - } - else - printf(",%s", unsupported[i]); - } - if (got) - printf("\n"); - } - } -#ifdef REG_DISCIPLINE - state.disc.disc.re_version = REG_VERSION; - state.disc.disc.re_compf = compf; - state.disc.disc.re_execf = execf; - if (!(state.disc.sp = sfstropen())) - bad("out of space [discipline string stream]\n", NiL, NiL, 0, 0); - preg.re_disc = &state.disc.disc; -#endif - if (test & TEST_CATCH) - { - signal(SIGALRM, gotcha); - signal(SIGBUS, gotcha); - signal(SIGSEGV, gotcha); - } - while ((p = my_getline(fp))) - { - - /* parse: */ - - line = p; - if (*p == ':' && !isspace(*(p + 1))) - { - while (*++p && *p != ':'); - if (!*p++) - { - if (test & TEST_BASELINE) - printf("%s\n", line); - continue; - } - } - while (isspace(*p)) - p++; - if (*p == 0 || *p == '#' || *p == 'T') - { - if (test & TEST_BASELINE) - printf("%s\n", line); - continue; - } - if (*p == ':' || *p == 'N') - { - if (test & TEST_BASELINE) - printf("%s\n", line); - else if (!(test & (TEST_ACTUAL|TEST_FAIL|TEST_PASS|TEST_SUMMARY))) - { - while (*++p && !isspace(*p)); - while (isspace(*p)) - p++; - printf("NOTE %s\n", p); - } - continue; - } - j = 0; - i = 0; - field[i++] = p; - for (;;) - { - switch (*p++) - { - case 0: - p--; - j = 0; - goto checkfield; - case '\t': - *(delim[i] = p - 1) = 0; - j = 1; - checkfield: - s = field[i - 1]; - if (streq(s, "NIL")) - field[i - 1] = 0; - else if (streq(s, "NULL")) - *s = 0; - while (*p == '\t') - { - p++; - j++; - } - tabs[i - 1] = j; - if (!*p) - break; - if (i >= elementsof(field)) - bad("too many fields\n", NiL, NiL, 0, 0); - field[i++] = p; - /*FALLTHROUGH*/ - default: - continue; - } - break; - } - if (!(spec = field[0])) - bad("NIL spec\n", NiL, NiL, 0, 0); - - /* interpret: */ - - cflags = REG_TEST_DEFAULT; - eflags = REG_EXEC_DEFAULT; - test &= TEST_GLOBAL; - state.extracted = 0; - nmatch = 20; - nsub = -1; - for (p = spec; *p; p++) - { - if (isdigit(*p)) - { - nmatch = strtol(p, &p, 10); - if (nmatch >= elementsof(match)) - bad("nmatch must be < 100\n", NiL, NiL, 0, 0); - p--; - continue; - } - switch (*p) - { - case 'A': - test |= TEST_ARE; - continue; - case 'B': - test |= TEST_BRE; - continue; - case 'C': - if (!(test & TEST_QUERY) && !(skip & level)) - bad("locale must be nested\n", NiL, NiL, 0, 0); - test &= ~TEST_QUERY; - if (locale) - bad("locale nesting not supported\n", NiL, NiL, 0, 0); - if (i != 2) - bad("locale field expected\n", NiL, NiL, 0, 0); - if (!(skip & level)) - { -#if defined(LC_COLLATE) && defined(LC_CTYPE) - s = field[1]; - if (!s || streq(s, "POSIX")) - s = "C"; - if (!(ans = setlocale(LC_COLLATE, s)) || streq(ans, "C") || streq(ans, "POSIX") || !(ans = setlocale(LC_CTYPE, s)) || streq(ans, "C") || streq(ans, "POSIX")) - skip = note(level, s, skip, test); - else - { - if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY))) - printf("NOTE \"%s\" locale\n", s); - locale = level; - } -#else - skip = note(level, skip, test, "locales not supported"); -#endif - } - cflags = NOTEST; - continue; - case 'E': - test |= TEST_ERE; - continue; - case 'K': - test |= TEST_KRE; - continue; - case 'L': - test |= TEST_LRE; - continue; - case 'S': - test |= TEST_SRE; - continue; - - case 'a': - cflags |= REG_LEFT|REG_RIGHT; - continue; - case 'b': - eflags |= REG_NOTBOL; - continue; - case 'c': - cflags |= REG_COMMENT; - continue; - case 'd': - cflags |= REG_SHELL_DOT; - continue; - case 'e': - eflags |= REG_NOTEOL; - continue; - case 'f': - cflags |= REG_MULTIPLE; - continue; - case 'g': - cflags |= NOTEST; - continue; - case 'h': - cflags |= REG_MULTIREF; - continue; - case 'i': - cflags |= REG_ICASE; - continue; - case 'j': - cflags |= REG_SPAN; - continue; - case 'k': - cflags |= REG_ESCAPE; - continue; - case 'l': - cflags |= REG_LEFT; - continue; - case 'm': - cflags |= REG_MINIMAL; - continue; - case 'n': - cflags |= REG_NEWLINE; - continue; - case 'o': - cflags |= REG_SHELL_GROUP; - continue; - case 'p': - cflags |= REG_SHELL_PATH; - continue; - case 'q': - cflags |= REG_DELIMITED; - continue; - case 'r': - cflags |= REG_RIGHT; - continue; - case 's': - cflags |= REG_SHELL_ESCAPED; - continue; - case 't': - cflags |= REG_MUSTDELIM; - continue; - case 'u': - test |= TEST_UNSPECIFIED; - continue; - case 'w': - cflags |= REG_NOSUB; - continue; - case 'x': - if (REG_LENIENT) - cflags |= REG_LENIENT; - else - test |= TEST_LENIENT; - continue; - case 'y': - eflags |= REG_LEFT; - continue; - case 'z': - cflags |= REG_NULL; - continue; - - case '$': - test |= TEST_EXPAND; - continue; - - case '/': - test |= TEST_SUB; - continue; - - case '?': - test |= TEST_VERIFY; - test &= ~(TEST_AND|TEST_OR); - state.verify = state.passed; - continue; - case '&': - test |= TEST_VERIFY|TEST_AND; - test &= ~TEST_OR; - continue; - case '|': - test |= TEST_VERIFY|TEST_OR; - test &= ~TEST_AND; - continue; - case ';': - test |= TEST_OR; - test &= ~TEST_AND; - continue; - - case '{': - level <<= 1; - if (skip & (level >> 1)) - { - skip |= level; - cflags = NOTEST; - } - else - { - skip &= ~level; - test |= TEST_QUERY; - } - continue; - case '}': - if (level == 1) - bad("invalid {...} nesting\n", NiL, NiL, 0, 0); - if ((skip & level) && !(skip & (level>>1))) - { - if (!(test & (TEST_BASELINE|TEST_SUMMARY))) - { - if (test & (TEST_ACTUAL|TEST_FAIL)) - printf("}\n"); - else if (!(test & TEST_PASS)) - printf("-%d\n", state.lineno); - } - } -#if defined(LC_COLLATE) && defined(LC_CTYPE) - else if (locale & level) - { - locale = 0; - if (!(skip & level)) - { - s = "C"; - setlocale(LC_COLLATE, s); - setlocale(LC_CTYPE, s); - if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY))) - printf("NOTE \"%s\" locale\n", s); - else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_PASS)) - printf("}\n"); - } - else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL)) - printf("}\n"); - } -#endif - level >>= 1; - cflags = NOTEST; - continue; - - default: - bad("bad spec\n", spec, NiL, 0, test); - break; - - } - break; - } - if ((cflags|eflags) == NOTEST || ((skip & level) && (test & TEST_BASELINE))) - { - if (test & TEST_BASELINE) - { - while (i > 1) - *delim[--i] = '\t'; - printf("%s\n", line); - } - continue; - } - if (test & TEST_OR) - { - if (!(test & TEST_VERIFY)) - { - test &= ~TEST_OR; - if (state.passed == state.verify && i > 1) - printf("NOTE\t%s\n", field[1]); - continue; - } - else if (state.passed > state.verify) - continue; - } - else if (test & TEST_AND) - { - if (state.passed == state.verify) - continue; - state.passed = state.verify; - } - if (i < 4) - bad("too few fields\n", NiL, NiL, 0, test); - while (i < elementsof(field)) - field[i++] = 0; - if ((re = field[1])) - { - if (streq(re, "SAME")) - { - re = ppat; - test |= TEST_SAME; - } - else - { - if (test & TEST_EXPAND) - escape(re); - strcpy(ppat = pat, re); - } - } - else - ppat = 0; - nstr = -1; - if ((s = field[2]) && (test & TEST_EXPAND)) - { - nstr = escape(s); -#if _REG_nexec - if (nstr != strlen(s)) - nexec = nstr; -#endif - } - if (!(ans = field[3])) - bad("NIL answer\n", NiL, NiL, 0, test); - msg = field[4]; - fflush(stdout); - if (test & TEST_SUB) -#if _REG_subcomp - cflags |= REG_DELIMITED; -#else - continue; -#endif - - compile: - - if (state.extracted || (skip & level)) - continue; -#if !(REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL)) -#ifdef REG_EXTENDED - if (REG_EXTENDED != 0 && (test & TEST_BRE)) -#else - if (test & TEST_BRE) -#endif - { - test &= ~TEST_BRE; - flags = cflags; - state.which = "BRE"; - } - else -#endif -#ifdef REG_EXTENDED - if (test & TEST_ERE) - { - test &= ~TEST_ERE; - flags = cflags | REG_EXTENDED; - state.which = "ERE"; - } - else -#endif -#ifdef REG_AUGMENTED - if (test & TEST_ARE) - { - test &= ~TEST_ARE; - flags = cflags | REG_AUGMENTED; - state.which = "ARE"; - } - else -#endif -#ifdef REG_LITERAL - if (test & TEST_LRE) - { - test &= ~TEST_LRE; - flags = cflags | REG_LITERAL; - state.which = "LRE"; - } - else -#endif -#ifdef REG_SHELL - if (test & TEST_SRE) - { - test &= ~TEST_SRE; - flags = cflags | REG_SHELL; - state.which = "SRE"; - } - else -#ifdef REG_AUGMENTED - if (test & TEST_KRE) - { - test &= ~TEST_KRE; - flags = cflags | REG_SHELL | REG_AUGMENTED; - state.which = "KRE"; - } - else -#endif -#endif - { - if (test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY)) - extract(tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test|TEST_OK); - continue; - } - if ((test & (TEST_QUERY|TEST_VERBOSE|TEST_VERIFY)) == TEST_VERBOSE) - { - printf("test %-3d %s ", state.lineno, state.which); - quote(re, -1, test|TEST_DELIMIT); - printf(" "); - quote(s, nstr, test|TEST_DELIMIT); - printf("\n"); - } - - nosub: - fun = "regcomp"; -#if _REG_nexec - if (nstr >= 0 && nstr != strlen(s)) - nexec = nstr; - - else -#endif - nexec = -1; - if (state.extracted || (skip & level)) - continue; - if (!(test & TEST_QUERY)) - testno++; -#ifdef REG_DISCIPLINE - if (state.stack) - stkset(stkstd, state.stack, 0); - flags |= REG_DISCIPLINE; - state.disc.ordinal = 0; - sfstrseek(state.disc.sp, 0, SEEK_SET); -#endif - if (!(test & TEST_CATCH)) - cret = regcomp(&preg, re, flags); - else if (!(cret = setjmp(state.gotcha))) - { - alarm(HUNG); - cret = regcomp(&preg, re, flags); - alarm(0); - } -#if _REG_subcomp - if (!cret && (test & TEST_SUB)) - { - fun = "regsubcomp"; - p = re + preg.re_npat; - if (!(test & TEST_CATCH)) - cret = regsubcomp(&preg, p, NiL, 0, 0); - else if (!(cret = setjmp(state.gotcha))) - { - alarm(HUNG); - cret = regsubcomp(&preg, p, NiL, 0, 0); - alarm(0); - } - if (!cret && *(p += preg.re_npat) && !(preg.re_sub->re_flags & REG_SUB_LAST)) - { - if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test)) - continue; - cret = REG_EFLAGS; - } - } -#endif - if (!cret) - { - if (!(flags & REG_NOSUB) && nsub < 0 && *ans == '(') - { - for (p = ans; *p; p++) - if (*p == '(') - nsub++; - else if (*p == '{') - nsub--; - if (nsub >= 0) - { - if (test & TEST_IGNORE_OVER) - { - if (nmatch > nsub) - nmatch = nsub + 1; - } - else if (nsub != preg.re_nsub) - { - if (nsub > preg.re_nsub) - { - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, "OK", NiL, 0, 0, skip, level, test|TEST_DELIMIT); - else - { - report("re_nsub incorrect", fun, re, NiL, -1, msg, flags, test); - printf("at least %d expected, %zd returned\n", nsub, preg.re_nsub); - state.errors++; - } - } - else - nsub = preg.re_nsub; - } - } - } - if (!(test & TEST_SUB) && *ans && *ans != '(' && !streq(ans, "OK") && !streq(ans, "NOMATCH")) - { - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, "OK", NiL, 0, 0, skip, level, test|TEST_DELIMIT); - else if (!(test & TEST_LENIENT)) - { - report("failed", fun, re, NiL, -1, msg, flags, test); - printf("%s expected, OK returned\n", ans); - } - catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test); - continue; - } - } - else - { - if (test & TEST_LENIENT) - /* we'll let it go this time */; - else if (!*ans || ans[0]=='(' || (cret == REG_BADPAT && streq(ans, "NOMATCH"))) - { - got = 0; - for (i = 1; i < elementsof(codes); i++) - if (cret==codes[i].code) - got = i; - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT); - else - { - report("failed", fun, re, NiL, -1, msg, flags, test); - printf("%s returned: ", codes[got].name); - error(&preg, cret); - } - } - else - { - expected = got = 0; - for (i = 1; i < elementsof(codes); i++) - { - if (streq(ans, codes[i].name)) - expected = i; - if (cret==codes[i].code) - got = i; - } - if (!expected) - { - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT); - else - { - report("failed: invalid error code", NiL, re, NiL, -1, msg, flags, test); - printf("%s expected, %s returned\n", ans, codes[got].name); - } - } - else if (cret != codes[expected].code && cret != REG_BADPAT) - { - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT); - else if (test & TEST_IGNORE_ERROR) - state.ignored++; - else - { - report("should fail and did", fun, re, NiL, -1, msg, flags, test); - printf("%s expected, %s returned: ", ans, codes[got].name); - state.errors--; - state.warnings++; - error(&preg, cret); - } - } - } - goto compile; - } - -#if _REG_nexec - execute: - if (nexec >= 0) - fun = "regnexec"; - else -#endif - fun = "regexec"; - - for (i = 0; i < elementsof(match); i++) - match[i] = state.NOMATCH; - -#if _REG_nexec - if (nexec >= 0) - { - eret = regnexec(&preg, s, nexec, nmatch, match, eflags); - s[nexec] = 0; - } - else -#endif - { - if (!(test & TEST_CATCH)) - eret = regexec(&preg, s, nmatch, match, eflags); - else if (!(eret = setjmp(state.gotcha))) - { - alarm(HUNG); - eret = regexec(&preg, s, nmatch, match, eflags); - alarm(0); - } - } -#if _REG_subcomp - if ((test & TEST_SUB) && !eret) - { - fun = "regsubexec"; - if (!(test & TEST_CATCH)) - eret = regsubexec(&preg, s, nmatch, match); - else if (!(eret = setjmp(state.gotcha))) - { - alarm(HUNG); - eret = regsubexec(&preg, s, nmatch, match); - alarm(0); - } - } -#endif - if (flags & REG_NOSUB) - { - if (eret) - { - if (eret != REG_NOMATCH || !streq(ans, "NOMATCH")) - { - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, "NOMATCH", NiL, 0, 0, skip, level, test|TEST_DELIMIT); - else - { - report("REG_NOSUB failed", fun, re, s, nstr, msg, flags, test); - error(&preg, eret); - } - } - } - else if (streq(ans, "NOMATCH")) - { - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT); - else - { - report("should fail and didn't", fun, re, s, nstr, msg, flags, test); - error(&preg, eret); - } - } - } - else if (eret) - { - if (eret != REG_NOMATCH || !streq(ans, "NOMATCH")) - { - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, "NOMATCH", NiL, 0, nsub, skip, level, test|TEST_DELIMIT); - else - { - report("failed", fun, re, s, nstr, msg, flags, test); - if (eret != REG_NOMATCH) - error(&preg, eret); - else if (*ans) - printf("expected: %s\n", ans); - else - printf("\n"); - } - } - } - else if (streq(ans, "NOMATCH")) - { - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT); - else - { - report("should fail and didn't", fun, re, s, nstr, msg, flags, test); - matchprint(match, nmatch, nsub, NiL, test); - } - } -#if _REG_subcomp - else if (test & TEST_SUB) - { - p = preg.re_sub->re_buf; - if (strcmp(p, ans)) - { - report("failed", fun, re, s, nstr, msg, flags, test); - quote(ans, -1, test|TEST_DELIMIT); - printf(" expected, "); - quote(p, -1, test|TEST_DELIMIT); - printf(" returned\n"); - } - } -#endif - else if (!*ans) - { - if (match[0].rm_so != state.NOMATCH.rm_so) - { - if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test); - else - { - report("failed: no match but match array assigned", NiL, re, s, nstr, msg, flags, test); - matchprint(match, nmatch, nsub, NiL, test); - } - } - } - else if (matchcheck(match, nmatch, nsub, ans, re, s, nstr, flags, test)) - { -#if _REG_nexec - if (nexec < 0 && !nonexec) - { - nexec = nstr >= 0 ? nstr : strlen(s); - s[nexec] = '\n'; - testno++; - goto execute; - } -#endif - if (!(test & (TEST_SUB|TEST_VERIFY)) && !nonosub) - { - if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test)) - continue; - flags |= REG_NOSUB; - goto nosub; - } - if (test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_OK); - } - else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)) - skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT); - if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test)) - continue; - goto compile; - } - if (test & TEST_SUMMARY) - printf("tests=%-4d errors=%-4d warnings=%-2d ignored=%-2d unspecified=%-2d signals=%d\n", testno, state.errors, state.warnings, state.ignored, state.unspecified, state.signals); - else if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS))) - { - printf("TEST\t%s", unit); - if (subunit) - printf(" %-.*s", subunitlen, subunit); - printf(", %d test%s", testno, testno == 1 ? "" : "s"); - if (state.ignored) - printf(", %d ignored mismatch%s", state.ignored, state.ignored == 1 ? "" : "es"); - if (state.warnings) - printf(", %d warning%s", state.warnings, state.warnings == 1 ? "" : "s"); - if (state.unspecified) - printf(", %d unspecified difference%s", state.unspecified, state.unspecified == 1 ? "" : "s"); - if (state.signals) - printf(", %d signal%s", state.signals, state.signals == 1 ? "" : "s"); - printf(", %d error%s\n", state.errors, state.errors == 1 ? "" : "s"); - } - if (fp != stdin) - fclose(fp); - } - return state.errors; -} - -int main(int argc, char **argv) -{ - static char *param[][4] = { - { NULL, "basic.dat" , NULL }, - { NULL, "categorize.dat" , NULL }, - { NULL, "forcedassoc.dat" , NULL }, - { NULL, "-c", "interpretation.dat", NULL }, - { NULL, "leftassoc.dat" , NULL }, - { NULL, "-c", "nullsubexpr.dat" , NULL }, - { NULL, "repetition.dat" , NULL }, - { NULL, "rightassoc.dat" , NULL }, - }; - int r, i; - - if (argv[1]) - return old_main(argc, argv); - - r = 0; - for (i = 0; i < sizeof(param) / sizeof(param[0]); i++) { - param[i][0] = argv[0]; - printf("Testing %s\n", param[i][1][0] != '-' ? param[i][1] : param[i][2]); - r |= old_main(3 /* not used */, param[i]); - } - return r; -} |