Mercurial > hg > th-libs
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); |