📄 pcretest.c
字号:
fprintf(f, "%2d: <unset>\n", i/2); else { fprintf(f, "%2d: ", i/2); (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i], cb->offset_vector[i+1] - cb->offset_vector[i], f); fprintf(f, "\n"); } } }/* Re-print the subject in canonical form, the first time or if giving fulldatails. On subsequent calls in the same match, we use pchars just to find theprinted lengths of the substrings. */if (f != NULL) fprintf(f, "--->");pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f);post_start = pchars((unsigned char *)(cb->subject + cb->start_match), cb->current_position - cb->start_match, f);subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);(void)pchars((unsigned char *)(cb->subject + cb->current_position), cb->subject_length - cb->current_position, f);if (f != NULL) fprintf(f, "\n");/* Always print appropriate indicators, with callout number if not alreadyshown. For automatic callouts, show the pattern offset. */if (cb->callout_number == 255) { fprintf(outfile, "%+3d ", cb->pattern_position); if (cb->pattern_position > 99) fprintf(outfile, "\n "); }else { if (callout_extra) fprintf(outfile, " "); else fprintf(outfile, "%3d ", cb->callout_number); }for (i = 0; i < pre_start; i++) fprintf(outfile, " ");fprintf(outfile, "^");if (post_start > 0) { for (i = 0; i < post_start - 1; i++) fprintf(outfile, " "); fprintf(outfile, "^"); }for (i = 0; i < subject_length - pre_start - post_start + 4; i++) fprintf(outfile, " ");fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length, pbuffer + cb->pattern_position);fprintf(outfile, "\n");first_callout = 0;if (cb->callout_data != NULL) { int callout_data = *((int *)(cb->callout_data)); if (callout_data != 0) { fprintf(outfile, "Callout data = %d\n", callout_data); return callout_data; } }return (cb->callout_number != callout_fail_id)? 0 : (++callout_count >= callout_fail_count)? 1 : 0;}/************************************************** Local malloc functions **************************************************//* Alternative malloc function, to test functionality and show the size of thecompiled re. */static void *new_malloc(size_t size){void *block = malloc(size);gotten_store = size;if (show_malloc) fprintf(outfile, "malloc %3d %p\n", (int)size, block);return block;}static void new_free(void *block){if (show_malloc) fprintf(outfile, "free %p\n", block);free(block);}/* For recursion malloc/free, to test stacking calls */static void *stack_malloc(size_t size){void *block = malloc(size);if (show_malloc) fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block);return block;}static void stack_free(void *block){if (show_malloc) fprintf(outfile, "stack_free %p\n", block);free(block);}/************************************************** Call pcre_fullinfo() **************************************************//* Get one piece of information from the pcre_fullinfo() function */static void new_info(pcre *re, pcre_extra *study, int option, void *ptr){int rc;if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0) fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);}/************************************************** Byte flipping function **************************************************/static unsigned long intbyteflip(unsigned long int value, int n){if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);return ((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | ((value & 0xff000000) >> 24);}/************************************************** Check match or recursion limit **************************************************/static intcheck_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len, int start_offset, int options, int *use_offsets, int use_size_offsets, int flag, unsigned long int *limit, int errnumber, const char *msg){int count;int min = 0;int mid = 64;int max = -1;extra->flags |= flag;for (;;) { *limit = mid; count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, use_offsets, use_size_offsets); if (count == errnumber) { /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */ min = mid; mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2; } else if (count >= 0 || count == PCRE_ERROR_NOMATCH || count == PCRE_ERROR_PARTIAL) { if (mid == min + 1) { fprintf(outfile, "Minimum %s limit = %d\n", msg, mid); break; } /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */ max = mid; mid = (min + mid)/2; } else break; /* Some other error */ }extra->flags &= ~flag;return count;}/************************************************** Check newline indicator **************************************************//* This is used both at compile and run-time to check for <xxx> escapes, wherexxx is LF, CR, CRLF, or ANY. Print a message and return 0 if there is no match.Arguments: p points after the leading '<' f file for error messageReturns: appropriate PCRE_NEWLINE_xxx flags, or 0*/static intcheck_newline(uschar *p, FILE *f){if (strncmp((char *)p, "cr>", 3) == 0) return PCRE_NEWLINE_CR;if (strncmp((char *)p, "lf>", 3) == 0) return PCRE_NEWLINE_LF;if (strncmp((char *)p, "crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;if (strncmp((char *)p, "any>", 4) == 0) return PCRE_NEWLINE_ANY;fprintf(f, "Unknown newline type at: <%s\n", p);return 0;}/************************************************** Usage function **************************************************/static voidusage(void){printf("Usage: pcretest [options] [<input> [<output>]]\n");printf(" -b show compiled code (bytecode)\n");printf(" -C show PCRE compile-time options and exit\n");printf(" -d debug: show compiled code and information (-b and -i)\n");#if !defined NODFAprintf(" -dfa force DFA matching for all subjects\n");#endifprintf(" -help show usage information\n");printf(" -i show information about compiled patterns\n" " -m output memory used information\n" " -o <n> set size of offsets vector to <n>\n");#if !defined NOPOSIXprintf(" -p use POSIX interface\n");#endifprintf(" -q quiet: do not output PCRE version number at start\n");printf(" -S <n> set stack size to <n> megabytes\n");printf(" -s output store (memory) used information\n" " -t time compilation and execution\n");printf(" -t <n> time compilation and execution, repeating <n> times\n");printf(" -tm time execution (matching) only\n");printf(" -tm <n> time execution (matching) only, repeating <n> times\n");}/************************************************** Main Program **************************************************//* Read lines from named file or stdin and write to named file or stdout; linesconsist of a regular expression, in delimiters and optionally followed byoptions, followed by a set of test data, terminated by an empty line. */int main(int argc, char **argv){FILE *infile = stdin;int options = 0;int study_options = 0;int op = 1;int timeit = 0;int timeitm = 0;int showinfo = 0;int showstore = 0;int quiet = 0;int size_offsets = 45;int size_offsets_max;int *offsets = NULL;#if !defined NOPOSIXint posix = 0;#endifint debug = 0;int done = 0;int all_use_dfa = 0;int yield = 0;int stack_size;/* These vectors store, end-to-end, a list of captured substring names. Assumethat 1024 is plenty long enough for the few names we'll be testing. */uschar copynames[1024];uschar getnames[1024];uschar *copynamesptr;uschar *getnamesptr;/* Get buffers from malloc() so that Electric Fence will check their misusewhen I am debugging. They grow automatically when very long lines are read. */buffer = (unsigned char *)malloc(buffer_size);dbuffer = (unsigned char *)malloc(buffer_size);pbuffer = (unsigned char *)malloc(buffer_size);/* The outfile variable is static so that new_malloc can use it. */outfile = stdout;/* The following _setmode() stuff is some Windows magic that tells its runtimelibrary to translate CRLF into a single LF character. At least, that's whatI've been told: never having used Windows I take this all on trust. Originallyit set 0x8000, but then I was advised that _O_BINARY was better. */#if defined(_WIN32) || defined(WIN32)_setmode( _fileno( stdout ), _O_BINARY );#endif/* Scan options */while (argc > 1 && argv[op][0] == '-') { unsigned char *endptr; if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0) showstore = 1; else if (strcmp(argv[op], "-q") == 0) quiet = 1; else if (strcmp(argv[op], "-b") == 0) debug = 1; else if (strcmp(argv[op], "-i") == 0) showinfo = 1; else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;#if !defined NODFA else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;#endif else if (strcmp(argv[op], "-o") == 0 && argc > 2 && ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)), *endptr == 0)) { op++; argc--; } else if (strcmp(argv[op], "-t") == 0 || strcmp(argv[op], "-tm") == 0) { int both = argv[op][2] == 0; int temp; if (argc > 2 && (temp = get_value((unsigned char *)argv[op+1], &endptr), *endptr == 0)) { timeitm = temp; op++; argc--; } else timeitm = LOOPREPEAT; if (both) timeit = timeitm; } else if (strcmp(argv[op], "-S") == 0 && argc > 2 && ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)), *endptr == 0)) {#if defined(_WIN32) || defined(WIN32) printf("PCRE: -S not supported on this OS\n"); exit(1);#else int rc; struct rlimit rlim; getrlimit(RLIMIT_STACK, &rlim); rlim.rlim_cur = stack_size * 1024 * 1024; rc = setrlimit(RLIMIT_STACK, &rlim); if (rc != 0) { printf("PCRE: setrlimit() failed with error %d\n", rc); exit(1); } op++; argc--;#endif }#if !defined NOPOSIX else if (strcmp(argv[op], "-p") == 0) posix = 1;#endif else if (strcmp(argv[op], "-C") == 0) { int rc; printf("PCRE version %s\n", pcre_version()); printf("Compiled with\n"); (void)pcre_config(PCRE_CONFIG_UTF8, &rc); printf(" %sUTF-8 support\n", rc? "" : "No "); (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); printf(" %sUnicode properties support\n", rc? "" : "No "); (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc); printf(" Newline sequence is %s\n", (rc == '\r')? "CR" : (rc == '\n')? "LF" : (rc == ('\r'<<8 | '\n'))? "CRLF" : (rc == -1)? "ANY" : "???"); (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc); printf(" Internal link size = %d\n", rc); (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc); printf(" POSIX malloc threshold = %d\n", rc); (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc); printf(" Default match limit = %d\n", rc); (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &rc); printf(" Default recursion depth limit = %d\n", rc); (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc); printf(" Match recursion uses %s\n", rc? "stack" : "heap"); exit(0); } else if (strcmp(argv[op], "-help") == 0 || strcmp(argv[op], "--help") == 0) { usage(); goto EXIT; } else { printf("** Unknown or malformed option %s\n", argv[op]); usage(); yield = 1; goto EXIT; } op++; argc--; }/* Get the store for the offsets vector, and remember what it was */size_offsets_max = size_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; }/* Sort out the input and output files */if (argc > 1) { infile = fopen(argv[op], INPUT_MODE); if (infile == NULL) { printf("** Failed to open %s\n", argv[op]); yield = 1; goto EXIT; } }if (argc > 2) { outfile = fopen(argv[op+1], OUTPUT_MODE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -