comparison tests.c @ 668:48e8820bc625

Some work on the regex tests.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 27 Jan 2020 19:23:06 +0200
parents e1d27caf0dbd
children dbc71c000376
comparison
equal deleted inserted replaced
667:039aa00cbfbf 668:48e8820bc625
566 566
567 #ifdef TH_EXPERIMENTAL_REGEX 567 #ifdef TH_EXPERIMENTAL_REGEX
568 568
569 typedef struct 569 typedef struct
570 { 570 {
571 th_char_t *str; 571 const th_char_t *str;
572 size_t nmatches; 572 const int flags;
573 int flags; 573 const th_char_t *expected[4];
574 } test_regex_def1; 574 } test_regex_def1;
575 575
576 576
577 typedef struct 577 typedef struct
578 { 578 {
579 th_char_t *pattern; 579 const th_char_t *pattern;
580 th_char_t *str; 580 const th_char_t *str;
581 size_t nmatches; 581 const int flags;
582 int flags; 582 const th_char_t *expected[4];
583 } test_regex_def2; 583 } test_regex_def2;
584 584
585 585
586 void test_regex_print_matches(const th_char_t *str, const th_regex_match_t *matches) 586 BOOL test_regex_list_matches(const th_char_t *str,
587 { 587 const th_regex_match_t *matches,
588 const th_char_t * const *expected,
589 const BOOL testOnly)
590 {
591 size_t nmatch = 0;
592 char *match = NULL;
593
588 for (const th_regex_match_t *mt = matches; 594 for (const th_regex_match_t *mt = matches;
589 mt != NULL; mt = (th_regex_match_t *) mt->node.next) 595 mt != NULL;
590 { 596 mt = (th_regex_match_t *) mt->node.next,
591 char *tmp = th_strndup(str + mt->start, mt->len); 597 nmatch++)
592 598 {
593 printf(" match [%3" PRIu_SIZE_T " ++ %3" PRIu_SIZE_T "]: '%s'\n", 599 char *match = th_strndup(str + mt->start, mt->len);
594 mt->start, mt->len, tmp); 600 if (expected[nmatch] == NULL)
595 601 {
596 th_free(tmp); 602 if (!testOnly)
597 } 603 {
604 THERR("Expected[%" PRIu_SIZE_T "] == NULL, but match '%s' returned.\n",
605 nmatch, match);
606 }
607
608 goto error;
609 }
610 else
611 {
612 BOOL seqMatch = strcmp(match, expected[nmatch]) == 0;
613 if (testOnly && !seqMatch)
614 goto error;
615
616 if (th_verbosity >= 1 || !seqMatch)
617 {
618 tprint(0, " [%3" PRIu_SIZE_T " ++ %3" PRIu_SIZE_T "]: '%s' == '%s': %s\n",
619 mt->start,
620 mt->len,
621 match,
622 expected[nmatch],
623 seqMatch ? "YES" : "NO!");
624 }
625 }
626
627 th_free(match);
628 }
629
630 return TRUE;
631
632 error:
633 th_free(match);
634 return FALSE;
598 } 635 }
599 636
600 637
601 void test_regex_list1(const test_regex_def1 *list, const th_char_t *pattern) 638 void test_regex_list1(const test_regex_def1 *list, const th_char_t *pattern)
602 { 639 {
603 th_regex_t *expr = NULL; 640 th_regex_t *expr = NULL;
604 int res; 641 int res;
605 642
606 printf("\n========================================\n\n");
607 printf("Compiling pattern \"%s\"\n", pattern);
608 if ((res = th_regex_compile(&expr, pattern)) != THERR_OK) 643 if ((res = th_regex_compile(&expr, pattern)) != THERR_OK)
609 { 644 {
610 THERR("Regex compilation failed: %s\n", 645 THERR("Regex \"%s\" compilation failed: %s\n",
646 pattern,
611 th_error_str(res)); 647 th_error_str(res));
612 goto out; 648 goto out;
613 } 649 }
614 650
615 if (th_verbosity > 0) 651 tprint(1, "\n----------------------------------------\n"
652 "\"%s\"\n", pattern);
653
654 if (th_verbosity >= 2)
616 th_regex_dump(&testio, 1, expr); 655 th_regex_dump(&testio, 1, expr);
617 656
618 for (const test_regex_def1 *def = list; def->str != NULL; def++) 657 for (const test_regex_def1 *def = list; def->str != NULL; def++)
619 { 658 {
620 th_regex_match_t *matches = NULL; 659 th_regex_match_t *matches = NULL;
621 size_t nmatches; 660 size_t nmatches;
622 661 BOOL matchOK;
623 printf("\n----------------------------------------\n"); 662
663 tprint(3, "\n----------------------------------------\n");
624 if ((res = th_regex_match(expr, def->str, 664 if ((res = th_regex_match(expr, def->str,
625 &nmatches, &matches, -1, def->flags)) != THERR_OK) 665 &nmatches, &matches, -1, def->flags)) != THERR_OK)
626 { 666 {
627 THERR("Regex match returned error: %s\n", 667 THERR("Regex match returned error: %s\n",
628 th_error_str(res)); 668 th_error_str(res));
629 goto out; 669 goto out;
630 } 670 }
631 671
632 printf("'%s': matched %" PRIu_SIZE_T " time(s), testresult=%s\n", 672 matchOK = test_regex_list_matches(def->str, matches, def->expected, TRUE);
633 def->str, 673 if (th_verbosity < 1 && !matchOK)
634 nmatches, 674 {
635 def->nmatches == nmatches ? "YES" : "NO"); 675 tprint(0,
636 676 "\n----------------------------------------\n"
637 test_regex_print_matches(def->str, matches); 677 " \"%s\" vs \"%s\" failures:\n",
678 def->str, pattern);
679 }
680 else
681 {
682 tprint(1, " \"%s\": matched %" PRIu_SIZE_T " time(s)\n",
683 def->str,
684 nmatches);
685 }
686
687 #ifdef TH_EXPERIMENTAL_REGEX_DEBUG
688 if (!matchOK && th_dbg_fh == NULL)
689 {
690 th_dbg_fh = &testio;
691 th_regex_match(expr, def->str, NULL, NULL, -1, def->flags);
692 th_dbg_fh = NULL;
693 }
694 #endif
695
696 test_regex_list_matches(def->str, matches, def->expected, FALSE);
697
638 th_regex_free_matches(matches); 698 th_regex_free_matches(matches);
639 } 699 }
640 700
641 out: 701 out:
642 th_regex_free(expr); 702 th_regex_free(expr);
643 } 703 }
644 704
645 705
646 void test_regex_list2(const test_regex_def2 *list) 706 void test_regex_list2(const test_regex_def2 *list)
647 { 707 {
648 printf("\n========================================\n\n");
649
650 for (const test_regex_def2 *def = list; def->str != NULL; def++) 708 for (const test_regex_def2 *def = list; def->str != NULL; def++)
651 { 709 {
652 th_regex_t *expr = NULL; 710 th_regex_t *expr = NULL;
653 th_regex_match_t *matches = NULL; 711 th_regex_match_t *matches = NULL;
654 size_t nmatches; 712 size_t nmatches;
655 int res; 713 int res;
656 714
657 printf("Compiling pattern \"%s\"\n", def->pattern);
658 if ((res = th_regex_compile(&expr, def->pattern)) != THERR_OK) 715 if ((res = th_regex_compile(&expr, def->pattern)) != THERR_OK)
659 { 716 {
660 THERR("Regex compilation failed: %s\n", 717 THERR("Regex \"%s\" compilation failed: %s\n",
718 def->pattern,
661 th_error_str(res)); 719 th_error_str(res));
662 goto out; 720 goto out;
663 } 721 }
664 722
665 if (th_verbosity > 0) 723 if (th_verbosity >= 2)
666 th_regex_dump(&testio, 1, expr); 724 th_regex_dump(&testio, 1, expr);
667 725
668 printf("----------------------------------------\n"); 726 tprint(3, "----------------------------------------\n");
669 727
670 if ((res = th_regex_match(expr, def->str, 728 if ((res = th_regex_match(expr, def->str,
671 &nmatches, &matches, -1, def->flags)) != THERR_OK) 729 &nmatches, &matches, -1, def->flags)) != THERR_OK)
672 { 730 {
673 THERR("Regex match returned error: %s\n", 731 THERR("Regex match returned error: %s\n",
674 th_error_str(res)); 732 th_error_str(res));
675 goto out; 733 goto out;
676 } 734 }
677 735
678 printf("'%s': matched %" PRIu_SIZE_T " time(s), testresult=%s\n", 736 tprint(1, "\"%s\" vs \"%s\": matched %" PRIu_SIZE_T " time(s)\n",
679 def->str, 737 def->pattern, def->str,
680 nmatches, 738 nmatches);
681 def->nmatches == nmatches ? "YES" : "NO"); 739
682 740 test_regex_list_matches(def->str, matches, def->expected, FALSE);
683 test_regex_print_matches(def->str, matches);
684 741
685 out: 742 out:
686 th_regex_free_matches(matches); 743 th_regex_free_matches(matches);
687 th_regex_free(expr); 744 th_regex_free(expr);
688 } 745 }
947 // Regular expressions 1004 // Regular expressions
948 // 1005 //
949 #ifdef TH_EXPERIMENTAL_REGEX 1006 #ifdef TH_EXPERIMENTAL_REGEX
950 if (test_set_start("Regular expressions")) 1007 if (test_set_start("Regular expressions"))
951 { 1008 {
952
953 #ifdef TH_EXPERIMENTAL_REGEX_DEBUG 1009 #ifdef TH_EXPERIMENTAL_REGEX_DEBUG
954 if (th_verbosity > 0) 1010 th_dbg_fh = (th_verbosity >= 3) ? &testio : NULL;
955 th_dbg_fh = &testio;
956 #endif 1011 #endif
957 1012
1013 if (1)
958 { 1014 {
959 const char *str = "z*k+abba fabboa? [a-zA-Z_-] \\{\\} k{4} ([0-9]+ yay){1,2} foo(bar|zoo)?"; 1015 const char *str = "z*k+abba fabboa? [a-zA-Z_-] \\{\\} k{4} ([0-9]+ yay){1,2} foo(bar|zoo)?";
960 th_regex_t *expr = NULL; 1016 th_regex_t *expr = NULL;
961 int res = th_regex_compile(&expr, str); 1017 int res = th_regex_compile(&expr, str);
962 1018
968 printf("ERROR: %s\n", th_error_str(res)); 1024 printf("ERROR: %s\n", th_error_str(res));
969 1025
970 th_regex_free(expr); 1026 th_regex_free(expr);
971 } 1027 }
972 1028
1029 if (1)
973 { 1030 {
974 static const test_regex_def1 tlist[] = 1031 static const test_regex_def1 tlist[] =
975 { 1032 {
976 { "abcfoabcccg" , 1, 0 }, 1033 { "abcfoabcccg" , 0, { "abcfoabcccg", } },
977 { "abcbcfoabcccg" , 1, 0 }, 1034 { "sabcbcfoabcccgz" , 0, { "abcbcfoabcccg", } },
978 { "abcbcfoabccg abcbcfoabccccg" , 2, 0 }, 1035 { "abcbcfoabccg abcbcfoabccccg" , 0, { "abcbcfoabccg", "abcbcfoabccccg" } },
979 { "ffdsafS abcbcfoabccg zasdf" , 1, 0 }, 1036 { NULL , 0, { NULL } }
980 { NULL , 0, 0 }
981 }; 1037 };
982 1038
983 test_regex_list1(tlist, "a(bc){1,2}fo[oab]*cc?g"); 1039 test_regex_list1(tlist, "a(bc){1,2}fo[oab]*cc?g");
984 } 1040 }
985 1041
1042 if (1)
986 { 1043 {
987 static const test_regex_def1 tlist[] = 1044 static const test_regex_def1 tlist[] =
988 { 1045 {
989 { "abcfoabccg" , 1, 0 }, 1046 { "abcfoabccg" , 0, { "abcfoabccg", } },
990 { "abcbcfoabccg" , 1, 0 }, 1047 { "abcbcfoabccg" , 0, { "abcbcfoabccg", } },
991 { "abcbcfoabccgabcbcfoabccg" , 1, 0 }, 1048 { "abcbcfoabccgabcbcfoabccg" , 0, { "abcbcfoabccg", } },
992 { "ffdsafS abcbcfoabccg zasdf" , 0, 0 }, 1049 { "ffdsafS abcbcfoabccg zasdf" , 0, { NULL } },
993 { NULL , 0, 0 } 1050 { NULL , 0, { NULL } }
994 }; 1051 };
995 1052
996 test_regex_list1(tlist, "^a(bc){1,2}fo[oab]*cc?g"); 1053 test_regex_list1(tlist, "^a(bc){1,2}fo[oab]*cc?g");
997 } 1054 }
998 1055
1056 if (1)
999 { 1057 {
1000 static const test_regex_def1 tlist[] = 1058 static const test_regex_def1 tlist[] =
1001 { 1059 {
1002 { "cg" , 1, 0 }, 1060 { "cg" , 0, { "g", } },
1003 { "g" , 1, 0 }, 1061 { "g" , 0, { "g", } },
1004 { "" , 0, 0 }, 1062 { "" , 0, { NULL, } },
1005 { "c" , 0, 0 }, 1063 { "c" , 0, { NULL, } },
1006 { NULL , 0, 0 } 1064 { NULL , 0, { NULL } }
1007 }; 1065 };
1008 1066
1009 test_regex_list1(tlist, "g$"); 1067 test_regex_list1(tlist, "g$");
1010 } 1068 }
1011 1069
1070 if (1)
1012 { 1071 {
1013 static const test_regex_def1 tlist[] = 1072 static const test_regex_def1 tlist[] =
1014 { 1073 {
1015 { "zoobar" , 1, 0 }, 1074 { "kzoobarzz" , 0, { "zoobar", } },
1016 { "hehzoo lol baromg" , 1, 0 }, 1075 { "hehzoo lol baromg" , 0, { "zoo lol bar", } },
1017 { "hoho zoo lol lol bar bar" , 1, 0 }, 1076 { "hoho zoo lol lol bar bar f" , 0, { "zoo lol lol bar", } },
1018 { "hoho zoobar bar" , 1, 0 }, 1077 { "hoho zoobar bar heh" , 0, { "zoobar", } },
1019 { NULL , 0, 0 } 1078 { NULL , 0, { NULL } }
1020 }; 1079 };
1021 1080
1022 test_regex_list1(tlist, "zoo.*?bar"); 1081 test_regex_list1(tlist, "zoo.*?bar");
1082 }
1083
1084 if (1)
1085 {
1086 static const test_regex_def1 tlist[] =
1087 {
1088 { "kzoobarzz" , 0, { "zoobar", } },
1089 { "hehzoo lol baromg" , 0, { "zoo lol bar", } },
1090 { "hoho zoo lol lol bar bar f" , 0, { "zoo lol lol bar bar", } },
1091 { "hoho zoobar bar heh" , 0, { "zoobar bar", } },
1092 { NULL , 0, { NULL } }
1093 };
1094
1023 test_regex_list1(tlist, "zoo.*bar"); 1095 test_regex_list1(tlist, "zoo.*bar");
1024 } 1096 }
1097
1025 } 1098 }
1026 #endif 1099 #endif
1027 1100
1028 // 1101 //
1029 // Print summary and exit 1102 // Print summary and exit