comparison th_regex.c @ 648:91c43398c6fc

Twiddle.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 25 Jan 2020 08:01:17 +0200
parents 1e7e3f96632e
children 2c9260f5cf44
comparison
equal deleted inserted replaced
647:1e7e3f96632e 648:91c43398c6fc
564 res = THERR_INVALID_DATA; 564 res = THERR_INVALID_DATA;
565 goto out; 565 goto out;
566 } 566 }
567 break; 567 break;
568 568
569 /*
570 case '|':
571 if ((res = th_regex_parse_ctx_node_commit_strchr(&ctx, FALSE)) != THERR_OK)
572 goto out;
573
574 // Alt pattern .. how to handle these?
575 break;
576 */
577
569 case '(': 578 case '(':
570 if ((res = th_regex_parse_ctx_node_commit_strchr(&ctx, FALSE)) != THERR_OK) 579 if ((res = th_regex_parse_ctx_node_commit_strchr(&ctx, FALSE)) != THERR_OK)
571 goto out; 580 goto out;
572 581
573 // Start of subpattern 582 // Start of subpattern
880 } 889 }
881 break; 890 break;
882 891
883 case TH_RE_TYPE_STR: 892 case TH_RE_TYPE_STR:
884 res = TRUE; 893 res = TRUE;
885 for (th_regex_char_t *str = node->match.str; *str != 0; ) 894 for (th_regex_char_t *str = node->match.str;
895 res && *str != 0;
896 str++, (*poffs)++)
886 { 897 {
887 if (haystack[*poffs] != *str) 898 if (haystack[*poffs] != *str)
888 {
889 res = FALSE; 899 res = FALSE;
890 break;
891 }
892 str++;
893 (*poffs)++;
894 } 900 }
895 break; 901 break;
896 } 902 }
897 903
898 return res; 904 return res;
914 for (size_t nnode = startnode; res && nnode < expr->nnodes; nnode++) 920 for (size_t nnode = startnode; res && nnode < expr->nnodes; nnode++)
915 { 921 {
916 const th_regex_node_t *node = &expr->nodes[nnode]; 922 const th_regex_node_t *node = &expr->nodes[nnode];
917 923
918 #ifdef TH_EXPERIMENTAL_REGEX_DEBUG 924 #ifdef TH_EXPERIMENTAL_REGEX_DEBUG
919 th_regex_dump_indent(stdout, level); 925 if (th_dbg_re_flags)
920 fprintf(stdout, 926 {
921 "[%" PRIu_SIZE_T "/%" PRIu_SIZE_T "] ", 927 th_regex_dump_indent(stdout, level);
922 nnode + 1, expr->nnodes); 928 fprintf(stdout,
923 929 "[%" PRIu_SIZE_T "/%" PRIu_SIZE_T "] ",
924 th_regex_dump_node(stdout, node); 930 nnode + 1, expr->nnodes);
925 931
926 fprintf(stdout, " <-> \"%s\"\n", 932 th_regex_dump_node(stdout, node);
927 haystack + soffs); 933
934 fprintf(stdout, " <-> \"%s\"\n",
935 haystack + soffs);
936 }
928 #endif 937 #endif
929 938
930 switch (node->mode) 939 switch (node->mode)
931 { 940 {
932 case TH_RE_MATCH_ONCE: 941 case TH_RE_MATCH_ONCE:
933 res = th_regex_match_one(haystack, &soffs, node, flags, level); 942 res = th_regex_match_one(haystack, &soffs, node, flags, level);
934 break; 943 break;
935 944
936 case TH_RE_MATCH_COUNT: 945 case TH_RE_MATCH_COUNT:
937 { 946 {
938 ssize_t count = 0; 947 ssize_t count = 0, ncount = 0;
939 948
940 do 949 do
941 { 950 {
942 BOOL match; 951 BOOL match;
943 size_t toffs = soffs, tnode; 952 size_t toffs = soffs, noffs;
944 953
945 DBG_RE_MATCH(" ROUND #%" PRIu_SIZE_T ": '%s'\n", 954 DBG_RE_MATCH(" ROUND #%" PRIu_SIZE_T ": '%s'\n",
946 count, haystack + toffs); 955 count, haystack + toffs);
947 956
957 res = FALSE;
958 match = TRUE;
948 do 959 do
949 { 960 {
950 match = TRUE; 961 noffs = toffs;
951 size_t noffs = toffs; 962 match = th_regex_match_one(haystack, &toffs, node, flags, level + 1);
952 for (tnode = nnode; match && tnode < expr->nnodes && haystack[toffs] != 0; ) 963 if (match)
953 { 964 {
954 match = th_regex_match_one(haystack, &toffs, &expr->nodes[tnode], flags, level + 1); 965 ncount++;
955 if (match) 966
956 tnode++; 967 if (node->repeatMin >= 0 && ncount >= node->repeatMin)
968 break;
957 } 969 }
958 970 } while (match && haystack[toffs] != 0 && toffs > noffs);
959 DBG_RE_MATCH(" '%s': %d (tnode=%" PRIu_SIZE_T ")\n", 971
960 haystack + noffs, match, tnode); 972 DBG_RE_MATCH(" ROUND #%" PRIu_SIZE_T " END: match=%s \"%s\"\n",
961 973 ncount, match ? "YES" : "NO", haystack + toffs);
962 if (node->repeatMin >= 0 && match) 974
963 break; 975 if (ncount > 0)
964 } while (!match && haystack[toffs] != 0); 976 {
965 977 match = th_regex_match_expr(haystack, &toffs, expr, nnode + 1, flags, level + 2);
966 DBG_RE_MATCH(" ROUND #%" PRIu_SIZE_T " END: match=%s, tnode=%" PRIu_SIZE_T "\n", 978 }
967 count, match ? "YES" : "NO", tnode); 979
980 DBG_RE_MATCH(" ROUND #%" PRIu_SIZE_T " END: match=%s \"%s\"\n",
981 count, match ? "YES" : "NO", haystack + toffs);
968 982
969 if (match) 983 if (match)
970 { 984 {
971 // Node matched 985 // Node matched
972 count++; 986 count++;
973 soffs = toffs; 987 soffs = toffs;
974 nnode = tnode; 988 nnode = expr->nnodes;
975 res = (node->repeatMax > 0 && count >= node->repeatMax); 989
990 res =
991 (node->repeatMax > 0 && ncount >= node->repeatMax) ||
992 (node->repeatMin >= 0 && ncount >= node->repeatMin);
976 } 993 }
977 else
978 {
979 // Node did not match, check if we got the minimum if set
980 res = (node->repeatMin >= 0 && count >= node->repeatMin);
981 }
982 994
983 } while (!res); 995 } while (!res);
984 996
985 DBG_RE_MATCH(" RESULT: count=%" PRId_SSIZE_T ", done=%s\n", 997 DBG_RE_MATCH(" RESULT: count=%" PRId_SSIZE_T ", ncount=%" PRId_SSIZE_T ", done=%s\n",
986 count, res ? "YES" : "NO"); 998 count, ncount, res ? "YES" : "NO");
987 } 999 }
988 break; 1000 break;
989 1001
990 case TH_RE_MATCH_ANCHOR_START: 1002 case TH_RE_MATCH_ANCHOR_START:
991 res = (soffs == 0); 1003 res = (soffs == 0);