/[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 90 by nigel, Sat Feb 24 21:41:21 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 include pcre_internal.h because we need the internal info for displaying  /* We include pcre_internal.h because we need the internal info for displaying
# Line 101  function (define NOINFOCHECK). */ Line 105  function (define NOINFOCHECK). */
105    
106  #define LOOPREPEAT 500000  #define LOOPREPEAT 500000
107    
 #define BUFFER_SIZE 30000  
 #define PBUFFER_SIZE BUFFER_SIZE  
 #define DBUFFER_SIZE BUFFER_SIZE  
   
   
108  /* Static variables */  /* Static variables */
109    
110  static FILE *outfile;  static FILE *outfile;
# Line 119  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 159  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 191  d = (c & utf8_table3[i]) << s; Line 275  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 222  and encodes it as a UTF-8 character in 0 Line 306  and encodes it as a UTF-8 character in 0
306    
307  Arguments:  Arguments:
308    cvalue     the character value    cvalue     the character value
309    buffer     pointer to buffer for result - at least 6 bytes long    utf8bytes  pointer to buffer for result - at least 6 bytes long
310    
311  Returns:     number of characters placed in the buffer  Returns:     number of characters placed in the buffer
312  */  */
313    
314  static int  static int
315  ord2utf8(int cvalue, uschar *buffer)  ord2utf8(int cvalue, uschar *utf8bytes)
316  {  {
317  register int i, j;  register int i, j;
318  for (i = 0; i < utf8_table1_size; i++)  for (i = 0; i < utf8_table1_size; i++)
319    if (cvalue <= utf8_table1[i]) break;    if (cvalue <= utf8_table1[i]) break;
320  buffer += i;  utf8bytes += i;
321  for (j = i; j > 0; j--)  for (j = i; j > 0; j--)
322   {   {
323   *buffer-- = 0x80 | (cvalue & 0x3f);   *utf8bytes-- = 0x80 | (cvalue & 0x3f);
324   cvalue >>= 6;   cvalue >>= 6;
325   }   }
326  *buffer = utf8_table2[i] | cvalue;  *utf8bytes = utf8_table2[i] | cvalue;
327  return i + 1;  return i + 1;
328  }  }
329    
# Line 461  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 526  return count; Line 610  return count;
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 553  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    uschar copynames[1024];
672    uschar getnames[1024];
673    
674  unsigned char *buffer;  uschar *copynamesptr;
675  unsigned char *dbuffer;  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 596  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 609  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);
# Line 625  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 637  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 723  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 735  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 783  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 838  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 893  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 927  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 961  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 1002  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 1163  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%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 1181  while (!done) Line 1324  while (!done)
1324            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
1325            ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",            ((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        if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0)        switch (get_options & PCRE_NEWLINE_CRLF)
1331          fprintf(outfile, "Case state changes\n");          {
1332            case PCRE_NEWLINE_CR:
1333            fprintf(outfile, "Forced newline sequence: CR\n");
1334            break;
1335    
1336            case PCRE_NEWLINE_LF:
1337            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 1343  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 1351  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 1389  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 1450  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 1518  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 1564  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 1581  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 1611  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)        else if ((((const pcre *)preg.re_pcre)->options & PCRE_NO_AUTO_CAPTURE)
# Line 1690  while (!done) Line 1906  while (!done)
1906            extra->flags = 0;            extra->flags = 0;
1907            }            }
1908    
1909          count = check_match_limit(re, extra, bptr, len, start_offset,          (void)check_match_limit(re, extra, bptr, len, start_offset,
1910            options|g_notempty, use_offsets, use_size_offsets,            options|g_notempty, use_offsets, use_size_offsets,
1911            PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit),            PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit),
1912            PCRE_ERROR_MATCHLIMIT, "match()");            PCRE_ERROR_MATCHLIMIT, "match()");
# Line 1778  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 1788  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 1800  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 1905  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.90  
changed lines
  Added in v.91

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12