/[pcre]/code/branches/pcre16/pcretest.c
ViewVC logotype

Diff of /code/branches/pcre16/pcretest.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

code/trunk/pcretest.c revision 658 by ph10, Mon Aug 15 17:43:44 2011 UTC code/branches/pcre16/pcretest.c revision 808 by ph10, Sun Dec 18 11:11:48 2011 UTC
# Line 4  Line 4 
4    
5  /* This program was hacked up as a tester for PCRE. I really should have  /* This program was hacked up as a tester for PCRE. I really should have
6  written it more tidily in the first place. Will I ever learn? It has grown and  written it more tidily in the first place. Will I ever learn? It has grown and
7  been extended and consequently is now rather, er, *very* untidy in places.  been extended and consequently is now rather, er, *very* untidy in places. The
8    addition of 16-bit support has made it even worse. :-(
9    
10  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
11  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 107  appropriately for an application, not fo Line 108  appropriately for an application, not fo
108  #include "pcre.h"  #include "pcre.h"
109  #include "pcre_internal.h"  #include "pcre_internal.h"
110    
111    /* The pcre_printint() function, which prints the internal form of a compiled
112    regex, is held in a separate file so that (a) it can be compiled in either
113    8-bit or 16-bit mode, and (b) it can be #included directly in pcre_compile.c
114    when that is compiled in debug mode. */
115    
116    #ifdef SUPPORT_PCRE8
117    void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
118    #endif
119    #ifdef SUPPORT_PCRE16
120    void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths);
121    #endif
122    
123  /* We need access to some of the data tables that PCRE uses. So as not to have  /* We need access to some of the data tables that PCRE uses. So as not to have
124  to keep two copies, we include the source file here, changing the names of the  to keep two copies, we include the source file here, changing the names of the
125  external symbols to prevent clashes. */  external symbols to prevent clashes. */
126    
127  #define _pcre_ucp_gentype      ucp_gentype  #define _pcre_ucp_gentype      ucp_gentype
128    #define _pcre_ucp_typerange    ucp_typerange
129  #define _pcre_utf8_table1      utf8_table1  #define _pcre_utf8_table1      utf8_table1
130  #define _pcre_utf8_table1_size utf8_table1_size  #define _pcre_utf8_table1_size utf8_table1_size
131  #define _pcre_utf8_table2      utf8_table2  #define _pcre_utf8_table2      utf8_table2
# Line 124  external symbols to prevent clashes. */ Line 138  external symbols to prevent clashes. */
138    
139  #include "pcre_tables.c"  #include "pcre_tables.c"
140    
 /* We also need the pcre_printint() function for printing out compiled  
 patterns. This function is in a separate file so that it can be included in  
 pcre_compile.c when that module is compiled with debugging enabled. It needs to  
 know which case is being compiled. */  
   
 #define COMPILING_PCRETEST  
 #include "pcre_printint.src"  
   
141  /* The definition of the macro PRINTABLE, which determines whether to print an  /* The definition of the macro PRINTABLE, which determines whether to print an
142  output character as-is or as a hex value when showing compiled patterns, is  output character as-is or as a hex value when showing compiled patterns, is
143  contained in the printint.src file. We uses it here also, in cases when the  the same as in the printint.src file. We uses it here in cases when the locale
144  locale has not been explicitly changed, so as to get consistent output from  has not been explicitly changed, so as to get consistent output from systems
145  systems that differ in their output from isprint() even in the "C" locale. */  that differ in their output from isprint() even in the "C" locale. */
146    
147  #define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c))  #ifdef EBCDIC
148    #define PRINTABLE(c) ((c) >= 64 && (c) < 255)
149    #else
150    #define PRINTABLE(c) ((c) >= 32 && (c) < 127)
151    #endif
152    
153    #define PRINTOK(c) (locale_set? isprint(c) : PRINTABLE(c))
154    
155  /* It is possible to compile this test program without including support for  /* It is possible to compile this test program without including support for
156  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 148  Makefile. */ Line 160  Makefile. */
160  #include "pcreposix.h"  #include "pcreposix.h"
161  #endif  #endif
162    
163  /* It is also possible, for the benefit of the version currently imported into  /* It is also possible, originally for the benefit of a version that was
164  Exim, to build pcretest without support for UTF8 (define NOUTF8), without the  imported into Exim, to build pcretest without support for UTF8 (define NOUTF8),
165  interface to the DFA matcher (NODFA), and without the doublecheck of the old  without the interface to the DFA matcher (NODFA), and without the doublecheck
166  "info" function (define NOINFOCHECK). In fact, we automatically cut out the  of the old "info" function (define NOINFOCHECK). In fact, we automatically cut
167  UTF8 support if PCRE is built without it. */  out the UTF8 support if PCRE is built without it. */
168    
169  #ifndef SUPPORT_UTF8  #ifndef SUPPORT_UTF8
170  #ifndef NOUTF8  #ifndef NOUTF8
# Line 160  UTF8 support if PCRE is built without it Line 172  UTF8 support if PCRE is built without it
172  #endif  #endif
173  #endif  #endif
174    
175    /* To make the code a bit tidier for 8-bit and 16-bit support, we define macros
176    for all the pcre[16]_xxx functions (except pcre16_fullinfo, which is called
177    only from one place and is handled differently). I couldn't dream up any way of
178    using a single macro to do this in a generic way, because of the many different
179    argument requirements. We know that at least one of SUPPORT_PCRE8 and
180    SUPPORT_PCRE16 must be set. First define macros for each individual mode; then
181    use these in the definitions of generic macros. */
182    
183    #ifdef SUPPORT_PCRE8
184    #define PCHARS8(lv, p, len, f) \
185      lv = pchars((pcre_uint8 *)p, len, f)
186    
187    #define PCHARSV8(p, len, f) \
188      (void)pchars((pcre_uint8 *)p, len, f)
189    
190    #define PCRE_COMPILE8(re, pat, options, error, erroffset, tables) \
191      re = pcre_compile((char *)pat, options, error, erroffset, tables)
192    
193    #define PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
194        offsets, size_offsets) \
195      count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, \
196        offsets, size_offsets)
197    
198    #define PCRE_STUDY8(extra, re, options, error) \
199      extra = pcre_study(re, options, error)
200    #endif
201    
202    
203    #ifdef SUPPORT_PCRE16
204    #define PCHARS16(lv, p, len, f) \
205      lv = pchars16((PCRE_SPTR16)p, len, f)
206    
207    #define PCHARSV16(p, len, f) \
208      (void)pchars16((PCRE_SPTR16)p, len, f)
209    
210    #define PCRE_COMPILE16(re, pat, options, error, erroffset, tables) \
211      re = pcre16_compile((PCRE_SPTR16)pat, options, error, erroffset, tables)
212    
213    #define PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
214        offsets, size_offsets) \
215      count = pcre16_exec(re, extra, (PCRE_SPTR16)bptr, len, start_offset, \
216        options, offsets, size_offsets)
217    
218    #define PCRE_STUDY16(extra, re, options, error) \
219      extra = pcre16_study(re, options, error)
220    #endif
221    
222    
223    /* ----- Both modes are supported; a runtime test is needed ----- */
224    
225    #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
226    
227    #define PCHARS(lv, p, len, f) \
228      if (use_pcre16) \
229        PCHARS16(lv, p, len, f); \
230      else \
231        PCHARS8(lv, p, len, f)
232    
233    #define PCHARSV(p, len, f) \
234      if (use_pcre16) \
235        PCHARSV16(p, len, f); \
236      else \
237        PCHARSV8(p, len, f)
238    
239    #define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \
240      if (use_pcre16) \
241        PCRE_COMPILE16(re, pat, options, error, erroffset, tables); \
242      else \
243        PCRE_COMPILE8(re, pat, options, error, erroffset, tables)
244    
245    #define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \
246        offsets, size_offsets) \
247      if (use_pcre16) \
248        PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
249          offsets, size_offsets); \
250      else \
251        PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
252          offsets, size_offsets)
253    
254    #define PCRE_STUDY(extra, re, options, error) \
255      if (use_pcre16) \
256        PCRE_STUDY16(extra, re, options, error); \
257      else \
258        PCRE_STUDY8(extra, re, options, error)
259    
260    /* ----- Only 8-bit mode is supported ----- */
261    
262    #elif defined SUPPORT_PCRE8
263    #define PCHARS       PCHARS8
264    #define PCHARSV      PCHARSV8
265    #define PCRE_COMPILE PCRE_COMPILE8
266    #define PCRE_EXEC    PCRE_EXEC8
267    #define PCRE_STUDY   PCRE_STUDY8
268    
269    /* ----- Only 16-bit mode is supported ----- */
270    
271    #else
272    #define PCHARS       PCHARS16
273    #define PCHARSV      PCHARSV16
274    #define PCRE_COMPILE PCRE_COMPILE16
275    #define PCRE_EXEC    PCRE_EXEC16
276    #define PCRE_STUDY   PCRE_STUDY16
277    #endif
278    
279    /* ----- End of mode-specific function call macros ----- */
280    
281    
282  /* Other parameters */  /* Other parameters */
283    
# Line 189  static int locale_set = 0; Line 307  static int locale_set = 0;
307  static int show_malloc;  static int show_malloc;
308  static int use_utf8;  static int use_utf8;
309  static size_t gotten_store;  static size_t gotten_store;
310    static size_t first_gotten_store = 0;
311  static const unsigned char *last_callout_mark = NULL;  static const unsigned char *last_callout_mark = NULL;
312    
313  /* The buffers grow automatically if very long input lines are encountered. */  /* The buffers grow automatically if very long input lines are encountered. */
314    
315  static int buffer_size = 50000;  static int buffer_size = 50000;
316  static uschar *buffer = NULL;  static pcre_uint8 *buffer = NULL;
317  static uschar *dbuffer = NULL;  static pcre_uint8 *dbuffer = NULL;
318  static uschar *pbuffer = NULL;  static pcre_uint8 *pbuffer = NULL;
319    
320    #ifdef SUPPORT_PCRE16
321    static int buffer16_size = 0;
322    static pcre_uint16 *buffer16 = NULL;
323    #endif
324    
325    /* If we have 8-bit support, default use_pcre16 to false; if there is also
326    16-bit support, it can be changed by an option. If there is no 8-bit support,
327    there must be 16-bit support, so default it to 1. */
328    
329    #ifdef SUPPORT_PCRE8
330    static int use_pcre16 = 0;
331    #else
332    static int use_pcre16 = 1;
333    #endif
334    
335  /* Textual explanations for runtime error codes */  /* Textual explanations for runtime error codes */
336    
# Line 227  static const char *errtexts[] = { Line 361  static const char *errtexts[] = {
361    "invalid combination of newline options",    "invalid combination of newline options",
362    "bad offset value",    "bad offset value",
363    NULL,  /* SHORTUTF8 is handled specially */    NULL,  /* SHORTUTF8 is handled specially */
364    "nested recursion at the same subject position"    "nested recursion at the same subject position",
365      "JIT stack limit reached",
366      "pattern compiled in wrong mode (8-bit/16-bit error)"
367  };  };
368    
369    
# Line 243  the L (locale) option also adjusts the t Line 379  the L (locale) option also adjusts the t
379  /* This is the set of tables distributed as default with PCRE. It recognizes  /* This is the set of tables distributed as default with PCRE. It recognizes
380  only ASCII characters. */  only ASCII characters. */
381    
382  static const unsigned char tables0[] = {  static const pcre_uint8 tables0[] = {
383    
384  /* This table is a lower casing table. */  /* This table is a lower casing table. */
385    
# Line 416  graph, print, punct, and cntrl. Other cl Line 552  graph, print, punct, and cntrl. Other cl
552  be at least an approximation of ISO 8859. In particular, there are characters  be at least an approximation of ISO 8859. In particular, there are characters
553  greater than 128 that are marked as spaces, letters, etc. */  greater than 128 that are marked as spaces, letters, etc. */
554    
555  static const unsigned char tables1[] = {  static const pcre_uint8 tables1[] = {
556  0,1,2,3,4,5,6,7,  0,1,2,3,4,5,6,7,
557  8,9,10,11,12,13,14,15,  8,9,10,11,12,13,14,15,
558  16,17,18,19,20,21,22,23,  16,17,18,19,20,21,22,23,
# Line 579  return sys_errlist[n]; Line 715  return sys_errlist[n];
715  #endif /* HAVE_STRERROR */  #endif /* HAVE_STRERROR */
716    
717    
718    /*************************************************
719    *         JIT memory callback                    *
720    *************************************************/
721    
722    static pcre_jit_stack* jit_callback(void *arg)
723    {
724    return (pcre_jit_stack *)arg;
725    }
726    
727    
728    /*************************************************
729    *            Convert UTF-8 string to value       *
730    *************************************************/
731    
732    /* This function takes one or more bytes that represents a UTF-8 character,
733    and returns the value of the character.
734    
735    Argument:
736      utf8bytes   a pointer to the byte vector
737      vptr        a pointer to an int to receive the value
738    
739    Returns:      >  0 => the number of bytes consumed
740                  -6 to 0 => malformed UTF-8 character at offset = (-return)
741    */
742    
743    #if !defined NOUTF8
744    
745    static int
746    utf82ord(pcre_uint8 *utf8bytes, int *vptr)
747    {
748    int c = *utf8bytes++;
749    int d = c;
750    int i, j, s;
751    
752    for (i = -1; i < 6; i++)               /* i is number of additional bytes */
753      {
754      if ((d & 0x80) == 0) break;
755      d <<= 1;
756      }
757    
758    if (i == -1) { *vptr = c; return 1; }  /* ascii character */
759    if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */
760    
761    /* i now has a value in the range 1-5 */
762    
763    s = 6*i;
764    d = (c & utf8_table3[i]) << s;
765    
766    for (j = 0; j < i; j++)
767      {
768      c = *utf8bytes++;
769      if ((c & 0xc0) != 0x80) return -(j+1);
770      s -= 6;
771      d |= (c & 0x3f) << s;
772      }
773    
774    /* Check that encoding was the correct unique one */
775    
776    for (j = 0; j < utf8_table1_size; j++)
777      if (d <= utf8_table1[j]) break;
778    if (j != i) return -(i+1);
779    
780    /* Valid value */
781    
782    *vptr = d;
783    return i+1;
784    }
785    
786    #endif
787    
788    
789    
790    /*************************************************
791    *       Convert character value to UTF-8         *
792    *************************************************/
793    
794    /* This function takes an integer value in the range 0 - 0x7fffffff
795    and encodes it as a UTF-8 character in 0 to 6 bytes.
796    
797    Arguments:
798      cvalue     the character value
799      utf8bytes  pointer to buffer for result - at least 6 bytes long
800    
801    Returns:     number of characters placed in the buffer
802    */
803    
804    #if !defined NOUTF8
805    
806    static int
807    ord2utf8(int cvalue, pcre_uint8 *utf8bytes)
808    {
809    register int i, j;
810    for (i = 0; i < utf8_table1_size; i++)
811      if (cvalue <= utf8_table1[i]) break;
812    utf8bytes += i;
813    for (j = i; j > 0; j--)
814     {
815     *utf8bytes-- = 0x80 | (cvalue & 0x3f);
816     cvalue >>= 6;
817     }
818    *utf8bytes = utf8_table2[i] | cvalue;
819    return i + 1;
820    }
821    
822    #endif
823    
824    
825    
826    #ifdef SUPPORT_PCRE16
827    /*************************************************
828    *         Convert a string to 16-bit             *
829    *************************************************/
830    
831    /* In non-UTF mode, the space needed for a 16-bit string is exactly double the
832    8-bit size. For a UTF-8 string, the size needed for UTF-16 is no more than
833    double, because up to 0xffff uses no more than 3 bytes in UTF-8 but possibly 4
834    in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in UTF-16. The
835    result is always left in buffer16. */
836    
837    static int
838    to16(pcre_uint8 *p, int utf, int len)
839    {
840    pcre_uint16 *pp;
841    
842    if (buffer16_size < 2*len + 2)
843      {
844      if (buffer16 != NULL) free(buffer16);
845      buffer16_size = 2*len + 2;
846      buffer16 = (pcre_uint16 *)malloc(buffer16_size);
847      if (buffer16 == NULL)
848        {
849        fprintf(stderr, "pcretest: malloc(%d) failed for buffer16\n", buffer16_size);
850        exit(1);
851        }
852      }
853    
854    pp = buffer16;
855    
856    if (!utf)
857      {
858      while (len-- > 0) *pp++ = *p++;
859      }
860    
861    else
862      {
863      int c;
864      while (len > 0)
865        {
866        int chlen = utf82ord(p, &c);
867        p += chlen;
868        len -= chlen;
869        if (c < 0x10000) *pp++ = c; else
870          {
871          c -= 0x10000;
872          *pp++ = 0xD800 | (c >> 10);
873          *pp++ = 0xDC00 | (c & 0x3ff);
874          }
875        }
876      }
877    
878    *pp = 0;
879    return pp - buffer16;
880    }
881    #endif
882    
883    
884  /*************************************************  /*************************************************
# Line 604  Returns:       pointer to the start of n Line 904  Returns:       pointer to the start of n
904                 NULL if no data read and EOF reached                 NULL if no data read and EOF reached
905  */  */
906    
907  static uschar *  static pcre_uint8 *
908  extend_inputline(FILE *f, uschar *start, const char *prompt)  extend_inputline(FILE *f, pcre_uint8 *start, const char *prompt)
909  {  {
910  uschar *here = start;  pcre_uint8 *here = start;
911    
912  for (;;)  for (;;)
913    {    {
# Line 654  for (;;) Line 954  for (;;)
954    else    else
955      {      {
956      int new_buffer_size = 2*buffer_size;      int new_buffer_size = 2*buffer_size;
957      uschar *new_buffer = (unsigned char *)malloc(new_buffer_size);      pcre_uint8 *new_buffer = (pcre_uint8 *)malloc(new_buffer_size);
958      uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size);      pcre_uint8 *new_dbuffer = (pcre_uint8 *)malloc(new_buffer_size);
959      uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size);      pcre_uint8 *new_pbuffer = (pcre_uint8 *)malloc(new_buffer_size);
960    
961      if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)      if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)
962        {        {
# Line 687  return NULL;  /* Control never gets here Line 987  return NULL;  /* Control never gets here
987    
988    
989    
   
   
   
   
990  /*************************************************  /*************************************************
991  *          Read number from string               *  *          Read number from string               *
992  *************************************************/  *************************************************/
# Line 707  Returns:        the unsigned long Line 1003  Returns:        the unsigned long
1003  */  */
1004    
1005  static int  static int
1006  get_value(unsigned char *str, unsigned char **endptr)  get_value(pcre_uint8 *str, pcre_uint8 **endptr)
1007  {  {
1008  int result = 0;  int result = 0;
1009  while(*str != 0 && isspace(*str)) str++;  while(*str != 0 && isspace(*str)) str++;
# Line 718  return(result); Line 1014  return(result);
1014    
1015    
1016    
1017    #ifdef SUPPORT_PCRE8
1018  /*************************************************  /*************************************************
1019  *            Convert UTF-8 string to value       *  *         Print 8-bit character string           *
1020  *************************************************/  *************************************************/
1021    
1022  /* This function takes one or more bytes that represents a UTF-8 character,  /* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed.
1023  and returns the value of the character.  If handed a NULL file, just counts chars without printing. */
   
 Argument:  
   utf8bytes   a pointer to the byte vector  
   vptr        a pointer to an int to receive the value  
   
 Returns:      >  0 => the number of bytes consumed  
               -6 to 0 => malformed UTF-8 character at offset = (-return)  
 */  
   
 #if !defined NOUTF8  
1024    
1025  static int  static int pchars(pcre_uint8 *p, int length, FILE *f)
 utf82ord(unsigned char *utf8bytes, int *vptr)  
 {  
 int c = *utf8bytes++;  
 int d = c;  
 int i, j, s;  
   
 for (i = -1; i < 6; i++)               /* i is number of additional bytes */  
   {  
   if ((d & 0x80) == 0) break;  
   d <<= 1;  
   }  
   
 if (i == -1) { *vptr = c; return 1; }  /* ascii character */  
 if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */  
   
 /* i now has a value in the range 1-5 */  
   
 s = 6*i;  
 d = (c & utf8_table3[i]) << s;  
   
 for (j = 0; j < i; j++)  
   {  
   c = *utf8bytes++;  
   if ((c & 0xc0) != 0x80) return -(j+1);  
   s -= 6;  
   d |= (c & 0x3f) << s;  
   }  
   
 /* Check that encoding was the correct unique one */  
   
 for (j = 0; j < utf8_table1_size; j++)  
   if (d <= utf8_table1[j]) break;  
 if (j != i) return -(i+1);  
   
 /* Valid value */  
   
 *vptr = d;  
 return i+1;  
 }  
   
 #endif  
   
   
   
 /*************************************************  
 *       Convert character value to UTF-8         *  
 *************************************************/  
   
 /* This function takes an integer value in the range 0 - 0x7fffffff  
 and encodes it as a UTF-8 character in 0 to 6 bytes.  
   
 Arguments:  
   cvalue     the character value  
   utf8bytes  pointer to buffer for result - at least 6 bytes long  
   
 Returns:     number of characters placed in the buffer  
 */  
   
 #if !defined NOUTF8  
   
 static int  
 ord2utf8(int cvalue, uschar *utf8bytes)  
 {  
 register int i, j;  
 for (i = 0; i < utf8_table1_size; i++)  
   if (cvalue <= utf8_table1[i]) break;  
 utf8bytes += i;  
 for (j = i; j > 0; j--)  
  {  
  *utf8bytes-- = 0x80 | (cvalue & 0x3f);  
  cvalue >>= 6;  
  }  
 *utf8bytes = utf8_table2[i] | cvalue;  
 return i + 1;  
 }  
   
 #endif  
   
   
   
 /*************************************************  
 *             Print character string             *  
 *************************************************/  
   
 /* Character string printing function. Must handle UTF-8 strings in utf8  
 mode. Yields number of characters printed. If handed a NULL file, just counts  
 chars without printing. */  
   
 static int pchars(unsigned char *p, int length, FILE *f)  
1026  {  {
1027  int c = 0;  int c = 0;
1028  int yield = 0;  int yield = 0;
# Line 841  while (length-- > 0) Line 1038  while (length-- > 0)
1038        {        {
1039        length -= rc - 1;        length -= rc - 1;
1040        p += rc;        p += rc;
1041        if (PRINTHEX(c))        if (PRINTOK(c))
1042          {          {
1043          if (f != NULL) fprintf(f, "%c", c);          if (f != NULL) fprintf(f, "%c", c);
1044          yield++;          yield++;
# Line 863  while (length-- > 0) Line 1060  while (length-- > 0)
1060     /* Not UTF-8, or malformed UTF-8  */     /* Not UTF-8, or malformed UTF-8  */
1061    
1062    c = *p++;    c = *p++;
1063    if (PRINTHEX(c))    if (PRINTOK(c))
1064      {      {
1065      if (f != NULL) fprintf(f, "%c", c);      if (f != NULL) fprintf(f, "%c", c);
1066      yield++;      yield++;
# Line 877  while (length-- > 0) Line 1074  while (length-- > 0)
1074    
1075  return yield;  return yield;
1076  }  }
1077    #endif
1078    
1079    
1080    
1081    #ifdef SUPPORT_PCRE16
1082    /*************************************************
1083    *           Print 16-bit character string        *
1084    *************************************************/
1085    
1086    /* Must handle UTF-16 strings in utf mode. Yields number of characters printed.
1087    If handed a NULL file, just counts chars without printing. */
1088    
1089    static int pchars16(PCRE_SPTR16 p, int length, FILE *f)
1090    {
1091    int yield = 0;
1092    
1093    while (length-- > 0)
1094      {
1095      int c = *p++ & 0xffff;
1096    
1097    #if !defined NOUTF8
1098      if (use_utf8 && c >= 0xD800 && c < 0xDC00 && length > 0)
1099        {
1100        int d = *p & 0xffff;
1101        if (d >= 0xDC00 && d < 0xDFFF)
1102          {
1103          c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000;
1104          length--;
1105          p++;
1106          }
1107        }
1108    #endif
1109    
1110      if (PRINTOK(c))
1111        {
1112        if (f != NULL) fprintf(f, "%c", c);
1113        yield++;
1114        }
1115      else
1116        {
1117        yield += 4;
1118        if (c < 0x100)
1119          {
1120          if (f != NULL) fprintf(f, "\\x%02x", c);
1121          }
1122        else
1123          {
1124          if (f != NULL) fprintf(f, "\\x{%02x}", c);
1125          yield += (c <= 0x000000ff)? 2 :
1126                   (c <= 0x00000fff)? 3 :
1127                   (c <= 0x0000ffff)? 4 :
1128                   (c <= 0x000fffff)? 5 : 6;
1129          }
1130        }
1131      }
1132    
1133    return yield;
1134    }
1135    #endif
1136    
1137    
1138    
# Line 905  if (callout_extra) Line 1161  if (callout_extra)
1161      else      else
1162        {        {
1163        fprintf(f, "%2d: ", i/2);        fprintf(f, "%2d: ", i/2);
1164        (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i],        PCHARSV(cb->subject + cb->offset_vector[i],
1165          cb->offset_vector[i+1] - cb->offset_vector[i], f);          cb->offset_vector[i+1] - cb->offset_vector[i], f);
1166        fprintf(f, "\n");        fprintf(f, "\n");
1167        }        }
# Line 918  printed lengths of the substrings. */ Line 1174  printed lengths of the substrings. */
1174    
1175  if (f != NULL) fprintf(f, "--->");  if (f != NULL) fprintf(f, "--->");
1176    
1177  pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f);  PCHARS(pre_start, cb->subject, cb->start_match, f);
1178  post_start = pchars((unsigned char *)(cb->subject + cb->start_match),  PCHARS(post_start, cb->subject + cb->start_match,
1179    cb->current_position - cb->start_match, f);    cb->current_position - cb->start_match, f);
1180    
1181  subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);  PCHARS(subject_length, cb->subject, cb->subject_length, NULL);
1182    
1183  (void)pchars((unsigned char *)(cb->subject + cb->current_position),  PCHARSV(cb->subject + cb->current_position,
1184    cb->subject_length - cb->current_position, f);    cb->subject_length - cb->current_position, f);
1185    
1186  if (f != NULL) fprintf(f, "\n");  if (f != NULL) fprintf(f, "\n");
# Line 987  return (cb->callout_number != callout_fa Line 1243  return (cb->callout_number != callout_fa
1243  *            Local malloc functions              *  *            Local malloc functions              *
1244  *************************************************/  *************************************************/
1245    
1246  /* Alternative malloc function, to test functionality and show the size of the  /* Alternative malloc function, to test functionality and save the size of a
1247  compiled re. */  compiled re, which is the first store request that pcre_compile() makes. The
1248    show_malloc variable is set only during matching. */
1249    
1250  static void *new_malloc(size_t size)  static void *new_malloc(size_t size)
1251  {  {
1252  void *block = malloc(size);  void *block = malloc(size);
1253  gotten_store = size;  gotten_store = size;
1254    if (first_gotten_store == 0) first_gotten_store = size;
1255  if (show_malloc)  if (show_malloc)
1256    fprintf(outfile, "malloc       %3d %p\n", (int)size, block);    fprintf(outfile, "malloc       %3d %p\n", (int)size, block);
1257  return block;  return block;
# Line 1006  if (show_malloc) Line 1264  if (show_malloc)
1264  free(block);  free(block);
1265  }  }
1266    
   
1267  /* For recursion malloc/free, to test stacking calls */  /* For recursion malloc/free, to test stacking calls */
1268    
1269  static void *stack_malloc(size_t size)  static void *stack_malloc(size_t size)
# Line 1029  free(block); Line 1286  free(block);
1286  *          Call pcre_fullinfo()                  *  *          Call pcre_fullinfo()                  *
1287  *************************************************/  *************************************************/
1288    
1289  /* Get one piece of information from the pcre_fullinfo() function */  /* Get one piece of information from the pcre_fullinfo() function. When only
1290    one of 8-bit or 16-bit is supported, use_pcre16 should always have the correct
1291    value, but the code is defensive. */
1292    
1293  static void new_info(pcre *re, pcre_extra *study, int option, void *ptr)  static void new_info(pcre *re, pcre_extra *study, int option, void *ptr)
1294  {  {
1295  int rc;  int rc;
1296  if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)  
1297    fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);  if (use_pcre16)
1298    #ifdef SUPPORT_PCRE16
1299      rc = pcre16_fullinfo(re, study, option, ptr);
1300    #else
1301      rc = PCRE_ERROR_BADMODE;
1302    #endif
1303    else
1304    #ifdef SUPPORT_PCRE8
1305      rc = pcre_fullinfo(re, study, option, ptr);
1306    #else
1307      rc = PCRE_ERROR_BADMODE;
1308    #endif
1309    
1310    if (rc < 0) fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc,
1311      use_pcre16? "16" : "", option);
1312  }  }
1313    
1314    
# Line 1062  return ((value & 0x000000ff) << 24) | Line 1335  return ((value & 0x000000ff) << 24) |
1335  *************************************************/  *************************************************/
1336    
1337  static int  static int
1338  check_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len,  check_match_limit(pcre *re, pcre_extra *extra, pcre_uint8 *bptr, int len,
1339    int start_offset, int options, int *use_offsets, int use_size_offsets,    int start_offset, int options, int *use_offsets, int use_size_offsets,
1340    int flag, unsigned long int *limit, int errnumber, const char *msg)    int flag, unsigned long int *limit, int errnumber, const char *msg)
1341  {  {
# Line 1077  for (;;) Line 1350  for (;;)
1350    {    {
1351    *limit = mid;    *limit = mid;
1352    
1353    count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options,    PCRE_EXEC(count, re, extra, bptr, len, start_offset, options,
1354      use_offsets, use_size_offsets);      use_offsets, use_size_offsets);
1355    
1356    if (count == errnumber)    if (count == errnumber)
# Line 1122  Returns:    < 0, = 0, or > 0, according Line 1395  Returns:    < 0, = 0, or > 0, according
1395  */  */
1396    
1397  static int  static int
1398  strncmpic(uschar *s, uschar *t, int n)  strncmpic(pcre_uint8 *s, pcre_uint8 *t, int n)
1399  {  {
1400  while (n--)  while (n--)
1401    {    {
# Line 1149  Returns:      appropriate PCRE_NEWLINE_x Line 1422  Returns:      appropriate PCRE_NEWLINE_x
1422  */  */
1423    
1424  static int  static int
1425  check_newline(uschar *p, FILE *f)  check_newline(pcre_uint8 *p, FILE *f)
1426  {  {
1427  if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;  if (strncmpic(p, (pcre_uint8 *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
1428  if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;  if (strncmpic(p, (pcre_uint8 *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
1429  if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;  if (strncmpic(p, (pcre_uint8 *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
1430  if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;  if (strncmpic(p, (pcre_uint8 *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
1431  if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;  if (strncmpic(p, (pcre_uint8 *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
1432  if (strncmpic(p, (uschar *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;  if (strncmpic(p, (pcre_uint8 *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;
1433  if (strncmpic(p, (uschar *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;  if (strncmpic(p, (pcre_uint8 *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;
1434  fprintf(f, "Unknown newline type at: <%s\n", p);  fprintf(f, "Unknown newline type at: <%s\n", p);
1435  return 0;  return 0;
1436  }  }
# Line 1179  printf("If input is a terminal, readline Line 1452  printf("If input is a terminal, readline
1452  printf("This version of pcretest is not linked with readline().\n");  printf("This version of pcretest is not linked with readline().\n");
1453  #endif  #endif
1454  printf("\nOptions:\n");  printf("\nOptions:\n");
1455    #ifdef SUPPORT_PCRE16
1456    printf("  -16      use 16-bit interface\n");
1457    #endif
1458  printf("  -b       show compiled code (bytecode)\n");  printf("  -b       show compiled code (bytecode)\n");
1459  printf("  -C       show PCRE compile-time options and exit\n");  printf("  -C       show PCRE compile-time options and exit\n");
1460  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 1195  printf("  -p       use POSIX interface\n Line 1471  printf("  -p       use POSIX interface\n
1471  #endif  #endif
1472  printf("  -q       quiet: do not output PCRE version number at start\n");  printf("  -q       quiet: do not output PCRE version number at start\n");
1473  printf("  -S <n>   set stack size to <n> megabytes\n");  printf("  -S <n>   set stack size to <n> megabytes\n");
1474  printf("  -s       force each pattern to be studied\n"  printf("  -s       force each pattern to be studied at basic level\n"
1475           "  -s+      force each pattern to be studied, using JIT if available\n"
1476         "  -t       time compilation and execution\n");         "  -t       time compilation and execution\n");
1477  printf("  -t <n>   time compilation and execution, repeating <n> times\n");  printf("  -t <n>   time compilation and execution, repeating <n> times\n");
1478  printf("  -tm      time execution (matching) only\n");  printf("  -tm      time execution (matching) only\n");
# Line 1223  int timeit = 0; Line 1500  int timeit = 0;
1500  int timeitm = 0;  int timeitm = 0;
1501  int showinfo = 0;  int showinfo = 0;
1502  int showstore = 0;  int showstore = 0;
1503  int force_study = 0;  int force_study = -1;
1504    int force_study_options = 0;
1505  int quiet = 0;  int quiet = 0;
1506  int size_offsets = 45;  int size_offsets = 45;
1507  int size_offsets_max;  int size_offsets_max;
# Line 1237  int all_use_dfa = 0; Line 1515  int all_use_dfa = 0;
1515  int yield = 0;  int yield = 0;
1516  int stack_size;  int stack_size;
1517    
1518    pcre_jit_stack *jit_stack = NULL;
1519    
1520  /* These vectors store, end-to-end, a list of captured substring names. Assume  /* These vectors store, end-to-end, a list of captured substring names. Assume
1521  that 1024 is plenty long enough for the few names we'll be testing. */  that 1024 is plenty long enough for the few names we'll be testing. */
1522    
1523  uschar copynames[1024];  pcre_uchar copynames[1024];
1524  uschar getnames[1024];  pcre_uchar getnames[1024];
   
 uschar *copynamesptr;  
 uschar *getnamesptr;  
1525    
1526  /* Get buffers from malloc() so that Electric Fence will check their misuse  pcre_uchar *copynamesptr;
1527  when I am debugging. They grow automatically when very long lines are read. */  pcre_uchar *getnamesptr;
1528    
1529  buffer = (unsigned char *)malloc(buffer_size);  /* Get buffers from malloc() so that valgrind will check their misuse when
1530  dbuffer = (unsigned char *)malloc(buffer_size);  debugging. They grow automatically when very long lines are read. The 16-bit
1531  pbuffer = (unsigned char *)malloc(buffer_size);  buffer (buffer16) is obtained only if needed. */
1532    
1533    buffer = (pcre_uint8 *)malloc(buffer_size);
1534    dbuffer = (pcre_uint8 *)malloc(buffer_size);
1535    pbuffer = (pcre_uint8 *)malloc(buffer_size);
1536    
1537  /* The outfile variable is static so that new_malloc can use it. */  /* The outfile variable is static so that new_malloc can use it. */
1538    
# Line 1270  _setmode( _fileno( stdout ), _O_BINARY ) Line 1551  _setmode( _fileno( stdout ), _O_BINARY )
1551    
1552  while (argc > 1 && argv[op][0] == '-')  while (argc > 1 && argv[op][0] == '-')
1553    {    {
1554    unsigned char *endptr;    pcre_uint8 *endptr;
1555    
1556    if (strcmp(argv[op], "-m") == 0) showstore = 1;    if (strcmp(argv[op], "-m") == 0) showstore = 1;
1557    else if (strcmp(argv[op], "-s") == 0) force_study = 1;    else if (strcmp(argv[op], "-s") == 0) force_study = 0;
1558      else if (strcmp(argv[op], "-s+") == 0)
1559        {
1560        force_study = 1;
1561        force_study_options = PCRE_STUDY_JIT_COMPILE;
1562        }
1563    #ifdef SUPPORT_PCRE16
1564      else if (strcmp(argv[op], "-16") == 0) use_pcre16 = 1;
1565    #endif
1566    
1567    else if (strcmp(argv[op], "-q") == 0) quiet = 1;    else if (strcmp(argv[op], "-q") == 0) quiet = 1;
1568    else if (strcmp(argv[op], "-b") == 0) debug = 1;    else if (strcmp(argv[op], "-b") == 0) debug = 1;
1569    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
# Line 1283  while (argc > 1 && argv[op][0] == '-') Line 1573  while (argc > 1 && argv[op][0] == '-')
1573    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;
1574  #endif  #endif
1575    else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&    else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&
1576        ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)),        ((size_offsets = get_value((pcre_uint8 *)argv[op+1], &endptr)),
1577          *endptr == 0))          *endptr == 0))
1578      {      {
1579      op++;      op++;
# Line 1293  while (argc > 1 && argv[op][0] == '-') Line 1583  while (argc > 1 && argv[op][0] == '-')
1583      {      {
1584      int both = argv[op][2] == 0;      int both = argv[op][2] == 0;
1585      int temp;      int temp;
1586      if (argc > 2 && (temp = get_value((unsigned char *)argv[op+1], &endptr),      if (argc > 2 && (temp = get_value((pcre_uint8 *)argv[op+1], &endptr),
1587                       *endptr == 0))                       *endptr == 0))
1588        {        {
1589        timeitm = temp;        timeitm = temp;
# Line 1304  while (argc > 1 && argv[op][0] == '-') Line 1594  while (argc > 1 && argv[op][0] == '-')
1594      if (both) timeit = timeitm;      if (both) timeit = timeitm;
1595      }      }
1596    else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&    else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&
1597        ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)),        ((stack_size = get_value((pcre_uint8 *)argv[op+1], &endptr)),
1598          *endptr == 0))          *endptr == 0))
1599      {      {
1600  #if defined(_WIN32) || defined(WIN32) || defined(__minix)  #if defined(_WIN32) || defined(WIN32) || defined(__minix)
# Line 1334  while (argc > 1 && argv[op][0] == '-') Line 1624  while (argc > 1 && argv[op][0] == '-')
1624      unsigned long int lrc;      unsigned long int lrc;
1625      printf("PCRE version %s\n", pcre_version());      printf("PCRE version %s\n", pcre_version());
1626      printf("Compiled with\n");      printf("Compiled with\n");
1627    
1628    /* At least one of SUPPORT_PCRE8 and SUPPORT_PCRE16 will be set. If both
1629    are set, either both UTFs are supported or both are not supported. */
1630    
1631    #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
1632        printf("  8-bit and 16-bit support\n");
1633        (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
1634        if (rc)
1635          printf("  UTF-8 and UTF-16 support\n");
1636        else
1637          printf("  No UTF-8 or UTF-16 support\n");
1638    #elif defined SUPPORT_PCRE8
1639        printf("  8-bit support only\n");
1640      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
1641      printf("  %sUTF-8 support\n", rc? "" : "No ");      printf("  %sUTF-8 support\n", rc? "" : "No ");
1642    #else
1643        printf("  16-bit support only\n");
1644        (void)pcre16_config(PCRE_CONFIG_UTF16, &rc);
1645        printf("  %sUTF-16 support\n", rc? "" : "No ");
1646    #endif
1647    
1648      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
1649      printf("  %sUnicode properties support\n", rc? "" : "No ");      printf("  %sUnicode properties support\n", rc? "" : "No ");
1650        (void)pcre_config(PCRE_CONFIG_JIT, &rc);
1651        if (rc)
1652          printf("  Just-in-time compiler support\n");
1653        else
1654          printf("  No just-in-time compiler support\n");
1655      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
1656      /* Note that these values are always the ASCII values, even      /* Note that these values are always the ASCII values, even
1657      in EBCDIC environments. CR is 13 and NL is 10. */      in EBCDIC environments. CR is 13 and NL is 10. */
# Line 1415  if (argc > 2) Line 1729  if (argc > 2)
1729    
1730  /* Set alternative malloc function */  /* Set alternative malloc function */
1731    
1732    #ifdef SUPPORT_PCRE8
1733  pcre_malloc = new_malloc;  pcre_malloc = new_malloc;
1734  pcre_free = new_free;  pcre_free = new_free;
1735  pcre_stack_malloc = stack_malloc;  pcre_stack_malloc = stack_malloc;
1736  pcre_stack_free = stack_free;  pcre_stack_free = stack_free;
1737    #endif
1738    
1739    #ifdef SUPPORT_PCRE16
1740    pcre16_malloc = new_malloc;
1741    pcre16_free = new_free;
1742    pcre16_stack_malloc = stack_malloc;
1743    pcre16_stack_free = stack_free;
1744    #endif
1745    
1746  /* Heading line unless quiet, then prompt for first regex if stdin */  /* Heading line unless quiet, then prompt for first regex if stdin */
1747    
# Line 1437  while (!done) Line 1760  while (!done)
1760  #endif  #endif
1761    
1762    const char *error;    const char *error;
1763    unsigned char *markptr;    pcre_uint8 *markptr;
1764    unsigned char *p, *pp, *ppp;    pcre_uint8 *p, *pp, *ppp;
1765    unsigned char *to_file = NULL;    pcre_uint8 *to_file = NULL;
1766    const unsigned char *tables = NULL;    const pcre_uint8 *tables = NULL;
1767    unsigned long int true_size, true_study_size = 0;    unsigned long int true_size, true_study_size = 0;
1768    size_t size, regex_gotten_store;    size_t size, regex_gotten_store;
1769    int do_allcaps = 0;    int do_allcaps = 0;
# Line 1472  while (!done) Line 1795  while (!done)
1795    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)
1796      {      {
1797      unsigned long int magic, get_options;      unsigned long int magic, get_options;
1798      uschar sbuf[8];      pcre_uint8 sbuf[8];
1799      FILE *f;      FILE *f;
1800    
1801      p++;      p++;
# Line 1495  while (!done) Line 1818  while (!done)
1818        (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];        (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];
1819    
1820      re = (real_pcre *)new_malloc(true_size);      re = (real_pcre *)new_malloc(true_size);
1821      regex_gotten_store = gotten_store;      regex_gotten_store = first_gotten_store;
1822    
1823      if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;      if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;
1824    
# Line 1538  while (!done) Line 1861  while (!done)
1861          {          {
1862          FAIL_READ:          FAIL_READ:
1863          fprintf(outfile, "Failed to read data from %s\n", p);          fprintf(outfile, "Failed to read data from %s\n", p);
1864          if (extra != NULL) new_free(extra);          if (extra != NULL) pcre_free_study(extra);
1865          if (re != NULL) new_free(re);          if (re != NULL) new_free(re);
1866          fclose(f);          fclose(f);
1867          continue;          continue;
# Line 1641  while (!done) Line 1964  while (!done)
1964  #endif  #endif
1965    
1966        case 'S':        case 'S':
1967        if (do_study == 0) do_study = 1; else        if (do_study == 0)
1968            {
1969            do_study = 1;
1970            if (*pp == '+')
1971              {
1972              study_options |= PCRE_STUDY_JIT_COMPILE;
1973              pp++;
1974              }
1975            }
1976          else
1977          {          {
1978          do_study = 0;          do_study = 0;
1979          no_force_study = 1;          no_force_study = 1;
# Line 1700  while (!done) Line 2032  while (!done)
2032    
2033        case '<':        case '<':
2034          {          {
2035          if (strncmpic(pp, (uschar *)"JS>", 3) == 0)          if (strncmpic(pp, (pcre_uint8 *)"JS>", 3) == 0)
2036            {            {
2037            options |= PCRE_JAVASCRIPT_COMPAT;            options |= PCRE_JAVASCRIPT_COMPAT;
2038            pp += 3;            pp += 3;
# Line 1728  while (!done) Line 2060  while (!done)
2060    
2061    /* Handle compiling via the POSIX interface, which doesn't support the    /* Handle compiling via the POSIX interface, which doesn't support the
2062    timing, showing, or debugging options, nor the ability to pass over    timing, showing, or debugging options, nor the ability to pass over
2063    local character tables. */    local character tables. Neither does it have 16-bit support. */
2064    
2065  #if !defined NOPOSIX  #if !defined NOPOSIX
2066    if (posix || do_posix)    if (posix || do_posix)
# Line 1744  while (!done) Line 2076  while (!done)
2076      if ((options & PCRE_UCP) != 0) cflags |= REG_UCP;      if ((options & PCRE_UCP) != 0) cflags |= REG_UCP;
2077      if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY;      if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY;
2078    
2079        first_gotten_store = 0;
2080      rc = regcomp(&preg, (char *)p, cflags);      rc = regcomp(&preg, (char *)p, cflags);
2081    
2082      /* Compilation failed; go back for another re, skipping to blank line      /* Compilation failed; go back for another re, skipping to blank line
# Line 1765  while (!done) Line 2098  while (!done)
2098      {      {
2099      unsigned long int get_options;      unsigned long int get_options;
2100    
2101        /* In 16-bit mode, convert the input. */
2102    
2103    #ifdef SUPPORT_PCRE16
2104        if (use_pcre16)
2105          {
2106          (void)to16(p, options & PCRE_UTF8, (int)strlen((char *)p));
2107          p = (pcre_uint8 *)buffer16;
2108          }
2109    #endif
2110    
2111        /* Compile many times when timing */
2112    
2113      if (timeit > 0)      if (timeit > 0)
2114        {        {
2115        register int i;        register int i;
# Line 1772  while (!done) Line 2117  while (!done)
2117        clock_t start_time = clock();        clock_t start_time = clock();
2118        for (i = 0; i < timeit; i++)        for (i = 0; i < timeit; i++)
2119          {          {
2120          re = pcre_compile((char *)p, options, &error, &erroroffset, tables);          PCRE_COMPILE(re, p, options, &error, &erroroffset, tables);
2121          if (re != NULL) free(re);          if (re != NULL) free(re);
2122          }          }
2123        time_taken = clock() - start_time;        time_taken = clock() - start_time;
# Line 1781  while (!done) Line 2126  while (!done)
2126            (double)CLOCKS_PER_SEC);            (double)CLOCKS_PER_SEC);
2127        }        }
2128    
2129      re = pcre_compile((char *)p, options, &error, &erroroffset, tables);      first_gotten_store = 0;
2130        PCRE_COMPILE(re, p, options, &error, &erroroffset, tables);
2131    
2132      /* Compilation failed; go back for another re, skipping to blank line      /* Compilation failed; go back for another re, skipping to blank line
2133      if non-interactive. */      if non-interactive. */
# Line 1815  while (!done) Line 2161  while (!done)
2161      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
2162      if ((get_options & PCRE_UTF8) != 0) use_utf8 = 1;      if ((get_options & PCRE_UTF8) != 0) use_utf8 = 1;
2163    
2164      /* Print information if required. There are now two info-returning      /* Extract the size for possible writing before possibly flipping it,
2165      functions. The old one has a limited interface and returns only limited      and remember the store that was got. */
2166      data. Check that it agrees with the newer one. */  
2167        true_size = ((real_pcre *)re)->size;
2168        regex_gotten_store = first_gotten_store;
2169    
2170        /* Output code size information if requested */
2171    
2172      if (log_store)      if (log_store)
2173        fprintf(outfile, "Memory allocation (code space): %d\n",        fprintf(outfile, "Memory allocation (code space): %d\n",
2174          (int)(gotten_store -          (int)(first_gotten_store -
2175                sizeof(real_pcre) -                sizeof(real_pcre) -
2176                ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));                ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));
2177    
     /* Extract the size for possible writing before possibly flipping it,  
     and remember the store that was got. */  
   
     true_size = ((real_pcre *)re)->size;  
     regex_gotten_store = gotten_store;  
   
2178      /* If -s or /S was present, study the regex to generate additional info to      /* If -s or /S was present, study the regex to generate additional info to
2179      help with the matching, unless the pattern has the SS option, which      help with the matching, unless the pattern has the SS option, which
2180      suppresses the effect of /S (used for a few test patterns where studying is      suppresses the effect of /S (used for a few test patterns where studying is
2181      never sensible). */      never sensible). */
2182    
2183      if (do_study || (force_study && !no_force_study))      if (do_study || (force_study >= 0 && !no_force_study))
2184        {        {
2185        if (timeit > 0)        if (timeit > 0)
2186          {          {
# Line 1844  while (!done) Line 2188  while (!done)
2188          clock_t time_taken;          clock_t time_taken;
2189          clock_t start_time = clock();          clock_t start_time = clock();
2190          for (i = 0; i < timeit; i++)          for (i = 0; i < timeit; i++)
2191            extra = pcre_study(re, study_options, &error);            {
2192              PCRE_STUDY(extra, re, study_options | force_study_options, &error);
2193              }
2194          time_taken = clock() - start_time;          time_taken = clock() - start_time;
2195          if (extra != NULL) free(extra);          if (extra != NULL) pcre_free_study(extra);
2196          fprintf(outfile, "  Study time %.4f milliseconds\n",          fprintf(outfile, "  Study time %.4f milliseconds\n",
2197            (((double)time_taken * 1000.0) / (double)timeit) /            (((double)time_taken * 1000.0) / (double)timeit) /
2198              (double)CLOCKS_PER_SEC);              (double)CLOCKS_PER_SEC);
2199          }          }
2200        extra = pcre_study(re, study_options, &error);        PCRE_STUDY(extra, re, study_options | force_study_options, &error);
2201        if (error != NULL)        if (error != NULL)
2202          fprintf(outfile, "Failed to study: %s\n", error);          fprintf(outfile, "Failed to study: %s\n", error);
2203        else if (extra != NULL)        else if (extra != NULL)
2204            {
2205          true_study_size = ((pcre_study_data *)(extra->study_data))->size;          true_study_size = ((pcre_study_data *)(extra->study_data))->size;
2206            if (log_store)
2207              {
2208              size_t jitsize;
2209              new_info(re, extra, PCRE_INFO_JITSIZE, &jitsize);
2210              if (jitsize != 0)
2211                fprintf(outfile, "Memory allocation (JIT code): %d\n", jitsize);
2212              }
2213            }
2214        }        }
2215    
2216      /* If /K was present, we set up for handling MARK data. */      /* If /K was present, we set up for handling MARK data. */
# Line 1888  while (!done) Line 2243  while (!done)
2243          (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));          (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));
2244        rre->top_backref =        rre->top_backref =
2245          (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));          (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));
2246        rre->first_byte =        rre->first_char =
2247          (pcre_uint16)byteflip(rre->first_byte, sizeof(rre->first_byte));          (pcre_uint16)byteflip(rre->first_char, sizeof(rre->first_char));
2248        rre->req_byte =        rre->req_char =
2249          (pcre_uint16)byteflip(rre->req_byte, sizeof(rre->req_byte));          (pcre_uint16)byteflip(rre->req_char, sizeof(rre->req_char));
2250        rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,        rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,
2251          sizeof(rre->name_table_offset));          sizeof(rre->name_table_offset));
2252        rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,        rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,
# Line 1908  while (!done) Line 2263  while (!done)
2263          }          }
2264        }        }
2265    
2266      /* Extract information from the compiled data if required */      /* Extract and display information from the compiled data if required. */
2267    
2268      SHOW_INFO:      SHOW_INFO:
2269    
2270      if (do_debug)      if (do_debug)
2271        {        {
2272        fprintf(outfile, "------------------------------------------------------------------\n");        fprintf(outfile, "------------------------------------------------------------------\n");
2273        pcre_printint(re, outfile, debug_lengths);        if (use_pcre16)
2274            pcre16_printint(re, outfile, debug_lengths);
2275          else
2276            pcre_printint(re, outfile, debug_lengths);
2277        }        }
2278    
2279      /* We already have the options in get_options (see above) */      /* We already have the options in get_options (see above) */
# Line 1929  while (!done) Line 2287  while (!done)
2287        int count, backrefmax, first_char, need_char, okpartial, jchanged,        int count, backrefmax, first_char, need_char, okpartial, jchanged,
2288          hascrorlf;          hascrorlf;
2289        int nameentrysize, namecount;        int nameentrysize, namecount;
2290        const uschar *nametable;        const pcre_uchar *nametable;
2291    
2292        new_info(re, NULL, PCRE_INFO_SIZE, &size);        new_info(re, NULL, PCRE_INFO_SIZE, &size);
2293        new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);        new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);
# Line 1943  while (!done) Line 2301  while (!done)
2301        new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);        new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);
2302        new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);        new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);
2303    
2304          /* The old, obsolete function pcre_info() works only in 8-bit mode. Check
2305          that it gives the same results as the new function. */
2306    
2307  #if !defined NOINFOCHECK  #if !defined NOINFOCHECK
2308        old_count = pcre_info(re, &old_options, &old_first_char);        if (!use_pcre16)
       if (count < 0) fprintf(outfile,  
         "Error %d from pcre_info()\n", count);  
       else  
2309          {          {
2310          if (old_count != count) fprintf(outfile,          old_count = pcre_info(re, &old_options, &old_first_char);
2311            "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,          if (count < 0) fprintf(outfile,
2312              old_count);            "Error %d from pcre_info()\n", count);
2313            else
2314          if (old_first_char != first_char) fprintf(outfile,            {
2315            "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",            if (old_count != count) fprintf(outfile,
2316              first_char, old_first_char);              "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,
2317                  old_count);
2318          if (old_options != (int)get_options) fprintf(outfile,  
2319            "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",            if (old_first_char != first_char) fprintf(outfile,
2320              get_options, old_options);              "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",
2321                  first_char, old_first_char);
2322    
2323              if (old_options != (int)get_options) fprintf(outfile,
2324                "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",
2325                  get_options, old_options);
2326              }
2327          }          }
2328  #endif  #endif
2329    
# Line 2047  while (!done) Line 2411  while (!done)
2411          }          }
2412        else        else
2413          {          {
2414          int ch = first_char & 255;          const char *caseless =
2415          const char *caseless = ((first_char & REQ_CASELESS) == 0)?            ((((real_pcre *)re)->flags & PCRE_FCH_CASELESS) == 0)?
2416            "" : " (caseless)";            "" : " (caseless)";
2417          if (PRINTHEX(ch))  
2418            fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless);          if (PRINTOK(first_char))
2419              fprintf(outfile, "First char = \'%c\'%s\n", first_char, caseless);
2420          else          else
2421            fprintf(outfile, "First char = %d%s\n", ch, caseless);            fprintf(outfile, "First char = %d%s\n", first_char, caseless);
2422          }          }
2423    
2424        if (need_char < 0)        if (need_char < 0)
# Line 2062  while (!done) Line 2427  while (!done)
2427          }          }
2428        else        else
2429          {          {
2430          int ch = need_char & 255;          const char *caseless =
2431          const char *caseless = ((need_char & REQ_CASELESS) == 0)?            ((((real_pcre *)re)->flags & PCRE_RCH_CASELESS) == 0)?
2432            "" : " (caseless)";            "" : " (caseless)";
2433          if (PRINTHEX(ch))  
2434            fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless);          if (PRINTOK(need_char))
2435              fprintf(outfile, "Need char = \'%c\'%s\n", need_char, caseless);
2436          else          else
2437            fprintf(outfile, "Need char = %d%s\n", ch, caseless);            fprintf(outfile, "Need char = %d%s\n", need_char, caseless);
2438          }          }
2439    
2440        /* Don't output study size; at present it is in any case a fixed        /* Don't output study size; at present it is in any case a fixed
# Line 2079  while (!done) Line 2445  while (!done)
2445        when auto-callouts are involved, the output from runs with and without        when auto-callouts are involved, the output from runs with and without
2446        -s should be identical. */        -s should be identical. */
2447    
2448        if (do_study || (force_study && showinfo && !no_force_study))        if (do_study || (force_study >= 0 && showinfo && !no_force_study))
2449          {          {
2450          if (extra == NULL)          if (extra == NULL)
2451            fprintf(outfile, "Study returned NULL\n");            fprintf(outfile, "Study returned NULL\n");
2452          else          else
2453            {            {
2454            uschar *start_bits = NULL;            pcre_uint8 *start_bits = NULL;
2455            int minlength;            int minlength;
2456    
2457            new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength);            new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength);
# Line 2108  while (!done) Line 2474  while (!done)
2474                    fprintf(outfile, "\n  ");                    fprintf(outfile, "\n  ");
2475                    c = 2;                    c = 2;
2476                    }                    }
2477                  if (PRINTHEX(i) && i != ' ')                  if (PRINTOK(i) && i != ' ')
2478                    {                    {
2479                    fprintf(outfile, "%c ", i);                    fprintf(outfile, "%c ", i);
2480                    c += 2;                    c += 2;
# Line 2123  while (!done) Line 2489  while (!done)
2489              fprintf(outfile, "\n");              fprintf(outfile, "\n");
2490              }              }
2491            }            }
2492    
2493            /* Show this only if the JIT was set by /S, not by -s. */
2494    
2495            if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0)
2496              {
2497              int jit;
2498              new_info(re, extra, PCRE_INFO_JIT, &jit);
2499              if (jit)
2500                fprintf(outfile, "JIT study was successful\n");
2501              else
2502    #ifdef SUPPORT_JIT
2503                fprintf(outfile, "JIT study was not successful\n");
2504    #else
2505                fprintf(outfile, "JIT support is not available in this version of PCRE\n");
2506    #endif
2507              }
2508          }          }
2509        }        }
2510    
# Line 2139  while (!done) Line 2521  while (!done)
2521          }          }
2522        else        else
2523          {          {
2524          uschar sbuf[8];          pcre_uint8 sbuf[8];
2525          sbuf[0] = (uschar)((true_size >> 24) & 255);          sbuf[0] = (pcre_uint8)((true_size >> 24) & 255);
2526          sbuf[1] = (uschar)((true_size >> 16) & 255);          sbuf[1] = (pcre_uint8)((true_size >> 16) & 255);
2527          sbuf[2] = (uschar)((true_size >>  8) & 255);          sbuf[2] = (pcre_uint8)((true_size >>  8) & 255);
2528          sbuf[3] = (uschar)((true_size) & 255);          sbuf[3] = (pcre_uint8)((true_size) & 255);
2529    
2530          sbuf[4] = (uschar)((true_study_size >> 24) & 255);          sbuf[4] = (pcre_uint8)((true_study_size >> 24) & 255);
2531          sbuf[5] = (uschar)((true_study_size >> 16) & 255);          sbuf[5] = (pcre_uint8)((true_study_size >> 16) & 255);
2532          sbuf[6] = (uschar)((true_study_size >>  8) & 255);          sbuf[6] = (pcre_uint8)((true_study_size >>  8) & 255);
2533          sbuf[7] = (uschar)((true_study_size) & 255);          sbuf[7] = (pcre_uint8)((true_study_size) & 255);
2534    
2535          if (fwrite(sbuf, 1, 8, f) < 8 ||          if (fwrite(sbuf, 1, 8, f) < 8 ||
2536              fwrite(re, 1, true_size, f) < true_size)              fwrite(re, 1, true_size, f) < true_size)
# Line 2176  while (!done) Line 2558  while (!done)
2558          }          }
2559    
2560        new_free(re);        new_free(re);
2561        if (extra != NULL) new_free(extra);        if (extra != NULL) pcre_free_study(extra);
2562        if (locale_set)        if (locale_set)
2563          {          {
2564          new_free((void *)tables);          new_free((void *)tables);
# Line 2191  while (!done) Line 2573  while (!done)
2573    
2574    for (;;)    for (;;)
2575      {      {
2576      uschar *q;      pcre_uint8 *q;
2577      uschar *bptr;      pcre_uint8 *bptr;
2578      int *use_offsets = offsets;      int *use_offsets = offsets;
2579      int use_size_offsets = size_offsets;      int use_size_offsets = size_offsets;
2580      int callout_data = 0;      int callout_data = 0;
# Line 2279  while (!done) Line 2661  while (!done)
2661  #if !defined NOUTF8  #if !defined NOUTF8
2662          if (use_utf8 && c > 255)          if (use_utf8 && c > 255)
2663            {            {
2664            unsigned char buff8[8];            pcre_uint8 buff8[8];
2665            int ii, utn;            int ii, utn;
2666            utn = ord2utf8(c, buff8);            utn = ord2utf8(c, buff8);
2667            for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];            for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
# Line 2295  while (!done) Line 2677  while (!done)
2677  #if !defined NOUTF8  #if !defined NOUTF8
2678          if (*p == '{')          if (*p == '{')
2679            {            {
2680            unsigned char *pt = p;            pcre_uint8 *pt = p;
2681            c = 0;            c = 0;
2682            while (isxdigit(*(++pt)))  
2683              c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W');            /* We used to have "while (isxdigit(*(++pt)))" here, but it fails
2684              when isxdigit() is a macro that refers to its argument more than
2685              once. This is banned by the C Standard, but apparently happens in at
2686              least one MacOS environment. */
2687    
2688              for (pt++; isxdigit(*pt); pt++)
2689                c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'a' - 10);
2690            if (*pt == '}')            if (*pt == '}')
2691              {              {
2692              unsigned char buff8[8];              pcre_uint8 buff8[8];
2693              int ii, utn;              int ii, utn;
2694              if (use_utf8)              if (use_utf8)
2695                {                {
# Line 2328  while (!done) Line 2716  while (!done)
2716          c = 0;          c = 0;
2717          while (i++ < 2 && isxdigit(*p))          while (i++ < 2 && isxdigit(*p))
2718            {            {
2719            c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W');            c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10);
2720            p++;            p++;
2721            }            }
2722          break;          break;
# Line 2363  while (!done) Line 2751  while (!done)
2751            }            }
2752          else if (isalnum(*p))          else if (isalnum(*p))
2753            {            {
2754            uschar *npp = copynamesptr;            pcre_uchar *npp = copynamesptr;
2755            while (isalnum(*p)) *npp++ = *p++;            while (isalnum(*p)) *npp++ = *p++;
2756            *npp++ = 0;            *npp++ = 0;
2757            *npp = 0;            *npp = 0;
# Line 2433  while (!done) Line 2821  while (!done)
2821            }            }
2822          else if (isalnum(*p))          else if (isalnum(*p))
2823            {            {
2824            uschar *npp = getnamesptr;            pcre_uchar *npp = getnamesptr;
2825            while (isalnum(*p)) *npp++ = *p++;            while (isalnum(*p)) *npp++ = *p++;
2826            *npp++ = 0;            *npp++ = 0;
2827            *npp = 0;            *npp = 0;
# Line 2444  while (!done) Line 2832  while (!done)
2832            }            }
2833          continue;          continue;
2834    
2835            case 'J':
2836            while(isdigit(*p)) n = n * 10 + *p++ - '0';
2837            if (extra != NULL
2838                && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0
2839                && extra->executable_jit != NULL)
2840              {
2841              if (jit_stack != NULL) pcre_jit_stack_free(jit_stack);
2842              jit_stack = pcre_jit_stack_alloc(1, n * 1024);
2843              pcre_assign_jit_stack(extra, jit_callback, jit_stack);
2844              }
2845            continue;
2846    
2847          case 'L':          case 'L':
2848          getlist = 1;          getlist = 1;
2849          continue;          continue;
# Line 2599  while (!done) Line 2999  while (!done)
2999            if (pmatch[i].rm_so >= 0)            if (pmatch[i].rm_so >= 0)
3000              {              {
3001              fprintf(outfile, "%2d: ", (int)i);              fprintf(outfile, "%2d: ", (int)i);
3002              (void)pchars(dbuffer + pmatch[i].rm_so,              PCHARSV(dbuffer + pmatch[i].rm_so,
3003                pmatch[i].rm_eo - pmatch[i].rm_so, outfile);                pmatch[i].rm_eo - pmatch[i].rm_so, outfile);
3004              fprintf(outfile, "\n");              fprintf(outfile, "\n");
3005              if (do_showcaprest || (i == 0 && do_showrest))              if (do_showcaprest || (i == 0 && do_showrest))
3006                {                {
3007                fprintf(outfile, "%2d+ ", (int)i);                fprintf(outfile, "%2d+ ", (int)i);
3008                (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo,                PCHARSV(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo,
3009                  outfile);                  outfile);
3010                fprintf(outfile, "\n");                fprintf(outfile, "\n");
3011                }                }
# Line 2613  while (!done) Line 3013  while (!done)
3013            }            }
3014          }          }
3015        free(pmatch);        free(pmatch);
3016          goto NEXT_DATA;
3017        }        }
3018    
3019    #endif  /* !defined NOPOSIX */
3020    
3021      /* Handle matching via the native interface - repeats for /g and /G */      /* Handle matching via the native interface - repeats for /g and /G */
3022    
3023      else  #ifdef SUPPORT_PCRE16
3024  #endif  /* !defined NOPOSIX */      if (use_pcre16)
3025          {
3026          len = to16(bptr, (((real_pcre *)re)->options) & PCRE_UTF8, len);
3027          bptr = (pcre_uint8 *)buffer16;
3028          }
3029    #endif
3030    
3031      for (;; gmatched++)    /* Loop for /g or /G */      for (;; gmatched++)    /* Loop for /g or /G */
3032        {        {
# Line 2643  while (!done) Line 3051  while (!done)
3051  #endif  #endif
3052    
3053          for (i = 0; i < timeitm; i++)          for (i = 0; i < timeitm; i++)
3054            count = pcre_exec(re, extra, (char *)bptr, len,            {
3055              PCRE_EXEC(count, re, extra, bptr, len,
3056              start_offset, options | g_notempty, use_offsets, use_size_offsets);              start_offset, options | g_notempty, use_offsets, use_size_offsets);
3057              }
3058          time_taken = clock() - start_time;          time_taken = clock() - start_time;
3059          fprintf(outfile, "Execute time %.4f milliseconds\n",          fprintf(outfile, "Execute time %.4f milliseconds\n",
3060            (((double)time_taken * 1000.0) / (double)timeitm) /            (((double)time_taken * 1000.0) / (double)timeitm) /
# Line 2654  while (!done) Line 3063  while (!done)
3063    
3064        /* If find_match_limit is set, we want to do repeated matches with        /* If find_match_limit is set, we want to do repeated matches with
3065        varying limits in order to find the minimum value for the match limit and        varying limits in order to find the minimum value for the match limit and
3066        for the recursion limit. */        for the recursion limit. The match limits are relevant only to the normal
3067          running of pcre_exec(), so disable the JIT optimization. This makes it
3068          possible to run the same set of tests with and without JIT externally
3069          requested. */
3070    
3071        if (find_match_limit)        if (find_match_limit)
3072          {          {
# Line 2663  while (!done) Line 3075  while (!done)
3075            extra = (pcre_extra *)malloc(sizeof(pcre_extra));            extra = (pcre_extra *)malloc(sizeof(pcre_extra));
3076            extra->flags = 0;            extra->flags = 0;
3077            }            }
3078            else extra->flags &= ~PCRE_EXTRA_EXECUTABLE_JIT;
3079    
3080          (void)check_match_limit(re, extra, bptr, len, start_offset,          (void)check_match_limit(re, extra, bptr, len, start_offset,
3081            options|g_notempty, use_offsets, use_size_offsets,            options|g_notempty, use_offsets, use_size_offsets,
# Line 2686  while (!done) Line 3099  while (!done)
3099            }            }
3100          extra->flags |= PCRE_EXTRA_CALLOUT_DATA;          extra->flags |= PCRE_EXTRA_CALLOUT_DATA;
3101          extra->callout_data = &callout_data;          extra->callout_data = &callout_data;
3102          count = pcre_exec(re, extra, (char *)bptr, len, start_offset,          PCRE_EXEC(count, re, extra, bptr, len, start_offset,
3103            options | g_notempty, use_offsets, use_size_offsets);            options | g_notempty, use_offsets, use_size_offsets);
3104          extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;          extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;
3105          }          }
# Line 2711  while (!done) Line 3124  while (!done)
3124    
3125        else        else
3126          {          {
3127          count = pcre_exec(re, extra, (char *)bptr, len,          PCRE_EXEC(count, re, extra, bptr, len, start_offset,
3128            start_offset, options | g_notempty, use_offsets, use_size_offsets);            options | g_notempty, use_offsets, use_size_offsets);
3129          if (count == 0)          if (count == 0)
3130            {            {
3131            fprintf(outfile, "Matched, but too many substrings\n");            fprintf(outfile, "Matched, but too many substrings\n");
# Line 2773  while (!done) Line 3186  while (!done)
3186            else            else
3187              {              {
3188              fprintf(outfile, "%2d: ", i/2);              fprintf(outfile, "%2d: ", i/2);
3189              (void)pchars(bptr + use_offsets[i],              PCHARSV(bptr + use_offsets[i],
3190                use_offsets[i+1] - use_offsets[i], outfile);                use_offsets[i+1] - use_offsets[i], outfile);
3191              fprintf(outfile, "\n");              fprintf(outfile, "\n");
3192              if (do_showcaprest || (i == 0 && do_showrest))              if (do_showcaprest || (i == 0 && do_showrest))
3193                {                {
3194                fprintf(outfile, "%2d+ ", i/2);                fprintf(outfile, "%2d+ ", i/2);
3195                (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1],                PCHARSV(bptr + use_offsets[i+1], len - use_offsets[i+1],
3196                  outfile);                  outfile);
3197                fprintf(outfile, "\n");                fprintf(outfile, "\n");
3198                }                }
# Line 2861  while (!done) Line 3274  while (!done)
3274                fprintf(outfile, "%2dL %s\n", i, stringlist[i]);                fprintf(outfile, "%2dL %s\n", i, stringlist[i]);
3275              if (stringlist[i] != NULL)              if (stringlist[i] != NULL)
3276                fprintf(outfile, "string list not terminated by NULL\n");                fprintf(outfile, "string list not terminated by NULL\n");
             /* free((void *)stringlist); */  
3277              pcre_free_substring_list(stringlist);              pcre_free_substring_list(stringlist);
3278              }              }
3279            }            }
# Line 2876  while (!done) Line 3288  while (!done)
3288          if (use_size_offsets > 1)          if (use_size_offsets > 1)
3289            {            {
3290            fprintf(outfile, ": ");            fprintf(outfile, ": ");
3291            pchars(bptr + use_offsets[0], use_offsets[1] - use_offsets[0],            PCHARSV(bptr + use_offsets[0], use_offsets[1] - use_offsets[0],
3292              outfile);              outfile);
3293            }            }
3294          fprintf(outfile, "\n");          fprintf(outfile, "\n");
# Line 3012  while (!done) Line 3424  while (!done)
3424  #endif  #endif
3425    
3426    if (re != NULL) new_free(re);    if (re != NULL) new_free(re);
3427    if (extra != NULL) new_free(extra);    if (extra != NULL) pcre_free_study(extra);
3428    if (locale_set)    if (locale_set)
3429      {      {
3430      new_free((void *)tables);      new_free((void *)tables);
3431      setlocale(LC_CTYPE, "C");      setlocale(LC_CTYPE, "C");
3432      locale_set = 0;      locale_set = 0;
3433      }      }
3434      if (jit_stack != NULL)
3435        {
3436        pcre_jit_stack_free(jit_stack);
3437        jit_stack = NULL;
3438        }
3439    }    }
3440    
3441  if (infile == stdin) fprintf(outfile, "\n");  if (infile == stdin) fprintf(outfile, "\n");
# Line 3033  free(dbuffer); Line 3450  free(dbuffer);
3450  free(pbuffer);  free(pbuffer);
3451  free(offsets);  free(offsets);
3452    
3453    #ifdef SUPPORT_PCRE16
3454    if (buffer16 != NULL) free(buffer16);
3455    #endif
3456    
3457  return yield;  return yield;
3458  }  }
3459    

Legend:
Removed from v.658  
changed lines
  Added in v.808

  ViewVC Help
Powered by ViewVC 1.1.5