+ 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);