/[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 151 by ph10, Tue Apr 17 15:07:29 2007 UTC revision 516 by ph10, Tue May 4 15:51:35 2010 UTC
# Line 36  POSSIBILITY OF SUCH DAMAGE. Line 36  POSSIBILITY OF SUCH DAMAGE.
36  */  */
37    
38    
39    #ifdef HAVE_CONFIG_H
40    #include "config.h"
41    #endif
42    
43  #include <ctype.h>  #include <ctype.h>
44  #include <stdio.h>  #include <stdio.h>
45  #include <string.h>  #include <string.h>
# Line 44  POSSIBILITY OF SUCH DAMAGE. Line 48  POSSIBILITY OF SUCH DAMAGE.
48  #include <locale.h>  #include <locale.h>
49  #include <errno.h>  #include <errno.h>
50    
51    #ifdef SUPPORT_LIBREADLINE
52    #ifdef HAVE_UNISTD_H
53    #include <unistd.h>
54    #endif
55    #include <readline/readline.h>
56    #include <readline/history.h>
57    #endif
58    
59    
60  /* A number of things vary for Windows builds. Originally, pcretest opened its  /* A number of things vary for Windows builds. Originally, pcretest opened its
61  input and output without "b"; then I was told that "b" was needed in some  input and output without "b"; then I was told that "b" was needed in some
# Line 59  input mode under Windows. */ Line 71  input mode under Windows. */
71  #define INPUT_MODE   "r"  #define INPUT_MODE   "r"
72  #define OUTPUT_MODE  "wb"  #define OUTPUT_MODE  "wb"
73    
74    #ifndef isatty
75    #define isatty _isatty         /* This is what Windows calls them, I'm told, */
76    #endif                         /* though in some environments they seem to   */
77                                   /* be already defined, hence the #ifndefs.    */
78    #ifndef fileno
79    #define fileno _fileno
80    #endif
81    
82  #else  #else
83  #include <sys/time.h>          /* These two includes are needed */  #include <sys/time.h>          /* These two includes are needed */
84  #include <sys/resource.h>      /* for setrlimit(). */  #include <sys/resource.h>      /* for setrlimit(). */
# Line 79  appropriately for an application, not fo Line 99  appropriately for an application, not fo
99  #include "pcre.h"  #include "pcre.h"
100  #include "pcre_internal.h"  #include "pcre_internal.h"
101    
102  /* We need access to the data tables that PCRE uses. So as not to have to keep  /* We need access to some of the data tables that PCRE uses. So as not to have
103  two copies, we include the source file here, changing the names of the external  to keep two copies, we include the source file here, changing the names of the
104  symbols to prevent clashes. */  external symbols to prevent clashes. */
105    
106    #define _pcre_ucp_gentype      ucp_gentype
107  #define _pcre_utf8_table1      utf8_table1  #define _pcre_utf8_table1      utf8_table1
108  #define _pcre_utf8_table1_size utf8_table1_size  #define _pcre_utf8_table1_size utf8_table1_size
109  #define _pcre_utf8_table2      utf8_table2  #define _pcre_utf8_table2      utf8_table2
# Line 90  symbols to prevent clashes. */ Line 111  symbols to prevent clashes. */
111  #define _pcre_utf8_table4      utf8_table4  #define _pcre_utf8_table4      utf8_table4
112  #define _pcre_utt              utt  #define _pcre_utt              utt
113  #define _pcre_utt_size         utt_size  #define _pcre_utt_size         utt_size
114    #define _pcre_utt_names        utt_names
115  #define _pcre_OP_lengths       OP_lengths  #define _pcre_OP_lengths       OP_lengths
116    
117  #include "pcre_tables.c"  #include "pcre_tables.c"
118    
119  /* We also need the pcre_printint() function for printing out compiled  /* We also need the pcre_printint() function for printing out compiled
120  patterns. This function is in a separate file so that it can be included in  patterns. This function is in a separate file so that it can be included in
121  pcre_compile.c when that module is compiled with debugging enabled.  pcre_compile.c when that module is compiled with debugging enabled. It needs to
122    know which case is being compiled. */
 The definition of the macro PRINTABLE, which determines whether to print an  
 output character as-is or as a hex value when showing compiled patterns, is  
 contained in this file. We uses it here also, in cases when the locale has not  
 been explicitly changed, so as to get consistent output from systems that  
 differ in their output from isprint() even in the "C" locale. */  
123    
124    #define COMPILING_PCRETEST
125  #include "pcre_printint.src"  #include "pcre_printint.src"
126    
127  #define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c))  /* The definition of the macro PRINTABLE, which determines whether to print an
128    output character as-is or as a hex value when showing compiled patterns, is
129    contained in the printint.src file. We uses it here also, in cases when the
130    locale has not been explicitly changed, so as to get consistent output from
131    systems that differ in their output from isprint() even in the "C" locale. */
132    
133    #define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c))
134    
135  /* It is possible to compile this test program without including support for  /* It is possible to compile this test program without including support for
136  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 152  static int callout_count; Line 175  static int callout_count;
175  static int callout_extra;  static int callout_extra;
176  static int callout_fail_count;  static int callout_fail_count;
177  static int callout_fail_id;  static int callout_fail_id;
178    static int debug_lengths;
179  static int first_callout;  static int first_callout;
180  static int locale_set = 0;  static int locale_set = 0;
181  static int show_malloc;  static int show_malloc;
# Line 183  optimal way of handling this, but hey, t Line 207  optimal way of handling this, but hey, t
207  Arguments:  Arguments:
208    f            the file to read    f            the file to read
209    start        where in buffer to start (this *must* be within buffer)    start        where in buffer to start (this *must* be within buffer)
210      prompt       for stdin or readline()
211    
212  Returns:       pointer to the start of new data  Returns:       pointer to the start of new data
213                 could be a copy of start, or could be moved                 could be a copy of start, or could be moved
# Line 190  Returns: pointer to the start of n Line 215  Returns: pointer to the start of n
215  */  */
216    
217  static uschar *  static uschar *
218  extend_inputline(FILE *f, uschar *start)  extend_inputline(FILE *f, uschar *start, const char *prompt)
219  {  {
220  uschar *here = start;  uschar *here = start;
221    
# Line 201  for (;;) Line 226  for (;;)
226    if (rlen > 1000)    if (rlen > 1000)
227      {      {
228      int dlen;      int dlen;
229      if (fgets((char *)here, rlen,  f) == NULL)  
230        return (here == start)? NULL : start;      /* If libreadline support is required, use readline() to read a line if the
231        input is a terminal. Note that readline() removes the trailing newline, so
232        we must put it back again, to be compatible with fgets(). */
233    
234    #ifdef SUPPORT_LIBREADLINE
235        if (isatty(fileno(f)))
236          {
237          size_t len;
238          char *s = readline(prompt);
239          if (s == NULL) return (here == start)? NULL : start;
240          len = strlen(s);
241          if (len > 0) add_history(s);
242          if (len > rlen - 1) len = rlen - 1;
243          memcpy(here, s, len);
244          here[len] = '\n';
245          here[len+1] = 0;
246          free(s);
247          }
248        else
249    #endif
250    
251        /* Read the next line by normal means, prompting if the file is stdin. */
252    
253          {
254          if (f == stdin) printf("%s", prompt);
255          if (fgets((char *)here, rlen,  f) == NULL)
256            return (here == start)? NULL : start;
257          }
258    
259      dlen = (int)strlen((char *)here);      dlen = (int)strlen((char *)here);
260      if (dlen > 0 && here[dlen - 1] == '\n') return start;      if (dlen > 0 && here[dlen - 1] == '\n') return start;
261      here += dlen;      here += dlen;
# Line 659  return count; Line 712  return count;
712    
713    
714  /*************************************************  /*************************************************
715    *         Case-independent strncmp() function    *
716    *************************************************/
717    
718    /*
719    Arguments:
720      s         first string
721      t         second string
722      n         number of characters to compare
723    
724    Returns:    < 0, = 0, or > 0, according to the comparison
725    */
726    
727    static int
728    strncmpic(uschar *s, uschar *t, int n)
729    {
730    while (n--)
731      {
732      int c = tolower(*s++) - tolower(*t++);
733      if (c) return c;
734      }
735    return 0;
736    }
737    
738    
739    
740    /*************************************************
741  *         Check newline indicator                *  *         Check newline indicator                *
742  *************************************************/  *************************************************/
743    
# Line 676  Returns: appropriate PCRE_NEWLINE_x Line 755  Returns: appropriate PCRE_NEWLINE_x
755  static int  static int
756  check_newline(uschar *p, FILE *f)  check_newline(uschar *p, FILE *f)
757  {  {
758  if (strncmp((char *)p, "cr>", 3) == 0) return PCRE_NEWLINE_CR;  if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
759  if (strncmp((char *)p, "lf>", 3) == 0) return PCRE_NEWLINE_LF;  if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
760  if (strncmp((char *)p, "crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;  if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
761  if (strncmp((char *)p, "anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;  if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
762  if (strncmp((char *)p, "any>", 4) == 0) return PCRE_NEWLINE_ANY;  if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
763    if (strncmpic(p, (uschar *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;
764    if (strncmpic(p, (uschar *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;
765  fprintf(f, "Unknown newline type at: <%s\n", p);  fprintf(f, "Unknown newline type at: <%s\n", p);
766  return 0;  return 0;
767  }  }
# Line 694  return 0; Line 775  return 0;
775  static void  static void
776  usage(void)  usage(void)
777  {  {
778  printf("Usage:     pcretest [options] [<input> [<output>]]\n");  printf("Usage:     pcretest [options] [<input file> [<output file>]]\n\n");
779    printf("Input and output default to stdin and stdout.\n");
780    #ifdef SUPPORT_LIBREADLINE
781    printf("If input is a terminal, readline() is used to read from it.\n");
782    #else
783    printf("This version of pcretest is not linked with readline().\n");
784    #endif
785    printf("\nOptions:\n");
786  printf("  -b       show compiled code (bytecode)\n");  printf("  -b       show compiled code (bytecode)\n");
787  printf("  -C       show PCRE compile-time options and exit\n");  printf("  -C       show PCRE compile-time options and exit\n");
788  printf("  -d       debug: show compiled code and information (-b and -i)\n");  printf("  -d       debug: show compiled code and information (-b and -i)\n");
# Line 703  printf(" -dfa force DFA matching fo Line 791  printf(" -dfa force DFA matching fo
791  #endif  #endif
792  printf("  -help    show usage information\n");  printf("  -help    show usage information\n");
793  printf("  -i       show information about compiled patterns\n"  printf("  -i       show information about compiled patterns\n"
794           "  -M       find MATCH_LIMIT minimum for each subject\n"
795         "  -m       output memory used information\n"         "  -m       output memory used information\n"
796         "  -o <n>   set size of offsets vector to <n>\n");         "  -o <n>   set size of offsets vector to <n>\n");
797  #if !defined NOPOSIX  #if !defined NOPOSIX
# Line 732  int main(int argc, char **argv) Line 821  int main(int argc, char **argv)
821  FILE *infile = stdin;  FILE *infile = stdin;
822  int options = 0;  int options = 0;
823  int study_options = 0;  int study_options = 0;
824    int default_find_match_limit = FALSE;
825  int op = 1;  int op = 1;
826  int timeit = 0;  int timeit = 0;
827  int timeitm = 0;  int timeitm = 0;
# Line 791  while (argc > 1 && argv[op][0] == '-') Line 881  while (argc > 1 && argv[op][0] == '-')
881    else if (strcmp(argv[op], "-b") == 0) debug = 1;    else if (strcmp(argv[op], "-b") == 0) debug = 1;
882    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
883    else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;    else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;
884      else if (strcmp(argv[op], "-M") == 0) default_find_match_limit = TRUE;
885  #if !defined NODFA  #if !defined NODFA
886    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;
887  #endif  #endif
# Line 843  while (argc > 1 && argv[op][0] == '-') Line 934  while (argc > 1 && argv[op][0] == '-')
934    else if (strcmp(argv[op], "-C") == 0)    else if (strcmp(argv[op], "-C") == 0)
935      {      {
936      int rc;      int rc;
937        unsigned long int lrc;
938      printf("PCRE version %s\n", pcre_version());      printf("PCRE version %s\n", pcre_version());
939      printf("Compiled with\n");      printf("Compiled with\n");
940      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
# Line 850  while (argc > 1 && argv[op][0] == '-') Line 942  while (argc > 1 && argv[op][0] == '-')
942      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
943      printf("  %sUnicode properties support\n", rc? "" : "No ");      printf("  %sUnicode properties support\n", rc? "" : "No ");
944      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
945      printf("  Newline sequence is %s\n", (rc == '\r')? "CR" :      /* Note that these values are always the ASCII values, even
946        (rc == '\n')? "LF" : (rc == ('\r'<<8 | '\n'))? "CRLF" :      in EBCDIC environments. CR is 13 and NL is 10. */
947        printf("  Newline sequence is %s\n", (rc == 13)? "CR" :
948          (rc == 10)? "LF" : (rc == (13<<8 | 10))? "CRLF" :
949        (rc == -2)? "ANYCRLF" :        (rc == -2)? "ANYCRLF" :
950        (rc == -1)? "ANY" : "???");        (rc == -1)? "ANY" : "???");
951        (void)pcre_config(PCRE_CONFIG_BSR, &rc);
952        printf("  \\R matches %s\n", rc? "CR, LF, or CRLF only" :
953                                         "all Unicode newlines");
954      (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);      (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);
955      printf("  Internal link size = %d\n", rc);      printf("  Internal link size = %d\n", rc);
956      (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);      (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);
957      printf("  POSIX malloc threshold = %d\n", rc);      printf("  POSIX malloc threshold = %d\n", rc);
958      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc);      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &lrc);
959      printf("  Default match limit = %d\n", rc);      printf("  Default match limit = %ld\n", lrc);
960      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &rc);      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &lrc);
961      printf("  Default recursion depth limit = %d\n", rc);      printf("  Default recursion depth limit = %ld\n", lrc);
962      (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc);      (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc);
963      printf("  Match recursion uses %s\n", rc? "stack" : "heap");      printf("  Match recursion uses %s\n", rc? "stack" : "heap");
964      goto EXIT;      goto EXIT;
# Line 943  while (!done) Line 1040  while (!done)
1040  #endif  #endif
1041    
1042    const char *error;    const char *error;
1043      unsigned char *markptr;
1044    unsigned char *p, *pp, *ppp;    unsigned char *p, *pp, *ppp;
1045    unsigned char *to_file = NULL;    unsigned char *to_file = NULL;
1046    const unsigned char *tables = NULL;    const unsigned char *tables = NULL;
1047    unsigned long int true_size, true_study_size = 0;    unsigned long int true_size, true_study_size = 0;
1048    size_t size, regex_gotten_store;    size_t size, regex_gotten_store;
1049      int do_mark = 0;
1050    int do_study = 0;    int do_study = 0;
1051    int do_debug = debug;    int do_debug = debug;
   int debug_lengths = 1;  
1052    int do_G = 0;    int do_G = 0;
1053    int do_g = 0;    int do_g = 0;
1054    int do_showinfo = showinfo;    int do_showinfo = showinfo;
# Line 959  while (!done) Line 1057  while (!done)
1057    int erroroffset, len, delimiter, poffset;    int erroroffset, len, delimiter, poffset;
1058    
1059    use_utf8 = 0;    use_utf8 = 0;
1060      debug_lengths = 1;
1061    
1062    if (infile == stdin) printf("  re> ");    if (extend_inputline(infile, buffer, "  re> ") == NULL) break;
   if (extend_inputline(infile, buffer) == NULL) break;  
1063    if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);    if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
1064    fflush(outfile);    fflush(outfile);
1065    
# Line 1061  while (!done) Line 1159  while (!done)
1159    
1160    if (isalnum(delimiter) || delimiter == '\\')    if (isalnum(delimiter) || delimiter == '\\')
1161      {      {
1162      fprintf(outfile, "** Delimiter must not be alphameric or \\\n");      fprintf(outfile, "** Delimiter must not be alphanumeric or \\\n");
1163      goto SKIP_DATA;      goto SKIP_DATA;
1164      }      }
1165    
# Line 1077  while (!done) Line 1175  while (!done)
1175        pp++;        pp++;
1176        }        }
1177      if (*pp != 0) break;      if (*pp != 0) break;
1178      if (infile == stdin) printf("    > ");      if ((pp = extend_inputline(infile, pp, "    > ")) == NULL)
     if ((pp = extend_inputline(infile, pp)) == NULL)  
1179        {        {
1180        fprintf(outfile, "** Unexpected EOF\n");        fprintf(outfile, "** Unexpected EOF\n");
1181        done = 1;        done = 1;
# Line 1131  while (!done) Line 1228  while (!done)
1228        case 'G': do_G = 1; break;        case 'G': do_G = 1; break;
1229        case 'I': do_showinfo = 1; break;        case 'I': do_showinfo = 1; break;
1230        case 'J': options |= PCRE_DUPNAMES; break;        case 'J': options |= PCRE_DUPNAMES; break;
1231          case 'K': do_mark = 1; break;
1232        case 'M': log_store = 1; break;        case 'M': log_store = 1; break;
1233        case 'N': options |= PCRE_NO_AUTO_CAPTURE; break;        case 'N': options |= PCRE_NO_AUTO_CAPTURE; break;
1234    
# Line 1170  while (!done) Line 1268  while (!done)
1268    
1269        case '<':        case '<':
1270          {          {
1271          int x = check_newline(pp, outfile);          if (strncmp((char *)pp, "JS>", 3) == 0)
1272          if (x == 0) goto SKIP_DATA;            {
1273          options |= x;            options |= PCRE_JAVASCRIPT_COMPAT;
1274          while (*pp++ != '>');            pp += 3;
1275              }
1276            else
1277              {
1278              int x = check_newline(pp, outfile);
1279              if (x == 0) goto SKIP_DATA;
1280              options |= x;
1281              while (*pp++ != '>');
1282              }
1283          }          }
1284        break;        break;
1285    
# Line 1203  while (!done) Line 1309  while (!done)
1309      if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL;      if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL;
1310      if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB;      if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB;
1311      if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8;      if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8;
1312        if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY;
1313    
1314      rc = regcomp(&preg, (char *)p, cflags);      rc = regcomp(&preg, (char *)p, cflags);
1315    
# Line 1223  while (!done) Line 1330  while (!done)
1330  #endif  /* !defined NOPOSIX */  #endif  /* !defined NOPOSIX */
1331    
1332      {      {
1333        unsigned long int get_options;
1334    
1335      if (timeit > 0)      if (timeit > 0)
1336        {        {
1337        register int i;        register int i;
# Line 1252  while (!done) Line 1361  while (!done)
1361          {          {
1362          for (;;)          for (;;)
1363            {            {
1364            if (extend_inputline(infile, buffer) == NULL)            if (extend_inputline(infile, buffer, NULL) == NULL)
1365              {              {
1366              done = 1;              done = 1;
1367              goto CONTINUE;              goto CONTINUE;
# Line 1266  while (!done) Line 1375  while (!done)
1375        goto CONTINUE;        goto CONTINUE;
1376        }        }
1377    
1378      /* Compilation succeeded; print data if required. There are now two      /* Compilation succeeded. It is now possible to set the UTF-8 option from
1379      info-returning functions. The old one has a limited interface and      within the regex; check for this so that we know how to process the data
1380      returns only limited data. Check that it agrees with the newer one. */      lines. */
1381    
1382        new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
1383        if ((get_options & PCRE_UTF8) != 0) use_utf8 = 1;
1384    
1385        /* Print information if required. There are now two info-returning
1386        functions. The old one has a limited interface and returns only limited
1387        data. Check that it agrees with the newer one. */
1388    
1389      if (log_store)      if (log_store)
1390        fprintf(outfile, "Memory allocation (code space): %d\n",        fprintf(outfile, "Memory allocation (code space): %d\n",
# Line 1307  while (!done) Line 1423  while (!done)
1423          true_study_size = ((pcre_study_data *)(extra->study_data))->size;          true_study_size = ((pcre_study_data *)(extra->study_data))->size;
1424        }        }
1425    
1426        /* If /K was present, we set up for handling MARK data. */
1427    
1428        if (do_mark)
1429          {
1430          if (extra == NULL)
1431            {
1432            extra = (pcre_extra *)malloc(sizeof(pcre_extra));
1433            extra->flags = 0;
1434            }
1435          extra->mark = &markptr;
1436          extra->flags |= PCRE_EXTRA_MARK;
1437          }
1438    
1439      /* If the 'F' option was present, we flip the bytes of all the integer      /* If the 'F' option was present, we flip the bytes of all the integer
1440      fields in the regex data block and the study block. This is to make it      fields in the regex data block and the study block. This is to make it
1441      possible to test PCRE's handling of byte-flipped patterns, e.g. those      possible to test PCRE's handling of byte-flipped patterns, e.g. those
# Line 1315  while (!done) Line 1444  while (!done)
1444      if (do_flip)      if (do_flip)
1445        {        {
1446        real_pcre *rre = (real_pcre *)re;        real_pcre *rre = (real_pcre *)re;
1447        rre->magic_number = byteflip(rre->magic_number, sizeof(rre->magic_number));        rre->magic_number =
1448            byteflip(rre->magic_number, sizeof(rre->magic_number));
1449        rre->size = byteflip(rre->size, sizeof(rre->size));        rre->size = byteflip(rre->size, sizeof(rre->size));
1450        rre->options = byteflip(rre->options, sizeof(rre->options));        rre->options = byteflip(rre->options, sizeof(rre->options));
1451        rre->top_bracket = byteflip(rre->top_bracket, sizeof(rre->top_bracket));        rre->flags = (pcre_uint16)byteflip(rre->flags, sizeof(rre->flags));
1452        rre->top_backref = byteflip(rre->top_backref, sizeof(rre->top_backref));        rre->top_bracket =
1453        rre->first_byte = byteflip(rre->first_byte, sizeof(rre->first_byte));          (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));
1454        rre->req_byte = byteflip(rre->req_byte, sizeof(rre->req_byte));        rre->top_backref =
1455        rre->name_table_offset = byteflip(rre->name_table_offset,          (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));
1456          rre->first_byte =
1457            (pcre_uint16)byteflip(rre->first_byte, sizeof(rre->first_byte));
1458          rre->req_byte =
1459            (pcre_uint16)byteflip(rre->req_byte, sizeof(rre->req_byte));
1460          rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,
1461          sizeof(rre->name_table_offset));          sizeof(rre->name_table_offset));
1462        rre->name_entry_size = byteflip(rre->name_entry_size,        rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,
1463          sizeof(rre->name_entry_size));          sizeof(rre->name_entry_size));
1464        rre->name_count = byteflip(rre->name_count, sizeof(rre->name_count));        rre->name_count = (pcre_uint16)byteflip(rre->name_count,
1465            sizeof(rre->name_count));
1466    
1467        if (extra != NULL)        if (extra != NULL)
1468          {          {
1469          pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);          pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);
1470          rsd->size = byteflip(rsd->size, sizeof(rsd->size));          rsd->size = byteflip(rsd->size, sizeof(rsd->size));
1471          rsd->options = byteflip(rsd->options, sizeof(rsd->options));          rsd->flags = byteflip(rsd->flags, sizeof(rsd->flags));
1472            rsd->minlength = byteflip(rsd->minlength, sizeof(rsd->minlength));
1473          }          }
1474        }        }
1475    
# Line 1346  while (!done) Line 1483  while (!done)
1483        pcre_printint(re, outfile, debug_lengths);        pcre_printint(re, outfile, debug_lengths);
1484        }        }
1485    
1486        /* We already have the options in get_options (see above) */
1487    
1488      if (do_showinfo)      if (do_showinfo)
1489        {        {
1490        unsigned long int get_options, all_options;        unsigned long int all_options;
1491  #if !defined NOINFOCHECK  #if !defined NOINFOCHECK
1492        int old_first_char, old_options, old_count;        int old_first_char, old_options, old_count;
1493  #endif  #endif
1494        int count, backrefmax, first_char, need_char;        int count, backrefmax, first_char, need_char, okpartial, jchanged,
1495            hascrorlf;
1496        int nameentrysize, namecount;        int nameentrysize, namecount;
1497        const uschar *nametable;        const uschar *nametable;
1498    
       new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);  
1499        new_info(re, NULL, PCRE_INFO_SIZE, &size);        new_info(re, NULL, PCRE_INFO_SIZE, &size);
1500        new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);        new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);
1501        new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax);        new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax);
# Line 1365  while (!done) Line 1504  while (!done)
1504        new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);        new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
1505        new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount);        new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount);
1506        new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable);        new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable);
1507          new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial);
1508          new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);
1509          new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);
1510    
1511  #if !defined NOINFOCHECK  #if !defined NOINFOCHECK
1512        old_count = pcre_info(re, &old_options, &old_first_char);        old_count = pcre_info(re, &old_options, &old_first_char);
# Line 1406  while (!done) Line 1548  while (!done)
1548            }            }
1549          }          }
1550    
1551        /* The NOPARTIAL bit is a private bit in the options, so we have        if (!okpartial) fprintf(outfile, "Partial matching not supported\n");
1552        to fish it out via out back door */        if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n");
1553    
1554        all_options = ((real_pcre *)re)->options;        all_options = ((real_pcre *)re)->options;
1555        if (do_flip)        if (do_flip) all_options = byteflip(all_options, sizeof(all_options));
         {  
         all_options = byteflip(all_options, sizeof(all_options));  
          }  
   
       if ((all_options & PCRE_NOPARTIAL) != 0)  
         fprintf(outfile, "Partial matching not supported\n");  
1556    
1557        if (get_options == 0) fprintf(outfile, "No options\n");        if (get_options == 0) fprintf(outfile, "No options\n");
1558          else fprintf(outfile, "Options:%s%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%s%s\n",
1559            ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",            ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",
1560            ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",            ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",
1561            ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",            ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",
1562            ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "",            ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "",
1563            ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "",            ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "",
1564            ((get_options & PCRE_DOTALL) != 0)? " dotall" : "",            ((get_options & PCRE_DOTALL) != 0)? " dotall" : "",
1565              ((get_options & PCRE_BSR_ANYCRLF) != 0)? " bsr_anycrlf" : "",
1566              ((get_options & PCRE_BSR_UNICODE) != 0)? " bsr_unicode" : "",
1567            ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",            ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
1568            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",
1569            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
# Line 1434  while (!done) Line 1572  while (!done)
1572            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",
1573            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");
1574    
1575          if (jchanged) fprintf(outfile, "Duplicate name status changes\n");
1576    
1577        switch (get_options & PCRE_NEWLINE_BITS)        switch (get_options & PCRE_NEWLINE_BITS)
1578          {          {
1579          case PCRE_NEWLINE_CR:          case PCRE_NEWLINE_CR:
# Line 1506  while (!done) Line 1646  while (!done)
1646          else          else
1647            {            {
1648            uschar *start_bits = NULL;            uschar *start_bits = NULL;
1649            new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);            int minlength;
1650    
1651              new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength);
1652              fprintf(outfile, "Subject length lower bound = %d\n", minlength);
1653    
1654              new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);
1655            if (start_bits == NULL)            if (start_bits == NULL)
1656              fprintf(outfile, "No starting byte set\n");              fprintf(outfile, "No set of starting bytes\n");
1657            else            else
1658              {              {
1659              int i;              int i;
# Line 1556  while (!done) Line 1700  while (!done)
1700        else        else
1701          {          {
1702          uschar sbuf[8];          uschar sbuf[8];
1703          sbuf[0] = (true_size >> 24)  & 255;          sbuf[0] = (uschar)((true_size >> 24) & 255);
1704          sbuf[1] = (true_size >> 16)  & 255;          sbuf[1] = (uschar)((true_size >> 16) & 255);
1705          sbuf[2] = (true_size >>  8)  & 255;          sbuf[2] = (uschar)((true_size >>  8) & 255);
1706          sbuf[3] = (true_size)  & 255;          sbuf[3] = (uschar)((true_size) & 255);
1707    
1708          sbuf[4] = (true_study_size >> 24)  & 255;          sbuf[4] = (uschar)((true_study_size >> 24) & 255);
1709          sbuf[5] = (true_study_size >> 16)  & 255;          sbuf[5] = (uschar)((true_study_size >> 16) & 255);
1710          sbuf[6] = (true_study_size >>  8)  & 255;          sbuf[6] = (uschar)((true_study_size >>  8) & 255);
1711          sbuf[7] = (true_study_size)  & 255;          sbuf[7] = (uschar)((true_study_size) & 255);
1712    
1713          if (fwrite(sbuf, 1, 8, f) < 8 ||          if (fwrite(sbuf, 1, 8, f) < 8 ||
1714              fwrite(re, 1, true_size, f) < true_size)              fwrite(re, 1, true_size, f) < true_size)
# Line 1608  while (!done) Line 1752  while (!done)
1752      int callout_data_set = 0;      int callout_data_set = 0;
1753      int count, c;      int count, c;
1754      int copystrings = 0;      int copystrings = 0;
1755      int find_match_limit = 0;      int find_match_limit = default_find_match_limit;
1756      int getstrings = 0;      int getstrings = 0;
1757      int getlist = 0;      int getlist = 0;
1758      int gmatched = 0;      int gmatched = 0;
# Line 1638  while (!done) Line 1782  while (!done)
1782      len = 0;      len = 0;
1783      for (;;)      for (;;)
1784        {        {
1785        if (infile == stdin) printf("data> ");        if (extend_inputline(infile, buffer + len, "data> ") == NULL)
       if (extend_inputline(infile, buffer + len) == NULL)  
1786          {          {
1787          if (len > 0) break;          if (len > 0) break;
1788          done = 1;          done = 1;
# Line 1707  while (!done) Line 1850  while (!done)
1850              {              {
1851              unsigned char buff8[8];              unsigned char buff8[8];
1852              int ii, utn;              int ii, utn;
1853              utn = ord2utf8(c, buff8);              if (use_utf8)
1854              for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];                {
1855              c = buff8[ii];   /* Last byte */                utn = ord2utf8(c, buff8);
1856                  for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
1857                  c = buff8[ii];   /* Last byte */
1858                  }
1859                else
1860                 {
1861                 if (c > 255)
1862                   fprintf(outfile, "** Character \\x{%x} is greater than 255 and "
1863                     "UTF-8 mode is not enabled.\n"
1864                     "** Truncation will probably give the wrong result.\n", c);
1865                 }
1866              p = pt + 1;              p = pt + 1;
1867              break;              break;
1868              }              }
# Line 1839  while (!done) Line 1992  while (!done)
1992          continue;          continue;
1993    
1994          case 'N':          case 'N':
1995          options |= PCRE_NOTEMPTY;          if ((options & PCRE_NOTEMPTY) != 0)
1996              options = (options & ~PCRE_NOTEMPTY) | PCRE_NOTEMPTY_ATSTART;
1997            else
1998              options |= PCRE_NOTEMPTY;
1999          continue;          continue;
2000    
2001          case 'O':          case 'O':
# Line 1862  while (!done) Line 2018  while (!done)
2018          continue;          continue;
2019    
2020          case 'P':          case 'P':
2021          options |= PCRE_PARTIAL;          options |= ((options & PCRE_PARTIAL_SOFT) == 0)?
2022              PCRE_PARTIAL_SOFT : PCRE_PARTIAL_HARD;
2023          continue;          continue;
2024    
2025          case 'Q':          case 'Q':
# Line 1897  while (!done) Line 2054  while (!done)
2054          show_malloc = 1;          show_malloc = 1;
2055          continue;          continue;
2056    
2057            case 'Y':
2058            options |= PCRE_NO_START_OPTIMIZE;
2059            continue;
2060    
2061          case 'Z':          case 'Z':
2062          options |= PCRE_NOTEOL;          options |= PCRE_NOTEOL;
2063          continue;          continue;
# Line 1919  while (!done) Line 2080  while (!done)
2080      *q = 0;      *q = 0;
2081      len = q - dbuffer;      len = q - dbuffer;
2082    
2083        /* Move the data to the end of the buffer so that a read over the end of
2084        the buffer will be seen by valgrind, even if it doesn't cause a crash. If
2085        we are using the POSIX interface, we must include the terminating zero. */
2086    
2087    #if !defined NOPOSIX
2088        if (posix || do_posix)
2089          {
2090          memmove(bptr + buffer_size - len - 1, bptr, len + 1);
2091          bptr += buffer_size - len - 1;
2092          }
2093        else
2094    #endif
2095          {
2096          memmove(bptr + buffer_size - len, bptr, len);
2097          bptr += buffer_size - len;
2098          }
2099    
2100      if ((all_use_dfa || use_dfa) && find_match_limit)      if ((all_use_dfa || use_dfa) && find_match_limit)
2101        {        {
2102        printf("**Match limit not relevant for DFA matching: ignored\n");        printf("**Match limit not relevant for DFA matching: ignored\n");
# Line 1938  while (!done) Line 2116  while (!done)
2116          pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets);          pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets);
2117        if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;        if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;
2118        if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;        if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;
2119          if ((options & PCRE_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY;
2120    
2121        rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags);        rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags);
2122    
# Line 1982  while (!done) Line 2161  while (!done)
2161    
2162      for (;; gmatched++)    /* Loop for /g or /G */      for (;; gmatched++)    /* Loop for /g or /G */
2163        {        {
2164          markptr = NULL;
2165    
2166        if (timeitm > 0)        if (timeitm > 0)
2167          {          {
2168          register int i;          register int i;
# Line 1993  while (!done) Line 2174  while (!done)
2174            {            {
2175            int workspace[1000];            int workspace[1000];
2176            for (i = 0; i < timeitm; i++)            for (i = 0; i < timeitm; i++)
2177              count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset,              count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset,
2178                options | g_notempty, use_offsets, use_size_offsets, workspace,                options | g_notempty, use_offsets, use_size_offsets, workspace,
2179                sizeof(workspace)/sizeof(int));                sizeof(workspace)/sizeof(int));
2180            }            }
# Line 2056  while (!done) Line 2237  while (!done)
2237        else if (all_use_dfa || use_dfa)        else if (all_use_dfa || use_dfa)
2238          {          {
2239          int workspace[1000];          int workspace[1000];
2240          count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset,          count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset,
2241            options | g_notempty, use_offsets, use_size_offsets, workspace,            options | g_notempty, use_offsets, use_size_offsets, workspace,
2242            sizeof(workspace)/sizeof(int));            sizeof(workspace)/sizeof(int));
2243          if (count == 0)          if (count == 0)
# Line 2127  while (!done) Line 2308  while (!done)
2308              }              }
2309            }            }
2310    
2311            if (markptr != NULL) fprintf(outfile, "MK: %s\n", markptr);
2312    
2313          for (i = 0; i < 32; i++)          for (i = 0; i < 32; i++)
2314            {            {
2315            if ((copystrings & (1 << i)) != 0)            if ((copystrings & (1 << i)) != 0)
# Line 2210  while (!done) Line 2393  while (!done)
2393    
2394        else if (count == PCRE_ERROR_PARTIAL)        else if (count == PCRE_ERROR_PARTIAL)
2395          {          {
2396          fprintf(outfile, "Partial match");          if (markptr == NULL) fprintf(outfile, "Partial match");
2397  #if !defined NODFA            else fprintf(outfile, "Partial match, mark=%s", markptr);
2398          if ((all_use_dfa || use_dfa) && use_size_offsets > 2)          if (use_size_offsets > 1)
2399            fprintf(outfile, ": %.*s", use_offsets[1] - use_offsets[0],            {
2400              bptr + use_offsets[0]);            fprintf(outfile, ": ");
2401  #endif            pchars(bptr + use_offsets[0], use_offsets[1] - use_offsets[0],
2402                outfile);
2403              }
2404          fprintf(outfile, "\n");          fprintf(outfile, "\n");
2405          break;  /* Out of the /g loop */          break;  /* Out of the /g loop */
2406          }          }
# Line 2245  while (!done) Line 2430  while (!done)
2430              {              {
2431              int d;              int d;
2432              (void)pcre_config(PCRE_CONFIG_NEWLINE, &d);              (void)pcre_config(PCRE_CONFIG_NEWLINE, &d);
2433              obits = (d == '\r')? PCRE_NEWLINE_CR :              /* Note that these values are always the ASCII ones, even in
2434                      (d == '\n')? PCRE_NEWLINE_LF :              EBCDIC environments. CR = 13, NL = 10. */
2435                      (d == ('\r'<<8 | '\n'))? PCRE_NEWLINE_CRLF :              obits = (d == 13)? PCRE_NEWLINE_CR :
2436                        (d == 10)? PCRE_NEWLINE_LF :
2437                        (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF :
2438                      (d == -2)? PCRE_NEWLINE_ANYCRLF :                      (d == -2)? PCRE_NEWLINE_ANYCRLF :
2439                      (d == -1)? PCRE_NEWLINE_ANY : 0;                      (d == -1)? PCRE_NEWLINE_ANY : 0;
2440              }              }
# Line 2274  while (!done) Line 2461  while (!done)
2461            {            {
2462            if (count == PCRE_ERROR_NOMATCH)            if (count == PCRE_ERROR_NOMATCH)
2463              {              {
2464              if (gmatched == 0) fprintf(outfile, "No match\n");              if (gmatched == 0)
2465                  {
2466                  if (markptr == NULL) fprintf(outfile, "No match\n");
2467                    else fprintf(outfile, "No match, mark = %s\n", markptr);
2468                  }
2469              }              }
2470            else fprintf(outfile, "Error %d\n", count);            else fprintf(outfile, "Error %d\n", count);
2471            break;  /* Out of the /g loop */            break;  /* Out of the /g loop */
# Line 2286  while (!done) Line 2477  while (!done)
2477        if (!do_g && !do_G) break;        if (!do_g && !do_G) break;
2478    
2479        /* If we have matched an empty string, first check to see if we are at        /* If we have matched an empty string, first check to see if we are at
2480        the end of the subject. If so, the /g loop is over. Otherwise, mimic        the end of the subject. If so, the /g loop is over. Otherwise, mimic what
2481        what Perl's /g options does. This turns out to be rather cunning. First        Perl's /g options does. This turns out to be rather cunning. First we set
2482        we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the        PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED and try the match again at the
2483        same point. If this fails (picked up above) we advance to the next        same point. If this fails (picked up above) we advance to the next
2484        character. */        character. */
2485    
# Line 2297  while (!done) Line 2488  while (!done)
2488        if (use_offsets[0] == use_offsets[1])        if (use_offsets[0] == use_offsets[1])
2489          {          {
2490          if (use_offsets[0] == len) break;          if (use_offsets[0] == len) break;
2491          g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED;          g_notempty = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED;
2492          }          }
2493    
2494        /* For /g, update the start offset, leaving the rest alone */        /* For /g, update the start offset, leaving the rest alone */

Legend:
Removed from v.151  
changed lines
  Added in v.516

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12