/[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 121 by ph10, Mon Mar 12 12:12:47 2007 UTC revision 391 by ph10, Tue Mar 17 21:16:01 2009 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    #define isatty _isatty         /* This is what Windows calls them, I'm told */
75    #define fileno _fileno
76    
77  #else  #else
78  #include <sys/time.h>          /* These two includes are needed */  #include <sys/time.h>          /* These two includes are needed */
79  #include <sys/resource.h>      /* for setrlimit(). */  #include <sys/resource.h>      /* for setrlimit(). */
# Line 67  input mode under Windows. */ Line 82  input mode under Windows. */
82  #endif  #endif
83    
84    
85  #define PCRE_SPY        /* For Win32 build, import data, not export */  /* We have to include pcre_internal.h because we need the internal info for
86    displaying the results of pcre_study() and we also need to know about the
87  /* We include pcre_internal.h because we need the internal info for displaying  internal macros, structures, and other internal data values; pcretest has
88  the results of pcre_study() and we also need to know about the internal  "inside information" compared to a program that strictly follows the PCRE API.
89  macros, structures, and other internal data values; pcretest has "inside  
90  information" compared to a program that strictly follows the PCRE API. */  Although pcre_internal.h does itself include pcre.h, we explicitly include it
91    here before pcre_internal.h so that the PCRE_EXP_xxx macros get set
92    appropriately for an application, not for building PCRE. */
93    
94    #include "pcre.h"
95  #include "pcre_internal.h"  #include "pcre_internal.h"
96    
97  /* 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
98  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
99  symbols to prevent clashes. */  external symbols to prevent clashes. */
100    
101    #define _pcre_ucp_gentype      ucp_gentype
102  #define _pcre_utf8_table1      utf8_table1  #define _pcre_utf8_table1      utf8_table1
103  #define _pcre_utf8_table1_size utf8_table1_size  #define _pcre_utf8_table1_size utf8_table1_size
104  #define _pcre_utf8_table2      utf8_table2  #define _pcre_utf8_table2      utf8_table2
# Line 87  symbols to prevent clashes. */ Line 106  symbols to prevent clashes. */
106  #define _pcre_utf8_table4      utf8_table4  #define _pcre_utf8_table4      utf8_table4
107  #define _pcre_utt              utt  #define _pcre_utt              utt
108  #define _pcre_utt_size         utt_size  #define _pcre_utt_size         utt_size
109    #define _pcre_utt_names        utt_names
110  #define _pcre_OP_lengths       OP_lengths  #define _pcre_OP_lengths       OP_lengths
111    
112  #include "pcre_tables.c"  #include "pcre_tables.c"
# Line 149  static int callout_count; Line 169  static int callout_count;
169  static int callout_extra;  static int callout_extra;
170  static int callout_fail_count;  static int callout_fail_count;
171  static int callout_fail_id;  static int callout_fail_id;
172    static int debug_lengths;
173  static int first_callout;  static int first_callout;
174  static int locale_set = 0;  static int locale_set = 0;
175  static int show_malloc;  static int show_malloc;
# Line 180  optimal way of handling this, but hey, t Line 201  optimal way of handling this, but hey, t
201  Arguments:  Arguments:
202    f            the file to read    f            the file to read
203    start        where in buffer to start (this *must* be within buffer)    start        where in buffer to start (this *must* be within buffer)
204      prompt       for stdin or readline()
205    
206  Returns:       pointer to the start of new data  Returns:       pointer to the start of new data
207                 could be a copy of start, or could be moved                 could be a copy of start, or could be moved
# Line 187  Returns:       pointer to the start of n Line 209  Returns:       pointer to the start of n
209  */  */
210    
211  static uschar *  static uschar *
212  extend_inputline(FILE *f, uschar *start)  extend_inputline(FILE *f, uschar *start, const char *prompt)
213  {  {
214  uschar *here = start;  uschar *here = start;
215    
# Line 198  for (;;) Line 220  for (;;)
220    if (rlen > 1000)    if (rlen > 1000)
221      {      {
222      int dlen;      int dlen;
223      if (fgets((char *)here, rlen,  f) == NULL)  
224        return (here == start)? NULL : start;      /* If libreadline support is required, use readline() to read a line if the
225        input is a terminal. Note that readline() removes the trailing newline, so
226        we must put it back again, to be compatible with fgets(). */
227    
228    #ifdef SUPPORT_LIBREADLINE
229        if (isatty(fileno(f)))
230          {
231          size_t len;
232          char *s = readline(prompt);
233          if (s == NULL) return (here == start)? NULL : start;
234          len = strlen(s);
235          if (len > 0) add_history(s);
236          if (len > rlen - 1) len = rlen - 1;
237          memcpy(here, s, len);
238          here[len] = '\n';
239          here[len+1] = 0;
240          free(s);
241          }
242        else
243    #endif
244    
245        /* Read the next line by normal means, prompting if the file is stdin. */
246    
247          {
248          if (f == stdin) printf(prompt);
249          if (fgets((char *)here, rlen,  f) == NULL)
250            return (here == start)? NULL : start;
251          }
252    
253      dlen = (int)strlen((char *)here);      dlen = (int)strlen((char *)here);
254      if (dlen > 0 && here[dlen - 1] == '\n') return start;      if (dlen > 0 && here[dlen - 1] == '\n') return start;
255      here += dlen;      here += dlen;
# Line 656  return count; Line 706  return count;
706    
707    
708  /*************************************************  /*************************************************
709    *         Case-independent strncmp() function    *
710    *************************************************/
711    
712    /*
713    Arguments:
714      s         first string
715      t         second string
716      n         number of characters to compare
717    
718    Returns:    < 0, = 0, or > 0, according to the comparison
719    */
720    
721    static int
722    strncmpic(uschar *s, uschar *t, int n)
723    {
724    while (n--)
725      {
726      int c = tolower(*s++) - tolower(*t++);
727      if (c) return c;
728      }
729    return 0;
730    }
731    
732    
733    
734    /*************************************************
735  *         Check newline indicator                *  *         Check newline indicator                *
736  *************************************************/  *************************************************/
737    
738  /* This is used both at compile and run-time to check for <xxx> escapes, where  /* This is used both at compile and run-time to check for <xxx> escapes, where
739  xxx is LF, CR, CRLF, or ANY. Print a message and return 0 if there is no match.  xxx is LF, CR, CRLF, ANYCRLF, or ANY. Print a message and return 0 if there is
740    no match.
741    
742  Arguments:  Arguments:
743    p           points after the leading '<'    p           points after the leading '<'
# Line 672  Returns:      appropriate PCRE_NEWLINE_x Line 749  Returns:      appropriate PCRE_NEWLINE_x
749  static int  static int
750  check_newline(uschar *p, FILE *f)  check_newline(uschar *p, FILE *f)
751  {  {
752  if (strncmp((char *)p, "cr>", 3) == 0) return PCRE_NEWLINE_CR;  if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
753  if (strncmp((char *)p, "lf>", 3) == 0) return PCRE_NEWLINE_LF;  if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
754  if (strncmp((char *)p, "crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;  if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
755  if (strncmp((char *)p, "any>", 4) == 0) return PCRE_NEWLINE_ANY;  if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
756    if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
757    if (strncmpic(p, (uschar *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;
758    if (strncmpic(p, (uschar *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;
759  fprintf(f, "Unknown newline type at: <%s\n", p);  fprintf(f, "Unknown newline type at: <%s\n", p);
760  return 0;  return 0;
761  }  }
# Line 689  return 0; Line 769  return 0;
769  static void  static void
770  usage(void)  usage(void)
771  {  {
772  printf("Usage:     pcretest [options] [<input> [<output>]]\n");  printf("Usage:     pcretest [options] [<input file> [<output file>]]\n\n");
773    printf("Input and output default to stdin and stdout.\n");
774    #ifdef SUPPORT_LIBREADLINE
775    printf("If input is a terminal, readline() is used to read from it.\n");
776    #else
777    printf("This version of pcretest is not linked with readline().\n");
778    #endif
779    printf("\nOptions:\n");
780  printf("  -b       show compiled code (bytecode)\n");  printf("  -b       show compiled code (bytecode)\n");
781  printf("  -C       show PCRE compile-time options and exit\n");  printf("  -C       show PCRE compile-time options and exit\n");
782  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 698  printf("  -dfa     force DFA matching fo Line 785  printf("  -dfa     force DFA matching fo
785  #endif  #endif
786  printf("  -help    show usage information\n");  printf("  -help    show usage information\n");
787  printf("  -i       show information about compiled patterns\n"  printf("  -i       show information about compiled patterns\n"
788           "  -M       find MATCH_LIMIT minimum for each subject\n"
789         "  -m       output memory used information\n"         "  -m       output memory used information\n"
790         "  -o <n>   set size of offsets vector to <n>\n");         "  -o <n>   set size of offsets vector to <n>\n");
791  #if !defined NOPOSIX  #if !defined NOPOSIX
# Line 727  int main(int argc, char **argv) Line 815  int main(int argc, char **argv)
815  FILE *infile = stdin;  FILE *infile = stdin;
816  int options = 0;  int options = 0;
817  int study_options = 0;  int study_options = 0;
818    int default_find_match_limit = FALSE;
819  int op = 1;  int op = 1;
820  int timeit = 0;  int timeit = 0;
821  int timeitm = 0;  int timeitm = 0;
# Line 786  while (argc > 1 && argv[op][0] == '-') Line 875  while (argc > 1 && argv[op][0] == '-')
875    else if (strcmp(argv[op], "-b") == 0) debug = 1;    else if (strcmp(argv[op], "-b") == 0) debug = 1;
876    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
877    else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;    else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;
878      else if (strcmp(argv[op], "-M") == 0) default_find_match_limit = TRUE;
879  #if !defined NODFA  #if !defined NODFA
880    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;
881  #endif  #endif
# Line 838  while (argc > 1 && argv[op][0] == '-') Line 928  while (argc > 1 && argv[op][0] == '-')
928    else if (strcmp(argv[op], "-C") == 0)    else if (strcmp(argv[op], "-C") == 0)
929      {      {
930      int rc;      int rc;
931        unsigned long int lrc;
932      printf("PCRE version %s\n", pcre_version());      printf("PCRE version %s\n", pcre_version());
933      printf("Compiled with\n");      printf("Compiled with\n");
934      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
# Line 845  while (argc > 1 && argv[op][0] == '-') Line 936  while (argc > 1 && argv[op][0] == '-')
936      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
937      printf("  %sUnicode properties support\n", rc? "" : "No ");      printf("  %sUnicode properties support\n", rc? "" : "No ");
938      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
939      printf("  Newline sequence is %s\n", (rc == '\r')? "CR" :      /* Note that these values are always the ASCII values, even
940        (rc == '\n')? "LF" : (rc == ('\r'<<8 | '\n'))? "CRLF" :      in EBCDIC environments. CR is 13 and NL is 10. */
941        printf("  Newline sequence is %s\n", (rc == 13)? "CR" :
942          (rc == 10)? "LF" : (rc == (13<<8 | 10))? "CRLF" :
943          (rc == -2)? "ANYCRLF" :
944        (rc == -1)? "ANY" : "???");        (rc == -1)? "ANY" : "???");
945        (void)pcre_config(PCRE_CONFIG_BSR, &rc);
946        printf("  \\R matches %s\n", rc? "CR, LF, or CRLF only" :
947                                         "all Unicode newlines");
948      (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);      (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);
949      printf("  Internal link size = %d\n", rc);      printf("  Internal link size = %d\n", rc);
950      (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);      (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);
951      printf("  POSIX malloc threshold = %d\n", rc);      printf("  POSIX malloc threshold = %d\n", rc);
952      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc);      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &lrc);
953      printf("  Default match limit = %d\n", rc);      printf("  Default match limit = %ld\n", lrc);
954      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &rc);      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &lrc);
955      printf("  Default recursion depth limit = %d\n", rc);      printf("  Default recursion depth limit = %ld\n", lrc);
956      (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc);      (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc);
957      printf("  Match recursion uses %s\n", rc? "stack" : "heap");      printf("  Match recursion uses %s\n", rc? "stack" : "heap");
958      goto EXIT;      goto EXIT;
# Line 884  offsets = (int *)malloc(size_offsets_max Line 981  offsets = (int *)malloc(size_offsets_max
981  if (offsets == NULL)  if (offsets == NULL)
982    {    {
983    printf("** Failed to get %d bytes of memory for offsets vector\n",    printf("** Failed to get %d bytes of memory for offsets vector\n",
984      size_offsets_max * sizeof(int));      (int)(size_offsets_max * sizeof(int)));
985    yield = 1;    yield = 1;
986    goto EXIT;    goto EXIT;
987    }    }
# Line 944  while (!done) Line 1041  while (!done)
1041    size_t size, regex_gotten_store;    size_t size, regex_gotten_store;
1042    int do_study = 0;    int do_study = 0;
1043    int do_debug = debug;    int do_debug = debug;
   int debug_lengths = 1;  
1044    int do_G = 0;    int do_G = 0;
1045    int do_g = 0;    int do_g = 0;
1046    int do_showinfo = showinfo;    int do_showinfo = showinfo;
# Line 953  while (!done) Line 1049  while (!done)
1049    int erroroffset, len, delimiter, poffset;    int erroroffset, len, delimiter, poffset;
1050    
1051    use_utf8 = 0;    use_utf8 = 0;
1052      debug_lengths = 1;
1053    
1054    if (infile == stdin) printf("  re> ");    if (extend_inputline(infile, buffer, "  re> ") == NULL) break;
   if (extend_inputline(infile, buffer) == NULL) break;  
1055    if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);    if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
1056    fflush(outfile);    fflush(outfile);
1057    
# Line 1055  while (!done) Line 1151  while (!done)
1151    
1152    if (isalnum(delimiter) || delimiter == '\\')    if (isalnum(delimiter) || delimiter == '\\')
1153      {      {
1154      fprintf(outfile, "** Delimiter must not be alphameric or \\\n");      fprintf(outfile, "** Delimiter must not be alphanumeric or \\\n");
1155      goto SKIP_DATA;      goto SKIP_DATA;
1156      }      }
1157    
# Line 1071  while (!done) Line 1167  while (!done)
1167        pp++;        pp++;
1168        }        }
1169      if (*pp != 0) break;      if (*pp != 0) break;
1170      if (infile == stdin) printf("    > ");      if ((pp = extend_inputline(infile, pp, "    > ")) == NULL)
     if ((pp = extend_inputline(infile, pp)) == NULL)  
1171        {        {
1172        fprintf(outfile, "** Unexpected EOF\n");        fprintf(outfile, "** Unexpected EOF\n");
1173        done = 1;        done = 1;
# Line 1135  while (!done) Line 1230  while (!done)
1230        case 'S': do_study = 1; break;        case 'S': do_study = 1; break;
1231        case 'U': options |= PCRE_UNGREEDY; break;        case 'U': options |= PCRE_UNGREEDY; break;
1232        case 'X': options |= PCRE_EXTRA; break;        case 'X': options |= PCRE_EXTRA; break;
1233        case 'Z': debug_lengths = 0;        case 'Z': debug_lengths = 0; break;
1234        case '8': options |= PCRE_UTF8; use_utf8 = 1; break;        case '8': options |= PCRE_UTF8; use_utf8 = 1; break;
1235        case '?': options |= PCRE_NO_UTF8_CHECK; break;        case '?': options |= PCRE_NO_UTF8_CHECK; break;
1236    
# Line 1164  while (!done) Line 1259  while (!done)
1259    
1260        case '<':        case '<':
1261          {          {
1262          int x = check_newline(pp, outfile);          if (strncmp((char *)pp, "JS>", 3) == 0)
1263          if (x == 0) goto SKIP_DATA;            {
1264          options |= x;            options |= PCRE_JAVASCRIPT_COMPAT;
1265          while (*pp++ != '>');            pp += 3;
1266              }
1267            else
1268              {
1269              int x = check_newline(pp, outfile);
1270              if (x == 0) goto SKIP_DATA;
1271              options |= x;
1272              while (*pp++ != '>');
1273              }
1274          }          }
1275        break;        break;
1276    
# Line 1246  while (!done) Line 1349  while (!done)
1349          {          {
1350          for (;;)          for (;;)
1351            {            {
1352            if (extend_inputline(infile, buffer) == NULL)            if (extend_inputline(infile, buffer, NULL) == NULL)
1353              {              {
1354              done = 1;              done = 1;
1355              goto CONTINUE;              goto CONTINUE;
# Line 1309  while (!done) Line 1412  while (!done)
1412      if (do_flip)      if (do_flip)
1413        {        {
1414        real_pcre *rre = (real_pcre *)re;        real_pcre *rre = (real_pcre *)re;
1415        rre->magic_number = byteflip(rre->magic_number, sizeof(rre->magic_number));        rre->magic_number =
1416            byteflip(rre->magic_number, sizeof(rre->magic_number));
1417        rre->size = byteflip(rre->size, sizeof(rre->size));        rre->size = byteflip(rre->size, sizeof(rre->size));
1418        rre->options = byteflip(rre->options, sizeof(rre->options));        rre->options = byteflip(rre->options, sizeof(rre->options));
1419        rre->top_bracket = byteflip(rre->top_bracket, sizeof(rre->top_bracket));        rre->flags = (pcre_uint16)byteflip(rre->flags, sizeof(rre->flags));
1420        rre->top_backref = byteflip(rre->top_backref, sizeof(rre->top_backref));        rre->top_bracket =
1421        rre->first_byte = byteflip(rre->first_byte, sizeof(rre->first_byte));          (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));
1422        rre->req_byte = byteflip(rre->req_byte, sizeof(rre->req_byte));        rre->top_backref =
1423        rre->name_table_offset = byteflip(rre->name_table_offset,          (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));
1424          rre->first_byte =
1425            (pcre_uint16)byteflip(rre->first_byte, sizeof(rre->first_byte));
1426          rre->req_byte =
1427            (pcre_uint16)byteflip(rre->req_byte, sizeof(rre->req_byte));
1428          rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,
1429          sizeof(rre->name_table_offset));          sizeof(rre->name_table_offset));
1430        rre->name_entry_size = byteflip(rre->name_entry_size,        rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,
1431          sizeof(rre->name_entry_size));          sizeof(rre->name_entry_size));
1432        rre->name_count = byteflip(rre->name_count, sizeof(rre->name_count));        rre->name_count = (pcre_uint16)byteflip(rre->name_count,
1433            sizeof(rre->name_count));
1434    
1435        if (extra != NULL)        if (extra != NULL)
1436          {          {
# Line 1346  while (!done) Line 1456  while (!done)
1456  #if !defined NOINFOCHECK  #if !defined NOINFOCHECK
1457        int old_first_char, old_options, old_count;        int old_first_char, old_options, old_count;
1458  #endif  #endif
1459        int count, backrefmax, first_char, need_char;        int count, backrefmax, first_char, need_char, okpartial, jchanged,
1460            hascrorlf;
1461        int nameentrysize, namecount;        int nameentrysize, namecount;
1462        const uschar *nametable;        const uschar *nametable;
1463    
# Line 1359  while (!done) Line 1470  while (!done)
1470        new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);        new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
1471        new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount);        new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount);
1472        new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable);        new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable);
1473          new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial);
1474          new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);
1475          new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);
1476    
1477  #if !defined NOINFOCHECK  #if !defined NOINFOCHECK
1478        old_count = pcre_info(re, &old_options, &old_first_char);        old_count = pcre_info(re, &old_options, &old_first_char);
# Line 1400  while (!done) Line 1514  while (!done)
1514            }            }
1515          }          }
1516    
1517        /* The NOPARTIAL bit is a private bit in the options, so we have        if (!okpartial) fprintf(outfile, "Partial matching not supported\n");
1518        to fish it out via out back door */        if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n");
1519    
1520        all_options = ((real_pcre *)re)->options;        all_options = ((real_pcre *)re)->options;
1521        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");  
1522    
1523        if (get_options == 0) fprintf(outfile, "No options\n");        if (get_options == 0) fprintf(outfile, "No options\n");
1524          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",
1525            ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",            ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",
1526            ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",            ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",
1527            ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",            ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",
1528            ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "",            ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "",
1529            ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "",            ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "",
1530            ((get_options & PCRE_DOTALL) != 0)? " dotall" : "",            ((get_options & PCRE_DOTALL) != 0)? " dotall" : "",
1531              ((get_options & PCRE_BSR_ANYCRLF) != 0)? " bsr_anycrlf" : "",
1532              ((get_options & PCRE_BSR_UNICODE) != 0)? " bsr_unicode" : "",
1533            ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",            ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
1534            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",
1535            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
# Line 1428  while (!done) Line 1538  while (!done)
1538            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",
1539            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");
1540    
1541          if (jchanged) fprintf(outfile, "Duplicate name status changes\n");
1542    
1543        switch (get_options & PCRE_NEWLINE_BITS)        switch (get_options & PCRE_NEWLINE_BITS)
1544          {          {
1545          case PCRE_NEWLINE_CR:          case PCRE_NEWLINE_CR:
# Line 1442  while (!done) Line 1554  while (!done)
1554          fprintf(outfile, "Forced newline sequence: CRLF\n");          fprintf(outfile, "Forced newline sequence: CRLF\n");
1555          break;          break;
1556    
1557            case PCRE_NEWLINE_ANYCRLF:
1558            fprintf(outfile, "Forced newline sequence: ANYCRLF\n");
1559            break;
1560    
1561          case PCRE_NEWLINE_ANY:          case PCRE_NEWLINE_ANY:
1562          fprintf(outfile, "Forced newline sequence: ANY\n");          fprintf(outfile, "Forced newline sequence: ANY\n");
1563          break;          break;
# Line 1546  while (!done) Line 1662  while (!done)
1662        else        else
1663          {          {
1664          uschar sbuf[8];          uschar sbuf[8];
1665          sbuf[0] = (true_size >> 24)  & 255;          sbuf[0] = (uschar)((true_size >> 24) & 255);
1666          sbuf[1] = (true_size >> 16)  & 255;          sbuf[1] = (uschar)((true_size >> 16) & 255);
1667          sbuf[2] = (true_size >>  8)  & 255;          sbuf[2] = (uschar)((true_size >>  8) & 255);
1668          sbuf[3] = (true_size)  & 255;          sbuf[3] = (uschar)((true_size) & 255);
1669    
1670          sbuf[4] = (true_study_size >> 24)  & 255;          sbuf[4] = (uschar)((true_study_size >> 24) & 255);
1671          sbuf[5] = (true_study_size >> 16)  & 255;          sbuf[5] = (uschar)((true_study_size >> 16) & 255);
1672          sbuf[6] = (true_study_size >>  8)  & 255;          sbuf[6] = (uschar)((true_study_size >>  8) & 255);
1673          sbuf[7] = (true_study_size)  & 255;          sbuf[7] = (uschar)((true_study_size) & 255);
1674    
1675          if (fwrite(sbuf, 1, 8, f) < 8 ||          if (fwrite(sbuf, 1, 8, f) < 8 ||
1676              fwrite(re, 1, true_size, f) < true_size)              fwrite(re, 1, true_size, f) < true_size)
# Line 1591  while (!done) Line 1707  while (!done)
1707    for (;;)    for (;;)
1708      {      {
1709      uschar *q;      uschar *q;
1710      uschar *bptr = dbuffer;      uschar *bptr;
1711      int *use_offsets = offsets;      int *use_offsets = offsets;
1712      int use_size_offsets = size_offsets;      int use_size_offsets = size_offsets;
1713      int callout_data = 0;      int callout_data = 0;
1714      int callout_data_set = 0;      int callout_data_set = 0;
1715      int count, c;      int count, c;
1716      int copystrings = 0;      int copystrings = 0;
1717      int find_match_limit = 0;      int find_match_limit = default_find_match_limit;
1718      int getstrings = 0;      int getstrings = 0;
1719      int getlist = 0;      int getlist = 0;
1720      int gmatched = 0;      int gmatched = 0;
# Line 1628  while (!done) Line 1744  while (!done)
1744      len = 0;      len = 0;
1745      for (;;)      for (;;)
1746        {        {
1747        if (infile == stdin) printf("data> ");        if (extend_inputline(infile, buffer + len, "data> ") == NULL)
       if (extend_inputline(infile, buffer + len) == NULL)  
1748          {          {
1749          if (len > 0) break;          if (len > 0) break;
1750          done = 1;          done = 1;
# Line 1647  while (!done) Line 1762  while (!done)
1762      p = buffer;      p = buffer;
1763      while (isspace(*p)) p++;      while (isspace(*p)) p++;
1764    
1765      q = dbuffer;      bptr = q = dbuffer;
1766      while ((c = *p++) != 0)      while ((c = *p++) != 0)
1767        {        {
1768        int i = 0;        int i = 0;
# Line 1697  while (!done) Line 1812  while (!done)
1812              {              {
1813              unsigned char buff8[8];              unsigned char buff8[8];
1814              int ii, utn;              int ii, utn;
1815              utn = ord2utf8(c, buff8);              if (use_utf8)
1816              for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];                {
1817              c = buff8[ii];   /* Last byte */                utn = ord2utf8(c, buff8);
1818                  for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
1819                  c = buff8[ii];   /* Last byte */
1820                  }
1821                else
1822                 {
1823                 if (c > 255)
1824                   fprintf(outfile, "** Character \\x{%x} is greater than 255 and "
1825                     "UTF-8 mode is not enabled.\n"
1826                     "** Truncation will probably give the wrong result.\n", c);
1827                 }
1828              p = pt + 1;              p = pt + 1;
1829              break;              break;
1830              }              }
# Line 1842  while (!done) Line 1967  while (!done)
1967            if (offsets == NULL)            if (offsets == NULL)
1968              {              {
1969              printf("** Failed to get %d bytes of memory for offsets vector\n",              printf("** Failed to get %d bytes of memory for offsets vector\n",
1970                size_offsets_max * sizeof(int));                (int)(size_offsets_max * sizeof(int)));
1971              yield = 1;              yield = 1;
1972              goto EXIT;              goto EXIT;
1973              }              }
# Line 1886  while (!done) Line 2011  while (!done)
2011          case 'S':          case 'S':
2012          show_malloc = 1;          show_malloc = 1;
2013          continue;          continue;
2014    
2015            case 'Y':
2016            options |= PCRE_NO_START_OPTIMIZE;
2017            continue;
2018    
2019          case 'Z':          case 'Z':
2020          options |= PCRE_NOTEOL;          options |= PCRE_NOTEOL;
# Line 1909  while (!done) Line 2038  while (!done)
2038      *q = 0;      *q = 0;
2039      len = q - dbuffer;      len = q - dbuffer;
2040    
2041        /* Move the data to the end of the buffer so that a read over the end of
2042        the buffer will be seen by valgrind, even if it doesn't cause a crash. If
2043        we are using the POSIX interface, we must include the terminating zero. */
2044    
2045    #if !defined NOPOSIX
2046        if (posix || do_posix)
2047          {
2048          memmove(bptr + buffer_size - len - 1, bptr, len + 1);
2049          bptr += buffer_size - len - 1;
2050          }
2051        else
2052    #endif
2053          {
2054          memmove(bptr + buffer_size - len, bptr, len);
2055          bptr += buffer_size - len;
2056          }
2057    
2058      if ((all_use_dfa || use_dfa) && find_match_limit)      if ((all_use_dfa || use_dfa) && find_match_limit)
2059        {        {
2060        printf("**Match limit not relevant for DFA matching: ignored\n");        printf("**Match limit not relevant for DFA matching: ignored\n");
# Line 1928  while (!done) Line 2074  while (!done)
2074          pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets);          pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets);
2075        if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;        if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;
2076        if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;        if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;
2077          if ((options & PCRE_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY;
2078    
2079        rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags);        rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags);
2080    
# Line 2211  while (!done) Line 2358  while (!done)
2358          }          }
2359    
2360        /* Failed to match. If this is a /g or /G loop and we previously set        /* Failed to match. If this is a /g or /G loop and we previously set
2361        g_notempty after a null match, this is not necessarily the end.        g_notempty after a null match, this is not necessarily the end. We want
2362        We want to advance the start offset, and continue. In the case of UTF-8        to advance the start offset, and continue. We won't be at the end of the
2363        matching, the advance must be one character, not one byte. Fudge the        string - that was checked before setting g_notempty.
2364        offset values to achieve this. We won't be at the end of the string -  
2365        that was checked before setting g_notempty. */        Complication arises in the case when the newline option is "any" or
2366          "anycrlf". If the previous match was at the end of a line terminated by
2367          CRLF, an advance of one character just passes the \r, whereas we should
2368          prefer the longer newline sequence, as does the code in pcre_exec().
2369          Fudge the offset value to achieve this.
2370    
2371          Otherwise, in the case of UTF-8 matching, the advance must be one
2372          character, not one byte. */
2373    
2374        else        else
2375          {          {
2376          if (g_notempty != 0)          if (g_notempty != 0)
2377            {            {
2378            int onechar = 1;            int onechar = 1;
2379              unsigned int obits = ((real_pcre *)re)->options;
2380            use_offsets[0] = start_offset;            use_offsets[0] = start_offset;
2381            if (use_utf8)            if ((obits & PCRE_NEWLINE_BITS) == 0)
2382                {
2383                int d;
2384                (void)pcre_config(PCRE_CONFIG_NEWLINE, &d);
2385                /* Note that these values are always the ASCII ones, even in
2386                EBCDIC environments. CR = 13, NL = 10. */
2387                obits = (d == 13)? PCRE_NEWLINE_CR :
2388                        (d == 10)? PCRE_NEWLINE_LF :
2389                        (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF :
2390                        (d == -2)? PCRE_NEWLINE_ANYCRLF :
2391                        (d == -1)? PCRE_NEWLINE_ANY : 0;
2392                }
2393              if (((obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANY ||
2394                   (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANYCRLF)
2395                  &&
2396                  start_offset < len - 1 &&
2397                  bptr[start_offset] == '\r' &&
2398                  bptr[start_offset+1] == '\n')
2399                onechar++;
2400              else if (use_utf8)
2401              {              {
2402              while (start_offset + onechar < len)              while (start_offset + onechar < len)
2403                {                {
# Line 2258  while (!done) Line 2432  while (!done)
2432        character. */        character. */
2433    
2434        g_notempty = 0;        g_notempty = 0;
2435    
2436        if (use_offsets[0] == use_offsets[1])        if (use_offsets[0] == use_offsets[1])
2437          {          {
2438          if (use_offsets[0] == len) break;          if (use_offsets[0] == len) break;

Legend:
Removed from v.121  
changed lines
  Added in v.391

  ViewVC Help
Powered by ViewVC 1.1.5