📄 pcretest.c
字号:
else if (isalnum(*p)) { uschar *npp = getnamesptr; while (isalnum(*p)) *npp++ = *p++; *npp++ = 0; *npp = 0; n = pcre_get_stringnumber(re, (char *)getnamesptr); if (n < 0) fprintf(outfile, "no parentheses with name \"%s\"\n", getnamesptr); getnamesptr = npp; } continue; case 'L': getlist = 1; continue; case 'M': find_match_limit = 1; continue; case 'N': options |= PCRE_NOTEMPTY; continue; case 'O': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (n > size_offsets_max) { size_offsets_max = n; free(offsets); use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", size_offsets_max * sizeof(int)); yield = 1; goto EXIT; } } use_size_offsets = n; if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */ continue; case 'P': options |= PCRE_PARTIAL; continue; case 'Q': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra->match_limit_recursion = n; continue; case 'q': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->flags |= PCRE_EXTRA_MATCH_LIMIT; extra->match_limit = n; continue;#if !defined NODFA case 'R': options |= PCRE_DFA_RESTART; continue;#endif case 'S': show_malloc = 1; continue; case 'Z': options |= PCRE_NOTEOL; continue; case '?': options |= PCRE_NO_UTF8_CHECK; continue; case '<': { int x = check_newline(p, outfile); if (x == 0) goto NEXT_DATA; options |= x; while (*p++ != '>'); } continue; } *q++ = c; } *q = 0; len = q - dbuffer; if ((all_use_dfa || use_dfa) && find_match_limit) { printf("**Match limit not relevant for DFA matching: ignored\n"); find_match_limit = 0; } /* Handle matching via the POSIX interface, which does not support timing or playing with the match limit or callout data. */#if !defined NOPOSIX if (posix || do_posix) { int rc; int eflags = 0; regmatch_t *pmatch = NULL; if (use_size_offsets > 0) pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets); if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags); if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, buffer_size); fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); } else if ((((const pcre *)preg.re_pcre)->options & PCRE_NO_AUTO_CAPTURE) != 0) { fprintf(outfile, "Matched with REG_NOSUB\n"); } else { size_t i; for (i = 0; i < (size_t)use_size_offsets; i++) { if (pmatch[i].rm_so >= 0) { fprintf(outfile, "%2d: ", (int)i); (void)pchars(dbuffer + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so, outfile); fprintf(outfile, "\n"); if (i == 0 && do_showrest) { fprintf(outfile, " 0+ "); (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, outfile); fprintf(outfile, "\n"); } } } } free(pmatch); } /* Handle matching via the native interface - repeats for /g and /G */ else#endif /* !defined NOPOSIX */ for (;; gmatched++) /* Loop for /g or /G */ { if (timeitm > 0) { register int i; clock_t time_taken; clock_t start_time = clock();#if !defined NODFA if (all_use_dfa || use_dfa) { int workspace[1000]; for (i = 0; i < timeitm; i++) count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets, workspace, sizeof(workspace)/sizeof(int)); } else#endif for (i = 0; i < timeitm; i++) count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); time_taken = clock() - start_time; fprintf(outfile, "Execute time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeitm) / (double)CLOCKS_PER_SEC); } /* If find_match_limit is set, we want to do repeated matches with varying limits in order to find the minimum value for the match limit and for the recursion limit. */ if (find_match_limit) { if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } (void)check_match_limit(re, extra, bptr, len, start_offset, options|g_notempty, use_offsets, use_size_offsets, PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit), PCRE_ERROR_MATCHLIMIT, "match()"); count = check_match_limit(re, extra, bptr, len, start_offset, options|g_notempty, use_offsets, use_size_offsets, PCRE_EXTRA_MATCH_LIMIT_RECURSION, &(extra->match_limit_recursion), PCRE_ERROR_RECURSIONLIMIT, "match() recursion"); } /* If callout_data is set, use the interface with additional data */ else if (callout_data_set) { if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->flags |= PCRE_EXTRA_CALLOUT_DATA; extra->callout_data = &callout_data; count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; } /* The normal case is just to do the match once, with the default value of match_limit. */#if !defined NODFA else if (all_use_dfa || use_dfa) { int workspace[1000]; count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets, workspace, sizeof(workspace)/sizeof(int)); if (count == 0) { fprintf(outfile, "Matched, but too many subsidiary matches\n"); count = use_size_offsets/2; } }#endif else { count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); if (count == 0) { fprintf(outfile, "Matched, but too many substrings\n"); count = use_size_offsets/3; } } /* Matched */ if (count >= 0) { int i, maxcount;#if !defined NODFA if (all_use_dfa || use_dfa) maxcount = use_size_offsets/2; else#endif maxcount = use_size_offsets/3; /* This is a check against a lunatic return value. */ if (count > maxcount) { fprintf(outfile, "** PCRE error: returned count %d is too big for offset size %d\n", count, use_size_offsets); count = use_size_offsets/3; if (do_g || do_G) { fprintf(outfile, "** /%c loop abandoned\n", do_g? 'g' : 'G'); do_g = do_G = FALSE; /* Break g/G loop */ } } for (i = 0; i < count * 2; i += 2) { if (use_offsets[i] < 0) fprintf(outfile, "%2d: <unset>\n", i/2); else { fprintf(outfile, "%2d: ", i/2); (void)pchars(bptr + use_offsets[i], use_offsets[i+1] - use_offsets[i], outfile); fprintf(outfile, "\n"); if (i == 0) { if (do_showrest) { fprintf(outfile, " 0+ "); (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1], outfile); fprintf(outfile, "\n"); } } } } for (i = 0; i < 32; i++) { if ((copystrings & (1 << i)) != 0) { char copybuffer[256]; int rc = pcre_copy_substring((char *)bptr, use_offsets, count, i, copybuffer, sizeof(copybuffer)); if (rc < 0) fprintf(outfile, "copy substring %d failed %d\n", i, rc); else fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc); } } for (copynamesptr = copynames; *copynamesptr != 0; copynamesptr += (int)strlen((char*)copynamesptr) + 1) { char copybuffer[256]; int rc = pcre_copy_named_substring(re, (char *)bptr, use_offsets, count, (char *)copynamesptr, copybuffer, sizeof(copybuffer)); if (rc < 0) fprintf(outfile, "copy substring %s failed %d\n", copynamesptr, rc); else fprintf(outfile, " C %s (%d) %s\n", copybuffer, rc, copynamesptr); } for (i = 0; i < 32; i++) { if ((getstrings & (1 << i)) != 0) { const char *substring; int rc = pcre_get_substring((char *)bptr, use_offsets, count, i, &substring); if (rc < 0) fprintf(outfile, "get substring %d failed %d\n", i, rc); else { fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc); pcre_free_substring(substring); } } } for (getnamesptr = getnames; *getnamesptr != 0; getnamesptr += (int)strlen((char*)getnamesptr) + 1) { const char *substring; int rc = pcre_get_named_substring(re, (char *)bptr, use_offsets, count, (char *)getnamesptr, &substring); if (rc < 0) fprintf(outfile, "copy substring %s failed %d\n", getnamesptr, rc); else { fprintf(outfile, " G %s (%d) %s\n", substring, rc, getnamesptr); pcre_free_substring(substring); } } if (getlist) { const char **stringlist; int rc = pcre_get_substring_list((char *)bptr, use_offsets, count, &stringlist); if (rc < 0) fprintf(outfile, "get substring list failed %d\n", rc); else { for (i = 0; i < count; i++) fprintf(outfile, "%2dL %s\n", i, stringlist[i]); if (stringlist[i] != NULL) fprintf(outfile, "string list not terminated by NULL\n"); /* free((void *)stringlist); */ pcre_free_substring_list(stringlist); } } } /* There was a partial match */ else if (count == PCRE_ERROR_PARTIAL) { fprintf(outfile, "Partial match");#if !defined NODFA if ((all_use_dfa || use_dfa) && use_size_offsets > 2) fprintf(outfile, ": %.*s", use_offsets[1] - use_offsets[0], bptr + use_offsets[0]);#endif fprintf(outfile, "\n"); break; /* Out of the /g loop */ } /* Failed to match. If this is a /g or /G loop and we previously set g_notempty after a null match, this is not necessarily the end. We want to advance the start offset, and continue. In the case of UTF-8 matching, the advance must be one character, not one byte. Fudge the offset values to achieve this. We won't be at the end of the string - that was checked before setting g_notempty. */ else { if (g_notempty != 0) { int onechar = 1; use_offsets[0] = start_offset; if (use_utf8) { while (start_offset + onechar < len) { int tb = bptr[start_offset+onechar]; if (tb <= 127) break; tb &= 0xc0; if (tb != 0 && tb != 0xc0) onechar++; } } use_offsets[1] = start_offset + onechar; } else { if (count == PCRE_ERROR_NOMATCH) { if (gmatched == 0) fprintf(outfile, "No match\n"); } else fprintf(outfile, "Error %d\n", count); break; /* Out of the /g loop */ } } /* If not /g or /G we are done */ if (!do_g && !do_G) break; /* If we have matched an empty string, first check to see if we are at the end of the subject. If so, the /g loop is over. Otherwise, mimic what Perl's /g options does. This tur
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -