4 * Copyright (C) 2007-2016 David Lutterkort
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Author: David Lutterkort <dlutter@redhat.com>
33 #define FA_DOT_DIR "FA_DOT_DIR"
40 static struct fa_list *fa_list;
42 static void print_regerror(int err, const char *regexp) {
45 size = regerror(err, NULL, NULL, 0);
46 if (ALLOC_N(errbuf, size) < 0)
48 regerror(err, NULL, errbuf, size);
49 if (strlen(regexp) > 40) {
50 char *s = strndup(regexp, 40);
51 fprintf(stderr, "Error building fa from %s...:\n", s);
54 fprintf(stderr, "Error building fa from %s:\n", regexp);
56 fprintf(stderr, " %s\n", errbuf);
60 static void setup(ATTRIBUTE_UNUSED CuTest *tc) {
64 static void teardown(ATTRIBUTE_UNUSED CuTest *tc) {
65 list_for_each(fl, fa_list) {
71 static struct fa *mark(struct fa *fa) {
78 list_cons(fa_list, fl);
83 static void assertAsRegexp(CuTest *tc, struct fa *fa) {
87 struct fa *empty = mark(fa_make_basic(FA_EPSILON));
90 /* Jump through some hoops to make FA1 a copy of FA */
91 fa1 = mark(fa_concat(fa, empty));
92 /* Minimize FA1, otherwise the regexp returned is enormous for the */
93 /* monster (~ 2MB) and fa_compile becomes incredibly slow */
98 r = fa_as_regexp(fa1, &re, &re_len);
99 CuAssertIntEquals(tc, 0, r);
101 r = fa_compile(re, re_len, &fa2);
102 if (r != REG_NOERROR) {
103 print_regerror(r, re);
105 CuAssertIntEquals(tc, REG_NOERROR, r);
106 CuAssertTrue(tc, fa_equals(fa, fa2));
112 static struct fa *make_fa(CuTest *tc,
113 const char *regexp, size_t reglen,
118 r = fa_compile(regexp, reglen, &fa);
121 if (exp_err == REG_NOERROR) {
122 if (r != REG_NOERROR)
123 print_regerror(r, regexp);
124 CuAssertIntEquals(tc, REG_NOERROR, r);
125 CuAssertPtrNotNull(tc, fa);
127 assertAsRegexp(tc, fa);
129 CuAssertIntEquals(tc, exp_err, r);
130 CuAssertPtrEquals(tc, NULL, fa);
135 static struct fa *make_good_fa(CuTest *tc, const char *regexp) {
136 return make_fa(tc, regexp, strlen(regexp), REG_NOERROR);
139 static void dot(struct fa *fa) {
140 static int count = 0;
146 if ((dot_dir = getenv(FA_DOT_DIR)) == NULL)
149 r = asprintf(&fname, "%s/fa_test_%02d.dot", dot_dir, count++);
153 if ((fp = fopen(fname, "w")) == NULL) {
164 static void testBadRegexps(CuTest *tc) {
165 const char *const re1 = "(x";
166 const char *const re2 = "a{5,3}";
167 make_fa(tc, re1, strlen(re1), REG_EPAREN);
168 make_fa(tc, re2, strlen(re2), REG_BADBR);
171 /* Stress test, mostly good to check that allocation is clean */
172 static void testMonster(CuTest *tc) {
173 #define WORD "[a-zA-Z_0-9]+"
174 #define CWS "([ \\n\\t]+|\\/\\*([^\\*]|\\*[^\\/])*\\*\\/)*"
175 #define QUOTED "\"[^\"]*\""
176 #define ELT "\\(" WORD "(," CWS WORD "){3}\\)"
178 static const char *const monster =
179 "(" WORD "|" QUOTED "|" "\\(" CWS ELT "(," CWS ELT ")*" CWS "\\))";
190 fa = make_good_fa(tc, monster);
192 fa_ambig_example(fa, fa, &upv, &upv_len, &pv, &v);
194 /* Monster can't be concatenated with itself */
195 CuAssertStrEquals(tc, "AAA", upv);
196 CuAssertStrEquals(tc, "AA", pv);
197 CuAssertStrEquals(tc, "A", v);
200 /* Monster can also not be starred */
201 fas = mark(fa_iter(fa, 0, -1));
202 /* Minimize FAS, otherwise the example returned is nondeterministic,
203 since example generation depends on the structure of the FA.
204 FIXME: Explain why UPV with the unminimized FAS changes to a much
205 longer string simply when allocation patterns change (e.g., by
206 running the test under valgrind vs. plain glibc malloc. Fishy ?
207 FA_EXAMPLE should depend on the structure of the FA, but not
208 incidental details like sorting of transitions.
211 fa_ambig_example(fas, fa, &upv, &upv_len, &pv, &v);
213 CuAssertStrEquals(tc, "AA", upv);
214 CuAssertStrEquals(tc, "AA", pv);
215 CuAssertStrEquals(tc, "A", v);
219 static void testChars(CuTest *tc) {
220 struct fa *fa1, *fa2, *fa3;
222 fa1 = make_good_fa(tc, ".");
223 fa2 = make_good_fa(tc, "[a-z]");
224 CuAssertTrue(tc, fa_contains(fa2, fa1));
226 fa1 = make_good_fa(tc, "(.|\n)");
227 CuAssertTrue(tc, fa_contains(fa2, fa1));
229 fa1 = mark(fa_intersect(fa1, fa2));
230 CuAssertTrue(tc, fa_equals(fa1, fa2));
232 fa1 = make_good_fa(tc, "[^b-dxyz]");
233 fa2 = make_good_fa(tc, "[a-z]");
234 fa3 = mark(fa_intersect(fa1, fa2));
235 fa2 = make_good_fa(tc, "[ae-w]");
236 CuAssertTrue(tc, fa_equals(fa2, fa3));
239 static void testManualAmbig(CuTest *tc) {
240 /* The point of this test is mostly to teach me how Anders Moeller's
241 algorithm for finding ambiguous strings works.
243 For the two languages a1 = a|ab and a2 = a|ba, a1.a2 has one
244 ambiguous word aba, which can be split as a.ba and ab.a.
246 This uses X and Y as the markers*/
248 struct fa *a1f = make_good_fa(tc, "Xa|XaXb");
249 struct fa *a1t = make_good_fa(tc, "(YX)*Xa|(YX)*Xa(YX)*Xb");
250 struct fa *a2f = make_good_fa(tc, "Xa|XbXa");
251 struct fa *a2t = make_good_fa(tc, "(YX)*Xa|((YX)*Xb(YX)*Xa)");
252 struct fa *mp = make_good_fa(tc, "YX(X(.|\n))+");
253 struct fa *ms = make_good_fa(tc, "YX(X(.|\n))*");
254 struct fa *sp = make_good_fa(tc, "(X(.|\n))+YX");
255 struct fa *ss = make_good_fa(tc, "(X(.|\n))*YX");
257 struct fa *a1f_mp = mark(fa_concat(a1f, mp));
258 struct fa *a1f_mp_a1t = mark(fa_intersect(a1f_mp, a1t));
259 struct fa *b1 = mark(fa_concat(a1f_mp_a1t, ms));
261 struct fa *sp_a2f = mark(fa_concat(sp, a2f));
262 struct fa *sp_a2f_a2t = mark(fa_intersect(sp_a2f, a2t));
263 struct fa *b2 = mark(fa_concat(ss, sp_a2f_a2t));
265 struct fa *amb = mark(fa_intersect(b1, b2));
266 struct fa *exp = make_good_fa(tc, "XaYXXbYXXa");
267 CuAssertTrue(tc, fa_equals(exp, amb));
270 static void testContains(CuTest *tc) {
271 struct fa *fa1, *fa2, *fa3;
273 fa1 = make_good_fa(tc, "ab*");
274 fa2 = make_good_fa(tc, "ab+");
275 fa3 = make_good_fa(tc, "ab+c*|acc");
277 CuAssertTrue(tc, fa_contains(fa1, fa1));
278 CuAssertTrue(tc, fa_contains(fa2, fa2));
279 CuAssertTrue(tc, fa_contains(fa3, fa3));
281 CuAssertTrue(tc, ! fa_contains(fa1, fa2));
282 CuAssertTrue(tc, fa_contains(fa2, fa1));
283 CuAssertTrue(tc, fa_contains(fa2, fa3));
284 CuAssertTrue(tc, ! fa_contains(fa3, fa2));
285 CuAssertTrue(tc, ! fa_contains(fa1, fa3));
286 CuAssertTrue(tc, ! fa_contains(fa3, fa1));
289 static void testIntersect(CuTest *tc) {
290 struct fa *fa1, *fa2, *fa;
292 fa1 = make_good_fa(tc, "[a-zA-Z]*[.:=]([0-9]|[^A-Z])*");
293 fa2 = make_good_fa(tc, "[a-z][:=][0-9a-z]+");
294 fa = mark(fa_intersect(fa1, fa2));
295 CuAssertPtrNotNull(tc, fa);
296 CuAssertTrue(tc, fa_equals(fa, fa2));
297 CuAssertTrue(tc, ! fa_equals(fa, fa1));
300 static void testComplement(CuTest *tc) {
301 struct fa *fa1 = make_good_fa(tc, "[b-y]+");
302 struct fa *fa2 = mark(fa_complement(fa1));
303 /* We use '()' to match the empty word explicitly */
304 struct fa *fa3 = make_good_fa(tc, "(()|[b-y]*[^b-y](.|\n)*)");
306 CuAssertTrue(tc, fa_equals(fa2, fa3));
308 fa2 = mark(fa_complement(fa2));
309 CuAssertTrue(tc, fa_equals(fa1, fa2));
312 static void testOverlap(CuTest *tc) {
313 struct fa *fa1 = make_good_fa(tc, "a|ab");
314 struct fa *fa2 = make_good_fa(tc, "a|ba");
315 struct fa *p = mark(fa_overlap(fa1, fa2));
316 struct fa *exp = make_good_fa(tc, "b");
318 CuAssertTrue(tc, fa_equals(exp, p));
320 fa1 = make_good_fa(tc, "a|b|c|abc");
321 fa2 = mark(fa_iter(fa1, 0, -1));
322 exp = make_good_fa(tc, "bc");
323 p = mark(fa_overlap(fa1, fa2));
325 CuAssertTrue(tc, fa_equals(exp, p));
328 static void assertExample(CuTest *tc, const char *regexp, const char *exp) {
329 struct fa *fa = make_good_fa(tc, regexp);
332 fa_example(fa, &xmpl, &xmpl_len);
333 CuAssertStrEquals(tc, exp, xmpl);
337 char *s = strdup(exp);
338 for (int i = 0; i < strlen(s); i++) s[i] = tolower(s[i]);
340 fa_example(fa, &xmpl, &xmpl_len);
341 CuAssertStrEquals(tc, s, xmpl);
346 static void testExample(CuTest *tc) {
347 assertExample(tc, "(.|\n)", "A");
348 assertExample(tc, "(\n|\t|x)", "x");
349 assertExample(tc, "[^b-y]", "A");
350 assertExample(tc, "x*", "x");
351 assertExample(tc, "yx*", "y");
352 assertExample(tc, "ab+cx*", "abc");
353 assertExample(tc, "ab+cx*|y*", "y");
354 assertExample(tc, "u*|[0-9]", "u");
355 assertExample(tc, "u+|[0-9]", "u");
356 assertExample(tc, "vu+|[0-9]", "0");
357 assertExample(tc, "vu{2}|[0-9]", "0");
358 assertExample(tc, "\\[", "[");
359 assertExample(tc, "[\\]", "\\");
360 assertExample(tc, "a{3}", "aaa");
361 assertExample(tc, "a{3,}", "aaa");
363 assertExample(tc, "\001((\002.)*\001)+\002", "\001\001\002");
364 assertExample(tc, "\001((\001.)*\002)+\002", "\001\002\002");
366 assertExample(tc, "a[^\001-\004]+b", "aAb");
368 /* A strange way to write a? - allowed by POSIX */
369 assertExample(tc, "(a|)", "a");
370 assertExample(tc, "(|a)", "a");
372 struct fa *fa1 = mark(fa_make_basic(FA_EMPTY));
375 fa_example(fa1, &xmpl, &xmpl_len);
376 CuAssertPtrEquals(tc, NULL, xmpl);
378 fa1 = mark(fa_make_basic(FA_EPSILON));
379 fa_example(fa1, &xmpl, &xmpl_len);
380 CuAssertStrEquals(tc, "", xmpl);
384 static void assertAmbig(CuTest *tc, const char *regexp1, const char *regexp2,
386 const char *exp_pv, const char *exp_v) {
388 struct fa *fa1 = make_good_fa(tc, regexp1);
389 struct fa *fa2 = make_good_fa(tc, regexp2);
392 fa_ambig_example(fa1, fa2, &upv, &upv_len, &pv, &v);
393 CuAssertPtrNotNull(tc, upv);
394 CuAssertPtrNotNull(tc, pv);
395 CuAssertPtrNotNull(tc, v);
397 CuAssertStrEquals(tc, exp_upv, upv);
398 CuAssertIntEquals(tc, strlen(exp_upv), upv_len);
399 CuAssertStrEquals(tc, exp_pv, pv);
400 CuAssertStrEquals(tc, exp_v, v);
404 static void assertNotAmbig(CuTest *tc, const char *regexp1,
405 const char *regexp2) {
406 struct fa *fa1 = make_good_fa(tc, regexp1);
407 struct fa *fa2 = make_good_fa(tc, regexp2);
410 fa_ambig_example(fa1, fa2, &upv, &upv_len, NULL, NULL);
411 CuAssertPtrEquals(tc, NULL, upv);
414 static void testAmbig(CuTest *tc) {
415 assertAmbig(tc, "a|ab", "a|ba", "aba", "ba", "a");
416 assertAmbig(tc, "(a|ab)*", "a|ba", "aba", "ba", "a");
417 assertAmbig(tc, "(a|b|c|d|abcd)", "(a|b|c|d|abcd)*",
419 assertAmbig(tc, "(a*)*", "a*", "a", "a", "");
420 assertAmbig(tc, "(a+)*", "a+", "aa", "aa", "a");
422 assertNotAmbig(tc, "a*", "a");
423 assertNotAmbig(tc, "(a*b)*", "a*b");
424 assertNotAmbig(tc, "(a|b|c|d|abcd)", "(a|b|c|d|abcd)");
427 static void testAmbigWithNuls(CuTest *tc) {
428 struct fa *fa1 = make_fa(tc, "X\0ba?", 5, REG_NOERROR);
429 struct fa *fa2 = make_fa(tc, "a?\0Y", 4, REG_NOERROR);
432 int r = fa_ambig_example(fa1, fa2, &upv, &upv_len, &pv, &v);
433 CuAssertIntEquals(tc, 0, r);
434 CuAssertIntEquals(tc, 6, (int)upv_len);
436 size_t u_len = pv - upv;
437 CuAssertIntEquals(tc, 3, u_len);
438 CuAssertIntEquals(tc, (int)'X', upv[0]);
439 CuAssertIntEquals(tc, (int)'\0', upv[1]);
440 CuAssertIntEquals(tc, (int)'b', upv[2]);
442 size_t p_len = v - pv;
443 CuAssertIntEquals(tc, 1, p_len);
444 CuAssertIntEquals(tc, (int)'a', pv[0]);
446 size_t v_len = upv_len - (v - upv);
447 CuAssertIntEquals(tc, 2, v_len);
448 CuAssertIntEquals(tc, (int)'\0', v[0]);
449 CuAssertIntEquals(tc, (int)'Y', v[1]);
453 static void assertFaAsRegexp(CuTest *tc, const char *regexp) {
456 struct fa *fa1 = make_good_fa(tc, regexp);
460 r = fa_as_regexp(fa1, &re, &re_len);
461 CuAssertIntEquals(tc, 0, r);
463 r = fa_compile(re, strlen(re), &fa2);
464 CuAssertIntEquals(tc, REG_NOERROR, r);
466 CuAssert(tc, regexp, fa_equals(fa1, fa2));
472 static void testAsRegexp(CuTest *tc) {
473 assertFaAsRegexp(tc, "a*");
474 assertFaAsRegexp(tc, "abcd");
475 assertFaAsRegexp(tc, "ab|cd");
476 assertFaAsRegexp(tc, "[a-z]+");
477 assertFaAsRegexp(tc, "[]a-]+");
478 assertFaAsRegexp(tc, "[^0-9A-Z]");
479 assertFaAsRegexp(tc, "ab|(xy[A-Z0-9])*(uv[^0-9]?)");
480 assertFaAsRegexp(tc, "[A-CE-GI-LN-QS-Z]");
483 static void testAsRegexpMinus(CuTest *tc) {
484 struct fa *fa1 = make_good_fa(tc, "[A-Za-z]+");
485 struct fa *fa2 = make_good_fa(tc, "Deny(Users|Groups|Other)");
486 struct fa *fa = mark(fa_minus(fa1, fa2));
491 r = fa_as_regexp(fa, &re, &re_len);
492 CuAssertIntEquals(tc, 0, r);
494 struct fa *far = make_good_fa(tc, re);
495 CuAssertTrue(tc, fa_equals(fa, far));
500 static void testRangeEnd(CuTest *tc) {
501 const char *const re = "[1-0]";
502 make_fa(tc, re, strlen(re), REG_ERANGE);
505 static void testNul(CuTest *tc) {
506 static const char *const re0 = "a\0b";
509 struct fa *fa1 = make_fa(tc, "a\0b", re0_len, REG_NOERROR);
510 struct fa *fa2 = make_good_fa(tc, "a.b");
515 CuAssertTrue(tc, fa_contains(fa1, fa2));
517 r = fa_as_regexp(fa1, &re, &re_len);
518 CuAssertIntEquals(tc, 0, r);
519 CuAssertIntEquals(tc, re0_len, re_len);
520 CuAssertIntEquals(tc, 0, memcmp(re0, re, re0_len));
524 static void testRestrictAlphabet(CuTest *tc) {
525 const char *re = "ab|(xy[B-Z0-9])*(uv[^0-9]?)";
526 struct fa *fa_exp = make_good_fa(tc, "((xy[0-9])*)uv[^0-9A-Z]?|ab");
527 struct fa *fa_act = NULL;
532 r = fa_restrict_alphabet(re, strlen(re), &nre, &nre_len, 'A', 'Z');
533 CuAssertIntEquals(tc, 0, r);
534 CuAssertIntEquals(tc, nre_len, strlen(nre));
535 fa_act = make_good_fa(tc, nre);
536 CuAssertTrue(tc, fa_equals(fa_exp, fa_act));
539 r = fa_restrict_alphabet("HELLO", strlen("HELLO"),
540 &nre, &nre_len, 'A', 'Z');
541 CuAssertIntEquals(tc, -2, r);
542 CuAssertPtrEquals(tc, NULL, nre);
544 r = fa_restrict_alphabet("a{2,", strlen("a{2"), &nre, &nre_len, 'A', 'Z');
545 CuAssertIntEquals(tc, REG_EBRACE, r);
548 static void testExpandCharRanges(CuTest *tc) {
549 const char *re = "[1-3]*|[a-b]([^\nU-X][^\n])*";
550 const char *re2 = "a\\|b";
556 r = fa_expand_char_ranges(re, strlen(re), &nre, &nre_len);
557 CuAssertIntEquals(tc, 0, r);
558 CuAssertStrEquals(tc, "[123]*|[ab]([^\nUVWX].)*", nre);
559 CuAssertIntEquals(tc, strlen(nre), nre_len);
562 r = fa_expand_char_ranges(re2, strlen(re2), &nre, &nre_len);
563 CuAssertIntEquals(tc, 0, r);
564 CuAssertStrEquals(tc, re2, nre);
568 static void testNoCase(CuTest *tc) {
569 struct fa *fa1 = make_good_fa(tc, "[a-z0-9]");
570 struct fa *fa2 = make_good_fa(tc, "B");
575 fa = fa_intersect(fa1, fa2);
576 CuAssertPtrNotNull(tc, fa);
577 r = fa_equals(fa, fa2);
579 CuAssertIntEquals(tc, 1, r);
581 fa = fa_concat(fa1, fa2);
582 exp = make_good_fa(tc, "[a-zA-Z0-9]B");
583 r = fa_equals(fa, exp);
585 CuAssertIntEquals(tc, 1, r);
588 static void testExpandNoCase(CuTest *tc) {
589 const char *p1 = "aB";
590 const char *p2 = "[a-cUV]";
591 const char *p3 = "[^a-z]";
596 r = fa_expand_nocase(p1, strlen(p1), &s, &len);
597 CuAssertIntEquals(tc, 0, r);
598 CuAssertStrEquals(tc, "[Aa][Bb]", s);
601 r = fa_expand_nocase(p2, strlen(p2), &s, &len);
602 CuAssertIntEquals(tc, 0, r);
603 CuAssertStrEquals(tc, "[A-CUVa-cuv]", s);
606 r = fa_expand_nocase(p3, strlen(p3), &s, &len);
607 CuAssertIntEquals(tc, 0, r);
608 CuAssertStrEquals(tc, "[^A-Za-z]", s);
612 static void testNoCaseComplement(CuTest *tc) {
613 const char *key_s = "keY";
614 struct fa *key = make_good_fa(tc, key_s);
615 struct fa *isect = NULL;
619 struct fa *comp = mark(fa_complement(key));
621 key = make_good_fa(tc, key_s);
623 /* We used to have a bug in totalize that caused the intersection
624 * to contain "keY" */
625 isect = fa_intersect(key, comp);
627 CuAssertIntEquals(tc, 1, fa_is_basic(isect, FA_EMPTY));
631 static void free_words(int n, char **words) {
632 for (int i=0; i < n; i++) {
638 static void testEnumerate(CuTest *tc) {
639 struct fa *fa1 = make_good_fa(tc, "[ab](cc|dd)");
640 static const char *const fa1_expected[] =
641 { "acc", "add", "bcc", "bdd" };
642 struct fa *fa_inf = make_good_fa(tc, "a(b*|d)c");
643 struct fa *fa_empty = make_good_fa(tc, "a?");
648 r = fa_enumerate(fa1, 2, &words);
649 CuAssertIntEquals(tc, -2, r);
650 CuAssertPtrEquals(tc, NULL, words);
652 r = fa_enumerate(fa1, 10, &words);
653 CuAssertIntEquals(tc, 4, r);
654 CuAssertPtrNotNull(tc, words);
656 for (int i=0; i < r; i++) {
658 for (int j=0; j < ARRAY_CARDINALITY(fa1_expected); j++) {
659 if (STREQ(words[i], fa1_expected[j]))
664 /* Ignore return of asprintf intentionally */
665 r = asprintf(&msg, "Generated word %s not expected", words[i]);
669 free_words(10, words);
671 r = fa_enumerate(fa_inf, 100, &words);
672 CuAssertIntEquals(tc, -2, r);
673 CuAssertPtrEquals(tc, NULL, words);
675 r = fa_enumerate(fa_empty, 10, &words);
676 CuAssertIntEquals(tc, 2, r);
677 CuAssertPtrNotNull(tc, words);
678 CuAssertStrEquals(tc, "", words[0]);
679 CuAssertStrEquals(tc, "a", words[1]);
680 free_words(10, words);
683 int main(int argc, char **argv) {
686 CuSuite* suite = CuSuiteNew();
687 CuSuiteSetup(suite, setup, teardown);
689 SUITE_ADD_TEST(suite, testBadRegexps);
690 SUITE_ADD_TEST(suite, testMonster);
691 SUITE_ADD_TEST(suite, testChars);
692 SUITE_ADD_TEST(suite, testManualAmbig);
693 SUITE_ADD_TEST(suite, testContains);
694 SUITE_ADD_TEST(suite, testIntersect);
695 SUITE_ADD_TEST(suite, testComplement);
696 SUITE_ADD_TEST(suite, testOverlap);
697 SUITE_ADD_TEST(suite, testExample);
698 SUITE_ADD_TEST(suite, testAmbig);
699 SUITE_ADD_TEST(suite, testAmbigWithNuls);
700 SUITE_ADD_TEST(suite, testAsRegexp);
701 SUITE_ADD_TEST(suite, testAsRegexpMinus);
702 SUITE_ADD_TEST(suite, testRangeEnd);
703 SUITE_ADD_TEST(suite, testNul);
704 SUITE_ADD_TEST(suite, testRestrictAlphabet);
705 SUITE_ADD_TEST(suite, testExpandCharRanges);
706 SUITE_ADD_TEST(suite, testNoCase);
707 SUITE_ADD_TEST(suite, testExpandNoCase);
708 SUITE_ADD_TEST(suite, testNoCaseComplement);
709 SUITE_ADD_TEST(suite, testEnumerate);
712 CuSuiteSummary(suite, &output);
713 CuSuiteDetails(suite, &output);
714 printf("%s\n", output);
716 int result = suite->failCount;
721 for (int i=1; i<argc; i++) {
724 if ((r = fa_compile(argv[i], strlen(argv[i]), &fa)) != REG_NOERROR) {
725 print_regerror(r, argv[i]);
730 fa_example(fa, &s, &s_len);
731 printf("Example for %s: %s\n", argv[i], s);
735 r = fa_as_regexp(fa, &re, &re_len);
737 printf("/%s/ = /%s/\n", argv[i], re);
740 printf("/%s/ = ***\n", argv[i]);
749 * indent-tabs-mode: nil