/[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 79 by nigel, Sat Feb 24 21:40:52 2007 UTC revision 91 by nigel, Sat Feb 24 21:41:34 2007 UTC
# Line 44  POSSIBILITY OF SUCH DAMAGE. Line 44  POSSIBILITY OF SUCH DAMAGE.
44  #include <locale.h>  #include <locale.h>
45  #include <errno.h>  #include <errno.h>
46    
47    #ifndef _WIN32
48    #include <sys/resource.h>
49    #endif
50    
51  #define PCRE_SPY        /* For Win32 build, import data, not export */  #define PCRE_SPY        /* For Win32 build, import data, not export */
52    
53  /* We need the internal info for displaying the results of pcre_study() and  /* We include pcre_internal.h because we need the internal info for displaying
54  other internal data; pcretest also uses some of the fixed tables, and generally  the results of pcre_study() and we also need to know about the internal
55  has "inside information" compared to a program that strictly follows the PCRE  macros, structures, and other internal data values; pcretest has "inside
56  API. */  information" compared to a program that strictly follows the PCRE API. */
57    
58  #include "pcre_internal.h"  #include "pcre_internal.h"
59    
60    /* We need access to the data tables that PCRE uses. So as not to have to keep
61    two copies, we include the source file here, changing the names of the external
62    symbols to prevent clashes. */
63    
64    #define _pcre_utf8_table1      utf8_table1
65    #define _pcre_utf8_table1_size utf8_table1_size
66    #define _pcre_utf8_table2      utf8_table2
67    #define _pcre_utf8_table3      utf8_table3
68    #define _pcre_utf8_table4      utf8_table4
69    #define _pcre_utt              utt
70    #define _pcre_utt_size         utt_size
71    #define _pcre_OP_lengths       OP_lengths
72    
73    #include "pcre_tables.c"
74    
75    /* We also need the pcre_printint() function for printing out compiled
76    patterns. This function is in a separate file so that it can be included in
77    pcre_compile.c when that module is compiled with debugging enabled. */
78    
79    #include "pcre_printint.src"
80    
81    
82  /* It is possible to compile this test program without including support for  /* It is possible to compile this test program without including support for
83  testing the POSIX interface, though this is not available via the standard  testing the POSIX interface, though this is not available via the standard
# Line 68  to the DFA matcher (NODFA), and without Line 93  to the DFA matcher (NODFA), and without
93  function (define NOINFOCHECK). */  function (define NOINFOCHECK). */
94    
95    
96    /* Other parameters */
97    
98  #ifndef CLOCKS_PER_SEC  #ifndef CLOCKS_PER_SEC
99  #ifdef CLK_TCK  #ifdef CLK_TCK
100  #define CLOCKS_PER_SEC CLK_TCK  #define CLOCKS_PER_SEC CLK_TCK
# Line 78  function (define NOINFOCHECK). */ Line 105  function (define NOINFOCHECK). */
105    
106  #define LOOPREPEAT 500000  #define LOOPREPEAT 500000
107    
108  #define BUFFER_SIZE 30000  /* Static variables */
 #define PBUFFER_SIZE BUFFER_SIZE  
 #define DBUFFER_SIZE BUFFER_SIZE  
   
109    
110  static FILE *outfile;  static FILE *outfile;
111  static int log_store = 0;  static int log_store = 0;
# Line 94  static int show_malloc; Line 118  static int show_malloc;
118  static int use_utf8;  static int use_utf8;
119  static size_t gotten_store;  static size_t gotten_store;
120    
121    /* The buffers grow automatically if very long input lines are encountered. */
122    
123    static int buffer_size = 50000;
124    static uschar *buffer = NULL;
125    static uschar *dbuffer = NULL;
126  static uschar *pbuffer = NULL;  static uschar *pbuffer = NULL;
127    
128    
129    
130  /*************************************************  /*************************************************
131    *        Read or extend an input line            *
132    *************************************************/
133    
134    /* Input lines are read into buffer, but both patterns and data lines can be
135    continued over multiple input lines. In addition, if the buffer fills up, we
136    want to automatically expand it so as to be able to handle extremely large
137    lines that are needed for certain stress tests. When the input buffer is
138    expanded, the other two buffers must also be expanded likewise, and the
139    contents of pbuffer, which are a copy of the input for callouts, must be
140    preserved (for when expansion happens for a data line). This is not the most
141    optimal way of handling this, but hey, this is just a test program!
142    
143    Arguments:
144      f            the file to read
145      start        where in buffer to start (this *must* be within buffer)
146    
147    Returns:       pointer to the start of new data
148                   could be a copy of start, or could be moved
149                   NULL if no data read and EOF reached
150    */
151    
152    static uschar *
153    extend_inputline(FILE *f, uschar *start)
154    {
155    uschar *here = start;
156    
157    for (;;)
158      {
159      int rlen = buffer_size - (here - buffer);
160      if (rlen > 1000)
161        {
162        int dlen;
163        if (fgets((char *)here, rlen,  f) == NULL)
164          return (here == start)? NULL : start;
165        dlen = (int)strlen((char *)here);
166        if (dlen > 0 && here[dlen - 1] == '\n') return start;
167        here += dlen;
168        }
169    
170      else
171        {
172        int new_buffer_size = 2*buffer_size;
173        uschar *new_buffer = (unsigned char *)malloc(new_buffer_size);
174        uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size);
175        uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size);
176    
177        if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)
178          {
179          fprintf(stderr, "pcretest: malloc(%d) failed\n", new_buffer_size);
180          exit(1);
181          }
182    
183        memcpy(new_buffer, buffer, buffer_size);
184        memcpy(new_pbuffer, pbuffer, buffer_size);
185    
186        buffer_size = new_buffer_size;
187    
188        start = new_buffer + (start - buffer);
189        here = new_buffer + (here - buffer);
190    
191        free(buffer);
192        free(dbuffer);
193        free(pbuffer);
194    
195        buffer = new_buffer;
196        dbuffer = new_dbuffer;
197        pbuffer = new_pbuffer;
198        }
199      }
200    
201    return NULL;  /* Control never gets here */
202    }
203    
204    
205    
206    
207    
208    
209    
210    /*************************************************
211  *          Read number from string               *  *          Read number from string               *
212  *************************************************/  *************************************************/
213    
# Line 134  return(result); Line 243  return(result);
243  and returns the value of the character.  and returns the value of the character.
244    
245  Argument:  Argument:
246    buffer   a pointer to the byte vector    utf8bytes   a pointer to the byte vector
247    vptr     a pointer to an int to receive the value    vptr        a pointer to an int to receive the value
248    
249  Returns:   >  0 => the number of bytes consumed  Returns:      >  0 => the number of bytes consumed
250             -6 to 0 => malformed UTF-8 character at offset = (-return)                -6 to 0 => malformed UTF-8 character at offset = (-return)
251  */  */
252    
253  #if !defined NOUTF8  #if !defined NOUTF8
254    
255  static int  static int
256  utf82ord(unsigned char *buffer, int *vptr)  utf82ord(unsigned char *utf8bytes, int *vptr)
257  {  {
258  int c = *buffer++;  int c = *utf8bytes++;
259  int d = c;  int d = c;
260  int i, j, s;  int i, j, s;
261    
# Line 162  if (i == 0 || i == 6) return 0;        / Line 271  if (i == 0 || i == 6) return 0;        /
271  /* i now has a value in the range 1-5 */  /* i now has a value in the range 1-5 */
272    
273  s = 6*i;  s = 6*i;
274  d = (c & _pcre_utf8_table3[i]) << s;  d = (c & utf8_table3[i]) << s;
275    
276  for (j = 0; j < i; j++)  for (j = 0; j < i; j++)
277    {    {
278    c = *buffer++;    c = *utf8bytes++;
279    if ((c & 0xc0) != 0x80) return -(j+1);    if ((c & 0xc0) != 0x80) return -(j+1);
280    s -= 6;    s -= 6;
281    d |= (c & 0x3f) << s;    d |= (c & 0x3f) << s;
# Line 174  for (j = 0; j < i; j++) Line 283  for (j = 0; j < i; j++)
283    
284  /* Check that encoding was the correct unique one */  /* Check that encoding was the correct unique one */
285    
286  for (j = 0; j < _pcre_utf8_table1_size; j++)  for (j = 0; j < utf8_table1_size; j++)
287    if (d <= _pcre_utf8_table1[j]) break;    if (d <= utf8_table1[j]) break;
288  if (j != i) return -(i+1);  if (j != i) return -(i+1);
289    
290  /* Valid value */  /* Valid value */
# Line 189  return i+1; Line 298  return i+1;
298    
299    
300  /*************************************************  /*************************************************
301    *       Convert character value to UTF-8         *
302    *************************************************/
303    
304    /* This function takes an integer value in the range 0 - 0x7fffffff
305    and encodes it as a UTF-8 character in 0 to 6 bytes.
306    
307    Arguments:
308      cvalue     the character value
309      utf8bytes  pointer to buffer for result - at least 6 bytes long
310    
311    Returns:     number of characters placed in the buffer
312    */
313    
314    static int
315    ord2utf8(int cvalue, uschar *utf8bytes)
316    {
317    register int i, j;
318    for (i = 0; i < utf8_table1_size; i++)
319      if (cvalue <= utf8_table1[i]) break;
320    utf8bytes += i;
321    for (j = i; j > 0; j--)
322     {
323     *utf8bytes-- = 0x80 | (cvalue & 0x3f);
324     cvalue >>= 6;
325     }
326    *utf8bytes = utf8_table2[i] | cvalue;
327    return i + 1;
328    }
329    
330    
331    
332    /*************************************************
333  *             Print character string             *  *             Print character string             *
334  *************************************************/  *************************************************/
335    
# Line 198  chars without printing. */ Line 339  chars without printing. */
339    
340  static int pchars(unsigned char *p, int length, FILE *f)  static int pchars(unsigned char *p, int length, FILE *f)
341  {  {
342  int c;  int c = 0;
343  int yield = 0;  int yield = 0;
344    
345  while (length-- > 0)  while (length-- > 0)
# Line 404  if ((rc = pcre_fullinfo(re, study, optio Line 545  if ((rc = pcre_fullinfo(re, study, optio
545  *         Byte flipping function                 *  *         Byte flipping function                 *
546  *************************************************/  *************************************************/
547    
548  static long int  static unsigned long int
549  byteflip(long int value, int n)  byteflip(unsigned long int value, int n)
550  {  {
551  if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);  if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
552  return ((value & 0x000000ff) << 24) |  return ((value & 0x000000ff) << 24) |
# Line 418  return ((value & 0x000000ff) << 24) | Line 559  return ((value & 0x000000ff) << 24) |
559    
560    
561  /*************************************************  /*************************************************
562    *        Check match or recursion limit          *
563    *************************************************/
564    
565    static int
566    check_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len,
567      int start_offset, int options, int *use_offsets, int use_size_offsets,
568      int flag, unsigned long int *limit, int errnumber, const char *msg)
569    {
570    int count;
571    int min = 0;
572    int mid = 64;
573    int max = -1;
574    
575    extra->flags |= flag;
576    
577    for (;;)
578      {
579      *limit = mid;
580    
581      count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options,
582        use_offsets, use_size_offsets);
583    
584      if (count == errnumber)
585        {
586        /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */
587        min = mid;
588        mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2;
589        }
590    
591      else if (count >= 0 || count == PCRE_ERROR_NOMATCH ||
592                             count == PCRE_ERROR_PARTIAL)
593        {
594        if (mid == min + 1)
595          {
596          fprintf(outfile, "Minimum %s limit = %d\n", msg, mid);
597          break;
598          }
599        /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */
600        max = mid;
601        mid = (min + mid)/2;
602        }
603      else break;    /* Some other error */
604      }
605    
606    extra->flags &= ~flag;
607    return count;
608    }
609    
610    
611    
612    /*************************************************
613    *         Check newline indicator                *
614    *************************************************/
615    
616    /* This is used both at compile and run-time to check for <xxx> escapes, where
617    xxx is LF, CR, or CRLF. Print a message and return 0 if there is no match.
618    
619    Arguments:
620      p           points after the leading '<'
621      f           file for error message
622    
623    Returns:      appropriate PCRE_NEWLINE_xxx flags, or 0
624    */
625    
626    static int
627    check_newline(uschar *p, FILE *f)
628    {
629    if (strncmp((char *)p, "cr>", 3) == 0) return PCRE_NEWLINE_CR;
630    if (strncmp((char *)p, "lf>", 3) == 0) return PCRE_NEWLINE_LF;
631    if (strncmp((char *)p, "crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
632    fprintf(f, "Unknown newline type at: <%s\n", p);
633    return 0;
634    }
635    
636    
637    
638    /*************************************************
639  *                Main Program                    *  *                Main Program                    *
640  *************************************************/  *************************************************/
641    
# Line 434  int op = 1; Line 652  int op = 1;
652  int timeit = 0;  int timeit = 0;
653  int showinfo = 0;  int showinfo = 0;
654  int showstore = 0;  int showstore = 0;
655    int quiet = 0;
656  int size_offsets = 45;  int size_offsets = 45;
657  int size_offsets_max;  int size_offsets_max;
658  int *offsets = NULL;  int *offsets = NULL;
# Line 444  int debug = 0; Line 663  int debug = 0;
663  int done = 0;  int done = 0;
664  int all_use_dfa = 0;  int all_use_dfa = 0;
665  int yield = 0;  int yield = 0;
666    int stack_size;
667    
668    /* These vectors store, end-to-end, a list of captured substring names. Assume
669    that 1024 is plenty long enough for the few names we'll be testing. */
670    
671  unsigned char *buffer;  uschar copynames[1024];
672  unsigned char *dbuffer;  uschar getnames[1024];
673    
674    uschar *copynamesptr;
675    uschar *getnamesptr;
676    
677  /* Get buffers from malloc() so that Electric Fence will check their misuse  /* Get buffers from malloc() so that Electric Fence will check their misuse
678  when I am debugging. */  when I am debugging. They grow automatically when very long lines are read. */
679    
680  buffer = (unsigned char *)malloc(BUFFER_SIZE);  buffer = (unsigned char *)malloc(buffer_size);
681  dbuffer = (unsigned char *)malloc(DBUFFER_SIZE);  dbuffer = (unsigned char *)malloc(buffer_size);
682  pbuffer = (unsigned char *)malloc(PBUFFER_SIZE);  pbuffer = (unsigned char *)malloc(buffer_size);
683    
684  /* The outfile variable is static so that new_malloc can use it. The _setmode()  /* The outfile variable is static so that new_malloc can use it. The _setmode()
685  stuff is some magic that I don't understand, but which apparently does good  stuff is some magic that I don't understand, but which apparently does good
# Line 474  while (argc > 1 && argv[op][0] == '-') Line 700  while (argc > 1 && argv[op][0] == '-')
700    if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0)    if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0)
701      showstore = 1;      showstore = 1;
702    else if (strcmp(argv[op], "-t") == 0) timeit = 1;    else if (strcmp(argv[op], "-t") == 0) timeit = 1;
703      else if (strcmp(argv[op], "-q") == 0) quiet = 1;
704    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
705    else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;    else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;
706  #if !defined NODFA  #if !defined NODFA
# Line 486  while (argc > 1 && argv[op][0] == '-') Line 713  while (argc > 1 && argv[op][0] == '-')
713      op++;      op++;
714      argc--;      argc--;
715      }      }
716      else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&
717          ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)),
718            *endptr == 0))
719        {
720    #ifdef _WIN32
721        printf("PCRE: -S not supported on this OS\n");
722        exit(1);
723    #else
724        int rc;
725        struct rlimit rlim;
726        getrlimit(RLIMIT_STACK, &rlim);
727        rlim.rlim_cur = stack_size * 1024 * 1024;
728        rc = setrlimit(RLIMIT_STACK, &rlim);
729        if (rc != 0)
730          {
731        printf("PCRE: setrlimit() failed with error %d\n", rc);
732        exit(1);
733          }
734        op++;
735        argc--;
736    #endif
737        }
738  #if !defined NOPOSIX  #if !defined NOPOSIX
739    else if (strcmp(argv[op], "-p") == 0) posix = 1;    else if (strcmp(argv[op], "-p") == 0) posix = 1;
740  #endif  #endif
# Line 499  while (argc > 1 && argv[op][0] == '-') Line 748  while (argc > 1 && argv[op][0] == '-')
748      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
749      printf("  %sUnicode properties support\n", rc? "" : "No ");      printf("  %sUnicode properties support\n", rc? "" : "No ");
750      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
751      printf("  Newline character is %s\n", (rc == '\r')? "CR" : "LF");      printf("  Newline sequence is %s\n", (rc == '\r')? "CR" :
752          (rc == '\n')? "LF" : "CRLF");
753      (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);      (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);
754      printf("  Internal link size = %d\n", rc);      printf("  Internal link size = %d\n", rc);
755      (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);      (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);
756      printf("  POSIX malloc threshold = %d\n", rc);      printf("  POSIX malloc threshold = %d\n", rc);
757      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc);      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc);
758      printf("  Default match limit = %d\n", rc);      printf("  Default match limit = %d\n", rc);
759        (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &rc);
760        printf("  Default recursion depth limit = %d\n", rc);
761      (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc);      (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc);
762      printf("  Match recursion uses %s\n", rc? "stack" : "heap");      printf("  Match recursion uses %s\n", rc? "stack" : "heap");
763      exit(0);      exit(0);
# Line 513  while (argc > 1 && argv[op][0] == '-') Line 765  while (argc > 1 && argv[op][0] == '-')
765    else    else
766      {      {
767      printf("** Unknown or malformed option %s\n", argv[op]);      printf("** Unknown or malformed option %s\n", argv[op]);
768      printf("Usage:   pcretest [-d] [-i] [-o <n>] [-p] [-s] [-t] [<input> [<output>]]\n");      printf("Usage:   pcretest [options] [<input> [<output>]]\n");
769      printf("  -C     show PCRE compile-time options and exit\n");      printf("  -C     show PCRE compile-time options and exit\n");
770      printf("  -d     debug: show compiled code; implies -i\n");      printf("  -d     debug: show compiled code; implies -i\n");
771  #if !defined NODFA  #if !defined NODFA
# Line 525  while (argc > 1 && argv[op][0] == '-') Line 777  while (argc > 1 && argv[op][0] == '-')
777  #if !defined NOPOSIX  #if !defined NOPOSIX
778      printf("  -p     use POSIX interface\n");      printf("  -p     use POSIX interface\n");
779  #endif  #endif
780        printf("  -S <n> set stack size to <n> megabytes\n");
781      printf("  -s     output store (memory) used information\n"      printf("  -s     output store (memory) used information\n"
782             "  -t     time compilation and execution\n");             "  -t     time compilation and execution\n");
783      yield = 1;      yield = 1;
# Line 577  pcre_free = new_free; Line 830  pcre_free = new_free;
830  pcre_stack_malloc = stack_malloc;  pcre_stack_malloc = stack_malloc;
831  pcre_stack_free = stack_free;  pcre_stack_free = stack_free;
832    
833  /* Heading line, then prompt for first regex if stdin */  /* Heading line unless quiet, then prompt for first regex if stdin */
834    
835  fprintf(outfile, "PCRE version %s\n\n", pcre_version());  if (!quiet) fprintf(outfile, "PCRE version %s\n\n", pcre_version());
836    
837  /* Main loop */  /* Main loop */
838    
# Line 611  while (!done) Line 864  while (!done)
864    use_utf8 = 0;    use_utf8 = 0;
865    
866    if (infile == stdin) printf("  re> ");    if (infile == stdin) printf("  re> ");
867    if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) break;    if (extend_inputline(infile, buffer) == NULL) break;
868    if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);    if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
869    fflush(outfile);    fflush(outfile);
870    
# Line 623  while (!done) Line 876  while (!done)
876    
877    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)
878      {      {
879      unsigned long int magic;      unsigned long int magic, get_options;
880      uschar sbuf[8];      uschar sbuf[8];
881      FILE *f;      FILE *f;
882    
# Line 671  while (!done) Line 924  while (!done)
924    
925      /* Need to know if UTF-8 for printing data strings */      /* Need to know if UTF-8 for printing data strings */
926    
927      new_info(re, NULL, PCRE_INFO_OPTIONS, &options);      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
928      use_utf8 = (options & PCRE_UTF8) != 0;      use_utf8 = (get_options & PCRE_UTF8) != 0;
929    
930      /* Now see if there is any following study data */      /* Now see if there is any following study data */
931    
# Line 726  while (!done) Line 979  while (!done)
979        pp++;        pp++;
980        }        }
981      if (*pp != 0) break;      if (*pp != 0) break;
   
     len = BUFFER_SIZE - (pp - buffer);  
     if (len < 256)  
       {  
       fprintf(outfile, "** Expression too long - missing delimiter?\n");  
       goto SKIP_DATA;  
       }  
   
982      if (infile == stdin) printf("    > ");      if (infile == stdin) printf("    > ");
983      if (fgets((char *)pp, len, infile) == NULL)      if ((pp = extend_inputline(infile, pp)) == NULL)
984        {        {
985        fprintf(outfile, "** Unexpected EOF\n");        fprintf(outfile, "** Unexpected EOF\n");
986        done = 1;        done = 1;
# Line 781  while (!done) Line 1026  while (!done)
1026        case 'F': do_flip = 1; break;        case 'F': do_flip = 1; break;
1027        case 'G': do_G = 1; break;        case 'G': do_G = 1; break;
1028        case 'I': do_showinfo = 1; break;        case 'I': do_showinfo = 1; break;
1029          case 'J': options |= PCRE_DUPNAMES; break;
1030        case 'M': log_store = 1; break;        case 'M': log_store = 1; break;
1031        case 'N': options |= PCRE_NO_AUTO_CAPTURE; break;        case 'N': options |= PCRE_NO_AUTO_CAPTURE; break;
1032    
# Line 815  while (!done) Line 1061  while (!done)
1061        *pp = 0;        *pp = 0;
1062        break;        break;
1063    
1064          case '<':
1065            {
1066            int x = check_newline(pp, outfile);
1067            if (x == 0) goto SKIP_DATA;
1068            options |= x;
1069            while (*pp++ != '>');
1070            }
1071          break;
1072    
1073        case '\r':                      /* So that it works in Windows */        case '\r':                      /* So that it works in Windows */
1074        case '\n':        case '\n':
1075        case ' ':        case ' ':
# Line 839  while (!done) Line 1094  while (!done)
1094      if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE;      if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE;
1095      if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE;      if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE;
1096      if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL;      if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL;
1097        if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB;
1098        if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8;
1099    
1100      rc = regcomp(&preg, (char *)p, cflags);      rc = regcomp(&preg, (char *)p, cflags);
1101    
1102      /* Compilation failed; go back for another re, skipping to blank line      /* Compilation failed; go back for another re, skipping to blank line
# Line 846  while (!done) Line 1104  while (!done)
1104    
1105      if (rc != 0)      if (rc != 0)
1106        {        {
1107        (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE);        (void)regerror(rc, &preg, (char *)buffer, buffer_size);
1108        fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer);        fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer);
1109        goto SKIP_DATA;        goto SKIP_DATA;
1110        }        }
# Line 887  while (!done) Line 1145  while (!done)
1145          {          {
1146          for (;;)          for (;;)
1147            {            {
1148            if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL)            if (extend_inputline(infile, buffer) == NULL)
1149              {              {
1150              done = 1;              done = 1;
1151              goto CONTINUE;              goto CONTINUE;
# Line 988  while (!done) Line 1246  while (!done)
1246        if (do_debug)        if (do_debug)
1247          {          {
1248          fprintf(outfile, "------------------------------------------------------------------\n");          fprintf(outfile, "------------------------------------------------------------------\n");
1249          _pcre_printint(re, outfile);          pcre_printint(re, outfile);
1250          }          }
1251    
1252        new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);        new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
# Line 1048  while (!done) Line 1306  while (!done)
1306        if (do_flip)        if (do_flip)
1307          {          {
1308          all_options = byteflip(all_options, sizeof(all_options));          all_options = byteflip(all_options, sizeof(all_options));
1309          }           }
1310    
1311        if ((all_options & PCRE_NOPARTIAL) != 0)        if ((all_options & PCRE_NOPARTIAL) != 0)
1312          fprintf(outfile, "Partial matching not supported\n");          fprintf(outfile, "Partial matching not supported\n");
1313    
1314        if (get_options == 0) fprintf(outfile, "No options\n");        if (get_options == 0) fprintf(outfile, "No options\n");
1315          else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s\n",          else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
1316            ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",            ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",
1317            ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",            ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",
1318            ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",            ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",
# Line 1064  while (!done) Line 1322  while (!done)
1322            ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",            ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
1323            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",
1324            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
1325              ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",
1326            ((get_options & PCRE_UTF8) != 0)? " utf8" : "",            ((get_options & PCRE_UTF8) != 0)? " utf8" : "",
1327            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "");            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",
1328              ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");
1329    
1330          switch (get_options & PCRE_NEWLINE_CRLF)
1331            {
1332            case PCRE_NEWLINE_CR:
1333            fprintf(outfile, "Forced newline sequence: CR\n");
1334            break;
1335    
1336        if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0)          case PCRE_NEWLINE_LF:
1337          fprintf(outfile, "Case state changes\n");          fprintf(outfile, "Forced newline sequence: LF\n");
1338            break;
1339    
1340            case PCRE_NEWLINE_CRLF:
1341            fprintf(outfile, "Forced newline sequence: CRLF\n");
1342            break;
1343    
1344            default:
1345            break;
1346            }
1347    
1348        if (first_char == -1)        if (first_char == -1)
1349          {          {
1350          fprintf(outfile, "First char at start or follows \\n\n");          fprintf(outfile, "First char at start or follows newline\n");
1351          }          }
1352        else if (first_char < 0)        else if (first_char < 0)
1353          {          {
# Line 1209  while (!done) Line 1484  while (!done)
1484    
1485    for (;;)    for (;;)
1486      {      {
1487      unsigned char *q;      uschar *q;
1488      unsigned char *bptr = dbuffer;      uschar *bptr = dbuffer;
1489      int *use_offsets = offsets;      int *use_offsets = offsets;
1490      int use_size_offsets = size_offsets;      int use_size_offsets = size_offsets;
1491      int callout_data = 0;      int callout_data = 0;
# Line 1227  while (!done) Line 1502  while (!done)
1502    
1503      options = 0;      options = 0;
1504    
1505        *copynames = 0;
1506        *getnames = 0;
1507    
1508        copynamesptr = copynames;
1509        getnamesptr = getnames;
1510    
1511      pcre_callout = callout;      pcre_callout = callout;
1512      first_callout = 1;      first_callout = 1;
1513      callout_extra = 0;      callout_extra = 0;
# Line 1235  while (!done) Line 1516  while (!done)
1516      callout_fail_id = -1;      callout_fail_id = -1;
1517      show_malloc = 0;      show_malloc = 0;
1518    
1519      if (infile == stdin) printf("data> ");      if (extra != NULL) extra->flags &=
1520      if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL)        ~(PCRE_EXTRA_MATCH_LIMIT|PCRE_EXTRA_MATCH_LIMIT_RECURSION);
1521    
1522        len = 0;
1523        for (;;)
1524        {        {
1525        done = 1;        if (infile == stdin) printf("data> ");
1526        goto CONTINUE;        if (extend_inputline(infile, buffer + len) == NULL)
1527            {
1528            if (len > 0) break;
1529            done = 1;
1530            goto CONTINUE;
1531            }
1532          if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
1533          len = (int)strlen((char *)buffer);
1534          if (buffer[len-1] == '\n') break;
1535        }        }
     if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);  
1536    
     len = (int)strlen((char *)buffer);  
1537      while (len > 0 && isspace(buffer[len-1])) len--;      while (len > 0 && isspace(buffer[len-1])) len--;
1538      buffer[len] = 0;      buffer[len] = 0;
1539      if (len == 0) break;      if (len == 0) break;
# Line 1273  while (!done) Line 1563  while (!done)
1563          c -= '0';          c -= '0';
1564          while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')          while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
1565            c = c * 8 + *p++ - '0';            c = c * 8 + *p++ - '0';
1566    
1567    #if !defined NOUTF8
1568            if (use_utf8 && c > 255)
1569              {
1570              unsigned char buff8[8];
1571              int ii, utn;
1572              utn = ord2utf8(c, buff8);
1573              for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
1574              c = buff8[ii];   /* Last byte */
1575              }
1576    #endif
1577          break;          break;
1578    
1579          case 'x':          case 'x':
# Line 1290  while (!done) Line 1591  while (!done)
1591              {              {
1592              unsigned char buff8[8];              unsigned char buff8[8];
1593              int ii, utn;              int ii, utn;
1594              utn = _pcre_ord2utf8(c, buff8);              utn = ord2utf8(c, buff8);
1595              for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];              for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
1596              c = buff8[ii];   /* Last byte */              c = buff8[ii];   /* Last byte */
1597              p = pt + 1;              p = pt + 1;
# Line 1334  while (!done) Line 1635  while (!done)
1635            }            }
1636          else if (isalnum(*p))          else if (isalnum(*p))
1637            {            {
1638            uschar name[256];            uschar *npp = copynamesptr;
           uschar *npp = name;  
1639            while (isalnum(*p)) *npp++ = *p++;            while (isalnum(*p)) *npp++ = *p++;
1640              *npp++ = 0;
1641            *npp = 0;            *npp = 0;
1642            n = pcre_get_stringnumber(re, (char *)name);            n = pcre_get_stringnumber(re, (char *)copynamesptr);
1643            if (n < 0)            if (n < 0)
1644              fprintf(outfile, "no parentheses with name \"%s\"\n", name);              fprintf(outfile, "no parentheses with name \"%s\"\n", copynamesptr);
1645            else copystrings |= 1 << n;            copynamesptr = npp;
1646            }            }
1647          else if (*p == '+')          else if (*p == '+')
1648            {            {
# Line 1402  while (!done) Line 1703  while (!done)
1703            }            }
1704          else if (isalnum(*p))          else if (isalnum(*p))
1705            {            {
1706            uschar name[256];            uschar *npp = getnamesptr;
           uschar *npp = name;  
1707            while (isalnum(*p)) *npp++ = *p++;            while (isalnum(*p)) *npp++ = *p++;
1708              *npp++ = 0;
1709            *npp = 0;            *npp = 0;
1710            n = pcre_get_stringnumber(re, (char *)name);            n = pcre_get_stringnumber(re, (char *)getnamesptr);
1711            if (n < 0)            if (n < 0)
1712              fprintf(outfile, "no parentheses with name \"%s\"\n", name);              fprintf(outfile, "no parentheses with name \"%s\"\n", getnamesptr);
1713            else getstrings |= 1 << n;            getnamesptr = npp;
1714            }            }
1715          continue;          continue;
1716    
# Line 1448  while (!done) Line 1749  while (!done)
1749          options |= PCRE_PARTIAL;          options |= PCRE_PARTIAL;
1750          continue;          continue;
1751    
1752            case 'Q':
1753            while(isdigit(*p)) n = n * 10 + *p++ - '0';
1754            if (extra == NULL)
1755              {
1756              extra = (pcre_extra *)malloc(sizeof(pcre_extra));
1757              extra->flags = 0;
1758              }
1759            extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
1760            extra->match_limit_recursion = n;
1761            continue;
1762    
1763            case 'q':
1764            while(isdigit(*p)) n = n * 10 + *p++ - '0';
1765            if (extra == NULL)
1766              {
1767              extra = (pcre_extra *)malloc(sizeof(pcre_extra));
1768              extra->flags = 0;
1769              }
1770            extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
1771            extra->match_limit = n;
1772            continue;
1773    
1774  #if !defined NODFA  #if !defined NODFA
1775          case 'R':          case 'R':
1776          options |= PCRE_DFA_RESTART;          options |= PCRE_DFA_RESTART;
# Line 1465  while (!done) Line 1788  while (!done)
1788          case '?':          case '?':
1789          options |= PCRE_NO_UTF8_CHECK;          options |= PCRE_NO_UTF8_CHECK;
1790          continue;          continue;
1791    
1792            case '<':
1793              {
1794              int x = check_newline(p, outfile);
1795              if (x == 0) goto NEXT_DATA;
1796              options |= x;
1797              while (*p++ != '>');
1798              }
1799            continue;
1800          }          }
1801        *q++ = c;        *q++ = c;
1802        }        }
# Line 1495  while (!done) Line 1827  while (!done)
1827    
1828        if (rc != 0)        if (rc != 0)
1829          {          {
1830          (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE);          (void)regerror(rc, &preg, (char *)buffer, buffer_size);
1831          fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer);          fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer);
1832          }          }
1833          else if ((((const pcre *)preg.re_pcre)->options & PCRE_NO_AUTO_CAPTURE)
1834                  != 0)
1835            {
1836            fprintf(outfile, "Matched with REG_NOSUB\n");
1837            }
1838        else        else
1839          {          {
1840          size_t i;          size_t i;
# Line 1558  while (!done) Line 1895  while (!done)
1895          }          }
1896    
1897        /* If find_match_limit is set, we want to do repeated matches with        /* If find_match_limit is set, we want to do repeated matches with
1898        varying limits in order to find the minimum value. */        varying limits in order to find the minimum value for the match limit and
1899          for the recursion limit. */
1900    
1901        if (find_match_limit)        if (find_match_limit)
1902          {          {
         int min = 0;  
         int mid = 64;  
         int max = -1;  
   
1903          if (extra == NULL)          if (extra == NULL)
1904            {            {
1905            extra = (pcre_extra *)malloc(sizeof(pcre_extra));            extra = (pcre_extra *)malloc(sizeof(pcre_extra));
1906            extra->flags = 0;            extra->flags = 0;
1907            }            }
         extra->flags |= PCRE_EXTRA_MATCH_LIMIT;  
   
         for (;;)  
           {  
           extra->match_limit = mid;  
           count = pcre_exec(re, extra, (char *)bptr, len, start_offset,  
             options | g_notempty, use_offsets, use_size_offsets);  
           if (count == PCRE_ERROR_MATCHLIMIT)  
             {  
             /* fprintf(outfile, "Testing match limit = %d\n", 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 match limit = %d\n", mid);  
               break;  
               }  
             /* fprintf(outfile, "Testing match limit = %d\n", mid); */  
             max = mid;  
             mid = (min + mid)/2;  
             }  
           else break;    /* Some other error */  
           }  
1908    
1909          extra->flags &= ~PCRE_EXTRA_MATCH_LIMIT;          (void)check_match_limit(re, extra, bptr, len, start_offset,
1910              options|g_notempty, use_offsets, use_size_offsets,
1911              PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit),
1912              PCRE_ERROR_MATCHLIMIT, "match()");
1913    
1914            count = check_match_limit(re, extra, bptr, len, start_offset,
1915              options|g_notempty, use_offsets, use_size_offsets,
1916              PCRE_EXTRA_MATCH_LIMIT_RECURSION, &(extra->match_limit_recursion),
1917              PCRE_ERROR_RECURSIONLIMIT, "match() recursion");
1918          }          }
1919    
1920        /* If callout_data is set, use the interface with additional data */        /* If callout_data is set, use the interface with additional data */
# Line 1679  while (!done) Line 1994  while (!done)
1994            {            {
1995            if ((copystrings & (1 << i)) != 0)            if ((copystrings & (1 << i)) != 0)
1996              {              {
1997              char copybuffer[16];              char copybuffer[256];
1998              int rc = pcre_copy_substring((char *)bptr, use_offsets, count,              int rc = pcre_copy_substring((char *)bptr, use_offsets, count,
1999                i, copybuffer, sizeof(copybuffer));                i, copybuffer, sizeof(copybuffer));
2000              if (rc < 0)              if (rc < 0)
# Line 1689  while (!done) Line 2004  while (!done)
2004              }              }
2005            }            }
2006    
2007            for (copynamesptr = copynames;
2008                 *copynamesptr != 0;
2009                 copynamesptr += (int)strlen((char*)copynamesptr) + 1)
2010              {
2011              char copybuffer[256];
2012              int rc = pcre_copy_named_substring(re, (char *)bptr, use_offsets,
2013                count, (char *)copynamesptr, copybuffer, sizeof(copybuffer));
2014              if (rc < 0)
2015                fprintf(outfile, "copy substring %s failed %d\n", copynamesptr, rc);
2016              else
2017                fprintf(outfile, "  C %s (%d) %s\n", copybuffer, rc, copynamesptr);
2018              }
2019    
2020          for (i = 0; i < 32; i++)          for (i = 0; i < 32; i++)
2021            {            {
2022            if ((getstrings & (1 << i)) != 0)            if ((getstrings & (1 << i)) != 0)
# Line 1701  while (!done) Line 2029  while (!done)
2029              else              else
2030                {                {
2031                fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc);                fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc);
               /* free((void *)substring); */  
2032                pcre_free_substring(substring);                pcre_free_substring(substring);
2033                }                }
2034              }              }
2035            }            }
2036    
2037            for (getnamesptr = getnames;
2038                 *getnamesptr != 0;
2039                 getnamesptr += (int)strlen((char*)getnamesptr) + 1)
2040              {
2041              const char *substring;
2042              int rc = pcre_get_named_substring(re, (char *)bptr, use_offsets,
2043                count, (char *)getnamesptr, &substring);
2044              if (rc < 0)
2045                fprintf(outfile, "copy substring %s failed %d\n", getnamesptr, rc);
2046              else
2047                {
2048                fprintf(outfile, "  G %s (%d) %s\n", substring, rc, getnamesptr);
2049                pcre_free_substring(substring);
2050                }
2051              }
2052    
2053          if (getlist)          if (getlist)
2054            {            {
2055            const char **stringlist;            const char **stringlist;
# Line 1806  while (!done) Line 2149  while (!done)
2149          len -= use_offsets[1];          len -= use_offsets[1];
2150          }          }
2151        }  /* End of loop for /g and /G */        }  /* End of loop for /g and /G */
2152    
2153        NEXT_DATA: continue;
2154      }    /* End of loop for data lines */      }    /* End of loop for data lines */
2155    
2156    CONTINUE:    CONTINUE:

Legend:
Removed from v.79  
changed lines
  Added in v.91

  ViewVC Help
Powered by ViewVC 1.1.5