7 |
#include <string.h> |
#include <string.h> |
8 |
#include <stdlib.h> |
#include <stdlib.h> |
9 |
#include <time.h> |
#include <time.h> |
10 |
|
#include <locale.h> |
11 |
|
|
12 |
/* Use the internal info for displaying the results of pcre_study(). */ |
/* Use the internal info for displaying the results of pcre_study(). */ |
13 |
|
|
22 |
#endif |
#endif |
23 |
#endif |
#endif |
24 |
|
|
25 |
#define LOOPREPEAT 10000 |
#define LOOPREPEAT 20000 |
26 |
|
|
27 |
|
|
28 |
static FILE *outfile; |
static FILE *outfile; |
314 |
else |
else |
315 |
{ |
{ |
316 |
printf("*** Unknown option %s\n", argv[op]); |
printf("*** Unknown option %s\n", argv[op]); |
317 |
|
printf("Usage: pcretest [-d] [-i] [-p] [-s] [-t] [<input> [<output>]]\n"); |
318 |
|
printf(" -d debug: show compiled code; implies -i\n" |
319 |
|
" -i show information about compiled pattern\n" |
320 |
|
" -p use POSIX interface\n" |
321 |
|
" -s output store information\n" |
322 |
|
" -t time compilation and execution\n"); |
323 |
return 1; |
return 1; |
324 |
} |
} |
325 |
op++; |
op++; |
364 |
pcre_extra *extra = NULL; |
pcre_extra *extra = NULL; |
365 |
regex_t preg; |
regex_t preg; |
366 |
const char *error; |
const char *error; |
367 |
unsigned char *p, *pp; |
unsigned char *p, *pp, *ppp; |
368 |
|
unsigned const char *tables = NULL; |
369 |
int do_study = 0; |
int do_study = 0; |
370 |
int do_debug = 0; |
int do_debug = debug; |
371 |
|
int do_showinfo = showinfo; |
372 |
int do_posix = 0; |
int do_posix = 0; |
373 |
int erroroffset, len, delimiter; |
int erroroffset, len, delimiter; |
374 |
|
|
431 |
case 'm': options |= PCRE_MULTILINE; break; |
case 'm': options |= PCRE_MULTILINE; break; |
432 |
case 's': options |= PCRE_DOTALL; break; |
case 's': options |= PCRE_DOTALL; break; |
433 |
case 'x': options |= PCRE_EXTENDED; break; |
case 'x': options |= PCRE_EXTENDED; break; |
434 |
|
|
435 |
case 'A': options |= PCRE_ANCHORED; break; |
case 'A': options |= PCRE_ANCHORED; break; |
436 |
case 'D': do_debug = 1; break; |
case 'D': do_debug = do_showinfo = 1; break; |
437 |
case 'E': options |= PCRE_DOLLAR_ENDONLY; break; |
case 'E': options |= PCRE_DOLLAR_ENDONLY; break; |
438 |
|
case 'I': do_showinfo = 1; break; |
439 |
case 'P': do_posix = 1; break; |
case 'P': do_posix = 1; break; |
440 |
case 'S': do_study = 1; break; |
case 'S': do_study = 1; break; |
441 |
case 'U': options |= PCRE_UNGREEDY; break; |
case 'U': options |= PCRE_UNGREEDY; break; |
442 |
case 'X': options |= PCRE_EXTRA; break; |
case 'X': options |= PCRE_EXTRA; break; |
443 |
|
|
444 |
|
case 'L': |
445 |
|
ppp = pp; |
446 |
|
while (*ppp != '\n' && *ppp != ' ') ppp++; |
447 |
|
*ppp = 0; |
448 |
|
if (setlocale(LC_CTYPE, (const char *)pp) == NULL) |
449 |
|
{ |
450 |
|
fprintf(outfile, "** Failed to set locale \"%s\"\n", pp); |
451 |
|
goto SKIP_DATA; |
452 |
|
} |
453 |
|
tables = pcre_maketables(); |
454 |
|
pp = ppp; |
455 |
|
break; |
456 |
|
|
457 |
case '\n': case ' ': break; |
case '\n': case ' ': break; |
458 |
default: |
default: |
459 |
fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); |
fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); |
462 |
} |
} |
463 |
|
|
464 |
/* Handle compiling via the POSIX interface, which doesn't support the |
/* Handle compiling via the POSIX interface, which doesn't support the |
465 |
timing, showing, or debugging options. */ |
timing, showing, or debugging options, nor the ability to pass over |
466 |
|
local character tables. */ |
467 |
|
|
468 |
if (posix || do_posix) |
if (posix || do_posix) |
469 |
{ |
{ |
495 |
clock_t start_time = clock(); |
clock_t start_time = clock(); |
496 |
for (i = 0; i < LOOPREPEAT; i++) |
for (i = 0; i < LOOPREPEAT; i++) |
497 |
{ |
{ |
498 |
re = pcre_compile((char *)p, options, &error, &erroroffset); |
re = pcre_compile((char *)p, options, &error, &erroroffset, tables); |
499 |
if (re != NULL) free(re); |
if (re != NULL) free(re); |
500 |
} |
} |
501 |
time_taken = clock() - start_time; |
time_taken = clock() - start_time; |
502 |
fprintf(outfile, "Compile time %.2f milliseconds\n", |
fprintf(outfile, "Compile time %.3f milliseconds\n", |
503 |
((double)time_taken)/(4 * CLOCKS_PER_SEC)); |
((double)time_taken * 1000.0) / |
504 |
|
((double)LOOPREPEAT * (double)CLOCKS_PER_SEC)); |
505 |
} |
} |
506 |
|
|
507 |
re = pcre_compile((char *)p, options, &error, &erroroffset); |
re = pcre_compile((char *)p, options, &error, &erroroffset, tables); |
508 |
|
|
509 |
/* Compilation failed; go back for another re, skipping to blank line |
/* Compilation failed; go back for another re, skipping to blank line |
510 |
if non-interactive. */ |
if non-interactive. */ |
528 |
} |
} |
529 |
fprintf(outfile, "\n"); |
fprintf(outfile, "\n"); |
530 |
} |
} |
531 |
continue; |
goto CONTINUE; |
532 |
} |
} |
533 |
|
|
534 |
/* Compilation succeeded; print data if required */ |
/* Compilation succeeded; print data if required */ |
535 |
|
|
536 |
if (showinfo || do_debug) |
if (do_showinfo) |
537 |
{ |
{ |
538 |
int first_char, count; |
int first_char, count; |
539 |
|
|
540 |
if (debug || do_debug) print_internals(re, outfile); |
if (do_debug) print_internals(re, outfile); |
541 |
|
|
542 |
count = pcre_info(re, &options, &first_char); |
count = pcre_info(re, &options, &first_char); |
543 |
if (count < 0) fprintf(outfile, |
if (count < 0) fprintf(outfile, |
587 |
extra = pcre_study(re, study_options, &error); |
extra = pcre_study(re, study_options, &error); |
588 |
time_taken = clock() - start_time; |
time_taken = clock() - start_time; |
589 |
if (extra != NULL) free(extra); |
if (extra != NULL) free(extra); |
590 |
fprintf(outfile, " Study time %.2f milliseconds\n", |
fprintf(outfile, " Study time %.3f milliseconds\n", |
591 |
((double)time_taken)/(4 * CLOCKS_PER_SEC)); |
((double)time_taken * 1000.0)/ |
592 |
|
((double)LOOPREPEAT * (double)CLOCKS_PER_SEC)); |
593 |
} |
} |
594 |
|
|
595 |
extra = pcre_study(re, study_options, &error); |
extra = pcre_study(re, study_options, &error); |
601 |
/* This looks at internal information. A bit kludgy to do it this |
/* This looks at internal information. A bit kludgy to do it this |
602 |
way, but it is useful for testing. */ |
way, but it is useful for testing. */ |
603 |
|
|
604 |
else if (showinfo || do_debug) |
else if (do_showinfo) |
605 |
{ |
{ |
606 |
real_pcre_extra *xx = (real_pcre_extra *)extra; |
real_pcre_extra *xx = (real_pcre_extra *)extra; |
607 |
if ((xx->options & PCRE_STUDY_MAPPED) == 0) |
if ((xx->options & PCRE_STUDY_MAPPED) == 0) |
767 |
register int i; |
register int i; |
768 |
clock_t time_taken; |
clock_t time_taken; |
769 |
clock_t start_time = clock(); |
clock_t start_time = clock(); |
770 |
for (i = 0; i < 4000; i++) |
for (i = 0; i < LOOPREPEAT; i++) |
771 |
count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets, |
count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets, |
772 |
size_offsets); |
size_offsets); |
773 |
time_taken = clock() - start_time; |
time_taken = clock() - start_time; |
774 |
fprintf(outfile, "Execute time %.2f milliseconds\n", |
fprintf(outfile, "Execute time %.3f milliseconds\n", |
775 |
((double)time_taken)/(4 * CLOCKS_PER_SEC)); |
((double)time_taken * 1000.0)/ |
776 |
|
((double)LOOPREPEAT * (double)CLOCKS_PER_SEC)); |
777 |
} |
} |
778 |
|
|
779 |
count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets, |
count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets, |
813 |
if (posix || do_posix) regfree(&preg); |
if (posix || do_posix) regfree(&preg); |
814 |
if (re != NULL) free(re); |
if (re != NULL) free(re); |
815 |
if (extra != NULL) free(extra); |
if (extra != NULL) free(extra); |
816 |
|
if (tables != NULL) |
817 |
|
{ |
818 |
|
free((void *)tables); |
819 |
|
setlocale(LC_CTYPE, "C"); |
820 |
|
} |
821 |
} |
} |
822 |
|
|
823 |
fprintf(outfile, "\n"); |
fprintf(outfile, "\n"); |