]>
git.saurik.com Git - apple/libc.git/blob - tests/regex/testregex.c
1 #pragma prototyped noticed
4 * regex(3) test harness
6 * build: cc -o testregex testregex.c
7 * help: testregex --man
8 * note: REG_* features are detected by #ifdef; if REG_* are enums
9 * then supply #define REG_foo REG_foo for each enum REG_foo
11 * Glenn Fowler <gsf@research.att.com>
14 * PLEASE: publish your tests so everyone can benefit
16 * The following license covers testregex.c and all associated test data.
18 * Permission is hereby granted, free of charge, to any person obtaining a
19 * copy of THIS SOFTWARE FILE (the "Software"), to deal in the Software
20 * without restriction, including without limitation the rights to use,
21 * copy, modify, merge, publish, distribute, and/or sell copies of the
22 * Software, and to permit persons to whom the Software is furnished to do
23 * so, subject to the following disclaimer:
25 * THIS SOFTWARE IS PROVIDED BY AT&T ``AS IS'' AND ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL AT&T BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 static const char id
[] = "\n@(#)$Id: testregex (AT&T Research) 2010-06-10 $\0\n";
42 #include <sys/types.h>
59 #define RE_DUP_MAX 32767
70 #define TEST_ARE 0x00000001
71 #define TEST_BRE 0x00000002
72 #define TEST_ERE 0x00000004
73 #define TEST_KRE 0x00000008
74 #define TEST_LRE 0x00000010
75 #define TEST_SRE 0x00000020
77 #define TEST_EXPAND 0x00000100
78 #define TEST_LENIENT 0x00000200
80 #define TEST_QUERY 0x00000400
81 #define TEST_SUB 0x00000800
82 #define TEST_UNSPECIFIED 0x00001000
83 #define TEST_VERIFY 0x00002000
84 #define TEST_AND 0x00004000
85 #define TEST_OR 0x00008000
87 #define TEST_DELIMIT 0x00010000
88 #define TEST_OK 0x00020000
89 #define TEST_SAME 0x00040000
91 #define TEST_ACTUAL 0x00100000
92 #define TEST_BASELINE 0x00200000
93 #define TEST_FAIL 0x00400000
94 #define TEST_PASS 0x00800000
95 #define TEST_SUMMARY 0x01000000
97 #define TEST_IGNORE_ERROR 0x02000000
98 #define TEST_IGNORE_OVER 0x04000000
99 #define TEST_IGNORE_POSITION 0x08000000
101 #define TEST_CATCH 0x10000000
102 #define TEST_VERBOSE 0x20000000
104 #define TEST_DECOMP 0x40000000
106 #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)
108 #ifdef REG_DISCIPLINE
113 typedef struct Disc_s
121 compf(const regex_t
* re
, const char* xstr
, size_t xlen
, regdisc_t
* disc
)
123 Disc_t
* dp
= (Disc_t
*)disc
;
125 return (void*)((char*)0 + ++dp
->ordinal
);
129 execf(const regex_t
* re
, void* data
, const char* xstr
, size_t xlen
, const char* sstr
, size_t slen
, char** snxt
, regdisc_t
* disc
)
131 Disc_t
* dp
= (Disc_t
*)disc
;
133 sfprintf(dp
->sp
, "{%-.*s}(%lu:%d)", xlen
, xstr
, (char*)data
- (char*)0, slen
);
138 resizef(void* handle
, void* data
, size_t size
)
142 return stkalloc((Sfio_t
*)handle
, size
);
155 #define H(x) do{if(html)fprintf(stderr,x);}while(0)
156 #define T(x) fprintf(stderr,x)
161 H("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n");
164 H("<TITLE>testregex man document</TITLE>\n");
166 H("<BODY bgcolor=white>\n");
169 T(" testregex - regex(3) test harness\n");
172 T(" testregex [ options ]\n");
175 T(" testregex reads regex(3) test specifications, one per line, from the\n");
176 T(" standard input and writes one output line for each failed test. A\n");
177 T(" summary line is written after all tests are done. Each successful\n");
178 T(" test is run again with REG_NOSUB. Unsupported features are noted\n");
179 T(" before the first test, and tests requiring these features are\n");
180 T(" silently ignored.\n");
183 T(" -c catch signals and non-terminating calls\n");
184 T(" -e ignore error return mismatches\n");
185 T(" -h list help on standard error\n");
186 T(" -n do not repeat successful tests with regnexec()\n");
187 T(" -o ignore match[] overrun errors\n");
188 T(" -p ignore negative position mismatches\n");
189 T(" -s use stack instead of malloc\n");
190 T(" -x do not repeat successful tests with REG_NOSUB\n");
191 T(" -v list each test line\n");
192 T(" -A list failed test lines with actual answers\n");
193 T(" -B list all test lines with actual answers\n");
194 T(" -F list failed test lines\n");
195 T(" -P list passed test lines\n");
196 T(" -S output one summary line\n");
199 T(" Input lines may be blank, a comment beginning with #, or a test\n");
200 T(" specification. A specification is five fields separated by one\n");
201 T(" or more tabs. NULL denotes the empty string and NIL denotes the\n");
204 T(" Field 1: the regex(3) flags to apply, one character per REG_feature\n");
205 T(" flag. The test is skipped if REG_feature is not supported by the\n");
206 T(" implementation. If the first character is not [BEASKLP] then the\n");
207 T(" specification is a global control line. One or more of [BEASKLP] may be\n");
208 T(" specified; the test will be repeated for each mode.\n");
210 T(" B basic BRE (grep, ed, sed)\n");
211 T(" E REG_EXTENDED ERE (egrep)\n");
212 T(" A REG_AUGMENTED ARE (egrep with negation)\n");
213 T(" S REG_SHELL SRE (sh glob)\n");
214 T(" K REG_SHELL|REG_AUGMENTED KRE (ksh glob)\n");
215 T(" L REG_LITERAL LRE (fgrep)\n");
217 T(" a REG_LEFT|REG_RIGHT implicit ^...$\n");
218 T(" b REG_NOTBOL lhs does not match ^\n");
219 T(" c REG_COMMENT ignore space and #...\\n\n");
220 T(" d REG_SHELL_DOT explicit leading . match\n");
221 T(" e REG_NOTEOL rhs does not match $\n");
222 T(" f REG_MULTIPLE multiple \\n separated patterns\n");
223 T(" g FNM_LEADING_DIR testfnmatch only -- match until /\n");
224 T(" H REG_ENHANCED tre enhancements (ignored otherwise)\n");
225 T(" h REG_MULTIREF multiple digit backref\n");
226 T(" i REG_ICASE ignore case\n");
227 T(" j REG_SPAN . matches \\n\n");
228 T(" k REG_ESCAPE \\ to ecape [...] delimiter\n");
229 T(" l REG_LEFT implicit ^...\n");
230 T(" m REG_MINIMAL minimal match\n");
231 T(" n REG_NEWLINE explicit \\n match\n");
232 T(" o REG_ENCLOSED (|&) magic inside [@|&](...)\n");
233 T(" p REG_SHELL_PATH explicit / match\n");
234 T(" q REG_DELIMITED delimited pattern\n");
235 T(" r REG_RIGHT implicit ...$\n");
236 T(" s REG_SHELL_ESCAPED \\ not special\n");
237 T(" t REG_MUSTDELIM all delimiters must be specified\n");
238 T(" u standard unspecified behavior -- errors not counted\n");
239 T(" v REG_CLASS_ESCAPE \\ special inside [...]\n");
240 T(" w REG_NOSUB no subexpression match array\n");
241 T(" x REG_LENIENT let some errors slide\n");
242 T(" y REG_LEFT regexec() implicit ^...\n");
243 T(" z REG_NULL NULL subexpressions ok\n");
244 T(" $ expand C \\c escapes in fields 2 and 3\n");
245 T(" / field 2 is a regsubcomp() expression\n");
246 T(" = field 3 is a regdecomp() expression\n");
248 T(" Field 1 control lines:\n");
250 T(" C set LC_COLLATE and LC_CTYPE to locale in field 2\n");
252 T(" ?test ... output field 5 if passed and != EXPECTED, silent otherwise\n");
253 T(" &test ... output field 5 if current and previous passed\n");
254 T(" |test ... output field 5 if current passed and previous failed\n");
255 T(" ; ... output field 2 if previous failed\n");
256 T(" {test ... skip if failed until }\n");
257 T(" } end of skip\n");
259 T(" : comment comment copied as output NOTE\n");
260 T(" :comment:test :comment: ignored\n");
261 T(" N[OTE] comment comment copied as output NOTE\n");
262 T(" T[EST] comment comment\n");
264 T(" number use number for nmatch (20 by default)\n");
266 T(" Field 2: the regular expression pattern; SAME uses the pattern from\n");
267 T(" the previous specification. RE_DUP_MAX inside {...} expands to the\n");
268 T(" value from <limits.h>.\n");
270 T(" Field 3: the string to match. X...{RE_DUP_MAX} expands to RE_DUP_MAX\n");
271 T(" copies of X.\n");
273 T(" Field 4: the test outcome. This is either one of the posix error\n");
274 T(" codes (with REG_ omitted) or the match array, a list of (m,n)\n");
275 T(" entries with m and n being first and last+1 positions in the\n");
276 T(" field 3 string, or NULL if REG_NOSUB is in effect and success\n");
277 T(" is expected. BADPAT is acceptable in place of any regcomp(3)\n");
278 T(" error code. The match[] array is initialized to (-2,-2) before\n");
279 T(" each test. All array elements from 0 to nmatch-1 must be specified\n");
280 T(" in the outcome. Unspecified endpoints (offset -1) are denoted by ?.\n");
281 T(" Unset endpoints (offset -2) are denoted by X. {x}(o:n) denotes a\n");
282 T(" matched (?{...}) expression, where x is the text enclosed by {...},\n");
283 T(" o is the expression ordinal counting from 1, and n is the length of\n");
284 T(" the unmatched portion of the subject string. If x starts with a\n");
285 T(" number then that is the return value of re_execf(), otherwise 0 is\n");
286 T(" returned. RE_DUP_MAX[-+]N expands to the <limits.h> value -+N.\n");
288 T(" Field 5: optional comment appended to the report.\n");
291 T(" If a regex implementation misbehaves with memory then all bets are off.\n");
294 T(" Glenn Fowler gsf@research.att.com (ksh strmatch, regex extensions)\n");
295 T(" David Korn dgk@research.att.com (ksh glob matcher)\n");
296 T(" Doug McIlroy mcilroy@dartmouth.edu (ast regex/testre in C++)\n");
297 T(" Tom Lord lord@regexps.com (rx tests)\n");
298 T(" Henry Spencer henry@zoo.toronto.edu (original public regex)\n");
299 T(" Andrew Hume andrew@research.att.com (gre tests)\n");
300 T(" John Maddock John_Maddock@compuserve.com (regex++ tests)\n");
301 T(" Philip Hazel ph10@cam.ac.uk (pcre tests)\n");
302 T(" Ville Laurikari vl@iki.fi (libtre tests)\n");
309 #define elementsof(x) (sizeof(x)/sizeof(x[0]))
313 #define streq(a,b) (*(a)==*(b)&&!strcmp(a,b))
319 #ifndef REG_TEST_DEFAULT
320 #define REG_TEST_DEFAULT 0
323 #ifndef REG_EXEC_DEFAULT
324 #define REG_EXEC_DEFAULT 0
327 static const char* unsupported
[] =
333 #ifndef REG_AUGMENTED
343 #ifndef REG_CLASS_ESCAPE
349 #ifndef REG_DELIMITED
352 #ifndef REG_DISCIPLINE
379 #ifndef REG_MUSTDELIM
397 #ifndef REG_SHELL_DOT
400 #ifndef REG_SHELL_ESCAPED
403 #ifndef REG_SHELL_GROUP
406 #ifndef REG_SHELL_PATH
412 #if REG_NOSUB & REG_TEST_DEFAULT
427 #ifndef REG_CLASS_ESCAPE
428 #define REG_CLASS_ESCAPE NOTEST
431 #define REG_COMMENT NOTEST
433 #ifndef REG_DELIMITED
434 #define REG_DELIMITED NOTEST
437 #define REG_ESCAPE NOTEST
440 #define REG_ICASE NOTEST
443 #define REG_LEFT NOTEST
446 #define REG_LENIENT 0
449 #define REG_MINIMAL NOTEST
452 #define REG_MULTIPLE NOTEST
455 #define REG_MULTIREF NOTEST
457 #ifndef REG_MUSTDELIM
458 #define REG_MUSTDELIM NOTEST
461 #define REG_NEWLINE NOTEST
464 #define REG_NOTBOL NOTEST
467 #define REG_NOTEOL NOTEST
470 #define REG_NULL NOTEST
473 #define REG_RIGHT NOTEST
475 #ifndef REG_SHELL_DOT
476 #define REG_SHELL_DOT NOTEST
478 #ifndef REG_SHELL_ESCAPED
479 #define REG_SHELL_ESCAPED NOTEST
481 #ifndef REG_SHELL_GROUP
482 #define REG_SHELL_GROUP NOTEST
484 #ifndef REG_SHELL_PATH
485 #define REG_SHELL_PATH NOTEST
488 #define REG_SPAN NOTEST
491 #define REG_UNKNOWN (-1)
494 #define REG_ENEWLINE (REG_UNKNOWN-1)
498 #define REG_ENULL (REG_UNKNOWN-2)
502 #define REG_ECOUNT (REG_UNKNOWN-3)
505 #define REG_BADESC (REG_UNKNOWN-4)
508 #define REG_EMEM (REG_UNKNOWN-5)
511 #define REG_EHUNG (REG_UNKNOWN-6)
514 #define REG_EBUS (REG_UNKNOWN-7)
517 #define REG_EFAULT (REG_UNKNOWN-8)
520 #define REG_EFLAGS (REG_UNKNOWN-9)
523 #define REG_EDELIM (REG_UNKNOWN-9)
526 static const struct { int code
; char* name
; } codes
[] =
528 REG_UNKNOWN
, "UNKNOWN",
529 REG_NOMATCH
, "NOMATCH",
530 REG_BADPAT
, "BADPAT",
531 REG_ECOLLATE
, "ECOLLATE",
532 REG_ECTYPE
, "ECTYPE",
533 REG_EESCAPE
, "EESCAPE",
534 REG_ESUBREG
, "ESUBREG",
535 REG_EBRACK
, "EBRACK",
536 REG_EPAREN
, "EPAREN",
537 REG_EBRACE
, "EBRACE",
539 REG_ERANGE
, "ERANGE",
540 REG_ESPACE
, "ESPACE",
541 REG_BADRPT
, "BADRPT",
542 REG_ENEWLINE
, "ENEWLINE",
548 REG_ECOUNT
, "ECOUNT",
549 REG_BADESC
, "BADESC",
553 REG_EFAULT
, "EFAULT",
554 REG_EFLAGS
, "EFLAGS",
555 REG_EDELIM
, "EDELIM",
574 #ifdef REG_DISCIPLINE
580 quote(char* s
, int len
, unsigned long test
)
582 unsigned char* u
= (unsigned char*)s
;
591 else if (!*u
&& len
<= 1)
593 else if (test
& TEST_EXPAND
)
596 len
= strlen((char*)u
);
598 if (test
& TEST_DELIMIT
)
607 if (test
& TEST_DELIMIT
)
639 if ((w
= mblen(s
, (char*)e
- s
)) > 1)
642 fwrite(s
, 1, w
, stdout
);
646 if (!iscntrl(c
) && isprint(c
))
649 printf("\\x%02x", c
);
652 if (test
& TEST_DELIMIT
)
660 report(char* comment
, char* fun
, char* re
, char* s
, int len
, char* msg
, int flags
, unsigned long test
)
663 printf("%s:", state
.file
);
664 printf("%d:", state
.lineno
);
668 quote(re
, -1, test
|TEST_DELIMIT
);
672 quote(s
, len
, test
|TEST_DELIMIT
);
675 if (test
& TEST_UNSPECIFIED
)
678 printf(" unspecified behavior");
683 printf(" %s", state
.which
);
684 if (flags
& REG_NOSUB
)
688 if (comment
[strlen(comment
)-1] == '\n')
689 printf(" %s", comment
);
692 printf(" %s: ", comment
);
699 error(regex_t
* preg
, int code
)
710 msg
= "memory fault";
713 msg
= "did not terminate";
716 regerror(code
, preg
, msg
= buf
, sizeof buf
);
723 bad(char* comment
, char* re
, char* s
, int len
, unsigned long test
)
725 printf("bad test case ");
726 report(comment
, NiL
, re
, s
, len
, NiL
, 0, test
);
739 for (b
= t
= s
; (*t
= *s
); s
++, t
++)
782 q
= c
== 'u' ? (s
+ 5) : (char*)0;
784 while (!e
|| !q
|| s
< q
)
788 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
789 c
= (c
<< 4) + *s
- 'a' + 10;
791 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
792 c
= (c
<< 4) + *s
- 'A' + 10;
794 case '0': case '1': case '2': case '3': case '4':
795 case '5': case '6': case '7': case '8': case '9':
796 c
= (c
<< 4) + *s
- '0';
820 case '0': case '1': case '2': case '3':
821 case '4': case '5': case '6': case '7':
828 case '0': case '1': case '2': case '3':
829 case '4': case '5': case '6': case '7':
830 c
= (c
<< 3) + *s
- '0';
841 bad("invalid C \\ escape\n", s
- 1, NiL
, 0, 0);
847 matchoffprint(int off
)
864 matchprint(regmatch_t
* match
, int nmatch
, int nsub
, char* ans
, unsigned long test
)
868 for (; nmatch
> nsub
+ 1; nmatch
--)
869 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)))
871 for (i
= 0; i
< nmatch
; i
++)
874 matchoffprint(match
[i
].rm_so
);
876 matchoffprint(match
[i
].rm_eo
);
879 if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
)))
882 printf(" expected: %s", ans
);
888 matchcheck(regmatch_t
* match
, int nmatch
, int nsub
, char* ans
, char* re
, char* s
, int len
, int flags
, unsigned long test
)
895 if (streq(ans
, "OK"))
896 return test
& (TEST_BASELINE
|TEST_PASS
|TEST_VERIFY
);
897 for (i
= 0, p
= ans
; i
< nmatch
&& *p
; i
++)
901 #ifdef REG_DISCIPLINE
904 if (!(x
= sfstruse(state
.disc
.sp
)))
905 bad("out of space [discipline string]\n", NiL
, NiL
, 0, 0);
908 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
910 report("callout failed", NiL
, re
, s
, len
, NiL
, flags
, test
);
912 printf(" expected, ");
914 printf(" returned\n");
920 bad("improper answer\n", re
, s
, -1, test
);
926 else if (*p
== 'R' && !memcmp(p
, "RE_DUP_MAX", 10))
930 if (*p
== '+' || *p
== '-')
931 m
+= strtol(p
, &p
, 10);
934 m
= strtol(p
, &p
, 10);
936 bad("improper answer\n", re
, s
, -1, test
);
942 else if (*p
== 'R' && !memcmp(p
, "RE_DUP_MAX", 10))
946 if (*p
== '+' || *p
== '-')
947 n
+= strtol(p
, &p
, 10);
950 n
= strtol(p
, &p
, 10);
952 bad("improper answer\n", re
, s
, -1, test
);
953 if (m
!=match
[i
].rm_so
|| n
!=match
[i
].rm_eo
)
955 if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
)))
957 report("failed: match was", NiL
, re
, s
, len
, NiL
, flags
, test
);
958 matchprint(match
, nmatch
, nsub
, ans
, test
);
963 for (; i
< nmatch
; i
++)
965 if (match
[i
].rm_so
!=-1 || match
[i
].rm_eo
!=-1)
967 if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_VERIFY
)))
969 if ((test
& TEST_IGNORE_POSITION
) && (match
[i
].rm_so
<0 || match
[i
].rm_eo
<0))
974 if (!(test
& TEST_SUMMARY
))
976 report("failed: match was", NiL
, re
, s
, len
, NiL
, flags
, test
);
977 matchprint(match
, nmatch
, nsub
, ans
, test
);
983 if (!(test
& TEST_IGNORE_OVER
) && match
[nmatch
].rm_so
!= state
.NOMATCH
.rm_so
)
985 if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
)))
987 report("failed: overran match array", NiL
, re
, s
, len
, NiL
, flags
, test
);
988 matchprint(match
, nmatch
+ 1, nsub
, NiL
, test
);
1005 sigaddset(&mask
, s
);
1008 else op
= SIG_SETMASK
;
1009 sigprocmask(op
, &mask
, NiL
);
1012 sigsetmask(s
? (sigsetmask(0L) & ~sigmask(s
)) : 0L);
1022 signal(sig
, gotcha
);
1038 longjmp(state
.gotcha
, ret
);
1044 static char buf
[32 * 1024];
1046 register char* s
= buf
;
1047 register char* e
= &buf
[sizeof(buf
)];
1052 if (!(b
= fgets(s
, e
- s
, fp
)))
1056 if (s
== b
|| *--s
!= '\n' || s
== b
|| *(s
- 1) != '\\')
1066 static unsigned long
1067 note(unsigned long level
, char* msg
, unsigned long skip
, unsigned long test
)
1069 if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_SUMMARY
)) && !skip
)
1073 printf("%s: ", msg
);
1074 printf("skipping lines %d", state
.lineno
);
1076 return skip
| level
;
1079 #define TABS(n) &ts[7-((n)&7)]
1081 static char ts
[] = "\t\t\t\t\t\t\t";
1083 static unsigned long
1084 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
)
1086 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_OK
|TEST_PASS
|TEST_SUMMARY
))
1088 state
.extracted
= 1;
1092 if ((test
& TEST_VERIFY
) && !(test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_SUMMARY
)))
1094 if (msg
&& strcmp(msg
, "EXPECTED"))
1095 printf("NOTE\t%s\n", msg
);
1098 test
&= ~(TEST_PASS
|TEST_QUERY
);
1100 if (test
& (TEST_QUERY
|TEST_VERIFY
))
1102 if (test
& TEST_BASELINE
)
1103 test
&= ~(TEST_BASELINE
|TEST_PASS
);
1108 if (!(test
& TEST_OK
))
1110 if (test
& TEST_UNSPECIFIED
)
1111 state
.unspecified
++;
1115 if (test
& (TEST_PASS
|TEST_SUMMARY
))
1117 test
&= ~TEST_DELIMIT
;
1118 printf("%s%s", spec
, TABS(*tabs
++));
1119 if ((test
& (TEST_BASELINE
|TEST_SAME
)) == (TEST_BASELINE
|TEST_SAME
))
1122 quote(re
, -1, test
);
1123 printf("%s", TABS(*tabs
++));
1125 printf("%s", TABS(*tabs
++));
1126 if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
)) || (!accept
&& !match
))
1129 printf("%s", accept
);
1131 matchprint(match
, nmatch
, nsub
, NiL
, test
);
1133 printf("%s%s", TABS(*tabs
++), msg
);
1136 else if (test
& TEST_QUERY
)
1137 skip
= note(level
, msg
, skip
, test
);
1138 else if (test
& TEST_VERIFY
)
1139 state
.extracted
= 1;
1144 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
)
1148 if (!(test
& TEST_CATCH
))
1153 else if (!(eret
= setjmp(state
.gotcha
)))
1159 else if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
1160 extract(tabs
, spec
, re
, s
, ans
, msg
, NiL
, NiL
, 0, 0, skip
, level
, test
);
1163 report("failed", "regfree", re
, NiL
, -1, msg
, flags
, test
);
1170 expand(char* os
, char* ot
)
1191 if (n
== 1 && !memcmp(s
, "E_DUP_MAX", 9))
1194 for (t
= ot
; os
< s
; *t
++ = *os
++);
1195 r
= ((t
- ot
) >= 5 && t
[-1] == '{' && t
[-2] == '.' && t
[-3] == '.' && t
[-4] == '.') ? t
[-5] : 0;
1198 if (*(s
+= 10) == '+' || *s
== '-')
1199 m
+= strtol(s
, &s
, 10);
1205 while (*s
&& *s
++ != '}');
1208 t
+= snprintf(t
, 32, "%ld", m
);
1223 main(int argc
, char** argv
)
1241 unsigned long level
;
1259 regmatch_t match
[100];
1262 static char pat
[32 * 1024];
1263 static char patbuf
[32 * 1024];
1264 static char strbuf
[32 * 1024];
1266 int nonosub
= REG_NOSUB
== 0;
1269 unsigned long test
= 0;
1271 static char* filter
[] = { "-", 0 };
1273 if ((p
= getenv("TestRegexLocale")) != NULL
)
1275 if (!setlocale(LC_ALL
, p
))
1277 fprintf(stderr
, "Can't initialize locale to %s\n", p
);
1281 printf("Initial locale: %s\n", p
);
1284 state
.NOMATCH
.rm_so
= state
.NOMATCH
.rm_eo
= -2;
1286 version
= (char*)id
+ 10;
1287 while (p
< &unit
[sizeof(unit
)-1] && (*p
= *version
++) && !isspace(*p
))
1290 while ((p
= *++argv
) && *p
== '-')
1301 test
|= TEST_IGNORE_ERROR
;
1314 test
|= TEST_IGNORE_OVER
;
1317 test
|= TEST_IGNORE_POSITION
;
1320 #ifdef REG_DISCIPLINE
1321 if (!(state
.stack
= stkalloc(stkstd
, 0)))
1322 fprintf(stderr
, "%s: out of space [stack]", unit
);
1323 state
.disc
.disc
.re_resizef
= resizef
;
1324 state
.disc
.disc
.re_resizehandle
= (void*)stkstd
;
1331 test
|= TEST_VERBOSE
;
1334 test
|= TEST_ACTUAL
;
1337 test
|= TEST_BASELINE
;
1346 test
|= TEST_SUMMARY
;
1349 fprintf(stderr
, "%s: %c: invalid option\n", unit
, *p
);
1357 while ((state
.file
= *argv
++))
1359 if (streq(state
.file
, "-") || streq(state
.file
, "/dev/stdin") || streq(state
.file
, "/dev/fd/0"))
1364 else if (!(fp
= fopen(state
.file
, "r")))
1366 fprintf(stderr
, "%s: %s: cannot read\n", unit
, state
.file
);
1369 testno
= state
.errors
= state
.ignored
= state
.lineno
= state
.passed
=
1370 state
.signals
= state
.unspecified
= state
.warnings
= 0;
1373 if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_SUMMARY
)))
1375 printf("TEST\t%s ", unit
);
1376 if ((s
= state
.file
))
1397 subunit
= state
.file
;
1400 subunitlen
= p
- subunit
;
1401 printf("%-.*s ", subunitlen
, subunit
);
1405 for (s
= version
; *s
&& (*s
!= ' ' || *(s
+ 1) != '$'); s
++)
1407 if (test
& TEST_CATCH
)
1409 if (test
& TEST_IGNORE_ERROR
)
1410 printf(", ignore error code mismatches");
1411 if (test
& TEST_IGNORE_POSITION
)
1412 printf(", ignore negative position mismatches");
1413 #ifdef REG_DISCIPLINE
1417 if (test
& TEST_VERBOSE
)
1418 printf(", verbose");
1420 #ifdef REG_VERSIONID
1421 if (regerror(REG_VERSIONID
, NiL
, pat
, sizeof(pat
)) > 0)
1425 #ifdef REG_TEST_VERSION
1426 s
= REG_TEST_VERSION
;
1430 printf("NOTE\t%s\n", s
);
1431 if (elementsof(unsupported
) > 1)
1433 #if (REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL)) || !defined(REG_EXTENDED)
1436 i
= REG_EXTENDED
!= 0;
1438 for (got
= 0; i
< elementsof(unsupported
) - 1; i
++)
1443 printf("NOTE\tunsupported: %s", unsupported
[i
]);
1446 printf(",%s", unsupported
[i
]);
1452 #ifdef REG_DISCIPLINE
1453 state
.disc
.disc
.re_version
= REG_VERSION
;
1454 state
.disc
.disc
.re_compf
= compf
;
1455 state
.disc
.disc
.re_execf
= execf
;
1456 if (!(state
.disc
.sp
= sfstropen()))
1457 bad("out of space [discipline string stream]\n", NiL
, NiL
, 0, 0);
1458 preg
.re_disc
= &state
.disc
.disc
;
1460 if (test
& TEST_CATCH
)
1462 signal(SIGALRM
, gotcha
);
1463 signal(SIGBUS
, gotcha
);
1464 signal(SIGSEGV
, gotcha
);
1466 while ((p
= mygetline(fp
)))
1472 if (*p
== ':' && !isspace(*(p
+ 1)))
1474 while (*++p
&& *p
!= ':');
1477 if (test
& TEST_BASELINE
)
1478 printf("%s\n", line
);
1484 if (*p
== 0 || *p
== '#' || *p
== 'T')
1486 if (test
& TEST_BASELINE
)
1487 printf("%s\n", line
);
1490 if (*p
== ':' || *p
== 'N')
1492 if (test
& TEST_BASELINE
)
1493 printf("%s\n", line
);
1494 else if (!(test
& (TEST_ACTUAL
|TEST_FAIL
|TEST_PASS
|TEST_SUMMARY
)))
1496 while (*++p
&& !isspace(*p
));
1499 printf("NOTE %s\n", p
);
1515 *(delim
[i
] = p
- 1) = 0;
1519 if (streq(s
, "NIL"))
1521 else if (streq(s
, "NULL"))
1531 if (i
>= elementsof(field
))
1532 bad("too many fields\n", NiL
, NiL
, 0, 0);
1540 if (!(spec
= field
[0]))
1541 bad("NIL spec\n", NiL
, NiL
, 0, 0);
1545 cflags
= REG_TEST_DEFAULT
;
1546 eflags
= REG_EXEC_DEFAULT
;
1547 #ifdef REG_BACKTRACKING_MATCHER
1548 if (getenv("REG_BACKTRACKING_MATCHER"))
1549 eflags
|= REG_BACKTRACKING_MATCHER
;
1551 test
&= TEST_GLOBAL
;
1552 state
.extracted
= 0;
1555 for (p
= spec
; *p
; p
++)
1559 nmatch
= strtol(p
, &p
, 10);
1560 if (nmatch
>= elementsof(match
))
1561 bad("nmatch must be < 100\n", NiL
, NiL
, 0, 0);
1574 if (!(test
& TEST_QUERY
) && !(skip
& level
))
1575 bad("locale must be nested\n", NiL
, NiL
, 0, 0);
1576 test
&= ~TEST_QUERY
;
1578 bad("locale nesting not supported\n", NiL
, NiL
, 0, 0);
1580 bad("locale field expected\n", NiL
, NiL
, 0, 0);
1581 if (!(skip
& level
))
1583 #if defined(LC_COLLATE) && defined(LC_CTYPE)
1585 if (!s
|| streq(s
, "POSIX"))
1587 if ((ans
= setlocale(LC_COLLATE
, s
)) && streq(ans
, "POSIX"))
1589 if (!ans
|| (!streq(ans
, s
) && streq(s
, "C")))
1591 else if ((ans
= setlocale(LC_CTYPE
, s
)) && streq(ans
, "POSIX"))
1593 if (!ans
|| (!streq(ans
, s
) && streq(s
, "C")))
1594 skip
= note(level
, s
, skip
, test
);
1597 if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_SUMMARY
)))
1598 printf("NOTE \"%s\" locale\n", s
);
1602 skip
= note(level
, skip
, test
, "locales not supported");
1621 cflags
|= REG_LEFT
|REG_RIGHT
;
1624 eflags
|= REG_NOTBOL
;
1627 cflags
|= REG_COMMENT
;
1630 cflags
|= REG_SHELL_DOT
;
1633 eflags
|= REG_NOTEOL
;
1636 cflags
|= REG_MULTIPLE
;
1643 cflags
|= REG_ENHANCED
;
1647 cflags
|= REG_MULTIREF
;
1650 cflags
|= REG_ICASE
;
1656 cflags
|= REG_ESCAPE
;
1662 cflags
|= REG_MINIMAL
;
1665 cflags
|= REG_NEWLINE
;
1668 cflags
|= REG_SHELL_GROUP
;
1671 cflags
|= REG_SHELL_PATH
;
1674 cflags
|= REG_DELIMITED
;
1677 cflags
|= REG_RIGHT
;
1680 cflags
|= REG_SHELL_ESCAPED
;
1683 cflags
|= REG_MUSTDELIM
;
1686 test
|= TEST_UNSPECIFIED
;
1689 cflags
|= REG_CLASS_ESCAPE
;
1692 cflags
|= REG_NOSUB
;
1696 cflags
|= REG_LENIENT
;
1698 test
|= TEST_LENIENT
;
1708 test
|= TEST_EXPAND
;
1716 test
|= TEST_DECOMP
;
1720 test
|= TEST_VERIFY
;
1721 test
&= ~(TEST_AND
|TEST_OR
);
1722 state
.verify
= state
.passed
;
1725 test
|= TEST_VERIFY
|TEST_AND
;
1729 test
|= TEST_VERIFY
|TEST_OR
;
1739 if (skip
& (level
>> 1))
1752 bad("invalid {...} nesting\n", NiL
, NiL
, 0, 0);
1753 if ((skip
& level
) && !(skip
& (level
>>1)))
1755 if (!(test
& (TEST_BASELINE
|TEST_SUMMARY
)))
1757 if (test
& (TEST_ACTUAL
|TEST_FAIL
))
1759 else if (!(test
& TEST_PASS
))
1760 printf("-%d\n", state
.lineno
);
1763 #if defined(LC_COLLATE) && defined(LC_CTYPE)
1764 else if (locale
& level
)
1767 if (!(skip
& level
))
1770 setlocale(LC_COLLATE
, s
);
1771 setlocale(LC_CTYPE
, s
);
1772 if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_SUMMARY
)))
1773 printf("NOTE \"%s\" locale\n", s
);
1774 else if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_PASS
))
1777 else if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
))
1786 bad("bad spec\n", spec
, NiL
, 0, test
);
1792 if ((cflags
|eflags
) == NOTEST
|| ((skip
& level
) && (test
& TEST_BASELINE
)))
1794 if (test
& TEST_BASELINE
)
1798 printf("%s\n", line
);
1804 if (!(test
& TEST_VERIFY
))
1807 if (state
.passed
== state
.verify
&& i
> 1)
1808 printf("NOTE\t%s\n", field
[1]);
1811 else if (state
.passed
> state
.verify
)
1814 else if (test
& TEST_AND
)
1816 if (state
.passed
== state
.verify
)
1818 state
.passed
= state
.verify
;
1820 if (i
< ((test
& TEST_DECOMP
) ? 3 : 4))
1821 bad("too few fields\n", NiL
, NiL
, 0, test
);
1822 while (i
< elementsof(field
))
1824 if ((re
= field
[1]))
1826 if (streq(re
, "SAME"))
1833 if (test
& TEST_EXPAND
)
1835 re
= expand(re
, patbuf
);
1836 strcpy(ppat
= pat
, re
);
1844 s
= expand(s
, strbuf
);
1845 if (test
& TEST_EXPAND
)
1849 if (nstr
!= strlen(s
))
1854 if (!(ans
= field
[(test
& TEST_DECOMP
) ? 2 : 3]))
1855 bad("NIL answer\n", NiL
, NiL
, 0, test
);
1858 if (test
& TEST_SUB
)
1860 cflags
|= REG_DELIMITED
;
1865 if (test
& TEST_DECOMP
)
1871 if (state
.extracted
|| (skip
& level
))
1873 #if !(REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL))
1875 if (REG_EXTENDED
!= 0 && (test
& TEST_BRE
))
1877 if (test
& TEST_BRE
)
1882 state
.which
= "BRE";
1887 if (test
& TEST_ERE
)
1890 flags
= cflags
| REG_EXTENDED
;
1891 state
.which
= "ERE";
1895 #ifdef REG_AUGMENTED
1896 if (test
& TEST_ARE
)
1899 flags
= cflags
| REG_AUGMENTED
;
1900 state
.which
= "ARE";
1905 if (test
& TEST_LRE
)
1908 flags
= cflags
| REG_LITERAL
;
1909 state
.which
= "LRE";
1914 if (test
& TEST_SRE
)
1917 flags
= cflags
| REG_SHELL
;
1918 state
.which
= "SRE";
1921 #ifdef REG_AUGMENTED
1922 if (test
& TEST_KRE
)
1925 flags
= cflags
| REG_SHELL
| REG_AUGMENTED
;
1926 state
.which
= "KRE";
1932 if (test
& (TEST_BASELINE
|TEST_PASS
|TEST_VERIFY
))
1933 extract(tabs
, line
, re
, s
, ans
, msg
, NiL
, NiL
, 0, 0, skip
, level
, test
|TEST_OK
);
1936 if ((test
& (TEST_QUERY
|TEST_VERBOSE
|TEST_VERIFY
)) == TEST_VERBOSE
)
1938 printf("test %-3d %s ", state
.lineno
, state
.which
);
1939 quote(re
, -1, test
|TEST_DELIMIT
);
1941 quote(s
, nstr
, test
|TEST_DELIMIT
);
1948 if (nstr
>= 0 && nstr
!= strlen(s
))
1954 if (state
.extracted
|| (skip
& level
))
1956 if (!(test
& TEST_QUERY
))
1958 #ifdef REG_DISCIPLINE
1960 stkset(stkstd
, state
.stack
, 0);
1961 flags
|= REG_DISCIPLINE
;
1962 state
.disc
.ordinal
= 0;
1963 sfstrseek(state
.disc
.sp
, 0, SEEK_SET
);
1965 if (!(test
& TEST_CATCH
))
1966 cret
= regcomp(&preg
, re
, flags
);
1967 else if (!(cret
= setjmp(state
.gotcha
)))
1970 cret
= regcomp(&preg
, re
, flags
);
1974 if (!cret
&& (test
& TEST_SUB
))
1977 p
= re
+ preg
.re_npat
;
1978 if (!(test
& TEST_CATCH
))
1979 cret
= regsubcomp(&preg
, p
, NiL
, 0, 0);
1980 else if (!(cret
= setjmp(state
.gotcha
)))
1983 cret
= regsubcomp(&preg
, p
, NiL
, 0, 0);
1986 if (!cret
&& *(p
+= preg
.re_npat
) && !(preg
.re_sub
->re_flags
& REG_SUB_LAST
))
1988 if (catchfree(&preg
, flags
, tabs
, line
, re
, s
, ans
, msg
, NiL
, NiL
, 0, 0, skip
, level
, test
))
1995 if (!cret
&& (test
& TEST_DECOMP
))
1999 if ((j
= nmatch
) > sizeof(buf
))
2002 p
= re
+ preg
.re_npat
;
2003 if (!(test
& TEST_CATCH
))
2004 i
= regdecomp(&preg
, -1, buf
, j
);
2005 else if (!(cret
= setjmp(state
.gotcha
)))
2008 i
= regdecomp(&preg
, -1, buf
, j
);
2013 catchfree(&preg
, flags
, tabs
, line
, re
, s
, ans
, msg
, NiL
, NiL
, 0, 0, skip
, level
, test
);
2016 if (i
!= (strlen(ans
) + 1))
2018 report("failed", fun
, re
, s
, nstr
, msg
, flags
, test
);
2019 printf(" %d byte buffer supplied, %d byte buffer required\n", j
, i
);
2022 else if (strcmp(buf
, ans
))
2024 report("failed", fun
, re
, s
, nstr
, msg
, flags
, test
);
2025 quote(ans
, -1, test
|TEST_DELIMIT
);
2026 printf(" expected, ");
2027 quote(buf
, -1, test
|TEST_DELIMIT
);
2028 printf(" returned\n");
2036 if (!(flags
& REG_NOSUB
) && nsub
< 0 && *ans
== '(')
2038 for (p
= ans
; *p
; p
++)
2045 if (test
& TEST_IGNORE_OVER
)
2050 else if (nsub
!= preg
.re_nsub
)
2052 if (nsub
> preg
.re_nsub
)
2054 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2055 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, "OK", NiL
, 0, 0, skip
, level
, test
|TEST_DELIMIT
);
2058 report("re_nsub incorrect", fun
, re
, NiL
, -1, msg
, flags
, test
);
2059 printf("at least %d expected, %lu returned\n", nsub
, preg
.re_nsub
);
2064 nsub
= preg
.re_nsub
;
2068 if (!(test
& (TEST_DECOMP
|TEST_SUB
)) && *ans
&& *ans
!= '(' && !streq(ans
, "OK") && !streq(ans
, "NOMATCH"))
2070 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2071 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, "OK", NiL
, 0, 0, skip
, level
, test
|TEST_DELIMIT
);
2072 else if (!(test
& TEST_LENIENT
))
2074 report("failed", fun
, re
, NiL
, -1, msg
, flags
, test
);
2075 printf("%s expected, OK returned\n", ans
);
2077 catchfree(&preg
, flags
, tabs
, line
, re
, s
, ans
, msg
, NiL
, NiL
, 0, 0, skip
, level
, test
);
2083 if (test
& TEST_LENIENT
)
2084 /* we'll let it go this time */;
2085 else if (!*ans
|| ans
[0]=='(' || (cret
== REG_BADPAT
&& streq(ans
, "NOMATCH")))
2088 for (i
= 1; i
< elementsof(codes
); i
++)
2089 if (cret
==codes
[i
].code
)
2091 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2092 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, codes
[got
].name
, NiL
, 0, 0, skip
, level
, test
|TEST_DELIMIT
);
2095 report("failed", fun
, re
, NiL
, -1, msg
, flags
, test
);
2096 printf("%s returned: ", codes
[got
].name
);
2103 for (i
= 1; i
< elementsof(codes
); i
++)
2105 if (streq(ans
, codes
[i
].name
))
2107 if (cret
==codes
[i
].code
)
2112 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2113 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, codes
[got
].name
, NiL
, 0, 0, skip
, level
, test
|TEST_DELIMIT
);
2116 report("failed: invalid error code", NiL
, re
, NiL
, -1, msg
, flags
, test
);
2117 printf("%s expected, %s returned\n", ans
, codes
[got
].name
);
2120 else if (cret
!= codes
[expected
].code
&& cret
!= REG_BADPAT
)
2122 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2123 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, codes
[got
].name
, NiL
, 0, 0, skip
, level
, test
|TEST_DELIMIT
);
2124 else if (test
& TEST_IGNORE_ERROR
)
2128 report("should fail and did", fun
, re
, NiL
, -1, msg
, flags
, test
);
2129 printf("%s expected, %s returned: ", ans
, codes
[got
].name
);
2147 for (i
= 0; i
< elementsof(match
); i
++)
2148 match
[i
] = state
.NOMATCH
;
2153 eret
= regnexec(&preg
, s
, nexec
, nmatch
, match
, eflags
);
2159 if (!(test
& TEST_CATCH
))
2160 eret
= regexec(&preg
, s
, nmatch
, match
, eflags
);
2161 else if (!(eret
= setjmp(state
.gotcha
)))
2164 eret
= regexec(&preg
, s
, nmatch
, match
, eflags
);
2169 if ((test
& TEST_SUB
) && !eret
)
2172 if (!(test
& TEST_CATCH
))
2173 eret
= regsubexec(&preg
, s
, nmatch
, match
);
2174 else if (!(eret
= setjmp(state
.gotcha
)))
2177 eret
= regsubexec(&preg
, s
, nmatch
, match
);
2182 if (flags
& REG_NOSUB
)
2186 if (eret
!= REG_NOMATCH
|| !streq(ans
, "NOMATCH"))
2188 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2189 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, "NOMATCH", NiL
, 0, 0, skip
, level
, test
|TEST_DELIMIT
);
2192 report("REG_NOSUB failed", fun
, re
, s
, nstr
, msg
, flags
, test
);
2197 else if (streq(ans
, "NOMATCH"))
2199 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2200 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, NiL
, match
, nmatch
, nsub
, skip
, level
, test
|TEST_DELIMIT
);
2203 report("should fail and didn't", fun
, re
, s
, nstr
, msg
, flags
, test
);
2208 else if (match
[0].rm_so
!= state
.NOMATCH
.rm_so
)
2210 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2211 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, NiL
, NiL
, 0, 0, skip
, level
, test
);
2214 report("failed: REG_NOSUB set but match array assigned", NiL
, re
, s
, nstr
, msg
, flags
, test
);
2215 matchprint(match
, nmatch
, nsub
, NiL
, test
);
2222 if (eret
!= REG_NOMATCH
|| !streq(ans
, "NOMATCH"))
2224 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2225 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, "NOMATCH", NiL
, 0, nsub
, skip
, level
, test
|TEST_DELIMIT
);
2228 report("failed", fun
, re
, s
, nstr
, msg
, flags
, test
);
2229 if (eret
!= REG_NOMATCH
)
2232 printf("expected: %s\n", ans
);
2238 else if (streq(ans
, "NOMATCH"))
2240 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2241 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, NiL
, match
, nmatch
, nsub
, skip
, level
, test
|TEST_DELIMIT
);
2244 report("should fail and didn't", fun
, re
, s
, nstr
, msg
, flags
, test
);
2245 matchprint(match
, nmatch
, nsub
, NiL
, test
);
2249 else if (test
& TEST_SUB
)
2251 p
= preg
.re_sub
->re_buf
;
2254 report("failed", fun
, re
, s
, nstr
, msg
, flags
, test
);
2255 quote(ans
, -1, test
|TEST_DELIMIT
);
2256 printf(" expected, ");
2257 quote(p
, -1, test
|TEST_DELIMIT
);
2258 printf(" returned\n");
2264 if (match
[0].rm_so
!= state
.NOMATCH
.rm_so
)
2266 if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2267 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, NiL
, NiL
, 0, 0, skip
, level
, test
);
2270 report("failed: no match but match array assigned", NiL
, re
, s
, nstr
, msg
, flags
, test
);
2271 matchprint(match
, nmatch
, nsub
, NiL
, test
);
2275 else if (matchcheck(match
, nmatch
, nsub
, ans
, re
, s
, nstr
, flags
, test
))
2278 if (nexec
< 0 && !nonexec
)
2280 nexec
= nstr
>= 0 ? nstr
: strlen(s
);
2286 if (!(test
& (TEST_DECOMP
|TEST_SUB
|TEST_VERIFY
)) && !nonosub
)
2288 if (catchfree(&preg
, flags
, tabs
, line
, re
, s
, ans
, msg
, NiL
, NiL
, 0, 0, skip
, level
, test
))
2293 if (test
& (TEST_BASELINE
|TEST_PASS
|TEST_VERIFY
))
2294 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, NiL
, match
, nmatch
, nsub
, skip
, level
, test
|TEST_OK
);
2296 else if (test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
|TEST_QUERY
|TEST_SUMMARY
|TEST_VERIFY
))
2297 skip
= extract(tabs
, line
, re
, s
, ans
, msg
, NiL
, match
, nmatch
, nsub
, skip
, level
, test
|TEST_DELIMIT
);
2298 if (catchfree(&preg
, flags
, tabs
, line
, re
, s
, ans
, msg
, NiL
, NiL
, 0, 0, skip
, level
, test
))
2302 if (test
& TEST_SUMMARY
)
2303 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
);
2304 else if (!(test
& (TEST_ACTUAL
|TEST_BASELINE
|TEST_FAIL
|TEST_PASS
)))
2306 printf("TEST\t%s", unit
);
2308 printf(" %-.*s", subunitlen
, subunit
);
2309 printf(", %d test%s", testno
, testno
== 1 ? "" : "s");
2311 printf(", %d ignored mismatche%s", state
.ignored
, state
.ignored
== 1 ? "" : "s");
2313 printf(", %d warning%s", state
.warnings
, state
.warnings
== 1 ? "" : "s");
2314 if (state
.unspecified
)
2315 printf(", %d unspecified difference%s", state
.unspecified
, state
.unspecified
== 1 ? "" : "s");
2317 printf(", %d signal%s", state
.signals
, state
.signals
== 1 ? "" : "s");
2318 printf(", %d error%s\n", state
.errors
, state
.errors
== 1 ? "" : "s");
2323 if (getenv("MallocStackLogging") != NULL
)
2325 printf("pid=%d\n", (int)getpid());