/[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 31 by nigel, Sat Feb 24 21:38:57 2007 UTC revision 41 by nigel, Sat Feb 24 21:39:17 2007 UTC
# Line 12  Line 12 
12  /* Use the internal info for displaying the results of pcre_study(). */  /* Use the internal info for displaying the results of pcre_study(). */
13    
14  #include "internal.h"  #include "internal.h"
15    
16    /* It is possible to compile this test program without including support for
17    testing the POSIX interface, though this is not available via the standard
18    Makefile. */
19    
20    #if !defined NOPOSIX
21  #include "pcreposix.h"  #include "pcreposix.h"
22    #endif
23    
24  #ifndef CLOCKS_PER_SEC  #ifndef CLOCKS_PER_SEC
25  #ifdef CLK_TCK  #ifdef CLK_TCK
# Line 48  static const char *OP_names[] = { Line 55  static const char *OP_names[] = {
55  };  };
56    
57    
58  static void print_internals(pcre *re, FILE *outfile)  static void print_internals(pcre *re)
59  {  {
60  unsigned char *code = ((real_pcre *)re)->code;  unsigned char *code = ((real_pcre *)re)->code;
61    
# Line 275  compiled re. */ Line 282  compiled re. */
282  static void *new_malloc(size_t size)  static void *new_malloc(size_t size)
283  {  {
284  if (log_store)  if (log_store)
285    fprintf(outfile, "Memory allocation request: %d (code space %d)\n",    fprintf(outfile, "Memory allocation (code space): %d\n",
286      (int)size, (int)size - offsetof(real_pcre, code[0]));      (int)((int)size - offsetof(real_pcre, code[0])));
287  return malloc(size);  return malloc(size);
288  }  }
289    
# Line 366  while (!done) Line 373  while (!done)
373    {    {
374    pcre *re = NULL;    pcre *re = NULL;
375    pcre_extra *extra = NULL;    pcre_extra *extra = NULL;
376    
377    #if !defined NOPOSIX  /* There are still compilers that require no indent */
378    regex_t preg;    regex_t preg;
379    #endif
380    
381    const char *error;    const char *error;
382    unsigned char *p, *pp, *ppp;    unsigned char *p, *pp, *ppp;
383    unsigned const char *tables = NULL;    unsigned const char *tables = NULL;
384    int do_study = 0;    int do_study = 0;
385    int do_debug = debug;    int do_debug = debug;
386      int do_G = 0;
387      int do_g = 0;
388    int do_showinfo = showinfo;    int do_showinfo = showinfo;
389      int do_showrest = 0;
390    int do_posix = 0;    int do_posix = 0;
391    int erroroffset, len, delimiter;    int erroroffset, len, delimiter;
392    
# Line 444  while (!done) Line 458  while (!done)
458      {      {
459      switch (*pp++)      switch (*pp++)
460        {        {
461          case 'g': do_g = 1; break;
462        case 'i': options |= PCRE_CASELESS; break;        case 'i': options |= PCRE_CASELESS; break;
463        case 'm': options |= PCRE_MULTILINE; break;        case 'm': options |= PCRE_MULTILINE; break;
464        case 's': options |= PCRE_DOTALL; break;        case 's': options |= PCRE_DOTALL; break;
465        case 'x': options |= PCRE_EXTENDED; break;        case 'x': options |= PCRE_EXTENDED; break;
466    
467          case '+': do_showrest = 1; break;
468        case 'A': options |= PCRE_ANCHORED; break;        case 'A': options |= PCRE_ANCHORED; break;
469        case 'D': do_debug = do_showinfo = 1; break;        case 'D': do_debug = do_showinfo = 1; break;
470        case 'E': options |= PCRE_DOLLAR_ENDONLY; break;        case 'E': options |= PCRE_DOLLAR_ENDONLY; break;
471          case 'G': do_G = 1; break;
472        case 'I': do_showinfo = 1; break;        case 'I': do_showinfo = 1; break;
473        case 'M': log_store = 1; break;        case 'M': log_store = 1; break;
474    
475    #if !defined NOPOSIX
476        case 'P': do_posix = 1; break;        case 'P': do_posix = 1; break;
477    #endif
478    
479        case 'S': do_study = 1; break;        case 'S': do_study = 1; break;
480        case 'U': options |= PCRE_UNGREEDY; break;        case 'U': options |= PCRE_UNGREEDY; break;
481        case 'X': options |= PCRE_EXTRA; break;        case 'X': options |= PCRE_EXTRA; break;
# Line 483  while (!done) Line 504  while (!done)
504    timing, showing, or debugging options, nor the ability to pass over    timing, showing, or debugging options, nor the ability to pass over
505    local character tables. */    local character tables. */
506    
507    #if !defined NOPOSIX
508    if (posix || do_posix)    if (posix || do_posix)
509      {      {
510      int rc;      int rc;
# Line 505  while (!done) Line 527  while (!done)
527    /* Handle compiling via the native interface */    /* Handle compiling via the native interface */
528    
529    else    else
530    #endif  /* !defined NOPOSIX */
531    
532      {      {
533      if (timeit)      if (timeit)
534        {        {
# Line 555  while (!done) Line 579  while (!done)
579        {        {
580        int first_char, count;        int first_char, count;
581    
582        if (do_debug) print_internals(re, outfile);        if (do_debug) print_internals(re);
583    
584        count = pcre_info(re, &options, &first_char);        count = pcre_info(re, &options, &first_char);
585        if (count < 0) fprintf(outfile,        if (count < 0) fprintf(outfile,
# Line 573  while (!done) Line 597  while (!done)
597              ((options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",              ((options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
598              ((options & PCRE_EXTRA) != 0)? " extra" : "",              ((options & PCRE_EXTRA) != 0)? " extra" : "",
599              ((options & PCRE_UNGREEDY) != 0)? " ungreedy" : "");              ((options & PCRE_UNGREEDY) != 0)? " ungreedy" : "");
600    
601            if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0)
602              fprintf(outfile, "Case state changes\n");
603    
604          if (first_char == -1)          if (first_char == -1)
605            {            {
606            fprintf(outfile, "First char at start or follows \\n\n");            fprintf(outfile, "First char at start or follows \\n\n");
# Line 588  while (!done) Line 616  while (!done)
616            else            else
617              fprintf(outfile, "First char = %d\n", first_char);              fprintf(outfile, "First char = %d\n", first_char);
618            }            }
619    
620            if (((((real_pcre *)re)->options) & PCRE_REQCHSET) != 0)
621              {
622              int req_char = ((real_pcre *)re)->req_char;
623              if (isprint(req_char))
624                fprintf(outfile, "Req char = \'%c\'\n", req_char);
625              else
626                fprintf(outfile, "Req char = %d\n", req_char);
627              }
628            else fprintf(outfile, "No req char\n");
629          }          }
630        }        }
631    
# Line 661  while (!done) Line 699  while (!done)
699    for (;;)    for (;;)
700      {      {
701      unsigned char *q;      unsigned char *q;
702        unsigned char *bptr = dbuffer;
703      int count, c;      int count, c;
704      int copystrings = 0;      int copystrings = 0;
705      int getstrings = 0;      int getstrings = 0;
706      int getlist = 0;      int getlist = 0;
707        int gmatched = 0;
708        int start_offset = 0;
709        int g_notempty = 0;
710      int offsets[45];      int offsets[45];
711      int size_offsets = sizeof(offsets)/sizeof(int);      int size_offsets = sizeof(offsets)/sizeof(int);
712    
713      options = 0;      options = 0;
714    
715      if (infile == stdin) printf("  data> ");      if (infile == stdin) printf("data> ");
716      if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)      if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)
717        {        {
718        done = 1;        done = 1;
# Line 744  while (!done) Line 786  while (!done)
786          getlist = 1;          getlist = 1;
787          continue;          continue;
788    
789            case 'N':
790            options |= PCRE_NOTEMPTY;
791            continue;
792    
793          case 'O':          case 'O':
794          while(isdigit(*p)) n = n * 10 + *p++ - '0';          while(isdigit(*p)) n = n * 10 + *p++ - '0';
795          if (n <= (int)(sizeof(offsets)/sizeof(int))) size_offsets = n;          if (n <= (int)(sizeof(offsets)/sizeof(int))) size_offsets = n;
# Line 761  while (!done) Line 807  while (!done)
807      /* Handle matching via the POSIX interface, which does not      /* Handle matching via the POSIX interface, which does not
808      support timing. */      support timing. */
809    
810    #if !defined NOPOSIX
811      if (posix || do_posix)      if (posix || do_posix)
812        {        {
813        int rc;        int rc;
814        int eflags = 0;        int eflags = 0;
815        regmatch_t pmatch[30];        regmatch_t pmatch[sizeof(offsets)/sizeof(int)];
816        if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;        if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;
817        if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;        if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;
818    
819        rc = regexec(&preg, (char *)dbuffer, sizeof(pmatch)/sizeof(regmatch_t),        rc = regexec(&preg, (const char *)bptr, size_offsets, pmatch, eflags);
         pmatch, eflags);  
820    
821        if (rc != 0)        if (rc != 0)
822          {          {
# Line 780  while (!done) Line 826  while (!done)
826        else        else
827          {          {
828          size_t i;          size_t i;
829          for (i = 0; i < sizeof(pmatch)/sizeof(regmatch_t); i++)          for (i = 0; i < size_offsets; i++)
830            {            {
831            if (pmatch[i].rm_so >= 0)            if (pmatch[i].rm_so >= 0)
832              {              {
# Line 788  while (!done) Line 834  while (!done)
834              pchars(dbuffer + pmatch[i].rm_so,              pchars(dbuffer + pmatch[i].rm_so,
835                pmatch[i].rm_eo - pmatch[i].rm_so);                pmatch[i].rm_eo - pmatch[i].rm_so);
836              fprintf(outfile, "\n");              fprintf(outfile, "\n");
837                if (i == 0 && do_showrest)
838                  {
839                  fprintf(outfile, " 0+ ");
840                  pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo);
841                  fprintf(outfile, "\n");
842                  }
843              }              }
844            }            }
845          }          }
846        }        }
847    
848      /* Handle matching via the native interface */      /* Handle matching via the native interface - repeats for /g and /G */
849    
850      else      else
851    #endif  /* !defined NOPOSIX */
852    
853        for (;; gmatched++)    /* Loop for /g or /G */
854        {        {
855        if (timeit)        if (timeit)
856          {          {
# Line 803  while (!done) Line 858  while (!done)
858          clock_t time_taken;          clock_t time_taken;
859          clock_t start_time = clock();          clock_t start_time = clock();
860          for (i = 0; i < LOOPREPEAT; i++)          for (i = 0; i < LOOPREPEAT; i++)
861            count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets,            count = pcre_exec(re, extra, (char *)bptr, len,
862              size_offsets);              start_offset, options | g_notempty, offsets, size_offsets);
863          time_taken = clock() - start_time;          time_taken = clock() - start_time;
864          fprintf(outfile, "Execute time %.3f milliseconds\n",          fprintf(outfile, "Execute time %.3f milliseconds\n",
865            ((double)time_taken * 1000.0)/            ((double)time_taken * 1000.0)/
866            ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));            ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
867          }          }
868    
869        count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets,        count = pcre_exec(re, extra, (char *)bptr, len,
870          size_offsets);          start_offset, options | g_notempty, offsets, size_offsets);
871    
872        if (count == 0)        if (count == 0)
873          {          {
# Line 820  while (!done) Line 875  while (!done)
875          count = size_offsets/3;          count = size_offsets/3;
876          }          }
877    
878          /* Matched */
879    
880        if (count >= 0)        if (count >= 0)
881          {          {
882          int i;          int i;
# Line 830  while (!done) Line 887  while (!done)
887            else            else
888              {              {
889              fprintf(outfile, "%2d: ", i/2);              fprintf(outfile, "%2d: ", i/2);
890              pchars(dbuffer + offsets[i], offsets[i+1] - offsets[i]);              pchars(bptr + offsets[i], offsets[i+1] - offsets[i]);
891              fprintf(outfile, "\n");              fprintf(outfile, "\n");
892                if (i == 0)
893                  {
894                  if (do_showrest)
895                    {
896                    fprintf(outfile, " 0+ ");
897                    pchars(bptr + offsets[i+1], len - offsets[i+1]);
898                    fprintf(outfile, "\n");
899                    }
900                  }
901              }              }
902            }            }
903    
# Line 839  while (!done) Line 905  while (!done)
905            {            {
906            if ((copystrings & (1 << i)) != 0)            if ((copystrings & (1 << i)) != 0)
907              {              {
908              char buffer[16];              char copybuffer[16];
909              int rc = pcre_copy_substring((char *)dbuffer, offsets, count,              int rc = pcre_copy_substring((char *)bptr, offsets, count,
910                i, buffer, sizeof(buffer));                i, copybuffer, sizeof(copybuffer));
911              if (rc < 0)              if (rc < 0)
912                fprintf(outfile, "copy substring %d failed %d\n", i, rc);                fprintf(outfile, "copy substring %d failed %d\n", i, rc);
913              else              else
914                fprintf(outfile, "%2dC %s (%d)\n", i, buffer, rc);                fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc);
915              }              }
916            }            }
917    
# Line 854  while (!done) Line 920  while (!done)
920            if ((getstrings & (1 << i)) != 0)            if ((getstrings & (1 << i)) != 0)
921              {              {
922              const char *substring;              const char *substring;
923              int rc = pcre_get_substring((char *)dbuffer, offsets, count,              int rc = pcre_get_substring((char *)bptr, offsets, count,
924                i, &substring);                i, &substring);
925              if (rc < 0)              if (rc < 0)
926                fprintf(outfile, "get substring %d failed %d\n", i, rc);                fprintf(outfile, "get substring %d failed %d\n", i, rc);
# Line 869  while (!done) Line 935  while (!done)
935          if (getlist)          if (getlist)
936            {            {
937            const char **stringlist;            const char **stringlist;
938            int rc = pcre_get_substring_list((char *)dbuffer, offsets, count,            int rc = pcre_get_substring_list((char *)bptr, offsets, count,
939              &stringlist);              &stringlist);
940            if (rc < 0)            if (rc < 0)
941              fprintf(outfile, "get substring list failed %d\n", rc);              fprintf(outfile, "get substring list failed %d\n", rc);
# Line 882  while (!done) Line 948  while (!done)
948              free((void *)stringlist);              free((void *)stringlist);
949              }              }
950            }            }
951            }
952    
953          /* Failed to match. If this is a /g or /G loop and we previously set
954          PCRE_NOTEMPTY after a null match, this is not necessarily the end.
955          We want to advance the start offset, and continue. Fudge the offset
956          values to achieve this. We won't be at the end of the string - that
957          was checked before setting PCRE_NOTEMPTY. */
958    
959          else
960            {
961            if (g_notempty != 0)
962              {
963              offsets[0] = start_offset;
964              offsets[1] = start_offset + 1;
965              }
966            else
967              {
968              if (gmatched == 0)   /* Error if no previous matches */
969                {
970                if (count == -1) fprintf(outfile, "No match\n");
971                  else fprintf(outfile, "Error %d\n", count);
972                }
973              break;  /* Out of the /g loop */
974              }
975            }
976    
977          /* If not /g or /G we are done */
978    
979          if (!do_g && !do_G) break;
980    
981          /* If we have matched an empty string, first check to see if we are at
982          the end of the subject. If so, the /g loop is over. Otherwise, mimic
983          what Perl's /g options does. This turns out to be rather cunning. First
984          we set PCRE_NOTEMPTY and try the match again at the same point. If this
985          fails (picked up above) we advance to the next character. */
986    
987          g_notempty = 0;
988          if (offsets[0] == offsets[1])
989            {
990            if (offsets[0] == len) break;
991            g_notempty = PCRE_NOTEMPTY;
992          }          }
993    
994          /* For /g, update the start offset, leaving the rest alone */
995    
996          if (do_g) start_offset = offsets[1];
997    
998          /* For /G, update the pointer and length */
999    
1000        else        else
1001          {          {
1002          if (count == -1) fprintf(outfile, "No match\n");          bptr += offsets[1];
1003            else fprintf(outfile, "Error %d\n", count);          len -= offsets[1];
1004          }          }
1005        }        }  /* End of loop for /g and /G */
1006      }      }    /* End of loop for data lines */
1007    
1008    CONTINUE:    CONTINUE:
1009    
1010    #if !defined NOPOSIX
1011    if (posix || do_posix) regfree(&preg);    if (posix || do_posix) regfree(&preg);
1012    #endif
1013    
1014    if (re != NULL) free(re);    if (re != NULL) free(re);
1015    if (extra != NULL) free(extra);    if (extra != NULL) free(extra);
1016    if (tables != NULL)    if (tables != NULL)

Legend:
Removed from v.31  
changed lines
  Added in v.41

  ViewVC Help
Powered by ViewVC 1.1.5