/[pcre]/code/trunk/pcretest.c
ViewVC logotype

Diff of /code/trunk/pcretest.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 23 by nigel, Sat Feb 24 21:38:41 2007 UTC revision 29 by nigel, Sat Feb 24 21:38:53 2007 UTC
# Line 7  Line 7 
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    
# Line 21  Line 22 
22  #endif  #endif
23  #endif  #endif
24    
25  #define LOOPREPEAT 10000  #define LOOPREPEAT 20000
26    
27    
28  static FILE *outfile;  static FILE *outfile;
# Line 313  while (argc > 1 && argv[op][0] == '-') Line 314  while (argc > 1 && argv[op][0] == '-')
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++;
# Line 357  while (!done) Line 364  while (!done)
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    
# Line 376  while (!done) Line 385  while (!done)
385    
386    delimiter = *p++;    delimiter = *p++;
387    
388    if (isalnum(delimiter))    if (isalnum(delimiter) || delimiter == '\\')
389      {      {
390      fprintf(outfile, "** Delimiter must not be alphameric\n");      fprintf(outfile, "** Delimiter must not be alphameric or \\\n");
391      goto SKIP_DATA;      goto SKIP_DATA;
392      }      }
393    
# Line 386  while (!done) Line 395  while (!done)
395    
396    for(;;)    for(;;)
397      {      {
398      while (*pp != 0 && *pp != delimiter) pp++;      while (*pp != 0)
399          {
400          if (*pp == '\\' && pp[1] != 0) pp++;
401            else if (*pp == delimiter) break;
402          pp++;
403          }
404      if (*pp != 0) break;      if (*pp != 0) break;
405    
406      len = sizeof(buffer) - (pp - buffer);      len = sizeof(buffer) - (pp - buffer);
# Line 406  while (!done) Line 420  while (!done)
420      if (infile != stdin) fprintf(outfile, "%s", (char *)pp);      if (infile != stdin) fprintf(outfile, "%s", (char *)pp);
421      }      }
422    
423      /* If the first character after the delimiter is backslash, make
424      the pattern end with backslash. This is purely to provide a way
425      of testing for the error message when a pattern ends with backslash. */
426    
427      if (pp[1] == '\\') *pp++ = '\\';
428    
429    /* Terminate the pattern at the delimiter */    /* Terminate the pattern at the delimiter */
430    
431    *pp++ = 0;    *pp++ = 0;
# Line 422  while (!done) Line 442  while (!done)
442        case 'm': options |= PCRE_MULTILINE; break;        case 'm': options |= PCRE_MULTILINE; break;
443        case 's': options |= PCRE_DOTALL; break;        case 's': options |= PCRE_DOTALL; break;
444        case 'x': options |= PCRE_EXTENDED; break;        case 'x': options |= PCRE_EXTENDED; break;
445    
446        case 'A': options |= PCRE_ANCHORED; break;        case 'A': options |= PCRE_ANCHORED; break;
447        case 'D': do_debug = 1; break;        case 'D': do_debug = do_showinfo = 1; break;
448        case 'E': options |= PCRE_DOLLAR_ENDONLY; break;        case 'E': options |= PCRE_DOLLAR_ENDONLY; break;
449          case 'I': do_showinfo = 1; break;
450        case 'P': do_posix = 1; break;        case 'P': do_posix = 1; break;
451        case 'S': do_study = 1; break;        case 'S': do_study = 1; break;
452        case 'U': options |= PCRE_UNGREEDY; break;        case 'U': options |= PCRE_UNGREEDY; break;
453        case 'X': options |= PCRE_EXTRA; break;        case 'X': options |= PCRE_EXTRA; break;
454    
455          case 'L':
456          ppp = pp;
457          while (*ppp != '\n' && *ppp != ' ') ppp++;
458          *ppp = 0;
459          if (setlocale(LC_CTYPE, (const char *)pp) == NULL)
460            {
461            fprintf(outfile, "** Failed to set locale \"%s\"\n", pp);
462            goto SKIP_DATA;
463            }
464          tables = pcre_maketables();
465          pp = ppp;
466          break;
467    
468        case '\n': case ' ': break;        case '\n': case ' ': break;
469        default:        default:
470        fprintf(outfile, "** Unknown option '%c'\n", pp[-1]);        fprintf(outfile, "** Unknown option '%c'\n", pp[-1]);
# Line 437  while (!done) Line 473  while (!done)
473      }      }
474    
475    /* Handle compiling via the POSIX interface, which doesn't support the    /* Handle compiling via the POSIX interface, which doesn't support the
476    timing, showing, or debugging options. */    timing, showing, or debugging options, nor the ability to pass over
477      local character tables. */
478    
479    if (posix || do_posix)    if (posix || do_posix)
480      {      {
# Line 469  while (!done) Line 506  while (!done)
506        clock_t start_time = clock();        clock_t start_time = clock();
507        for (i = 0; i < LOOPREPEAT; i++)        for (i = 0; i < LOOPREPEAT; i++)
508          {          {
509          re = pcre_compile((char *)p, options, &error, &erroroffset);          re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
510          if (re != NULL) free(re);          if (re != NULL) free(re);
511          }          }
512        time_taken = clock() - start_time;        time_taken = clock() - start_time;
513        fprintf(outfile, "Compile time %.2f milliseconds\n",        fprintf(outfile, "Compile time %.3f milliseconds\n",
514          ((double)time_taken)/(4 * CLOCKS_PER_SEC));          ((double)time_taken * 1000.0) /
515            ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
516        }        }
517    
518      re = pcre_compile((char *)p, options, &error, &erroroffset);      re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
519    
520      /* Compilation failed; go back for another re, skipping to blank line      /* Compilation failed; go back for another re, skipping to blank line
521      if non-interactive. */      if non-interactive. */
# Line 501  while (!done) Line 539  while (!done)
539            }            }
540          fprintf(outfile, "\n");          fprintf(outfile, "\n");
541          }          }
542        continue;        goto CONTINUE;
543        }        }
544    
545      /* Compilation succeeded; print data if required */      /* Compilation succeeded; print data if required */
546    
547      if (showinfo || do_debug)      if (do_showinfo)
548        {        {
549        int first_char, count;        int first_char, count;
550    
551        if (debug || do_debug) print_internals(re, outfile);        if (do_debug) print_internals(re, outfile);
552    
553        count = pcre_info(re, &options, &first_char);        count = pcre_info(re, &options, &first_char);
554        if (count < 0) fprintf(outfile,        if (count < 0) fprintf(outfile,
# Line 560  while (!done) Line 598  while (!done)
598            extra = pcre_study(re, study_options, &error);            extra = pcre_study(re, study_options, &error);
599          time_taken = clock() - start_time;          time_taken = clock() - start_time;
600          if (extra != NULL) free(extra);          if (extra != NULL) free(extra);
601          fprintf(outfile, "  Study time %.2f milliseconds\n",          fprintf(outfile, "  Study time %.3f milliseconds\n",
602            ((double)time_taken)/(4 * CLOCKS_PER_SEC));            ((double)time_taken * 1000.0)/
603              ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
604          }          }
605    
606        extra = pcre_study(re, study_options, &error);        extra = pcre_study(re, study_options, &error);
# Line 573  while (!done) Line 612  while (!done)
612        /* This looks at internal information. A bit kludgy to do it this        /* This looks at internal information. A bit kludgy to do it this
613        way, but it is useful for testing. */        way, but it is useful for testing. */
614    
615        else if (showinfo || do_debug)        else if (do_showinfo)
616          {          {
617          real_pcre_extra *xx = (real_pcre_extra *)extra;          real_pcre_extra *xx = (real_pcre_extra *)extra;
618          if ((xx->options & PCRE_STUDY_MAPPED) == 0)          if ((xx->options & PCRE_STUDY_MAPPED) == 0)
# Line 616  while (!done) Line 655  while (!done)
655      {      {
656      unsigned char *q;      unsigned char *q;
657      int count, c;      int count, c;
658        int copystrings = 0;
659        int getstrings = 0;
660        int getlist = 0;
661      int offsets[45];      int offsets[45];
662      int size_offsets = sizeof(offsets)/sizeof(int);      int size_offsets = sizeof(offsets)/sizeof(int);
663    
# Line 681  while (!done) Line 723  while (!done)
723          options |= PCRE_NOTBOL;          options |= PCRE_NOTBOL;
724          continue;          continue;
725    
726            case 'C':
727            while(isdigit(*p)) n = n * 10 + *p++ - '0';
728            copystrings |= 1 << n;
729            continue;
730    
731            case 'G':
732            while(isdigit(*p)) n = n * 10 + *p++ - '0';
733            getstrings |= 1 << n;
734            continue;
735    
736            case 'L':
737            getlist = 1;
738            continue;
739    
740          case 'O':          case 'O':
741          while(isdigit(*p)) n = n * 10 + *p++ - '0';          while(isdigit(*p)) n = n * 10 + *p++ - '0';
742          if (n <= (int)(sizeof(offsets)/sizeof(int))) size_offsets = n;          if (n <= (int)(sizeof(offsets)/sizeof(int))) size_offsets = n;
# Line 739  while (!done) Line 795  while (!done)
795          register int i;          register int i;
796          clock_t time_taken;          clock_t time_taken;
797          clock_t start_time = clock();          clock_t start_time = clock();
798          for (i = 0; i < 4000; i++)          for (i = 0; i < LOOPREPEAT; i++)
799            count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets,            count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets,
800              size_offsets);              size_offsets);
801          time_taken = clock() - start_time;          time_taken = clock() - start_time;
802          fprintf(outfile, "Execute time %.2f milliseconds\n",          fprintf(outfile, "Execute time %.3f milliseconds\n",
803            ((double)time_taken)/(4 * CLOCKS_PER_SEC));            ((double)time_taken * 1000.0)/
804              ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
805          }          }
806    
807        count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets,        count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets,
# Line 759  while (!done) Line 816  while (!done)
816        if (count >= 0)        if (count >= 0)
817          {          {
818          int i;          int i;
819          count *= 2;          for (i = 0; i < count * 2; i += 2)
         for (i = 0; i < count; i += 2)  
820            {            {
821            if (offsets[i] < 0)            if (offsets[i] < 0)
822              fprintf(outfile, "%2d: <unset>\n", i/2);              fprintf(outfile, "%2d: <unset>\n", i/2);
# Line 771  while (!done) Line 827  while (!done)
827              fprintf(outfile, "\n");              fprintf(outfile, "\n");
828              }              }
829            }            }
830    
831            for (i = 0; i < 32; i++)
832              {
833              if ((copystrings & (1 << i)) != 0)
834                {
835                char buffer[16];
836                int rc = pcre_copy_substring((char *)dbuffer, offsets, count,
837                  i, buffer, sizeof(buffer));
838                if (rc < 0)
839                  fprintf(outfile, "copy substring %d failed %d\n", i, rc);
840                else
841                  fprintf(outfile, "%2dC %s (%d)\n", i, buffer, rc);
842                }
843              }
844    
845            for (i = 0; i < 32; i++)
846              {
847              if ((getstrings & (1 << i)) != 0)
848                {
849                const char *substring;
850                int rc = pcre_get_substring((char *)dbuffer, offsets, count,
851                  i, &substring);
852                if (rc < 0)
853                  fprintf(outfile, "get substring %d failed %d\n", i, rc);
854                else
855                  {
856                  fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc);
857                  free((void *)substring);
858                  }
859                }
860              }
861    
862            if (getlist)
863              {
864              const char **stringlist;
865              int rc = pcre_get_substring_list((char *)dbuffer, offsets, count,
866                &stringlist);
867              if (rc < 0)
868                fprintf(outfile, "get substring list failed %d\n", rc);
869              else
870                {
871                for (i = 0; i < count; i++)
872                  fprintf(outfile, "%2dL %s\n", i, stringlist[i]);
873                if (stringlist[i] != NULL)
874                  fprintf(outfile, "string list not terminated by NULL\n");
875                free((void *)stringlist);
876                }
877              }
878    
879          }          }
880        else        else
881          {          {
# Line 784  while (!done) Line 889  while (!done)
889    if (posix || do_posix) regfree(&preg);    if (posix || do_posix) regfree(&preg);
890    if (re != NULL) free(re);    if (re != NULL) free(re);
891    if (extra != NULL) free(extra);    if (extra != NULL) free(extra);
892      if (tables != NULL)
893        {
894        free((void *)tables);
895        setlocale(LC_CTYPE, "C");
896        }
897    }    }
898    
899  fprintf(outfile, "\n");  fprintf(outfile, "\n");

Legend:
Removed from v.23  
changed lines
  Added in v.29

  ViewVC Help
Powered by ViewVC 1.1.5