# HG changeset patch # User Matti Hamalainen # Date 1580145786 -7200 # Node ID 48e8820bc625e1ebbfb902c062bc548d74be35a4 # Parent 039aa00cbfbf51c50c4be8f39eafc9c45eb4ac0a Some work on the regex tests. diff -r 039aa00cbfbf -r 48e8820bc625 tests.c --- a/tests.c Mon Jan 27 17:07:06 2020 +0200 +++ b/tests.c Mon Jan 27 19:23:06 2020 +0200 @@ -568,33 +568,70 @@ typedef struct { - th_char_t *str; - size_t nmatches; - int flags; + const th_char_t *str; + const int flags; + const th_char_t *expected[4]; } test_regex_def1; typedef struct { - th_char_t *pattern; - th_char_t *str; - size_t nmatches; - int flags; + const th_char_t *pattern; + const th_char_t *str; + const int flags; + const th_char_t *expected[4]; } test_regex_def2; -void test_regex_print_matches(const th_char_t *str, const th_regex_match_t *matches) +BOOL test_regex_list_matches(const th_char_t *str, + const th_regex_match_t *matches, + const th_char_t * const *expected, + const BOOL testOnly) { + size_t nmatch = 0; + char *match = NULL; + for (const th_regex_match_t *mt = matches; - mt != NULL; mt = (th_regex_match_t *) mt->node.next) + mt != NULL; + mt = (th_regex_match_t *) mt->node.next, + nmatch++) { - char *tmp = th_strndup(str + mt->start, mt->len); + char *match = th_strndup(str + mt->start, mt->len); + if (expected[nmatch] == NULL) + { + if (!testOnly) + { + THERR("Expected[%" PRIu_SIZE_T "] == NULL, but match '%s' returned.\n", + nmatch, match); + } + + goto error; + } + else + { + BOOL seqMatch = strcmp(match, expected[nmatch]) == 0; + if (testOnly && !seqMatch) + goto error; - printf(" match [%3" PRIu_SIZE_T " ++ %3" PRIu_SIZE_T "]: '%s'\n", - mt->start, mt->len, tmp); + if (th_verbosity >= 1 || !seqMatch) + { + tprint(0, " [%3" PRIu_SIZE_T " ++ %3" PRIu_SIZE_T "]: '%s' == '%s': %s\n", + mt->start, + mt->len, + match, + expected[nmatch], + seqMatch ? "YES" : "NO!"); + } + } - th_free(tmp); + th_free(match); } + + return TRUE; + +error: + th_free(match); + return FALSE; } @@ -603,24 +640,27 @@ th_regex_t *expr = NULL; int res; - printf("\n========================================\n\n"); - printf("Compiling pattern \"%s\"\n", pattern); if ((res = th_regex_compile(&expr, pattern)) != THERR_OK) { - THERR("Regex compilation failed: %s\n", + THERR("Regex \"%s\" compilation failed: %s\n", + pattern, th_error_str(res)); goto out; } - if (th_verbosity > 0) + tprint(1, "\n----------------------------------------\n" + "\"%s\"\n", pattern); + + if (th_verbosity >= 2) th_regex_dump(&testio, 1, expr); for (const test_regex_def1 *def = list; def->str != NULL; def++) { th_regex_match_t *matches = NULL; size_t nmatches; + BOOL matchOK; - printf("\n----------------------------------------\n"); + tprint(3, "\n----------------------------------------\n"); if ((res = th_regex_match(expr, def->str, &nmatches, &matches, -1, def->flags)) != THERR_OK) { @@ -629,12 +669,32 @@ goto out; } - printf("'%s': matched %" PRIu_SIZE_T " time(s), testresult=%s\n", - def->str, - nmatches, - def->nmatches == nmatches ? "YES" : "NO"); + matchOK = test_regex_list_matches(def->str, matches, def->expected, TRUE); + if (th_verbosity < 1 && !matchOK) + { + tprint(0, + "\n----------------------------------------\n" + " \"%s\" vs \"%s\" failures:\n", + def->str, pattern); + } + else + { + tprint(1, " \"%s\": matched %" PRIu_SIZE_T " time(s)\n", + def->str, + nmatches); + } - test_regex_print_matches(def->str, matches); +#ifdef TH_EXPERIMENTAL_REGEX_DEBUG + if (!matchOK && th_dbg_fh == NULL) + { + th_dbg_fh = &testio; + th_regex_match(expr, def->str, NULL, NULL, -1, def->flags); + th_dbg_fh = NULL; + } +#endif + + test_regex_list_matches(def->str, matches, def->expected, FALSE); + th_regex_free_matches(matches); } @@ -645,8 +705,6 @@ void test_regex_list2(const test_regex_def2 *list) { - printf("\n========================================\n\n"); - for (const test_regex_def2 *def = list; def->str != NULL; def++) { th_regex_t *expr = NULL; @@ -654,18 +712,18 @@ size_t nmatches; int res; - printf("Compiling pattern \"%s\"\n", def->pattern); if ((res = th_regex_compile(&expr, def->pattern)) != THERR_OK) { - THERR("Regex compilation failed: %s\n", + THERR("Regex \"%s\" compilation failed: %s\n", + def->pattern, th_error_str(res)); goto out; } - if (th_verbosity > 0) + if (th_verbosity >= 2) th_regex_dump(&testio, 1, expr); - printf("----------------------------------------\n"); + tprint(3, "----------------------------------------\n"); if ((res = th_regex_match(expr, def->str, &nmatches, &matches, -1, def->flags)) != THERR_OK) @@ -675,12 +733,11 @@ goto out; } - printf("'%s': matched %" PRIu_SIZE_T " time(s), testresult=%s\n", - def->str, - nmatches, - def->nmatches == nmatches ? "YES" : "NO"); + tprint(1, "\"%s\" vs \"%s\": matched %" PRIu_SIZE_T " time(s)\n", + def->pattern, def->str, + nmatches); - test_regex_print_matches(def->str, matches); + test_regex_list_matches(def->str, matches, def->expected, FALSE); out: th_regex_free_matches(matches); @@ -949,12 +1006,11 @@ #ifdef TH_EXPERIMENTAL_REGEX if (test_set_start("Regular expressions")) { - #ifdef TH_EXPERIMENTAL_REGEX_DEBUG - if (th_verbosity > 0) - th_dbg_fh = &testio; + th_dbg_fh = (th_verbosity >= 3) ? &testio : NULL; #endif + if (1) { const char *str = "z*k+abba fabboa? [a-zA-Z_-] \\{\\} k{4} ([0-9]+ yay){1,2} foo(bar|zoo)?"; th_regex_t *expr = NULL; @@ -970,58 +1026,75 @@ th_regex_free(expr); } + if (1) { static const test_regex_def1 tlist[] = { - { "abcfoabcccg" , 1, 0 }, - { "abcbcfoabcccg" , 1, 0 }, - { "abcbcfoabccg abcbcfoabccccg" , 2, 0 }, - { "ffdsafS abcbcfoabccg zasdf" , 1, 0 }, - { NULL , 0, 0 } + { "abcfoabcccg" , 0, { "abcfoabcccg", } }, + { "sabcbcfoabcccgz" , 0, { "abcbcfoabcccg", } }, + { "abcbcfoabccg abcbcfoabccccg" , 0, { "abcbcfoabccg", "abcbcfoabccccg" } }, + { NULL , 0, { NULL } } }; test_regex_list1(tlist, "a(bc){1,2}fo[oab]*cc?g"); } + if (1) { static const test_regex_def1 tlist[] = { - { "abcfoabccg" , 1, 0 }, - { "abcbcfoabccg" , 1, 0 }, - { "abcbcfoabccgabcbcfoabccg" , 1, 0 }, - { "ffdsafS abcbcfoabccg zasdf" , 0, 0 }, - { NULL , 0, 0 } + { "abcfoabccg" , 0, { "abcfoabccg", } }, + { "abcbcfoabccg" , 0, { "abcbcfoabccg", } }, + { "abcbcfoabccgabcbcfoabccg" , 0, { "abcbcfoabccg", } }, + { "ffdsafS abcbcfoabccg zasdf" , 0, { NULL } }, + { NULL , 0, { NULL } } }; test_regex_list1(tlist, "^a(bc){1,2}fo[oab]*cc?g"); } + if (1) { static const test_regex_def1 tlist[] = { - { "cg" , 1, 0 }, - { "g" , 1, 0 }, - { "" , 0, 0 }, - { "c" , 0, 0 }, - { NULL , 0, 0 } + { "cg" , 0, { "g", } }, + { "g" , 0, { "g", } }, + { "" , 0, { NULL, } }, + { "c" , 0, { NULL, } }, + { NULL , 0, { NULL } } }; test_regex_list1(tlist, "g$"); } + if (1) { static const test_regex_def1 tlist[] = { - { "zoobar" , 1, 0 }, - { "hehzoo lol baromg" , 1, 0 }, - { "hoho zoo lol lol bar bar" , 1, 0 }, - { "hoho zoobar bar" , 1, 0 }, - { NULL , 0, 0 } + { "kzoobarzz" , 0, { "zoobar", } }, + { "hehzoo lol baromg" , 0, { "zoo lol bar", } }, + { "hoho zoo lol lol bar bar f" , 0, { "zoo lol lol bar", } }, + { "hoho zoobar bar heh" , 0, { "zoobar", } }, + { NULL , 0, { NULL } } }; test_regex_list1(tlist, "zoo.*?bar"); + } + + if (1) + { + static const test_regex_def1 tlist[] = + { + { "kzoobarzz" , 0, { "zoobar", } }, + { "hehzoo lol baromg" , 0, { "zoo lol bar", } }, + { "hoho zoo lol lol bar bar f" , 0, { "zoo lol lol bar bar", } }, + { "hoho zoobar bar heh" , 0, { "zoobar bar", } }, + { NULL , 0, { NULL } } + }; + test_regex_list1(tlist, "zoo.*bar"); } + } #endif