testregex.c 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121
  1. #pragma prototyped noticed
  2. /*
  3. * regex(3) test harness
  4. *
  5. * build: cc -o testregex testregex.c
  6. * help: testregex --man
  7. * note: REG_* features are detected by #ifdef; if REG_* are enums
  8. * then supply #define REG_foo REG_foo for each enum REG_foo
  9. *
  10. * Glenn Fowler <gsf@research.att.com>
  11. * AT&T Labs Research
  12. *
  13. * PLEASE: publish your tests so everyone can benefit
  14. *
  15. * Permission is hereby granted, free of charge, to any person obtaining a
  16. * copy of THIS SOFTWARE FILE (the "Software"), to deal in the Software
  17. * without restriction, including without limitation the rights to use,
  18. * copy, modify, merge, publish, distribute, and/or sell copies of the
  19. * Software, and to permit persons to whom the Software is furnished to do
  20. * so, subject to the following disclaimer:
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY AT&T ``AS IS'' AND ANY EXPRESS OR IMPLIED
  23. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  24. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  25. * IN NO EVENT SHALL AT&T BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. static const char id[] = "\n@(#)$Id: testregex (AT&T Research) 2005-05-20 $\0\n";
  34. #if _PACKAGE_ast
  35. #include <ast.h>
  36. #else
  37. #include <sys/types.h>
  38. #endif
  39. #include <stdio.h>
  40. #include <regex.h>
  41. #include <ctype.h>
  42. #include <setjmp.h>
  43. #include <signal.h>
  44. #include <string.h>
  45. #include <unistd.h>
  46. #ifdef __STDC__
  47. #include <stdlib.h>
  48. #include <locale.h>
  49. #endif
  50. #if !_PACKAGE_ast
  51. #undef REG_DISCIPLINE
  52. #endif
  53. #ifndef REG_DELIMITED
  54. #undef _REG_subcomp
  55. #endif
  56. #define TEST_ARE 0x00000001
  57. #define TEST_BRE 0x00000002
  58. #define TEST_ERE 0x00000004
  59. #define TEST_KRE 0x00000008
  60. #define TEST_LRE 0x00000010
  61. #define TEST_SRE 0x00000020
  62. #define TEST_EXPAND 0x00000040
  63. #define TEST_LENIENT 0x00000080
  64. #define TEST_QUERY 0x00000100
  65. #define TEST_SUB 0x00000200
  66. #define TEST_UNSPECIFIED 0x00000400
  67. #define TEST_VERIFY 0x00000800
  68. #define TEST_AND 0x00001000
  69. #define TEST_OR 0x00002000
  70. #define TEST_DELIMIT 0x00010000
  71. #define TEST_OK 0x00020000
  72. #define TEST_SAME 0x00040000
  73. #define TEST_ACTUAL 0x00100000
  74. #define TEST_BASELINE 0x00200000
  75. #define TEST_FAIL 0x00400000
  76. #define TEST_PASS 0x00800000
  77. #define TEST_SUMMARY 0x01000000
  78. #define TEST_IGNORE_ERROR 0x02000000
  79. #define TEST_IGNORE_OVER 0x04000000
  80. #define TEST_IGNORE_POSITION 0x08000000
  81. #define TEST_CATCH 0x10000000
  82. #define TEST_VERBOSE 0x20000000
  83. #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)
  84. #ifdef REG_DISCIPLINE
  85. #include <stk.h>
  86. typedef struct Disc_s
  87. {
  88. regdisc_t disc;
  89. int ordinal;
  90. Sfio_t* sp;
  91. } Disc_t;
  92. static void*
  93. compf(const regex_t* re, const char* xstr, size_t xlen, regdisc_t* disc)
  94. {
  95. Disc_t* dp = (Disc_t*)disc;
  96. return (void*)++dp->ordinal;
  97. }
  98. static int
  99. execf(const regex_t* re, void* data, const char* xstr, size_t xlen, const char* sstr, size_t slen, char** snxt, regdisc_t* disc)
  100. {
  101. Disc_t* dp = (Disc_t*)disc;
  102. sfprintf(dp->sp, "{%-.*s}(%d:%d)", xlen, xstr, (int)data, slen);
  103. return atoi(xstr);
  104. }
  105. static void*
  106. resizef(void* handle, void* data, size_t size)
  107. {
  108. if (!size)
  109. return 0;
  110. return stkalloc((Sfio_t*)handle, size);
  111. }
  112. #endif
  113. #ifndef NiL
  114. #ifdef __STDC__
  115. #define NiL 0
  116. #else
  117. #define NiL (char*)0
  118. #endif
  119. #endif
  120. #define H(x) do{if(html)fprintf(stderr,x);}while(0)
  121. #define T(x) fprintf(stderr,x)
  122. static void
  123. help(int html)
  124. {
  125. H("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n");
  126. H("<HTML>\n");
  127. H("<HEAD>\n");
  128. H("<TITLE>testregex man document</TITLE>\n");
  129. H("</HEAD>\n");
  130. H("<BODY bgcolor=white>\n");
  131. H("<PRE>\n");
  132. T("NAME\n");
  133. T(" testregex - regex(3) test harness\n");
  134. T("\n");
  135. T("SYNOPSIS\n");
  136. T(" testregex [ options ]\n");
  137. T("\n");
  138. T("DESCRIPTION\n");
  139. T(" testregex reads regex(3) test specifications, one per line, from the\n");
  140. T(" standard input and writes one output line for each failed test. A\n");
  141. T(" summary line is written after all tests are done. Each successful\n");
  142. T(" test is run again with REG_NOSUB. Unsupported features are noted\n");
  143. T(" before the first test, and tests requiring these features are\n");
  144. T(" silently ignored.\n");
  145. T("\n");
  146. T("OPTIONS\n");
  147. T(" -c catch signals and non-terminating calls\n");
  148. T(" -e ignore error return mismatches\n");
  149. T(" -h list help on standard error\n");
  150. T(" -n do not repeat successful tests with regnexec()\n");
  151. T(" -o ignore match[] overrun errors\n");
  152. T(" -p ignore negative position mismatches\n");
  153. T(" -s use stack instead of malloc\n");
  154. T(" -x do not repeat successful tests with REG_NOSUB\n");
  155. T(" -v list each test line\n");
  156. T(" -A list failed test lines with actual answers\n");
  157. T(" -B list all test lines with actual answers\n");
  158. T(" -F list failed test lines\n");
  159. T(" -P list passed test lines\n");
  160. T(" -S output one summary line\n");
  161. T("\n");
  162. T("INPUT FORMAT\n");
  163. T(" Input lines may be blank, a comment beginning with #, or a test\n");
  164. T(" specification. A specification is five fields separated by one\n");
  165. T(" or more tabs. NULL denotes the empty string and NIL denotes the\n");
  166. T(" 0 pointer.\n");
  167. T("\n");
  168. T(" Field 1: the regex(3) flags to apply, one character per REG_feature\n");
  169. T(" flag. The test is skipped if REG_feature is not supported by the\n");
  170. T(" implementation. If the first character is not [BEASKL] then the\n");
  171. T(" specification is a global control line. One or more of [BEASKL] may be\n");
  172. T(" specified; the test will be repeated for each mode.\n");
  173. T("\n");
  174. T(" B basic BRE (grep, ed, sed)\n");
  175. T(" E REG_EXTENDED ERE (egrep)\n");
  176. T(" A REG_AUGMENTED ARE (egrep with negation)\n");
  177. T(" S REG_SHELL SRE (sh glob)\n");
  178. T(" K REG_SHELL|REG_AUGMENTED KRE (ksh glob)\n");
  179. T(" L REG_LITERAL LRE (fgrep)\n");
  180. T("\n");
  181. T(" a REG_LEFT|REG_RIGHT implicit ^...$\n");
  182. T(" b REG_NOTBOL lhs does not match ^\n");
  183. T(" c REG_COMMENT ignore space and #...\\n\n");
  184. T(" d REG_SHELL_DOT explicit leading . match\n");
  185. T(" e REG_NOTEOL rhs does not match $\n");
  186. T(" f REG_MULTIPLE multiple \\n separated patterns\n");
  187. T(" g FNM_LEADING_DIR testfnmatch only -- match until /\n");
  188. T(" h REG_MULTIREF multiple digit backref\n");
  189. T(" i REG_ICASE ignore case\n");
  190. T(" j REG_SPAN . matches \\n\n");
  191. T(" k REG_ESCAPE \\ to ecape [...] delimiter\n");
  192. T(" l REG_LEFT implicit ^...\n");
  193. T(" m REG_MINIMAL minimal match\n");
  194. T(" n REG_NEWLINE explicit \\n match\n");
  195. T(" o REG_ENCLOSED (|&) magic inside [@|&](...)\n");
  196. T(" p REG_SHELL_PATH explicit / match\n");
  197. T(" q REG_DELIMITED delimited pattern\n");
  198. T(" r REG_RIGHT implicit ...$\n");
  199. T(" s REG_SHELL_ESCAPED \\ not special\n");
  200. T(" t REG_MUSTDELIM all delimiters must be specified\n");
  201. T(" u standard unspecified behavior -- errors not counted\n");
  202. T(" w REG_NOSUB no subexpression match array\n");
  203. T(" x REG_LENIENT let some errors slide\n");
  204. T(" y REG_LEFT regexec() implicit ^...\n");
  205. T(" z REG_NULL NULL subexpressions ok\n");
  206. T(" $ expand C \\c escapes in fields 2 and 3\n");
  207. T(" / field 2 is a regsubcomp() expression\n");
  208. T("\n");
  209. T(" Field 1 control lines:\n");
  210. T("\n");
  211. T(" C set LC_COLLATE and LC_CTYPE to locale in field 2\n");
  212. T("\n");
  213. T(" ?test ... output field 5 if passed and != EXPECTED, silent otherwise\n");
  214. T(" &test ... output field 5 if current and previous passed\n");
  215. T(" |test ... output field 5 if current passed and previous failed\n");
  216. T(" ; ... output field 2 if previous failed\n");
  217. T(" {test ... skip if failed until }\n");
  218. T(" } end of skip\n");
  219. T("\n");
  220. T(" : comment comment copied as output NOTE\n");
  221. T(" :comment:test :comment: ignored\n");
  222. T(" N[OTE] comment comment copied as output NOTE\n");
  223. T(" T[EST] comment comment\n");
  224. T("\n");
  225. T(" number use number for nmatch (20 by default)\n");
  226. T("\n");
  227. T(" Field 2: the regular expression pattern; SAME uses the pattern from\n");
  228. T(" the previous specification.\n");
  229. T("\n");
  230. T(" Field 3: the string to match.\n");
  231. T("\n");
  232. T(" Field 4: the test outcome. This is either one of the posix error\n");
  233. T(" codes (with REG_ omitted) or the match array, a list of (m,n)\n");
  234. T(" entries with m and n being first and last+1 positions in the\n");
  235. T(" field 3 string, or NULL if REG_NOSUB is in effect and success\n");
  236. T(" is expected. BADPAT is acceptable in place of any regcomp(3)\n");
  237. T(" error code. The match[] array is initialized to (-2,-2) before\n");
  238. T(" each test. All array elements from 0 to nmatch-1 must be specified\n");
  239. T(" in the outcome. Unspecified endpoints (offset -1) are denoted by ?.\n");
  240. T(" Unset endpoints (offset -2) are denoted by X. {x}(o:n) denotes a\n");
  241. T(" matched (?{...}) expression, where x is the text enclosed by {...},\n");
  242. T(" o is the expression ordinal counting from 1, and n is the length of\n");
  243. T(" the unmatched portion of the subject string. If x starts with a\n");
  244. T(" number then that is the return value of re_execf(), otherwise 0 is\n");
  245. T(" returned.\n");
  246. T("\n");
  247. T(" Field 5: optional comment appended to the report.\n");
  248. T("\n");
  249. T("CAVEAT\n");
  250. T(" If a regex implementation misbehaves with memory then all bets are off.\n");
  251. T("\n");
  252. T("CONTRIBUTORS\n");
  253. T(" Glenn Fowler gsf@research.att.com (ksh strmatch, regex extensions)\n");
  254. T(" David Korn dgk@research.att.com (ksh glob matcher)\n");
  255. T(" Doug McIlroy mcilroy@dartmouth.edu (ast regex/testre in C++)\n");
  256. T(" Tom Lord lord@regexps.com (rx tests)\n");
  257. T(" Henry Spencer henry@zoo.toronto.edu (original public regex)\n");
  258. T(" Andrew Hume andrew@research.att.com (gre tests)\n");
  259. T(" John Maddock John_Maddock@compuserve.com (regex++ tests)\n");
  260. T(" Philip Hazel ph10@cam.ac.uk (pcre tests)\n");
  261. T(" Ville Laurikari vl@iki.fi (libtre tests)\n");
  262. H("</PRE>\n");
  263. H("</BODY>\n");
  264. H("</HTML>\n");
  265. }
  266. #ifndef elementsof
  267. #define elementsof(x) (sizeof(x)/sizeof(x[0]))
  268. #endif
  269. #ifndef streq
  270. #define streq(a,b) (*(a)==*(b)&&!strcmp(a,b))
  271. #endif
  272. #define HUNG 2
  273. #define NOTEST (~0)
  274. #ifndef REG_TEST_DEFAULT
  275. #define REG_TEST_DEFAULT 0
  276. #endif
  277. #ifndef REG_EXEC_DEFAULT
  278. #define REG_EXEC_DEFAULT 0
  279. #endif
  280. static const char* unsupported[] =
  281. {
  282. "BASIC",
  283. #ifndef REG_EXTENDED
  284. "EXTENDED",
  285. #endif
  286. #ifndef REG_AUGMENTED
  287. "AUGMENTED",
  288. #endif
  289. #ifndef REG_SHELL
  290. "SHELL",
  291. #endif
  292. #ifndef REG_COMMENT
  293. "COMMENT",
  294. #endif
  295. #ifndef REG_DELIMITED
  296. "DELIMITED",
  297. #endif
  298. #ifndef REG_DISCIPLINE
  299. "DISCIPLINE",
  300. #endif
  301. #ifndef REG_ESCAPE
  302. "ESCAPE",
  303. #endif
  304. #ifndef REG_ICASE
  305. "ICASE",
  306. #endif
  307. #ifndef REG_LEFT
  308. "LEFT",
  309. #endif
  310. #ifndef REG_LENIENT
  311. "LENIENT",
  312. #endif
  313. #ifndef REG_LITERAL
  314. "LITERAL",
  315. #endif
  316. #ifndef REG_MINIMAL
  317. "MINIMAL",
  318. #endif
  319. #ifndef REG_MULTIPLE
  320. "MULTIPLE",
  321. #endif
  322. #ifndef REG_MULTIREF
  323. "MULTIREF",
  324. #endif
  325. #ifndef REG_MUSTDELIM
  326. "MUSTDELIM",
  327. #endif
  328. #ifndef REG_NEWLINE
  329. "NEWLINE",
  330. #endif
  331. #ifndef REG_NOTBOL
  332. "NOTBOL",
  333. #endif
  334. #ifndef REG_NOTEOL
  335. "NOTEOL",
  336. #endif
  337. #ifndef REG_NULL
  338. "NULL",
  339. #endif
  340. #ifndef REG_RIGHT
  341. "RIGHT",
  342. #endif
  343. #ifndef REG_SHELL_DOT
  344. "SHELL_DOT",
  345. #endif
  346. #ifndef REG_SHELL_ESCAPED
  347. "SHELL_ESCAPED",
  348. #endif
  349. #ifndef REG_SHELL_GROUP
  350. "SHELL_GROUP",
  351. #endif
  352. #ifndef REG_SHELL_PATH
  353. "SHELL_PATH",
  354. #endif
  355. #ifndef REG_SPAN
  356. "SPAN",
  357. #endif
  358. #if REG_NOSUB & REG_TEST_DEFAULT
  359. "SUBMATCH",
  360. #endif
  361. #if !_REG_nexec
  362. "regnexec",
  363. #endif
  364. #if !_REG_subcomp
  365. "regsubcomp",
  366. #endif
  367. 0
  368. };
  369. #ifndef REG_COMMENT
  370. #define REG_COMMENT NOTEST
  371. #endif
  372. #ifndef REG_DELIMITED
  373. #define REG_DELIMITED NOTEST
  374. #endif
  375. #ifndef REG_ESCAPE
  376. #define REG_ESCAPE NOTEST
  377. #endif
  378. #ifndef REG_ICASE
  379. #define REG_ICASE NOTEST
  380. #endif
  381. #ifndef REG_LEFT
  382. #define REG_LEFT NOTEST
  383. #endif
  384. #ifndef REG_LENIENT
  385. #define REG_LENIENT 0
  386. #endif
  387. #ifndef REG_MINIMAL
  388. #define REG_MINIMAL NOTEST
  389. #endif
  390. #ifndef REG_MULTIPLE
  391. #define REG_MULTIPLE NOTEST
  392. #endif
  393. #ifndef REG_MULTIREF
  394. #define REG_MULTIREF NOTEST
  395. #endif
  396. #ifndef REG_MUSTDELIM
  397. #define REG_MUSTDELIM NOTEST
  398. #endif
  399. #ifndef REG_NEWLINE
  400. #define REG_NEWLINE NOTEST
  401. #endif
  402. #ifndef REG_NOTBOL
  403. #define REG_NOTBOL NOTEST
  404. #endif
  405. #ifndef REG_NOTEOL
  406. #define REG_NOTEOL NOTEST
  407. #endif
  408. #ifndef REG_NULL
  409. #define REG_NULL NOTEST
  410. #endif
  411. #ifndef REG_RIGHT
  412. #define REG_RIGHT NOTEST
  413. #endif
  414. #ifndef REG_SHELL_DOT
  415. #define REG_SHELL_DOT NOTEST
  416. #endif
  417. #ifndef REG_SHELL_ESCAPED
  418. #define REG_SHELL_ESCAPED NOTEST
  419. #endif
  420. #ifndef REG_SHELL_GROUP
  421. #define REG_SHELL_GROUP NOTEST
  422. #endif
  423. #ifndef REG_SHELL_PATH
  424. #define REG_SHELL_PATH NOTEST
  425. #endif
  426. #ifndef REG_SPAN
  427. #define REG_SPAN NOTEST
  428. #endif
  429. #define REG_UNKNOWN (-1)
  430. #ifndef REG_ENEWLINE
  431. #define REG_ENEWLINE (REG_UNKNOWN-1)
  432. #endif
  433. #ifndef REG_ENULL
  434. #ifndef REG_EMPTY
  435. #define REG_ENULL (REG_UNKNOWN-2)
  436. #else
  437. #define REG_ENULL REG_EMPTY
  438. #endif
  439. #endif
  440. #ifndef REG_ECOUNT
  441. #define REG_ECOUNT (REG_UNKNOWN-3)
  442. #endif
  443. #ifndef REG_BADESC
  444. #define REG_BADESC (REG_UNKNOWN-4)
  445. #endif
  446. #ifndef REG_EMEM
  447. #define REG_EMEM (REG_UNKNOWN-5)
  448. #endif
  449. #ifndef REG_EHUNG
  450. #define REG_EHUNG (REG_UNKNOWN-6)
  451. #endif
  452. #ifndef REG_EBUS
  453. #define REG_EBUS (REG_UNKNOWN-7)
  454. #endif
  455. #ifndef REG_EFAULT
  456. #define REG_EFAULT (REG_UNKNOWN-8)
  457. #endif
  458. #ifndef REG_EFLAGS
  459. #define REG_EFLAGS (REG_UNKNOWN-9)
  460. #endif
  461. #ifndef REG_EDELIM
  462. #define REG_EDELIM (REG_UNKNOWN-9)
  463. #endif
  464. static const struct { int code; char* name; } codes[] =
  465. {
  466. REG_UNKNOWN, "UNKNOWN",
  467. REG_NOMATCH, "NOMATCH",
  468. REG_BADPAT, "BADPAT",
  469. REG_ECOLLATE, "ECOLLATE",
  470. REG_ECTYPE, "ECTYPE",
  471. REG_EESCAPE, "EESCAPE",
  472. REG_ESUBREG, "ESUBREG",
  473. REG_EBRACK, "EBRACK",
  474. REG_EPAREN, "EPAREN",
  475. REG_EBRACE, "EBRACE",
  476. REG_BADBR, "BADBR",
  477. REG_ERANGE, "ERANGE",
  478. REG_ESPACE, "ESPACE",
  479. REG_BADRPT, "BADRPT",
  480. REG_ENEWLINE, "ENEWLINE",
  481. REG_ENULL, "ENULL",
  482. REG_ECOUNT, "ECOUNT",
  483. REG_BADESC, "BADESC",
  484. REG_EMEM, "EMEM",
  485. REG_EHUNG, "EHUNG",
  486. REG_EBUS, "EBUS",
  487. REG_EFAULT, "EFAULT",
  488. REG_EFLAGS, "EFLAGS",
  489. REG_EDELIM, "EDELIM",
  490. };
  491. static struct
  492. {
  493. regmatch_t NOMATCH;
  494. int errors;
  495. int extracted;
  496. int ignored;
  497. int lineno;
  498. int passed;
  499. int signals;
  500. int unspecified;
  501. int verify;
  502. int warnings;
  503. char* file;
  504. char* stack;
  505. char* which;
  506. jmp_buf gotcha;
  507. #ifdef REG_DISCIPLINE
  508. Disc_t disc;
  509. #endif
  510. } state;
  511. static void
  512. quote(char* s, int len, unsigned long test)
  513. {
  514. unsigned char* u = (unsigned char*)s;
  515. unsigned char* e;
  516. int c;
  517. if (!u)
  518. printf("NIL");
  519. else if (!*u && len <= 1)
  520. printf("NULL");
  521. else if (test & TEST_EXPAND)
  522. {
  523. if (len < 0)
  524. len = strlen((char*)u);
  525. e = u + len;
  526. if (test & TEST_DELIMIT)
  527. printf("\"");
  528. while (u < e)
  529. switch (c = *u++)
  530. {
  531. case '\\':
  532. printf("\\\\");
  533. break;
  534. case '"':
  535. if (test & TEST_DELIMIT)
  536. printf("\\\"");
  537. else
  538. printf("\"");
  539. break;
  540. case '\a':
  541. printf("\\a");
  542. break;
  543. case '\b':
  544. printf("\\b");
  545. break;
  546. case 033:
  547. printf("\\e");
  548. break;
  549. case '\f':
  550. printf("\\f");
  551. break;
  552. case '\n':
  553. printf("\\n");
  554. break;
  555. case '\r':
  556. printf("\\r");
  557. break;
  558. case '\t':
  559. printf("\\t");
  560. break;
  561. case '\v':
  562. printf("\\v");
  563. break;
  564. default:
  565. if (!iscntrl(c) && isprint(c))
  566. putchar(c);
  567. else
  568. printf("\\x%02x", c);
  569. break;
  570. }
  571. if (test & TEST_DELIMIT)
  572. printf("\"");
  573. }
  574. else
  575. printf("%s", s);
  576. }
  577. static void
  578. report(char* comment, char* fun, char* re, char* s, int len, char* msg, int flags, unsigned long test)
  579. {
  580. if (state.file)
  581. printf("%s:", state.file);
  582. printf("%d:", state.lineno);
  583. if (re)
  584. {
  585. printf(" ");
  586. quote(re, -1, test|TEST_DELIMIT);
  587. if (s)
  588. {
  589. printf(" versus ");
  590. quote(s, len, test|TEST_DELIMIT);
  591. }
  592. }
  593. if (test & TEST_UNSPECIFIED)
  594. {
  595. state.unspecified++;
  596. printf(" unspecified behavior");
  597. }
  598. else
  599. state.errors++;
  600. if (state.which)
  601. printf(" %s", state.which);
  602. if (flags & REG_NOSUB)
  603. printf(" NOSUB");
  604. if (fun)
  605. printf(" %s", fun);
  606. if (comment[strlen(comment)-1] == '\n')
  607. printf(" %s", comment);
  608. else
  609. {
  610. printf(" %s: ", comment);
  611. if (msg)
  612. printf("%s: ", msg);
  613. }
  614. }
  615. static void
  616. error(regex_t* preg, int code)
  617. {
  618. char* msg;
  619. char buf[256];
  620. switch (code)
  621. {
  622. case REG_EBUS:
  623. msg = "bus error";
  624. break;
  625. case REG_EFAULT:
  626. msg = "memory fault";
  627. break;
  628. case REG_EHUNG:
  629. msg = "did not terminate";
  630. break;
  631. default:
  632. regerror(code, preg, msg = buf, sizeof buf);
  633. break;
  634. }
  635. printf("%s\n", msg);
  636. }
  637. static void
  638. bad(char* comment, char* re, char* s, int len, unsigned long test)
  639. {
  640. printf("bad test case ");
  641. report(comment, NiL, re, s, len, NiL, 0, test);
  642. exit(1);
  643. }
  644. static int
  645. escape(char* s)
  646. {
  647. char* b;
  648. char* t;
  649. char* q;
  650. char* e;
  651. int c;
  652. for (b = t = s; *t = *s; s++, t++)
  653. if (*s == '\\')
  654. switch (*++s)
  655. {
  656. case '\\':
  657. break;
  658. case 'a':
  659. *t = '\a';
  660. break;
  661. case 'b':
  662. *t = '\b';
  663. break;
  664. case 'c':
  665. if (*t = *++s)
  666. *t &= 037;
  667. else
  668. s--;
  669. break;
  670. case 'e':
  671. case 'E':
  672. *t = 033;
  673. break;
  674. case 'f':
  675. *t = '\f';
  676. break;
  677. case 'n':
  678. *t = '\n';
  679. break;
  680. case 'r':
  681. *t = '\r';
  682. break;
  683. case 's':
  684. *t = ' ';
  685. break;
  686. case 't':
  687. *t = '\t';
  688. break;
  689. case 'v':
  690. *t = '\v';
  691. break;
  692. case 'u':
  693. case 'x':
  694. c = 0;
  695. q = c == 'u' ? (s + 5) : (char*)0;
  696. e = s + 1;
  697. while (!e || !q || s < q)
  698. {
  699. switch (*++s)
  700. {
  701. case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  702. c = (c << 4) + *s - 'a' + 10;
  703. continue;
  704. case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
  705. c = (c << 4) + *s - 'A' + 10;
  706. continue;
  707. case '0': case '1': case '2': case '3': case '4':
  708. case '5': case '6': case '7': case '8': case '9':
  709. c = (c << 4) + *s - '0';
  710. continue;
  711. case '{':
  712. case '[':
  713. if (s != e)
  714. {
  715. s--;
  716. break;
  717. }
  718. e = 0;
  719. continue;
  720. case '}':
  721. case ']':
  722. if (e)
  723. s--;
  724. break;
  725. default:
  726. s--;
  727. break;
  728. }
  729. break;
  730. }
  731. *t = c;
  732. break;
  733. case '0': case '1': case '2': case '3':
  734. case '4': case '5': case '6': case '7':
  735. c = *s - '0';
  736. q = s + 2;
  737. while (s < q)
  738. {
  739. switch (*++s)
  740. {
  741. case '0': case '1': case '2': case '3':
  742. case '4': case '5': case '6': case '7':
  743. c = (c << 3) + *s - '0';
  744. break;
  745. default:
  746. q = --s;
  747. break;
  748. }
  749. }
  750. *t = c;
  751. break;
  752. default:
  753. *(s + 1) = 0;
  754. bad("invalid C \\ escape\n", s - 1, NiL, 0, 0);
  755. }
  756. return t - b;
  757. }
  758. static void
  759. matchoffprint(int off)
  760. {
  761. switch (off)
  762. {
  763. case -2:
  764. printf("X");
  765. break;
  766. case -1:
  767. printf("?");
  768. break;
  769. default:
  770. printf("%d", off);
  771. break;
  772. }
  773. }
  774. static void
  775. matchprint(regmatch_t* match, int nmatch, int nsub, char* ans, unsigned long test)
  776. {
  777. int i;
  778. for (; nmatch > nsub + 1; nmatch--)
  779. 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))
  780. break;
  781. for (i = 0; i < nmatch; i++)
  782. {
  783. printf("(");
  784. matchoffprint(match[i].rm_so);
  785. printf(",");
  786. matchoffprint(match[i].rm_eo);
  787. printf(")");
  788. }
  789. if (!(test & (TEST_ACTUAL|TEST_BASELINE)))
  790. {
  791. if (ans)
  792. printf(" expected: %s", ans);
  793. printf("\n");
  794. }
  795. }
  796. static int
  797. matchcheck(regmatch_t* match, int nmatch, int nsub, char* ans, char* re, char* s, int len, int flags, unsigned long test)
  798. {
  799. char* p;
  800. int i;
  801. int m;
  802. int n;
  803. if (streq(ans, "OK"))
  804. return test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY);
  805. for (i = 0, p = ans; i < nmatch && *p; i++)
  806. {
  807. if (*p == '{')
  808. {
  809. #ifdef REG_DISCIPLINE
  810. char* x;
  811. x = sfstruse(state.disc.sp);
  812. if (strcmp(p, x))
  813. {
  814. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  815. return 0;
  816. report("callout failed", NiL, re, s, len, NiL, flags, test);
  817. quote(p, -1, test);
  818. printf(" expected, ");
  819. quote(x, -1, test);
  820. printf(" returned\n");
  821. }
  822. #endif
  823. break;
  824. }
  825. if (*p++ != '(')
  826. bad("improper answer\n", re, s, -1, test);
  827. if (*p == '?')
  828. {
  829. m = -1;
  830. p++;
  831. }
  832. else
  833. m = strtol(p, &p, 10);
  834. if (*p++ != ',')
  835. bad("improper answer\n", re, s, -1, test);
  836. if (*p == '?')
  837. {
  838. n = -1;
  839. p++;
  840. }
  841. else
  842. n = strtol(p, &p, 10);
  843. if (*p++ != ')')
  844. bad("improper answer\n", re, s, -1, test);
  845. if (m!=match[i].rm_so || n!=match[i].rm_eo)
  846. {
  847. if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)))
  848. {
  849. report("failed: match was", NiL, re, s, len, NiL, flags, test);
  850. matchprint(match, nmatch, nsub, ans, test);
  851. }
  852. return 0;
  853. }
  854. }
  855. for (; i < nmatch; i++)
  856. {
  857. if (match[i].rm_so!=-1 || match[i].rm_eo!=-1)
  858. {
  859. if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_VERIFY)))
  860. {
  861. if ((test & TEST_IGNORE_POSITION) && (match[i].rm_so<0 || match[i].rm_eo<0))
  862. {
  863. state.ignored++;
  864. return 0;
  865. }
  866. if (!(test & TEST_SUMMARY))
  867. {
  868. report("failed: match was", NiL, re, s, len, NiL, flags, test);
  869. matchprint(match, nmatch, nsub, ans, test);
  870. }
  871. }
  872. return 0;
  873. }
  874. }
  875. if (!(test & TEST_IGNORE_OVER) && match[nmatch].rm_so != state.NOMATCH.rm_so)
  876. {
  877. if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY)))
  878. {
  879. report("failed: overran match array", NiL, re, s, len, NiL, flags, test);
  880. matchprint(match, nmatch + 1, nsub, NiL, test);
  881. }
  882. return 0;
  883. }
  884. return 1;
  885. }
  886. static void
  887. sigunblock(int s)
  888. {
  889. #ifdef SIG_SETMASK
  890. int op;
  891. sigset_t mask;
  892. sigemptyset(&mask);
  893. if (s)
  894. {
  895. sigaddset(&mask, s);
  896. op = SIG_UNBLOCK;
  897. }
  898. else op = SIG_SETMASK;
  899. sigprocmask(op, &mask, NiL);
  900. #else
  901. #ifdef sigmask
  902. sigsetmask(s ? (sigsetmask(0L) & ~sigmask(s)) : 0L);
  903. #endif
  904. #endif
  905. }
  906. static void
  907. gotcha(int sig)
  908. {
  909. int ret;
  910. signal(sig, gotcha);
  911. alarm(0);
  912. state.signals++;
  913. switch (sig)
  914. {
  915. case SIGALRM:
  916. ret = REG_EHUNG;
  917. break;
  918. case SIGBUS:
  919. ret = REG_EBUS;
  920. break;
  921. default:
  922. ret = REG_EFAULT;
  923. break;
  924. }
  925. sigunblock(sig);
  926. longjmp(state.gotcha, ret);
  927. }
  928. static char*
  929. my_getline(FILE* fp)
  930. {
  931. static char buf[32 * 1024];
  932. register char* s = buf;
  933. register char* e = &buf[sizeof(buf)];
  934. register char* b;
  935. for (;;)
  936. {
  937. if (!(b = fgets(s, e - s, fp)))
  938. return 0;
  939. state.lineno++;
  940. s += strlen(s);
  941. if (s == b || *--s != '\n' || s == b || *(s - 1) != '\\')
  942. {
  943. *s = 0;
  944. break;
  945. }
  946. s--;
  947. }
  948. return buf;
  949. }
  950. static unsigned long
  951. note(unsigned long level, char* msg, unsigned long skip, unsigned long test)
  952. {
  953. if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)) && !skip)
  954. {
  955. printf("NOTE\t");
  956. if (msg)
  957. printf("%s: ", msg);
  958. printf("skipping lines %d", state.lineno);
  959. }
  960. return skip | level;
  961. }
  962. #define TABS(n) &ts[7-((n)&7)]
  963. static char ts[] = "\t\t\t\t\t\t\t";
  964. static unsigned long
  965. 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)
  966. {
  967. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_OK|TEST_PASS|TEST_SUMMARY))
  968. {
  969. state.extracted = 1;
  970. if (test & TEST_OK)
  971. {
  972. state.passed++;
  973. if ((test & TEST_VERIFY) && !(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
  974. {
  975. if (msg && strcmp(msg, "EXPECTED"))
  976. printf("NOTE\t%s\n", msg);
  977. return skip;
  978. }
  979. test &= ~(TEST_PASS|TEST_QUERY);
  980. }
  981. if (test & (TEST_QUERY|TEST_VERIFY))
  982. {
  983. if (test & TEST_BASELINE)
  984. test &= ~(TEST_BASELINE|TEST_PASS);
  985. else
  986. test |= TEST_PASS;
  987. skip |= level;
  988. }
  989. if (!(test & TEST_OK))
  990. {
  991. if (test & TEST_UNSPECIFIED)
  992. state.unspecified++;
  993. else
  994. state.errors++;
  995. }
  996. if (test & (TEST_PASS|TEST_SUMMARY))
  997. return skip;
  998. test &= ~TEST_DELIMIT;
  999. printf("%s%s", spec, TABS(*tabs++));
  1000. if ((test & (TEST_BASELINE|TEST_SAME)) == (TEST_BASELINE|TEST_SAME))
  1001. printf("SAME");
  1002. else
  1003. quote(re, -1, test);
  1004. printf("%s", TABS(*tabs++));
  1005. quote(s, -1, test);
  1006. printf("%s", TABS(*tabs++));
  1007. if (!(test & (TEST_ACTUAL|TEST_BASELINE)) || !accept && !match)
  1008. printf("%s", ans);
  1009. else if (accept)
  1010. printf("%s", accept);
  1011. else
  1012. matchprint(match, nmatch, nsub, NiL, test);
  1013. if (msg)
  1014. printf("%s%s", TABS(*tabs++), msg);
  1015. putchar('\n');
  1016. }
  1017. else if (test & TEST_QUERY)
  1018. skip = note(level, msg, skip, test);
  1019. else if (test & TEST_VERIFY)
  1020. state.extracted = 1;
  1021. return skip;
  1022. }
  1023. static int
  1024. 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)
  1025. {
  1026. int eret;
  1027. if (!(test & TEST_CATCH))
  1028. {
  1029. regfree(preg);
  1030. eret = 0;
  1031. }
  1032. else if (!(eret = setjmp(state.gotcha)))
  1033. {
  1034. alarm(HUNG);
  1035. regfree(preg);
  1036. alarm(0);
  1037. }
  1038. else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1039. extract(tabs, spec, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
  1040. else
  1041. {
  1042. report("failed", "regfree", re, NiL, -1, msg, flags, test);
  1043. error(preg, eret);
  1044. }
  1045. return eret;
  1046. }
  1047. int
  1048. main(int argc, char** argv)
  1049. {
  1050. int flags;
  1051. int cflags;
  1052. int eflags;
  1053. int nmatch;
  1054. int nexec;
  1055. int nstr;
  1056. int cret;
  1057. int eret;
  1058. int nsub;
  1059. int i;
  1060. int j;
  1061. int expected;
  1062. int got;
  1063. int locale;
  1064. int subunitlen;
  1065. int testno;
  1066. unsigned long level;
  1067. unsigned long skip;
  1068. char* p;
  1069. char* line;
  1070. char* spec;
  1071. char* re;
  1072. char* s;
  1073. char* ans;
  1074. char* msg;
  1075. char* fun;
  1076. char* ppat;
  1077. char* subunit;
  1078. char* version;
  1079. char* field[6];
  1080. char* delim[6];
  1081. FILE* fp;
  1082. int tabs[6];
  1083. char unit[64];
  1084. regmatch_t match[100];
  1085. regex_t preg;
  1086. static char pat[32 * 1024];
  1087. int nonosub = REG_NOSUB == 0;
  1088. int nonexec = 0;
  1089. unsigned long test = 0;
  1090. static char* filter[] = { "-", 0 };
  1091. state.NOMATCH.rm_so = state.NOMATCH.rm_eo = -2;
  1092. p = unit;
  1093. version = (char*)id + 10;
  1094. while (p < &unit[sizeof(unit)-1] && (*p = *version++) && !isspace(*p))
  1095. p++;
  1096. *p = 0;
  1097. while ((p = *++argv) && *p == '-')
  1098. for (;;)
  1099. {
  1100. switch (*++p)
  1101. {
  1102. case 0:
  1103. break;
  1104. case 'c':
  1105. test |= TEST_CATCH;
  1106. continue;
  1107. case 'e':
  1108. test |= TEST_IGNORE_ERROR;
  1109. continue;
  1110. case 'h':
  1111. case '?':
  1112. help(0);
  1113. return 2;
  1114. case '-':
  1115. help(p[1] == 'h');
  1116. return 2;
  1117. case 'n':
  1118. nonexec = 1;
  1119. continue;
  1120. case 'o':
  1121. test |= TEST_IGNORE_OVER;
  1122. continue;
  1123. case 'p':
  1124. test |= TEST_IGNORE_POSITION;
  1125. continue;
  1126. case 's':
  1127. #ifdef REG_DISCIPLINE
  1128. if (!(state.stack = stkalloc(stkstd, 0)))
  1129. fprintf(stderr, "%s: out of space [stack]", unit);
  1130. state.disc.disc.re_resizef = resizef;
  1131. state.disc.disc.re_resizehandle = (void*)stkstd;
  1132. #endif
  1133. continue;
  1134. case 'x':
  1135. nonosub = 1;
  1136. continue;
  1137. case 'v':
  1138. test |= TEST_VERBOSE;
  1139. continue;
  1140. case 'A':
  1141. test |= TEST_ACTUAL;
  1142. continue;
  1143. case 'B':
  1144. test |= TEST_BASELINE;
  1145. continue;
  1146. case 'F':
  1147. test |= TEST_FAIL;
  1148. continue;
  1149. case 'P':
  1150. test |= TEST_PASS;
  1151. continue;
  1152. case 'S':
  1153. test |= TEST_SUMMARY;
  1154. continue;
  1155. default:
  1156. fprintf(stderr, "%s: %c: invalid option\n", unit, *p);
  1157. return 2;
  1158. }
  1159. break;
  1160. }
  1161. if (!*argv)
  1162. argv = filter;
  1163. locale = 0;
  1164. while (state.file = *argv++)
  1165. {
  1166. if (streq(state.file, "-") || streq(state.file, "/dev/stdin") || streq(state.file, "/dev/fd/0"))
  1167. {
  1168. state.file = 0;
  1169. fp = stdin;
  1170. }
  1171. else if (!(fp = fopen(state.file, "r")))
  1172. {
  1173. fprintf(stderr, "%s: %s: cannot read\n", unit, state.file);
  1174. return 2;
  1175. }
  1176. testno = state.errors = state.ignored = state.lineno = state.passed =
  1177. state.signals = state.unspecified = state.warnings = 0;
  1178. skip = 0;
  1179. level = 1;
  1180. if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
  1181. {
  1182. printf("TEST\t%s ", unit);
  1183. if (s = state.file)
  1184. {
  1185. subunit = p = 0;
  1186. for (;;)
  1187. {
  1188. switch (*s++)
  1189. {
  1190. case 0:
  1191. break;
  1192. case '/':
  1193. subunit = s;
  1194. continue;
  1195. case '.':
  1196. p = s - 1;
  1197. continue;
  1198. default:
  1199. continue;
  1200. }
  1201. break;
  1202. }
  1203. if (!subunit)
  1204. subunit = state.file;
  1205. if (p < subunit)
  1206. p = s - 1;
  1207. subunitlen = p - subunit;
  1208. printf("%-.*s ", subunitlen, subunit);
  1209. }
  1210. else
  1211. subunit = 0;
  1212. for (s = version; *s && (*s != ' ' || *(s + 1) != '$'); s++)
  1213. putchar(*s);
  1214. if (test & TEST_CATCH)
  1215. printf(", catch");
  1216. if (test & TEST_IGNORE_ERROR)
  1217. printf(", ignore error code mismatches");
  1218. if (test & TEST_IGNORE_POSITION)
  1219. printf(", ignore negative position mismatches");
  1220. #ifdef REG_DISCIPLINE
  1221. if (state.stack)
  1222. printf(", stack");
  1223. #endif
  1224. if (test & TEST_VERBOSE)
  1225. printf(", verbose");
  1226. printf("\n");
  1227. #ifdef REG_VERSIONID
  1228. if (regerror(REG_VERSIONID, NiL, pat, sizeof(pat)) > 0)
  1229. s = pat;
  1230. else
  1231. #endif
  1232. #ifdef REG_TEST_VERSION
  1233. s = REG_TEST_VERSION;
  1234. #else
  1235. s = "regex";
  1236. #endif
  1237. printf("NOTE\t%s\n", s);
  1238. if (elementsof(unsupported) > 1)
  1239. {
  1240. #if (REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL)) || !defined(REG_EXTENDED)
  1241. i = 0;
  1242. #else
  1243. i = REG_EXTENDED != 0;
  1244. #endif
  1245. for (got = 0; i < elementsof(unsupported) - 1; i++)
  1246. {
  1247. if (!got)
  1248. {
  1249. got = 1;
  1250. printf("NOTE\tunsupported: %s", unsupported[i]);
  1251. }
  1252. else
  1253. printf(",%s", unsupported[i]);
  1254. }
  1255. if (got)
  1256. printf("\n");
  1257. }
  1258. }
  1259. #ifdef REG_DISCIPLINE
  1260. state.disc.disc.re_version = REG_VERSION;
  1261. state.disc.disc.re_compf = compf;
  1262. state.disc.disc.re_execf = execf;
  1263. if (!(state.disc.sp = sfstropen()))
  1264. bad("out of space [discipline string stream]\n", NiL, NiL, 0, 0);
  1265. preg.re_disc = &state.disc.disc;
  1266. #endif
  1267. if (test & TEST_CATCH)
  1268. {
  1269. signal(SIGALRM, gotcha);
  1270. signal(SIGBUS, gotcha);
  1271. signal(SIGSEGV, gotcha);
  1272. }
  1273. while (p = my_getline(fp))
  1274. {
  1275. /* parse: */
  1276. line = p;
  1277. if (*p == ':' && !isspace(*(p + 1)))
  1278. {
  1279. while (*++p && *p != ':');
  1280. if (!*p++)
  1281. {
  1282. if (test & TEST_BASELINE)
  1283. printf("%s\n", line);
  1284. continue;
  1285. }
  1286. }
  1287. while (isspace(*p))
  1288. p++;
  1289. if (*p == 0 || *p == '#' || *p == 'T')
  1290. {
  1291. if (test & TEST_BASELINE)
  1292. printf("%s\n", line);
  1293. continue;
  1294. }
  1295. if (*p == ':' || *p == 'N')
  1296. {
  1297. if (test & TEST_BASELINE)
  1298. printf("%s\n", line);
  1299. else if (!(test & (TEST_ACTUAL|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
  1300. {
  1301. while (*++p && !isspace(*p));
  1302. while (isspace(*p))
  1303. p++;
  1304. printf("NOTE %s\n", p);
  1305. }
  1306. continue;
  1307. }
  1308. j = 0;
  1309. i = 0;
  1310. field[i++] = p;
  1311. for (;;)
  1312. {
  1313. switch (*p++)
  1314. {
  1315. case 0:
  1316. p--;
  1317. j = 0;
  1318. goto checkfield;
  1319. case '\t':
  1320. *(delim[i] = p - 1) = 0;
  1321. j = 1;
  1322. checkfield:
  1323. s = field[i - 1];
  1324. if (streq(s, "NIL"))
  1325. field[i - 1] = 0;
  1326. else if (streq(s, "NULL"))
  1327. *s = 0;
  1328. while (*p == '\t')
  1329. {
  1330. p++;
  1331. j++;
  1332. }
  1333. tabs[i - 1] = j;
  1334. if (!*p)
  1335. break;
  1336. if (i >= elementsof(field))
  1337. bad("too many fields\n", NiL, NiL, 0, 0);
  1338. field[i++] = p;
  1339. /*FALLTHROUGH*/
  1340. default:
  1341. continue;
  1342. }
  1343. break;
  1344. }
  1345. if (!(spec = field[0]))
  1346. bad("NIL spec\n", NiL, NiL, 0, 0);
  1347. /* interpret: */
  1348. cflags = REG_TEST_DEFAULT;
  1349. eflags = REG_EXEC_DEFAULT;
  1350. test &= TEST_GLOBAL;
  1351. state.extracted = 0;
  1352. nmatch = 20;
  1353. nsub = -1;
  1354. for (p = spec; *p; p++)
  1355. {
  1356. if (isdigit(*p))
  1357. {
  1358. nmatch = strtol(p, &p, 10);
  1359. if (nmatch >= elementsof(match))
  1360. bad("nmatch must be < 100\n", NiL, NiL, 0, 0);
  1361. p--;
  1362. continue;
  1363. }
  1364. switch (*p)
  1365. {
  1366. case 'A':
  1367. test |= TEST_ARE;
  1368. continue;
  1369. case 'B':
  1370. test |= TEST_BRE;
  1371. continue;
  1372. case 'C':
  1373. if (!(test & TEST_QUERY) && !(skip & level))
  1374. bad("locale must be nested\n", NiL, NiL, 0, 0);
  1375. test &= ~TEST_QUERY;
  1376. if (locale)
  1377. bad("locale nesting not supported\n", NiL, NiL, 0, 0);
  1378. if (i != 2)
  1379. bad("locale field expected\n", NiL, NiL, 0, 0);
  1380. if (!(skip & level))
  1381. {
  1382. #if defined(LC_COLLATE) && defined(LC_CTYPE)
  1383. s = field[1];
  1384. if (!s || streq(s, "POSIX"))
  1385. s = "C";
  1386. if (!(ans = setlocale(LC_COLLATE, s)) || streq(ans, "C") || streq(ans, "POSIX") || !(ans = setlocale(LC_CTYPE, s)) || streq(ans, "C") || streq(ans, "POSIX"))
  1387. skip = note(level, s, skip, test);
  1388. else
  1389. {
  1390. if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
  1391. printf("NOTE \"%s\" locale\n", s);
  1392. locale = level;
  1393. }
  1394. #else
  1395. skip = note(level, skip, test, "locales not supported");
  1396. #endif
  1397. }
  1398. cflags = NOTEST;
  1399. continue;
  1400. case 'E':
  1401. test |= TEST_ERE;
  1402. continue;
  1403. case 'K':
  1404. test |= TEST_KRE;
  1405. continue;
  1406. case 'L':
  1407. test |= TEST_LRE;
  1408. continue;
  1409. case 'S':
  1410. test |= TEST_SRE;
  1411. continue;
  1412. case 'a':
  1413. cflags |= REG_LEFT|REG_RIGHT;
  1414. continue;
  1415. case 'b':
  1416. eflags |= REG_NOTBOL;
  1417. continue;
  1418. case 'c':
  1419. cflags |= REG_COMMENT;
  1420. continue;
  1421. case 'd':
  1422. cflags |= REG_SHELL_DOT;
  1423. continue;
  1424. case 'e':
  1425. eflags |= REG_NOTEOL;
  1426. continue;
  1427. case 'f':
  1428. cflags |= REG_MULTIPLE;
  1429. continue;
  1430. case 'g':
  1431. cflags |= NOTEST;
  1432. continue;
  1433. case 'h':
  1434. cflags |= REG_MULTIREF;
  1435. continue;
  1436. case 'i':
  1437. cflags |= REG_ICASE;
  1438. continue;
  1439. case 'j':
  1440. cflags |= REG_SPAN;
  1441. continue;
  1442. case 'k':
  1443. cflags |= REG_ESCAPE;
  1444. continue;
  1445. case 'l':
  1446. cflags |= REG_LEFT;
  1447. continue;
  1448. case 'm':
  1449. cflags |= REG_MINIMAL;
  1450. continue;
  1451. case 'n':
  1452. cflags |= REG_NEWLINE;
  1453. continue;
  1454. case 'o':
  1455. cflags |= REG_SHELL_GROUP;
  1456. continue;
  1457. case 'p':
  1458. cflags |= REG_SHELL_PATH;
  1459. continue;
  1460. case 'q':
  1461. cflags |= REG_DELIMITED;
  1462. continue;
  1463. case 'r':
  1464. cflags |= REG_RIGHT;
  1465. continue;
  1466. case 's':
  1467. cflags |= REG_SHELL_ESCAPED;
  1468. continue;
  1469. case 't':
  1470. cflags |= REG_MUSTDELIM;
  1471. continue;
  1472. case 'u':
  1473. test |= TEST_UNSPECIFIED;
  1474. continue;
  1475. case 'w':
  1476. cflags |= REG_NOSUB;
  1477. continue;
  1478. case 'x':
  1479. if (REG_LENIENT)
  1480. cflags |= REG_LENIENT;
  1481. else
  1482. test |= TEST_LENIENT;
  1483. continue;
  1484. case 'y':
  1485. eflags |= REG_LEFT;
  1486. continue;
  1487. case 'z':
  1488. cflags |= REG_NULL;
  1489. continue;
  1490. case '$':
  1491. test |= TEST_EXPAND;
  1492. continue;
  1493. case '/':
  1494. test |= TEST_SUB;
  1495. continue;
  1496. case '?':
  1497. test |= TEST_VERIFY;
  1498. test &= ~(TEST_AND|TEST_OR);
  1499. state.verify = state.passed;
  1500. continue;
  1501. case '&':
  1502. test |= TEST_VERIFY|TEST_AND;
  1503. test &= ~TEST_OR;
  1504. continue;
  1505. case '|':
  1506. test |= TEST_VERIFY|TEST_OR;
  1507. test &= ~TEST_AND;
  1508. continue;
  1509. case ';':
  1510. test |= TEST_OR;
  1511. test &= ~TEST_AND;
  1512. continue;
  1513. case '{':
  1514. level <<= 1;
  1515. if (skip & (level >> 1))
  1516. {
  1517. skip |= level;
  1518. cflags = NOTEST;
  1519. }
  1520. else
  1521. {
  1522. skip &= ~level;
  1523. test |= TEST_QUERY;
  1524. }
  1525. continue;
  1526. case '}':
  1527. if (level == 1)
  1528. bad("invalid {...} nesting\n", NiL, NiL, 0, 0);
  1529. if ((skip & level) && !(skip & (level>>1)))
  1530. {
  1531. if (!(test & (TEST_BASELINE|TEST_SUMMARY)))
  1532. {
  1533. if (test & (TEST_ACTUAL|TEST_FAIL))
  1534. printf("}\n");
  1535. else if (!(test & TEST_PASS))
  1536. printf("-%d\n", state.lineno);
  1537. }
  1538. }
  1539. #if defined(LC_COLLATE) && defined(LC_CTYPE)
  1540. else if (locale & level)
  1541. {
  1542. locale = 0;
  1543. if (!(skip & level))
  1544. {
  1545. s = "C";
  1546. setlocale(LC_COLLATE, s);
  1547. setlocale(LC_CTYPE, s);
  1548. if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_SUMMARY)))
  1549. printf("NOTE \"%s\" locale\n", s);
  1550. else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_PASS))
  1551. printf("}\n");
  1552. }
  1553. else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL))
  1554. printf("}\n");
  1555. }
  1556. #endif
  1557. level >>= 1;
  1558. cflags = NOTEST;
  1559. continue;
  1560. default:
  1561. bad("bad spec\n", spec, NiL, 0, test);
  1562. break;
  1563. }
  1564. break;
  1565. }
  1566. if ((cflags|eflags) == NOTEST || (skip & level) && (test & TEST_BASELINE))
  1567. {
  1568. if (test & TEST_BASELINE)
  1569. {
  1570. while (i > 1)
  1571. *delim[--i] = '\t';
  1572. printf("%s\n", line);
  1573. }
  1574. continue;
  1575. }
  1576. if (test & TEST_OR)
  1577. {
  1578. if (!(test & TEST_VERIFY))
  1579. {
  1580. test &= ~TEST_OR;
  1581. if (state.passed == state.verify && i > 1)
  1582. printf("NOTE\t%s\n", field[1]);
  1583. continue;
  1584. }
  1585. else if (state.passed > state.verify)
  1586. continue;
  1587. }
  1588. else if (test & TEST_AND)
  1589. {
  1590. if (state.passed == state.verify)
  1591. continue;
  1592. state.passed = state.verify;
  1593. }
  1594. if (i < 4)
  1595. bad("too few fields\n", NiL, NiL, 0, test);
  1596. while (i < elementsof(field))
  1597. field[i++] = 0;
  1598. if (re = field[1])
  1599. {
  1600. if (streq(re, "SAME"))
  1601. {
  1602. re = ppat;
  1603. test |= TEST_SAME;
  1604. }
  1605. else
  1606. {
  1607. if (test & TEST_EXPAND)
  1608. escape(re);
  1609. strcpy(ppat = pat, re);
  1610. }
  1611. }
  1612. else
  1613. ppat = 0;
  1614. nstr = -1;
  1615. if ((s = field[2]) && (test & TEST_EXPAND))
  1616. {
  1617. nstr = escape(s);
  1618. #if _REG_nexec
  1619. if (nstr != strlen(s))
  1620. nexec = nstr;
  1621. #endif
  1622. }
  1623. if (!(ans = field[3]))
  1624. bad("NIL answer\n", NiL, NiL, 0, test);
  1625. msg = field[4];
  1626. fflush(stdout);
  1627. if (test & TEST_SUB)
  1628. #if _REG_subcomp
  1629. cflags |= REG_DELIMITED;
  1630. #else
  1631. continue;
  1632. #endif
  1633. compile:
  1634. if (state.extracted || (skip & level))
  1635. continue;
  1636. #if !(REG_TEST_DEFAULT & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL))
  1637. #ifdef REG_EXTENDED
  1638. if (REG_EXTENDED != 0 && (test & TEST_BRE))
  1639. #else
  1640. if (test & TEST_BRE)
  1641. #endif
  1642. {
  1643. test &= ~TEST_BRE;
  1644. flags = cflags;
  1645. state.which = "BRE";
  1646. }
  1647. else
  1648. #endif
  1649. #ifdef REG_EXTENDED
  1650. if (test & TEST_ERE)
  1651. {
  1652. test &= ~TEST_ERE;
  1653. flags = cflags | REG_EXTENDED;
  1654. state.which = "ERE";
  1655. }
  1656. else
  1657. #endif
  1658. #ifdef REG_AUGMENTED
  1659. if (test & TEST_ARE)
  1660. {
  1661. test &= ~TEST_ARE;
  1662. flags = cflags | REG_AUGMENTED;
  1663. state.which = "ARE";
  1664. }
  1665. else
  1666. #endif
  1667. #ifdef REG_LITERAL
  1668. if (test & TEST_LRE)
  1669. {
  1670. test &= ~TEST_LRE;
  1671. flags = cflags | REG_LITERAL;
  1672. state.which = "LRE";
  1673. }
  1674. else
  1675. #endif
  1676. #ifdef REG_SHELL
  1677. if (test & TEST_SRE)
  1678. {
  1679. test &= ~TEST_SRE;
  1680. flags = cflags | REG_SHELL;
  1681. state.which = "SRE";
  1682. }
  1683. else
  1684. #ifdef REG_AUGMENTED
  1685. if (test & TEST_KRE)
  1686. {
  1687. test &= ~TEST_KRE;
  1688. flags = cflags | REG_SHELL | REG_AUGMENTED;
  1689. state.which = "KRE";
  1690. }
  1691. else
  1692. #endif
  1693. #endif
  1694. {
  1695. if (test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY))
  1696. extract(tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test|TEST_OK);
  1697. continue;
  1698. }
  1699. if ((test & (TEST_QUERY|TEST_VERBOSE|TEST_VERIFY)) == TEST_VERBOSE)
  1700. {
  1701. printf("test %-3d %s ", state.lineno, state.which);
  1702. quote(re, -1, test|TEST_DELIMIT);
  1703. printf(" ");
  1704. quote(s, nstr, test|TEST_DELIMIT);
  1705. printf("\n");
  1706. }
  1707. nosub:
  1708. fun = "regcomp";
  1709. #if _REG_nexec
  1710. if (nstr >= 0 && nstr != strlen(s))
  1711. nexec = nstr;
  1712. else
  1713. #endif
  1714. nexec = -1;
  1715. if (state.extracted || (skip & level))
  1716. continue;
  1717. if (!(test & TEST_QUERY))
  1718. testno++;
  1719. #ifdef REG_DISCIPLINE
  1720. if (state.stack)
  1721. stkset(stkstd, state.stack, 0);
  1722. flags |= REG_DISCIPLINE;
  1723. state.disc.ordinal = 0;
  1724. sfstrseek(state.disc.sp, 0, SEEK_SET);
  1725. #endif
  1726. if (!(test & TEST_CATCH))
  1727. cret = regcomp(&preg, re, flags);
  1728. else if (!(cret = setjmp(state.gotcha)))
  1729. {
  1730. alarm(HUNG);
  1731. cret = regcomp(&preg, re, flags);
  1732. alarm(0);
  1733. }
  1734. #if _REG_subcomp
  1735. if (!cret && (test & TEST_SUB))
  1736. {
  1737. fun = "regsubcomp";
  1738. p = re + preg.re_npat;
  1739. if (!(test & TEST_CATCH))
  1740. cret = regsubcomp(&preg, p, NiL, 0, 0);
  1741. else if (!(cret = setjmp(state.gotcha)))
  1742. {
  1743. alarm(HUNG);
  1744. cret = regsubcomp(&preg, p, NiL, 0, 0);
  1745. alarm(0);
  1746. }
  1747. if (!cret && *(p += preg.re_npat) && !(preg.re_sub->re_flags & REG_SUB_LAST))
  1748. {
  1749. if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test))
  1750. continue;
  1751. cret = REG_EFLAGS;
  1752. }
  1753. }
  1754. #endif
  1755. if (!cret)
  1756. {
  1757. if (!(flags & REG_NOSUB) && nsub < 0 && *ans == '(')
  1758. {
  1759. for (p = ans; *p; p++)
  1760. if (*p == '(')
  1761. nsub++;
  1762. else if (*p == '{')
  1763. nsub--;
  1764. if (nsub >= 0)
  1765. {
  1766. if (test & TEST_IGNORE_OVER)
  1767. {
  1768. if (nmatch > nsub)
  1769. nmatch = nsub + 1;
  1770. }
  1771. else if (nsub != preg.re_nsub)
  1772. {
  1773. if (nsub > preg.re_nsub)
  1774. {
  1775. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1776. skip = extract(tabs, line, re, s, ans, msg, "OK", NiL, 0, 0, skip, level, test|TEST_DELIMIT);
  1777. else
  1778. {
  1779. report("re_nsub incorrect", fun, re, NiL, -1, msg, flags, test);
  1780. printf("at least %d expected, %d returned\n", nsub, preg.re_nsub);
  1781. state.errors++;
  1782. }
  1783. }
  1784. else
  1785. nsub = preg.re_nsub;
  1786. }
  1787. }
  1788. }
  1789. if (!(test & TEST_SUB) && *ans && *ans != '(' && !streq(ans, "OK") && !streq(ans, "NOMATCH"))
  1790. {
  1791. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1792. skip = extract(tabs, line, re, s, ans, msg, "OK", NiL, 0, 0, skip, level, test|TEST_DELIMIT);
  1793. else if (!(test & TEST_LENIENT))
  1794. {
  1795. report("failed", fun, re, NiL, -1, msg, flags, test);
  1796. printf("%s expected, OK returned\n", ans);
  1797. }
  1798. catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
  1799. continue;
  1800. }
  1801. }
  1802. else
  1803. {
  1804. if (test & TEST_LENIENT)
  1805. /* we'll let it go this time */;
  1806. else if (!*ans || ans[0]=='(' || cret == REG_BADPAT && streq(ans, "NOMATCH"))
  1807. {
  1808. got = 0;
  1809. for (i = 1; i < elementsof(codes); i++)
  1810. if (cret==codes[i].code)
  1811. got = i;
  1812. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1813. skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT);
  1814. else
  1815. {
  1816. report("failed", fun, re, NiL, -1, msg, flags, test);
  1817. printf("%s returned: ", codes[got].name);
  1818. error(&preg, cret);
  1819. }
  1820. }
  1821. else
  1822. {
  1823. expected = got = 0;
  1824. for (i = 1; i < elementsof(codes); i++)
  1825. {
  1826. if (streq(ans, codes[i].name))
  1827. expected = i;
  1828. if (cret==codes[i].code)
  1829. got = i;
  1830. }
  1831. if (!expected)
  1832. {
  1833. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1834. skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT);
  1835. else
  1836. {
  1837. report("failed: invalid error code", NiL, re, NiL, -1, msg, flags, test);
  1838. printf("%s expected, %s returned\n", ans, codes[got].name);
  1839. }
  1840. }
  1841. else if (cret != codes[expected].code && cret != REG_BADPAT)
  1842. {
  1843. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1844. skip = extract(tabs, line, re, s, ans, msg, codes[got].name, NiL, 0, 0, skip, level, test|TEST_DELIMIT);
  1845. else if (test & TEST_IGNORE_ERROR)
  1846. state.ignored++;
  1847. else
  1848. {
  1849. report("should fail and did", fun, re, NiL, -1, msg, flags, test);
  1850. printf("%s expected, %s returned: ", ans, codes[got].name);
  1851. state.errors--;
  1852. state.warnings++;
  1853. error(&preg, cret);
  1854. }
  1855. }
  1856. }
  1857. goto compile;
  1858. }
  1859. #if _REG_nexec
  1860. execute:
  1861. if (nexec >= 0)
  1862. fun = "regnexec";
  1863. else
  1864. #endif
  1865. fun = "regexec";
  1866. for (i = 0; i < elementsof(match); i++)
  1867. match[i] = state.NOMATCH;
  1868. #if _REG_nexec
  1869. if (nexec >= 0)
  1870. {
  1871. eret = regnexec(&preg, s, nexec, nmatch, match, eflags);
  1872. s[nexec] = 0;
  1873. }
  1874. else
  1875. #endif
  1876. {
  1877. if (!(test & TEST_CATCH))
  1878. eret = regexec(&preg, s, nmatch, match, eflags);
  1879. else if (!(eret = setjmp(state.gotcha)))
  1880. {
  1881. alarm(HUNG);
  1882. eret = regexec(&preg, s, nmatch, match, eflags);
  1883. alarm(0);
  1884. }
  1885. }
  1886. #if _REG_subcomp
  1887. if ((test & TEST_SUB) && !eret)
  1888. {
  1889. fun = "regsubexec";
  1890. if (!(test & TEST_CATCH))
  1891. eret = regsubexec(&preg, s, nmatch, match);
  1892. else if (!(eret = setjmp(state.gotcha)))
  1893. {
  1894. alarm(HUNG);
  1895. eret = regsubexec(&preg, s, nmatch, match);
  1896. alarm(0);
  1897. }
  1898. }
  1899. #endif
  1900. if (flags & REG_NOSUB)
  1901. {
  1902. if (eret)
  1903. {
  1904. if (eret != REG_NOMATCH || !streq(ans, "NOMATCH"))
  1905. {
  1906. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1907. skip = extract(tabs, line, re, s, ans, msg, "NOMATCH", NiL, 0, 0, skip, level, test|TEST_DELIMIT);
  1908. else
  1909. {
  1910. report("REG_NOSUB failed", fun, re, s, nstr, msg, flags, test);
  1911. error(&preg, eret);
  1912. }
  1913. }
  1914. }
  1915. else if (streq(ans, "NOMATCH"))
  1916. {
  1917. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1918. skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT);
  1919. else
  1920. {
  1921. report("should fail and didn't", fun, re, s, nstr, msg, flags, test);
  1922. error(&preg, eret);
  1923. }
  1924. }
  1925. }
  1926. else if (eret)
  1927. {
  1928. if (eret != REG_NOMATCH || !streq(ans, "NOMATCH"))
  1929. {
  1930. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1931. skip = extract(tabs, line, re, s, ans, msg, "NOMATCH", NiL, 0, nsub, skip, level, test|TEST_DELIMIT);
  1932. else
  1933. {
  1934. report("failed", fun, re, s, nstr, msg, flags, test);
  1935. if (eret != REG_NOMATCH)
  1936. error(&preg, eret);
  1937. else if (*ans)
  1938. printf("expected: %s\n", ans);
  1939. else
  1940. printf("\n");
  1941. }
  1942. }
  1943. }
  1944. else if (streq(ans, "NOMATCH"))
  1945. {
  1946. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1947. skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT);
  1948. else
  1949. {
  1950. report("should fail and didn't", fun, re, s, nstr, msg, flags, test);
  1951. matchprint(match, nmatch, nsub, NiL, test);
  1952. }
  1953. }
  1954. #if _REG_subcomp
  1955. else if (test & TEST_SUB)
  1956. {
  1957. p = preg.re_sub->re_buf;
  1958. if (strcmp(p, ans))
  1959. {
  1960. report("failed", fun, re, s, nstr, msg, flags, test);
  1961. quote(ans, -1, test|TEST_DELIMIT);
  1962. printf(" expected, ");
  1963. quote(p, -1, test|TEST_DELIMIT);
  1964. printf(" returned\n");
  1965. }
  1966. }
  1967. #endif
  1968. else if (!*ans)
  1969. {
  1970. if (match[0].rm_so != state.NOMATCH.rm_so)
  1971. {
  1972. if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  1973. skip = extract(tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test);
  1974. else
  1975. {
  1976. report("failed: no match but match array assigned", NiL, re, s, nstr, msg, flags, test);
  1977. matchprint(match, nmatch, nsub, NiL, test);
  1978. }
  1979. }
  1980. }
  1981. else if (matchcheck(match, nmatch, nsub, ans, re, s, nstr, flags, test))
  1982. {
  1983. #if _REG_nexec
  1984. if (nexec < 0 && !nonexec)
  1985. {
  1986. nexec = nstr >= 0 ? nstr : strlen(s);
  1987. s[nexec] = '\n';
  1988. testno++;
  1989. goto execute;
  1990. }
  1991. #endif
  1992. if (!(test & (TEST_SUB|TEST_VERIFY)) && !nonosub)
  1993. {
  1994. if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test))
  1995. continue;
  1996. flags |= REG_NOSUB;
  1997. goto nosub;
  1998. }
  1999. if (test & (TEST_BASELINE|TEST_PASS|TEST_VERIFY))
  2000. skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_OK);
  2001. }
  2002. else if (test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS|TEST_QUERY|TEST_SUMMARY|TEST_VERIFY))
  2003. skip = extract(tabs, line, re, s, ans, msg, NiL, match, nmatch, nsub, skip, level, test|TEST_DELIMIT);
  2004. if (catchfree(&preg, flags, tabs, line, re, s, ans, msg, NiL, NiL, 0, 0, skip, level, test))
  2005. continue;
  2006. goto compile;
  2007. }
  2008. if (test & TEST_SUMMARY)
  2009. 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);
  2010. else if (!(test & (TEST_ACTUAL|TEST_BASELINE|TEST_FAIL|TEST_PASS)))
  2011. {
  2012. printf("TEST\t%s", unit);
  2013. if (subunit)
  2014. printf(" %-.*s", subunitlen, subunit);
  2015. printf(", %d test%s", testno, testno == 1 ? "" : "s");
  2016. if (state.ignored)
  2017. printf(", %d ignored mismatche%s", state.ignored, state.ignored == 1 ? "" : "s");
  2018. if (state.warnings)
  2019. printf(", %d warning%s", state.warnings, state.warnings == 1 ? "" : "s");
  2020. if (state.unspecified)
  2021. printf(", %d unspecified difference%s", state.unspecified, state.unspecified == 1 ? "" : "s");
  2022. if (state.signals)
  2023. printf(", %d signal%s", state.signals, state.signals == 1 ? "" : "s");
  2024. printf(", %d error%s\n", state.errors, state.errors == 1 ? "" : "s");
  2025. }
  2026. if (fp != stdin)
  2027. fclose(fp);
  2028. }
  2029. return 0;
  2030. }