/[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 813 by ph10, Tue Dec 20 14:03:16 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    
185    #define PCHARS8(lv, p, len, f) \
186      lv = pchars((pcre_uint8 *)p, len, f)
187    
188    #define PCHARSV8(p, len, f) \
189      (void)pchars((pcre_uint8 *)p, len, f)
190    
191    #define PCRE_COMPILE8(re, pat, options, error, erroffset, tables) \
192      re = pcre_compile((char *)pat, options, error, erroffset, tables)
193    
194    #define PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
195        offsets, size_offsets) \
196      count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, \
197        offsets, size_offsets)
198    
199    #define PCRE_FREE_STUDY8(extra) \
200      pcre_free_study(extra)
201    
202    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER8(re, extra, tables) \
203      pcre_pattern_to_host_byte_order(re, extra, tables)
204    
205    #define PCRE_STUDY8(extra, re, options, error) \
206      extra = pcre_study(re, options, error)
207    
208    #endif /* SUPPORT_PCRE8 */
209    
210    
211    #ifdef SUPPORT_PCRE16
212    
213    #define PCHARS16(lv, p, len, f) \
214      lv = pchars16((PCRE_SPTR16)p, len, f)
215    
216    #define PCHARSV16(p, len, f) \
217      (void)pchars16((PCRE_SPTR16)p, len, f)
218    
219    #define PCRE_COMPILE16(re, pat, options, error, erroffset, tables) \
220      re = pcre16_compile((PCRE_SPTR16)pat, options, error, erroffset, tables)
221    
222    #define PCRE_FREE_STUDY16(extra) \
223      pcre16_free_study(extra)
224    
225    #define PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
226        offsets, size_offsets) \
227      count = pcre16_exec(re, extra, (PCRE_SPTR16)bptr, len, start_offset, \
228        options, offsets, size_offsets)
229    
230    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER16(re, extra, tables) \
231      pcre16_pattern_to_host_byte_order(re, extra, tables)
232    
233    #define PCRE_STUDY16(extra, re, options, error) \
234      extra = pcre16_study(re, options, error)
235    
236    #endif /* SUPPORT_PCRE16 */
237    
238    
239    /* ----- Both modes are supported; a runtime test is needed ----- */
240    
241    #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
242    
243    #define PCHARS(lv, p, len, f) \
244      if (use_pcre16) \
245        PCHARS16(lv, p, len, f); \
246      else \
247        PCHARS8(lv, p, len, f)
248    
249    #define PCHARSV(p, len, f) \
250      if (use_pcre16) \
251        PCHARSV16(p, len, f); \
252      else \
253        PCHARSV8(p, len, f)
254    
255    #define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \
256      if (use_pcre16) \
257        PCRE_COMPILE16(re, pat, options, error, erroffset, tables); \
258      else \
259        PCRE_COMPILE8(re, pat, options, error, erroffset, tables)
260    
261    #define PCRE_FREE_STUDY(extra) \
262      if (use_pcre16) \
263        PCRE_FREE_STUDY16(extra); \
264      else \
265        PCRE_FREE_STUDY8(extra)
266    
267    #define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \
268        offsets, size_offsets) \
269      if (use_pcre16) \
270        PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
271          offsets, size_offsets); \
272      else \
273        PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
274          offsets, size_offsets)
275    
276    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER(re, extra, tables) \
277      if (use_pcre16) \
278        PCRE_PATTERN_TO_HOST_BYTE_ORDER16(re, extra, tables); \
279      else \
280        PCRE_PATTERN_TO_HOST_BYTE_ORDER8(re, extra, tables)
281    
282    #define PCRE_STUDY(extra, re, options, error) \
283      if (use_pcre16) \
284        PCRE_STUDY16(extra, re, options, error); \
285      else \
286        PCRE_STUDY8(extra, re, options, error)
287    
288    /* ----- Only 8-bit mode is supported ----- */
289    
290    #elif defined SUPPORT_PCRE8
291    #define PCHARS           PCHARS8
292    #define PCHARSV          PCHARSV8
293    #define PCRE_COMPILE     PCRE_COMPILE8
294    #define PCRE_EXEC        PCRE_EXEC8
295    #define PCRE_FREE_STUDY  PCRE_FREE_STUDY8
296    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER8
297    #define PCRE_STUDY       PCRE_STUDY8
298    
299    /* ----- Only 16-bit mode is supported ----- */
300    
301    #else
302    #define PCHARS           PCHARS16
303    #define PCHARSV          PCHARSV16
304    #define PCRE_COMPILE     PCRE_COMPILE16
305    #define PCRE_EXEC        PCRE_EXEC16
306    #define PCRE_FREE_STUDY  PCRE_FREE_STUDY16
307    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER16
308    #define PCRE_STUDY       PCRE_STUDY16
309    #endif
310    
311    /* ----- End of mode-specific function call macros ----- */
312    
313    
314  /* Other parameters */  /* Other parameters */
315    
# Line 187  static int debug_lengths; Line 337  static int debug_lengths;
337  static int first_callout;  static int first_callout;
338  static int locale_set = 0;  static int locale_set = 0;
339  static int show_malloc;  static int show_malloc;
340  static int use_utf8;  static int use_utf;
341  static size_t gotten_store;  static size_t gotten_store;
342    static size_t first_gotten_store = 0;
343  static const unsigned char *last_callout_mark = NULL;  static const unsigned char *last_callout_mark = NULL;
344    
345  /* The buffers grow automatically if very long input lines are encountered. */  /* The buffers grow automatically if very long input lines are encountered. */
346    
347  static int buffer_size = 50000;  static int buffer_size = 50000;
348  static uschar *buffer = NULL;  static pcre_uint8 *buffer = NULL;
349  static uschar *dbuffer = NULL;  static pcre_uint8 *dbuffer = NULL;
350  static uschar *pbuffer = NULL;  static pcre_uint8 *pbuffer = NULL;
351    
352    /* Another buffer is needed translation to 16-bit character strings. It will
353    obtained and extended as required. */
354    
355    #ifdef SUPPORT_PCRE16
356    static int buffer16_size = 0;
357    static pcre_uint16 *buffer16 = NULL;
358    
359    /* We need the table of operator lengths that is used for 16-bit compiling, in
360    order to swap bytes in a pattern for saving/reloading testing. Luckily, the
361    data is defined as a macro. However, we must ensure that LINK_SIZE is adjusted
362    appropriately for the 16-bit world. Just as a safety check, make sure that
363    COMPILE_PCRE16 is *not* set. */
364    
365    #ifdef COMPILE_PCRE16
366    #error COMPILE_PCRE16 must not be set when compiling pcretest.c
367    #endif
368    
369    #if LINK_SIZE == 2
370    #undef LINK_SIZE
371    #define LINK_SIZE 1
372    #elif LINK_SIZE == 3 || LINK_SIZE == 4
373    #undef LINK_SIZE
374    #define LINK_SIZE 2
375    #else
376    #error LINK_SIZE must be either 2, 3, or 4
377    #endif
378    
379    static const pcre_uint16 OP_lengths16[] = { OP_LENGTHS };
380    
381    #endif  /* SUPPORT_PCRE16 */
382    
383    /* If we have 8-bit support, default use_pcre16 to false; if there is also
384    16-bit support, it can be changed by an option. If there is no 8-bit support,
385    there must be 16-bit support, so default it to 1. */
386    
387    #ifdef SUPPORT_PCRE8
388    static int use_pcre16 = 0;
389    #else
390    static int use_pcre16 = 1;
391    #endif
392    
393  /* Textual explanations for runtime error codes */  /* Textual explanations for runtime error codes */
394    
# Line 227  static const char *errtexts[] = { Line 419  static const char *errtexts[] = {
419    "invalid combination of newline options",    "invalid combination of newline options",
420    "bad offset value",    "bad offset value",
421    NULL,  /* SHORTUTF8 is handled specially */    NULL,  /* SHORTUTF8 is handled specially */
422    "nested recursion at the same subject position"    "nested recursion at the same subject position",
423      "JIT stack limit reached",
424      "pattern compiled in wrong mode (8-bit/16-bit error)"
425  };  };
426    
427    
# Line 243  the L (locale) option also adjusts the t Line 437  the L (locale) option also adjusts the t
437  /* 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
438  only ASCII characters. */  only ASCII characters. */
439    
440  static const unsigned char tables0[] = {  static const pcre_uint8 tables0[] = {
441    
442  /* This table is a lower casing table. */  /* This table is a lower casing table. */
443    
# Line 416  graph, print, punct, and cntrl. Other cl Line 610  graph, print, punct, and cntrl. Other cl
610  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
611  greater than 128 that are marked as spaces, letters, etc. */  greater than 128 that are marked as spaces, letters, etc. */
612    
613  static const unsigned char tables1[] = {  static const pcre_uint8 tables1[] = {
614  0,1,2,3,4,5,6,7,  0,1,2,3,4,5,6,7,
615  8,9,10,11,12,13,14,15,  8,9,10,11,12,13,14,15,
616  16,17,18,19,20,21,22,23,  16,17,18,19,20,21,22,23,
# Line 579  return sys_errlist[n]; Line 773  return sys_errlist[n];
773  #endif /* HAVE_STRERROR */  #endif /* HAVE_STRERROR */
774    
775    
776    /*************************************************
777    *         JIT memory callback                    *
778    *************************************************/
779    
780    static pcre_jit_stack* jit_callback(void *arg)
781    {
782    return (pcre_jit_stack *)arg;
783    }
784    
785    
786    /*************************************************
787    *            Convert UTF-8 string to value       *
788    *************************************************/
789    
790    /* This function takes one or more bytes that represents a UTF-8 character,
791    and returns the value of the character.
792    
793    Argument:
794      utf8bytes   a pointer to the byte vector
795      vptr        a pointer to an int to receive the value
796    
797    Returns:      >  0 => the number of bytes consumed
798                  -6 to 0 => malformed UTF-8 character at offset = (-return)
799    */
800    
801    #if !defined NOUTF8
802    
803    static int
804    utf82ord(pcre_uint8 *utf8bytes, int *vptr)
805    {
806    int c = *utf8bytes++;
807    int d = c;
808    int i, j, s;
809    
810    for (i = -1; i < 6; i++)               /* i is number of additional bytes */
811      {
812      if ((d & 0x80) == 0) break;
813      d <<= 1;
814      }
815    
816    if (i == -1) { *vptr = c; return 1; }  /* ascii character */
817    if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */
818    
819    /* i now has a value in the range 1-5 */
820    
821    s = 6*i;
822    d = (c & utf8_table3[i]) << s;
823    
824    for (j = 0; j < i; j++)
825      {
826      c = *utf8bytes++;
827      if ((c & 0xc0) != 0x80) return -(j+1);
828      s -= 6;
829      d |= (c & 0x3f) << s;
830      }
831    
832    /* Check that encoding was the correct unique one */
833    
834    for (j = 0; j < utf8_table1_size; j++)
835      if (d <= utf8_table1[j]) break;
836    if (j != i) return -(i+1);
837    
838    /* Valid value */
839    
840    *vptr = d;
841    return i+1;
842    }
843    
844    #endif
845    
846    
847    
848    /*************************************************
849    *       Convert character value to UTF-8         *
850    *************************************************/
851    
852    /* This function takes an integer value in the range 0 - 0x7fffffff
853    and encodes it as a UTF-8 character in 0 to 6 bytes.
854    
855    Arguments:
856      cvalue     the character value
857      utf8bytes  pointer to buffer for result - at least 6 bytes long
858    
859    Returns:     number of characters placed in the buffer
860    */
861    
862    #if !defined NOUTF8
863    
864    static int
865    ord2utf8(int cvalue, pcre_uint8 *utf8bytes)
866    {
867    register int i, j;
868    for (i = 0; i < utf8_table1_size; i++)
869      if (cvalue <= utf8_table1[i]) break;
870    utf8bytes += i;
871    for (j = i; j > 0; j--)
872     {
873     *utf8bytes-- = 0x80 | (cvalue & 0x3f);
874     cvalue >>= 6;
875     }
876    *utf8bytes = utf8_table2[i] | cvalue;
877    return i + 1;
878    }
879    
880    #endif
881    
882    
883    
884    #ifdef SUPPORT_PCRE16
885    /*************************************************
886    *         Convert a string to 16-bit             *
887    *************************************************/
888    
889    /* In non-UTF mode, the space needed for a 16-bit string is exactly double the
890    8-bit size. For a UTF-8 string, the size needed for UTF-16 is no more than
891    double, because up to 0xffff uses no more than 3 bytes in UTF-8 but possibly 4
892    in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in UTF-16. The
893    result is always left in buffer16.
894    
895    Arguments:
896      p          points to a byte string
897      utf        true if UTF-8 (to be converted to UTF-16)
898      len        number of bytes in the string (excluding trailing zero)
899    
900    Returns:     number of 16-bit data items used (excluding trailing zero)
901                 OR -1 if a UTF-8 string is malformed
902    */
903    
904    static int
905    to16(pcre_uint8 *p, int utf, int len)
906    {
907    pcre_uint16 *pp;
908    
909    if (buffer16_size < 2*len + 2)
910      {
911      if (buffer16 != NULL) free(buffer16);
912      buffer16_size = 2*len + 2;
913      buffer16 = (pcre_uint16 *)malloc(buffer16_size);
914      if (buffer16 == NULL)
915        {
916        fprintf(stderr, "pcretest: malloc(%d) failed for buffer16\n", buffer16_size);
917        exit(1);
918        }
919      }
920    
921    pp = buffer16;
922    
923    if (!utf)
924      {
925      while (len-- > 0) *pp++ = *p++;
926      }
927    
928    else
929      {
930      int c;
931      while (len > 0)
932        {
933        int chlen = utf82ord(p, &c);
934        if (chlen <= 0) return -1;
935        p += chlen;
936        len -= chlen;
937        if (c < 0x10000) *pp++ = c; else
938          {
939          c -= 0x10000;
940          *pp++ = 0xD800 | (c >> 10);
941          *pp++ = 0xDC00 | (c & 0x3ff);
942          }
943        }
944      }
945    
946    *pp = 0;
947    return pp - buffer16;
948    }
949    #endif
950    
951    
952  /*************************************************  /*************************************************
# Line 604  Returns:       pointer to the start of n Line 972  Returns:       pointer to the start of n
972                 NULL if no data read and EOF reached                 NULL if no data read and EOF reached
973  */  */
974    
975  static uschar *  static pcre_uint8 *
976  extend_inputline(FILE *f, uschar *start, const char *prompt)  extend_inputline(FILE *f, pcre_uint8 *start, const char *prompt)
977  {  {
978  uschar *here = start;  pcre_uint8 *here = start;
979    
980  for (;;)  for (;;)
981    {    {
# Line 654  for (;;) Line 1022  for (;;)
1022    else    else
1023      {      {
1024      int new_buffer_size = 2*buffer_size;      int new_buffer_size = 2*buffer_size;
1025      uschar *new_buffer = (unsigned char *)malloc(new_buffer_size);      pcre_uint8 *new_buffer = (pcre_uint8 *)malloc(new_buffer_size);
1026      uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size);      pcre_uint8 *new_dbuffer = (pcre_uint8 *)malloc(new_buffer_size);
1027      uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size);      pcre_uint8 *new_pbuffer = (pcre_uint8 *)malloc(new_buffer_size);
1028    
1029      if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)      if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)
1030        {        {
# Line 687  return NULL;  /* Control never gets here Line 1055  return NULL;  /* Control never gets here
1055    
1056    
1057    
   
   
   
   
1058  /*************************************************  /*************************************************
1059  *          Read number from string               *  *          Read number from string               *
1060  *************************************************/  *************************************************/
# Line 707  Returns:        the unsigned long Line 1071  Returns:        the unsigned long
1071  */  */
1072    
1073  static int  static int
1074  get_value(unsigned char *str, unsigned char **endptr)  get_value(pcre_uint8 *str, pcre_uint8 **endptr)
1075  {  {
1076  int result = 0;  int result = 0;
1077  while(*str != 0 && isspace(*str)) str++;  while(*str != 0 && isspace(*str)) str++;
# Line 718  return(result); Line 1082  return(result);
1082    
1083    
1084    
   
1085  /*************************************************  /*************************************************
1086  *            Convert UTF-8 string to value       *  *             Print one character                *
1087  *************************************************/  *************************************************/
1088    
1089  /* This function takes one or more bytes that represents a UTF-8 character,  /* Print a single character either literally, or as a hex escape. */
 and returns the value of the character.  
   
 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  
1090    
1091  static int  static int pchar(int c, FILE *f)
 utf82ord(unsigned char *utf8bytes, int *vptr)  
1092  {  {
1093  int c = *utf8bytes++;  if (PRINTOK(c))
 int d = c;  
 int i, j, s;  
   
 for (i = -1; i < 6; i++)               /* i is number of additional bytes */  
1094    {    {
1095    if ((d & 0x80) == 0) break;    if (f != NULL) fprintf(f, "%c", c);
1096    d <<= 1;    return 1;
1097    }    }
1098    
1099  if (i == -1) { *vptr = c; return 1; }  /* ascii character */  if (c < 0x100)
 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++)  
1100    {    {
1101    c = *utf8bytes++;    if (use_utf)
1102    if ((c & 0xc0) != 0x80) return -(j+1);      {
1103    s -= 6;      if (f != NULL) fprintf(f, "\\x{%02x}", c);
1104    d |= (c & 0x3f) << s;      return 6;
1105        }
1106      else
1107        {
1108        if (f != NULL) fprintf(f, "\\x%02x", c);
1109        return 4;
1110        }
1111    }    }
1112    
1113  /* Check that encoding was the correct unique one */  if (f != NULL) fprintf(f, "\\x{%02x}", c);
1114    return (c <= 0x000000ff)? 6 :
1115  for (j = 0; j < utf8_table1_size; j++)         (c <= 0x00000fff)? 7 :
1116    if (d <= utf8_table1[j]) break;         (c <= 0x0000ffff)? 8 :
1117  if (j != i) return -(i+1);         (c <= 0x000fffff)? 9 : 10;
   
 /* Valid value */  
   
 *vptr = d;  
 return i+1;  
1118  }  }
1119    
 #endif  
   
1120    
1121    
1122    #ifdef SUPPORT_PCRE8
1123  /*************************************************  /*************************************************
1124  *       Convert character value to UTF-8         *  *         Print 8-bit character string           *
1125  *************************************************/  *************************************************/
1126    
1127  /* This function takes an integer value in the range 0 - 0x7fffffff  /* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed.
1128  and encodes it as a UTF-8 character in 0 to 6 bytes.  If handed a NULL file, just counts chars without printing. */
1129    
1130  Arguments:  static int pchars(pcre_uint8 *p, int length, FILE *f)
1131    cvalue     the character value  {
1132    utf8bytes  pointer to buffer for result - at least 6 bytes long  int c = 0;
1133    int yield = 0;
 Returns:     number of characters placed in the buffer  
 */  
1134    
1135    while (length-- > 0)
1136      {
1137  #if !defined NOUTF8  #if !defined NOUTF8
1138      if (use_utf)
1139        {
1140        int rc = utf82ord(p, &c);
1141        if (rc > 0 && rc <= length + 1)   /* Mustn't run over the end */
1142          {
1143          length -= rc - 1;
1144          p += rc;
1145          yield += pchar(c, f);
1146          continue;
1147          }
1148        }
1149    #endif
1150      c = *p++;
1151      yield += pchar(c, f);
1152      }
1153    
1154  static int  return yield;
 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;  
1155  }  }
   
1156  #endif  #endif
1157    
1158    
1159    
1160    #ifdef SUPPORT_PCRE16
1161  /*************************************************  /*************************************************
1162  *             Print character string             *  *           Print 16-bit character string        *
1163  *************************************************/  *************************************************/
1164    
1165  /* Character string printing function. Must handle UTF-8 strings in utf8  /* Must handle UTF-16 strings in utf mode. Yields number of characters printed.
1166  mode. Yields number of characters printed. If handed a NULL file, just counts  If handed a NULL file, just counts chars without printing. */
 chars without printing. */  
1167    
1168  static int pchars(unsigned char *p, int length, FILE *f)  static int pchars16(PCRE_SPTR16 p, int length, FILE *f)
1169  {  {
 int c = 0;  
1170  int yield = 0;  int yield = 0;
1171    
1172  while (length-- > 0)  while (length-- > 0)
1173    {    {
1174      int c = *p++ & 0xffff;
1175  #if !defined NOUTF8  #if !defined NOUTF8
1176    if (use_utf8)    if (use_utf && c >= 0xD800 && c < 0xDC00 && length > 0)
1177      {      {
1178      int rc = utf82ord(p, &c);      int d = *p & 0xffff;
1179        if (d >= 0xDC00 && d < 0xDFFF)
     if (rc > 0 && rc <= length + 1)   /* Mustn't run over the end */  
1180        {        {
1181        length -= rc - 1;        c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000;
1182        p += rc;        length--;
1183        if (PRINTHEX(c))        p++;
         {  
         if (f != NULL) fprintf(f, "%c", c);  
         yield++;  
         }  
       else  
         {  
         int n = 4;  
         if (f != NULL) fprintf(f, "\\x{%02x}", c);  
         yield += (n <= 0x000000ff)? 2 :  
                  (n <= 0x00000fff)? 3 :  
                  (n <= 0x0000ffff)? 4 :  
                  (n <= 0x000fffff)? 5 : 6;  
         }  
       continue;  
1184        }        }
1185      }      }
1186  #endif  #endif
1187      yield += pchar(c, f);
    /* Not UTF-8, or malformed UTF-8  */  
   
   c = *p++;  
   if (PRINTHEX(c))  
     {  
     if (f != NULL) fprintf(f, "%c", c);  
     yield++;  
     }  
   else  
     {  
     if (f != NULL) fprintf(f, "\\x%02x", c);  
     yield += 4;  
     }  
1188    }    }
1189    
1190  return yield;  return yield;
1191  }  }
1192    #endif
1193    
1194    
1195    
# Line 905  if (callout_extra) Line 1218  if (callout_extra)
1218      else      else
1219        {        {
1220        fprintf(f, "%2d: ", i/2);        fprintf(f, "%2d: ", i/2);
1221        (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i],        PCHARSV(cb->subject + cb->offset_vector[i],
1222          cb->offset_vector[i+1] - cb->offset_vector[i], f);          cb->offset_vector[i+1] - cb->offset_vector[i], f);
1223        fprintf(f, "\n");        fprintf(f, "\n");
1224        }        }
# Line 918  printed lengths of the substrings. */ Line 1231  printed lengths of the substrings. */
1231    
1232  if (f != NULL) fprintf(f, "--->");  if (f != NULL) fprintf(f, "--->");
1233    
1234  pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f);  PCHARS(pre_start, cb->subject, cb->start_match, f);
1235  post_start = pchars((unsigned char *)(cb->subject + cb->start_match),  PCHARS(post_start, cb->subject + cb->start_match,
1236    cb->current_position - cb->start_match, f);    cb->current_position - cb->start_match, f);
1237    
1238  subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);  PCHARS(subject_length, cb->subject, cb->subject_length, NULL);
1239    
1240  (void)pchars((unsigned char *)(cb->subject + cb->current_position),  PCHARSV(cb->subject + cb->current_position,
1241    cb->subject_length - cb->current_position, f);    cb->subject_length - cb->current_position, f);
1242    
1243  if (f != NULL) fprintf(f, "\n");  if (f != NULL) fprintf(f, "\n");
# Line 987  return (cb->callout_number != callout_fa Line 1300  return (cb->callout_number != callout_fa
1300  *            Local malloc functions              *  *            Local malloc functions              *
1301  *************************************************/  *************************************************/
1302    
1303  /* Alternative malloc function, to test functionality and show the size of the  /* Alternative malloc function, to test functionality and save the size of a
1304  compiled re. */  compiled re, which is the first store request that pcre_compile() makes. The
1305    show_malloc variable is set only during matching. */
1306    
1307  static void *new_malloc(size_t size)  static void *new_malloc(size_t size)
1308  {  {
1309  void *block = malloc(size);  void *block = malloc(size);
1310  gotten_store = size;  gotten_store = size;
1311    if (first_gotten_store == 0) first_gotten_store = size;
1312  if (show_malloc)  if (show_malloc)
1313    fprintf(outfile, "malloc       %3d %p\n", (int)size, block);    fprintf(outfile, "malloc       %3d %p\n", (int)size, block);
1314  return block;  return block;
# Line 1006  if (show_malloc) Line 1321  if (show_malloc)
1321  free(block);  free(block);
1322  }  }
1323    
   
1324  /* For recursion malloc/free, to test stacking calls */  /* For recursion malloc/free, to test stacking calls */
1325    
1326  static void *stack_malloc(size_t size)  static void *stack_malloc(size_t size)
# Line 1029  free(block); Line 1343  free(block);
1343  *          Call pcre_fullinfo()                  *  *          Call pcre_fullinfo()                  *
1344  *************************************************/  *************************************************/
1345    
1346  /* Get one piece of information from the pcre_fullinfo() function */  /* Get one piece of information from the pcre_fullinfo() function. When only
1347    one of 8-bit or 16-bit is supported, use_pcre16 should always have the correct
1348    value, but the code is defensive. */
1349    
1350  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)
1351  {  {
1352  int rc;  int rc;
1353  if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)  
1354    fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);  if (use_pcre16)
1355    #ifdef SUPPORT_PCRE16
1356      rc = pcre16_fullinfo(re, study, option, ptr);
1357    #else
1358      rc = PCRE_ERROR_BADMODE;
1359    #endif
1360    else
1361    #ifdef SUPPORT_PCRE8
1362      rc = pcre_fullinfo(re, study, option, ptr);
1363    #else
1364      rc = PCRE_ERROR_BADMODE;
1365    #endif
1366    
1367    if (rc < 0) fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc,
1368      use_pcre16? "16" : "", option);
1369  }  }
1370    
1371    
1372    
1373  /*************************************************  /*************************************************
1374  *         Byte flipping function                 *  *             Swap byte functions                *
1375  *************************************************/  *************************************************/
1376    
1377  static unsigned long int  /* The following functions swap the bytes of a pcre_uint16
1378  byteflip(unsigned long int value, int n)  and pcre_uint32 value.
1379    
1380    Arguments:
1381      value        any number
1382    
1383    Returns:       the byte swapped value
1384    */
1385    
1386    static pcre_uint32
1387    swap_uint32(pcre_uint32 value)
1388  {  {
 if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);  
1389  return ((value & 0x000000ff) << 24) |  return ((value & 0x000000ff) << 24) |
1390         ((value & 0x0000ff00) <<  8) |         ((value & 0x0000ff00) <<  8) |
1391         ((value & 0x00ff0000) >>  8) |         ((value & 0x00ff0000) >>  8) |
1392         ((value & 0xff000000) >> 24);         (value >> 24);
1393  }  }
1394    
1395    static pcre_uint16
1396    swap_uint16(pcre_uint16 value)
1397    {
1398    return (value >> 8) | (value << 8);
1399    }
1400    
1401    
1402    
1403    /*************************************************
1404    *        Flip bytes in a compiled pattern        *
1405    *************************************************/
1406    
1407    /* This function is called if the 'F' option was present on a pattern that is
1408    to be written to a file. We flip the bytes of all the integer fields in the
1409    regex data block and the study block. In 16-bit mode this also flips relevant
1410    bytes in the pattern itself. This is to make it possible to test PCRE's
1411    ability to reload byte-flipped patterns, e.g. those compiled on a different
1412    architecture. */
1413    
1414    static void
1415    regexflip(pcre *ere, pcre_extra *extra)
1416    {
1417    real_pcre *re = (real_pcre *)ere;
1418    int op;
1419    
1420    #ifdef SUPPORT_PCRE16
1421    pcre_uint16 *ptr = (pcre_uint16 *)re + re->name_table_offset;
1422    int length = re->name_count * re->name_entry_size;
1423    #ifdef SUPPORT_UTF
1424    BOOL utf = (re->options & PCRE_UTF16) != 0;
1425    BOOL utf16_char = FALSE;
1426    #endif /* SUPPORT_UTF */
1427    #endif /* SUPPORT_PCRE16 */
1428    
1429    /* Always flip the bytes in the main data block and study blocks. */
1430    
1431    re->magic_number = REVERSED_MAGIC_NUMBER;
1432    re->size = swap_uint32(re->size);
1433    re->options = swap_uint32(re->options);
1434    re->flags = swap_uint16(re->flags);
1435    re->top_bracket = swap_uint16(re->top_bracket);
1436    re->top_backref = swap_uint16(re->top_backref);
1437    re->first_char = swap_uint16(re->first_char);
1438    re->req_char = swap_uint16(re->req_char);
1439    re->name_table_offset = swap_uint16(re->name_table_offset);
1440    re->name_entry_size = swap_uint16(re->name_entry_size);
1441    re->name_count = swap_uint16(re->name_count);
1442    
1443    if (extra != NULL)
1444      {
1445      pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);
1446      rsd->size = swap_uint32(rsd->size);
1447      rsd->flags = swap_uint32(rsd->flags);
1448      rsd->minlength = swap_uint32(rsd->minlength);
1449      }
1450    
1451    /* In 8-bit mode, that is all we need to do. In 16-bit mode we must swap bytes
1452    in the name table, if present, and then in the pattern itself. */
1453    
1454    #ifdef SUPPORT_PCRE16
1455    if (!use_pcre16) return;
1456    
1457    while(TRUE)
1458      {
1459      /* Swap previous characters. */
1460      while (length-- > 0)
1461        {
1462        *ptr = swap_uint16(*ptr);
1463        ptr++;
1464        }
1465    #ifdef SUPPORT_UTF
1466      if (utf16_char)
1467        {
1468        if ((ptr[-1] & 0xfc00) == 0xd800)
1469          {
1470          /* We know that there is only one extra character in UTF-16. */
1471          *ptr = swap_uint16(*ptr);
1472          ptr++;
1473          }
1474        }
1475      utf16_char = FALSE;
1476    #endif /* SUPPORT_UTF */
1477    
1478      /* Get next opcode. */
1479    
1480      length = 0;
1481      op = *ptr;
1482      *ptr++ = swap_uint16(op);
1483    
1484      switch (op)
1485        {
1486        case OP_END:
1487        return;
1488    
1489        case OP_CHAR:
1490        case OP_CHARI:
1491        case OP_NOT:
1492        case OP_NOTI:
1493        case OP_STAR:
1494        case OP_MINSTAR:
1495        case OP_PLUS:
1496        case OP_MINPLUS:
1497        case OP_QUERY:
1498        case OP_MINQUERY:
1499        case OP_UPTO:
1500        case OP_MINUPTO:
1501        case OP_EXACT:
1502        case OP_POSSTAR:
1503        case OP_POSPLUS:
1504        case OP_POSQUERY:
1505        case OP_POSUPTO:
1506        case OP_STARI:
1507        case OP_MINSTARI:
1508        case OP_PLUSI:
1509        case OP_MINPLUSI:
1510        case OP_QUERYI:
1511        case OP_MINQUERYI:
1512        case OP_UPTOI:
1513        case OP_MINUPTOI:
1514        case OP_EXACTI:
1515        case OP_POSSTARI:
1516        case OP_POSPLUSI:
1517        case OP_POSQUERYI:
1518        case OP_POSUPTOI:
1519        case OP_NOTSTAR:
1520        case OP_NOTMINSTAR:
1521        case OP_NOTPLUS:
1522        case OP_NOTMINPLUS:
1523        case OP_NOTQUERY:
1524        case OP_NOTMINQUERY:
1525        case OP_NOTUPTO:
1526        case OP_NOTMINUPTO:
1527        case OP_NOTEXACT:
1528        case OP_NOTPOSSTAR:
1529        case OP_NOTPOSPLUS:
1530        case OP_NOTPOSQUERY:
1531        case OP_NOTPOSUPTO:
1532        case OP_NOTSTARI:
1533        case OP_NOTMINSTARI:
1534        case OP_NOTPLUSI:
1535        case OP_NOTMINPLUSI:
1536        case OP_NOTQUERYI:
1537        case OP_NOTMINQUERYI:
1538        case OP_NOTUPTOI:
1539        case OP_NOTMINUPTOI:
1540        case OP_NOTEXACTI:
1541        case OP_NOTPOSSTARI:
1542        case OP_NOTPOSPLUSI:
1543        case OP_NOTPOSQUERYI:
1544        case OP_NOTPOSUPTOI:
1545    #ifdef SUPPORT_UTF
1546        if (utf) utf16_char = TRUE;
1547    #endif
1548        length = OP_lengths16[op] - 1;
1549        break;
1550    
1551        case OP_CLASS:
1552        case OP_NCLASS:
1553        /* Skip the character bit map. */
1554        ptr += 32/sizeof(pcre_uint16);
1555        length = 0;
1556        break;
1557    
1558        case OP_XCLASS:
1559        /* Reverse the size of the XCLASS instance. */
1560        ptr++;
1561        *ptr = swap_uint16(*ptr);
1562        if (LINK_SIZE > 1)
1563          {
1564          /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
1565          ptr++;
1566          *ptr = swap_uint16(*ptr);
1567          }
1568        ptr++;
1569    
1570        if (LINK_SIZE > 1)
1571          length = ((ptr[-LINK_SIZE] << 16) | ptr[-LINK_SIZE + 1]) -
1572            (1 + LINK_SIZE + 1);
1573        else
1574          length = ptr[-LINK_SIZE] - (1 + LINK_SIZE + 1);
1575    
1576        op = *ptr;
1577        *ptr = swap_uint16(op);
1578        if ((op & XCL_MAP) != 0)
1579          {
1580          /* Skip the character bit map. */
1581          ptr += 32/sizeof(pcre_uint16);
1582          length -= 32/sizeof(pcre_uint16);
1583          }
1584        break;
1585    
1586        default:
1587        length = OP_lengths16[op] - 1;
1588        break;
1589        }
1590      }
1591    /* Control should never reach here in 16 bit mode. */
1592    #endif /* SUPPORT_PCRE16 */
1593    }
1594    
1595    
1596    
# Line 1062  return ((value & 0x000000ff) << 24) | Line 1599  return ((value & 0x000000ff) << 24) |
1599  *************************************************/  *************************************************/
1600    
1601  static int  static int
1602  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,
1603    int start_offset, int options, int *use_offsets, int use_size_offsets,    int start_offset, int options, int *use_offsets, int use_size_offsets,
1604    int flag, unsigned long int *limit, int errnumber, const char *msg)    int flag, unsigned long int *limit, int errnumber, const char *msg)
1605  {  {
# Line 1077  for (;;) Line 1614  for (;;)
1614    {    {
1615    *limit = mid;    *limit = mid;
1616    
1617    count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options,    PCRE_EXEC(count, re, extra, bptr, len, start_offset, options,
1618      use_offsets, use_size_offsets);      use_offsets, use_size_offsets);
1619    
1620    if (count == errnumber)    if (count == errnumber)
# Line 1122  Returns:    < 0, = 0, or > 0, according Line 1659  Returns:    < 0, = 0, or > 0, according
1659  */  */
1660    
1661  static int  static int
1662  strncmpic(uschar *s, uschar *t, int n)  strncmpic(pcre_uint8 *s, pcre_uint8 *t, int n)
1663  {  {
1664  while (n--)  while (n--)
1665    {    {
# Line 1149  Returns:      appropriate PCRE_NEWLINE_x Line 1686  Returns:      appropriate PCRE_NEWLINE_x
1686  */  */
1687    
1688  static int  static int
1689  check_newline(uschar *p, FILE *f)  check_newline(pcre_uint8 *p, FILE *f)
1690  {  {
1691  if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;  if (strncmpic(p, (pcre_uint8 *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
1692  if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;  if (strncmpic(p, (pcre_uint8 *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
1693  if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;  if (strncmpic(p, (pcre_uint8 *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
1694  if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;  if (strncmpic(p, (pcre_uint8 *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
1695  if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;  if (strncmpic(p, (pcre_uint8 *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
1696  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;
1697  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;
1698  fprintf(f, "Unknown newline type at: <%s\n", p);  fprintf(f, "Unknown newline type at: <%s\n", p);
1699  return 0;  return 0;
1700  }  }
# Line 1179  printf("If input is a terminal, readline Line 1716  printf("If input is a terminal, readline
1716  printf("This version of pcretest is not linked with readline().\n");  printf("This version of pcretest is not linked with readline().\n");
1717  #endif  #endif
1718  printf("\nOptions:\n");  printf("\nOptions:\n");
1719    #ifdef SUPPORT_PCRE16
1720    printf("  -16      use 16-bit interface\n");
1721    #endif
1722  printf("  -b       show compiled code (bytecode)\n");  printf("  -b       show compiled code (bytecode)\n");
1723  printf("  -C       show PCRE compile-time options and exit\n");  printf("  -C       show PCRE compile-time options and exit\n");
1724  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 1735  printf("  -p       use POSIX interface\n
1735  #endif  #endif
1736  printf("  -q       quiet: do not output PCRE version number at start\n");  printf("  -q       quiet: do not output PCRE version number at start\n");
1737  printf("  -S <n>   set stack size to <n> megabytes\n");  printf("  -S <n>   set stack size to <n> megabytes\n");
1738  printf("  -s       force each pattern to be studied\n"  printf("  -s       force each pattern to be studied at basic level\n"
1739           "  -s+      force each pattern to be studied, using JIT if available\n"
1740         "  -t       time compilation and execution\n");         "  -t       time compilation and execution\n");
1741  printf("  -t <n>   time compilation and execution, repeating <n> times\n");  printf("  -t <n>   time compilation and execution, repeating <n> times\n");
1742  printf("  -tm      time execution (matching) only\n");  printf("  -tm      time execution (matching) only\n");
# Line 1223  int timeit = 0; Line 1764  int timeit = 0;
1764  int timeitm = 0;  int timeitm = 0;
1765  int showinfo = 0;  int showinfo = 0;
1766  int showstore = 0;  int showstore = 0;
1767  int force_study = 0;  int force_study = -1;
1768    int force_study_options = 0;
1769  int quiet = 0;  int quiet = 0;
1770  int size_offsets = 45;  int size_offsets = 45;
1771  int size_offsets_max;  int size_offsets_max;
# Line 1237  int all_use_dfa = 0; Line 1779  int all_use_dfa = 0;
1779  int yield = 0;  int yield = 0;
1780  int stack_size;  int stack_size;
1781    
1782    pcre_jit_stack *jit_stack = NULL;
1783    
1784  /* 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
1785  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. */
1786    
1787  uschar copynames[1024];  pcre_uchar copynames[1024];
1788  uschar getnames[1024];  pcre_uchar getnames[1024];
1789    
1790  uschar *copynamesptr;  pcre_uchar *copynamesptr;
1791  uschar *getnamesptr;  pcre_uchar *getnamesptr;
1792    
1793  /* Get buffers from malloc() so that Electric Fence will check their misuse  /* Get buffers from malloc() so that valgrind will check their misuse when
1794  when I am debugging. They grow automatically when very long lines are read. */  debugging. They grow automatically when very long lines are read. The 16-bit
1795    buffer (buffer16) is obtained only if needed. */
1796  buffer = (unsigned char *)malloc(buffer_size);  
1797  dbuffer = (unsigned char *)malloc(buffer_size);  buffer = (pcre_uint8 *)malloc(buffer_size);
1798  pbuffer = (unsigned char *)malloc(buffer_size);  dbuffer = (pcre_uint8 *)malloc(buffer_size);
1799    pbuffer = (pcre_uint8 *)malloc(buffer_size);
1800    
1801  /* The outfile variable is static so that new_malloc can use it. */  /* The outfile variable is static so that new_malloc can use it. */
1802    
# Line 1270  _setmode( _fileno( stdout ), _O_BINARY ) Line 1815  _setmode( _fileno( stdout ), _O_BINARY )
1815    
1816  while (argc > 1 && argv[op][0] == '-')  while (argc > 1 && argv[op][0] == '-')
1817    {    {
1818    unsigned char *endptr;    pcre_uint8 *endptr;
1819    
1820    if (strcmp(argv[op], "-m") == 0) showstore = 1;    if (strcmp(argv[op], "-m") == 0) showstore = 1;
1821    else if (strcmp(argv[op], "-s") == 0) force_study = 1;    else if (strcmp(argv[op], "-s") == 0) force_study = 0;
1822      else if (strcmp(argv[op], "-s+") == 0)
1823        {
1824        force_study = 1;
1825        force_study_options = PCRE_STUDY_JIT_COMPILE;
1826        }
1827    #ifdef SUPPORT_PCRE16
1828      else if (strcmp(argv[op], "-16") == 0) use_pcre16 = 1;
1829    #endif
1830    
1831    else if (strcmp(argv[op], "-q") == 0) quiet = 1;    else if (strcmp(argv[op], "-q") == 0) quiet = 1;
1832    else if (strcmp(argv[op], "-b") == 0) debug = 1;    else if (strcmp(argv[op], "-b") == 0) debug = 1;
1833    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 1837  while (argc > 1 && argv[op][0] == '-')
1837    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;
1838  #endif  #endif
1839    else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&    else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&
1840        ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)),        ((size_offsets = get_value((pcre_uint8 *)argv[op+1], &endptr)),
1841          *endptr == 0))          *endptr == 0))
1842      {      {
1843      op++;      op++;
# Line 1293  while (argc > 1 && argv[op][0] == '-') Line 1847  while (argc > 1 && argv[op][0] == '-')
1847      {      {
1848      int both = argv[op][2] == 0;      int both = argv[op][2] == 0;
1849      int temp;      int temp;
1850      if (argc > 2 && (temp = get_value((unsigned char *)argv[op+1], &endptr),      if (argc > 2 && (temp = get_value((pcre_uint8 *)argv[op+1], &endptr),
1851                       *endptr == 0))                       *endptr == 0))
1852        {        {
1853        timeitm = temp;        timeitm = temp;
# Line 1304  while (argc > 1 && argv[op][0] == '-') Line 1858  while (argc > 1 && argv[op][0] == '-')
1858      if (both) timeit = timeitm;      if (both) timeit = timeitm;
1859      }      }
1860    else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&    else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&
1861        ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)),        ((stack_size = get_value((pcre_uint8 *)argv[op+1], &endptr)),
1862          *endptr == 0))          *endptr == 0))
1863      {      {
1864  #if defined(_WIN32) || defined(WIN32) || defined(__minix)  #if defined(_WIN32) || defined(WIN32) || defined(__minix)
# Line 1334  while (argc > 1 && argv[op][0] == '-') Line 1888  while (argc > 1 && argv[op][0] == '-')
1888      unsigned long int lrc;      unsigned long int lrc;
1889      printf("PCRE version %s\n", pcre_version());      printf("PCRE version %s\n", pcre_version());
1890      printf("Compiled with\n");      printf("Compiled with\n");
1891    
1892    /* At least one of SUPPORT_PCRE8 and SUPPORT_PCRE16 will be set. If both
1893    are set, either both UTFs are supported or both are not supported. */
1894    
1895    #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
1896        printf("  8-bit and 16-bit support\n");
1897        (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
1898        if (rc)
1899          printf("  UTF-8 and UTF-16 support\n");
1900        else
1901          printf("  No UTF-8 or UTF-16 support\n");
1902    #elif defined SUPPORT_PCRE8
1903        printf("  8-bit support only\n");
1904      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
1905      printf("  %sUTF-8 support\n", rc? "" : "No ");      printf("  %sUTF-8 support\n", rc? "" : "No ");
1906    #else
1907        printf("  16-bit support only\n");
1908        (void)pcre16_config(PCRE_CONFIG_UTF16, &rc);
1909        printf("  %sUTF-16 support\n", rc? "" : "No ");
1910    #endif
1911    
1912      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
1913      printf("  %sUnicode properties support\n", rc? "" : "No ");      printf("  %sUnicode properties support\n", rc? "" : "No ");
1914        (void)pcre_config(PCRE_CONFIG_JIT, &rc);
1915        if (rc)
1916          printf("  Just-in-time compiler support\n");
1917        else
1918          printf("  No just-in-time compiler support\n");
1919      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
1920      /* Note that these values are always the ASCII values, even      /* Note that these values are always the ASCII values, even
1921      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 1993  if (argc > 2)
1993    
1994  /* Set alternative malloc function */  /* Set alternative malloc function */
1995    
1996    #ifdef SUPPORT_PCRE8
1997  pcre_malloc = new_malloc;  pcre_malloc = new_malloc;
1998  pcre_free = new_free;  pcre_free = new_free;
1999  pcre_stack_malloc = stack_malloc;  pcre_stack_malloc = stack_malloc;
2000  pcre_stack_free = stack_free;  pcre_stack_free = stack_free;
2001    #endif
2002    
2003    #ifdef SUPPORT_PCRE16
2004    pcre16_malloc = new_malloc;
2005    pcre16_free = new_free;
2006    pcre16_stack_malloc = stack_malloc;
2007    pcre16_stack_free = stack_free;
2008    #endif
2009    
2010  /* Heading line unless quiet, then prompt for first regex if stdin */  /* Heading line unless quiet, then prompt for first regex if stdin */
2011    
# Line 1437  while (!done) Line 2024  while (!done)
2024  #endif  #endif
2025    
2026    const char *error;    const char *error;
2027    unsigned char *markptr;    pcre_uint8 *markptr;
2028    unsigned char *p, *pp, *ppp;    pcre_uint8 *p, *pp, *ppp;
2029    unsigned char *to_file = NULL;    pcre_uint8 *to_file = NULL;
2030    const unsigned char *tables = NULL;    const pcre_uint8 *tables = NULL;
2031    unsigned long int true_size, true_study_size = 0;    unsigned long int true_size, true_study_size = 0;
2032    size_t size, regex_gotten_store;    size_t size, regex_gotten_store;
2033    int do_allcaps = 0;    int do_allcaps = 0;
# Line 1456  while (!done) Line 2043  while (!done)
2043    int do_flip = 0;    int do_flip = 0;
2044    int erroroffset, len, delimiter, poffset;    int erroroffset, len, delimiter, poffset;
2045    
2046    use_utf8 = 0;    use_utf = 0;
2047    debug_lengths = 1;    debug_lengths = 1;
2048    
2049    if (extend_inputline(infile, buffer, "  re> ") == NULL) break;    if (extend_inputline(infile, buffer, "  re> ") == NULL) break;
# Line 1472  while (!done) Line 2059  while (!done)
2059    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)
2060      {      {
2061      unsigned long int magic, get_options;      unsigned long int magic, get_options;
2062      uschar sbuf[8];      pcre_uint8 sbuf[8];
2063      FILE *f;      FILE *f;
2064    
2065      p++;      p++;
# Line 1495  while (!done) Line 2082  while (!done)
2082        (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];        (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];
2083    
2084      re = (real_pcre *)new_malloc(true_size);      re = (real_pcre *)new_malloc(true_size);
2085      regex_gotten_store = gotten_store;      regex_gotten_store = first_gotten_store;
2086    
2087      if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;      if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;
2088    
2089      magic = ((real_pcre *)re)->magic_number;      magic = ((real_pcre *)re)->magic_number;
2090      if (magic != MAGIC_NUMBER)      if (magic != MAGIC_NUMBER)
2091        {        {
2092        if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER)        if (swap_uint32(magic) == MAGIC_NUMBER)
2093          {          {
2094          do_flip = 1;          do_flip = 1;
2095          }          }
# Line 1517  while (!done) Line 2104  while (!done)
2104      fprintf(outfile, "Compiled pattern%s loaded from %s\n",      fprintf(outfile, "Compiled pattern%s loaded from %s\n",
2105        do_flip? " (byte-inverted)" : "", p);        do_flip? " (byte-inverted)" : "", p);
2106    
     /* Need to know if UTF-8 for printing data strings */  
   
     new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);  
     use_utf8 = (get_options & PCRE_UTF8) != 0;  
   
2107      /* Now see if there is any following study data. */      /* Now see if there is any following study data. */
2108    
2109      if (true_study_size != 0)      if (true_study_size != 0)
# Line 1538  while (!done) Line 2120  while (!done)
2120          {          {
2121          FAIL_READ:          FAIL_READ:
2122          fprintf(outfile, "Failed to read data from %s\n", p);          fprintf(outfile, "Failed to read data from %s\n", p);
2123          if (extra != NULL) new_free(extra);          if (extra != NULL)
2124              {
2125              PCRE_FREE_STUDY(extra);
2126              }
2127          if (re != NULL) new_free(re);          if (re != NULL) new_free(re);
2128          fclose(f);          fclose(f);
2129          continue;          continue;
# Line 1548  while (!done) Line 2133  while (!done)
2133        }        }
2134      else fprintf(outfile, "No study data\n");      else fprintf(outfile, "No study data\n");
2135    
2136        /* Flip the necessary bytes. */
2137        if (do_flip)
2138          {
2139          PCRE_PATTERN_TO_HOST_BYTE_ORDER(re, extra, NULL);
2140          }
2141    
2142        /* Need to know if UTF-8 for printing data strings */
2143    
2144        new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
2145        use_utf = (get_options & PCRE_UTF8) != 0;
2146    
2147      fclose(f);      fclose(f);
2148      goto SHOW_INFO;      goto SHOW_INFO;
2149      }      }
2150    
2151    /* In-line pattern (the usual case). Get the delimiter and seek the end of    /* In-line pattern (the usual case). Get the delimiter and seek the end of
2152    the pattern; if is isn't complete, read more. */    the pattern; if it isn't complete, read more. */
2153    
2154    delimiter = *p++;    delimiter = *p++;
2155    
# Line 1641  while (!done) Line 2237  while (!done)
2237  #endif  #endif
2238    
2239        case 'S':        case 'S':
2240        if (do_study == 0) do_study = 1; else        if (do_study == 0)
2241            {
2242            do_study = 1;
2243            if (*pp == '+')
2244              {
2245              study_options |= PCRE_STUDY_JIT_COMPILE;
2246              pp++;
2247              }
2248            }
2249          else
2250          {          {
2251          do_study = 0;          do_study = 0;
2252          no_force_study = 1;          no_force_study = 1;
# Line 1653  while (!done) Line 2258  while (!done)
2258        case 'X': options |= PCRE_EXTRA; break;        case 'X': options |= PCRE_EXTRA; break;
2259        case 'Y': options |= PCRE_NO_START_OPTIMISE; break;        case 'Y': options |= PCRE_NO_START_OPTIMISE; break;
2260        case 'Z': debug_lengths = 0; break;        case 'Z': debug_lengths = 0; break;
2261        case '8': options |= PCRE_UTF8; use_utf8 = 1; break;        case '8': options |= PCRE_UTF8; use_utf = 1; break;
2262        case '?': options |= PCRE_NO_UTF8_CHECK; break;        case '?': options |= PCRE_NO_UTF8_CHECK; break;
2263    
2264        case 'T':        case 'T':
# Line 1700  while (!done) Line 2305  while (!done)
2305    
2306        case '<':        case '<':
2307          {          {
2308          if (strncmpic(pp, (uschar *)"JS>", 3) == 0)          if (strncmpic(pp, (pcre_uint8 *)"JS>", 3) == 0)
2309            {            {
2310            options |= PCRE_JAVASCRIPT_COMPAT;            options |= PCRE_JAVASCRIPT_COMPAT;
2311            pp += 3;            pp += 3;
# Line 1728  while (!done) Line 2333  while (!done)
2333    
2334    /* Handle compiling via the POSIX interface, which doesn't support the    /* Handle compiling via the POSIX interface, which doesn't support the
2335    timing, showing, or debugging options, nor the ability to pass over    timing, showing, or debugging options, nor the ability to pass over
2336    local character tables. */    local character tables. Neither does it have 16-bit support. */
2337    
2338  #if !defined NOPOSIX  #if !defined NOPOSIX
2339    if (posix || do_posix)    if (posix || do_posix)
# Line 1744  while (!done) Line 2349  while (!done)
2349      if ((options & PCRE_UCP) != 0) cflags |= REG_UCP;      if ((options & PCRE_UCP) != 0) cflags |= REG_UCP;
2350      if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY;      if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY;
2351    
2352        first_gotten_store = 0;
2353      rc = regcomp(&preg, (char *)p, cflags);      rc = regcomp(&preg, (char *)p, cflags);
2354    
2355      /* 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 2371  while (!done)
2371      {      {
2372      unsigned long int get_options;      unsigned long int get_options;
2373    
2374        /* In 16-bit mode, convert the input. */
2375    
2376    #ifdef SUPPORT_PCRE16
2377        if (use_pcre16)
2378          {
2379          if (to16(p, options & PCRE_UTF8, (int)strlen((char *)p)) < 0)
2380            {
2381            fprintf(outfile, "**Failed: invalid UTF-8 string cannot be "
2382              "converted to UTF-16\n");
2383            goto SKIP_DATA;
2384            }
2385          p = (pcre_uint8 *)buffer16;
2386          }
2387    #endif
2388    
2389        /* Compile many times when timing */
2390    
2391      if (timeit > 0)      if (timeit > 0)
2392        {        {
2393        register int i;        register int i;
# Line 1772  while (!done) Line 2395  while (!done)
2395        clock_t start_time = clock();        clock_t start_time = clock();
2396        for (i = 0; i < timeit; i++)        for (i = 0; i < timeit; i++)
2397          {          {
2398          re = pcre_compile((char *)p, options, &error, &erroroffset, tables);          PCRE_COMPILE(re, p, options, &error, &erroroffset, tables);
2399          if (re != NULL) free(re);          if (re != NULL) free(re);
2400          }          }
2401        time_taken = clock() - start_time;        time_taken = clock() - start_time;
# Line 1781  while (!done) Line 2404  while (!done)
2404            (double)CLOCKS_PER_SEC);            (double)CLOCKS_PER_SEC);
2405        }        }
2406    
2407      re = pcre_compile((char *)p, options, &error, &erroroffset, tables);      first_gotten_store = 0;
2408        PCRE_COMPILE(re, p, options, &error, &erroroffset, tables);
2409    
2410      /* Compilation failed; go back for another re, skipping to blank line      /* Compilation failed; go back for another re, skipping to blank line
2411      if non-interactive. */      if non-interactive. */
# Line 1813  while (!done) Line 2437  while (!done)
2437      lines. */      lines. */
2438    
2439      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
2440      if ((get_options & PCRE_UTF8) != 0) use_utf8 = 1;      if ((get_options & PCRE_UTF8) != 0) use_utf = 1;
2441    
2442      /* Print information if required. There are now two info-returning      /* Extract the size for possible writing before possibly flipping it,
2443      functions. The old one has a limited interface and returns only limited      and remember the store that was got. */
2444      data. Check that it agrees with the newer one. */  
2445        true_size = ((real_pcre *)re)->size;
2446        regex_gotten_store = first_gotten_store;
2447    
2448        /* Output code size information if requested */
2449    
2450      if (log_store)      if (log_store)
2451        fprintf(outfile, "Memory allocation (code space): %d\n",        fprintf(outfile, "Memory allocation (code space): %d\n",
2452          (int)(gotten_store -          (int)(first_gotten_store -
2453                sizeof(real_pcre) -                sizeof(real_pcre) -
2454                ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));                ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));
2455    
     /* 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;  
   
2456      /* 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
2457      help with the matching, unless the pattern has the SS option, which      help with the matching, unless the pattern has the SS option, which
2458      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
2459      never sensible). */      never sensible). */
2460    
2461      if (do_study || (force_study && !no_force_study))      if (do_study || (force_study >= 0 && !no_force_study))
2462        {        {
2463        if (timeit > 0)        if (timeit > 0)
2464          {          {
# Line 1844  while (!done) Line 2466  while (!done)
2466          clock_t time_taken;          clock_t time_taken;
2467          clock_t start_time = clock();          clock_t start_time = clock();
2468          for (i = 0; i < timeit; i++)          for (i = 0; i < timeit; i++)
2469            extra = pcre_study(re, study_options, &error);            {
2470              PCRE_STUDY(extra, re, study_options | force_study_options, &error);
2471              }
2472          time_taken = clock() - start_time;          time_taken = clock() - start_time;
2473          if (extra != NULL) free(extra);          if (extra != NULL)
2474              {
2475              PCRE_FREE_STUDY(extra);
2476              }
2477          fprintf(outfile, "  Study time %.4f milliseconds\n",          fprintf(outfile, "  Study time %.4f milliseconds\n",
2478            (((double)time_taken * 1000.0) / (double)timeit) /            (((double)time_taken * 1000.0) / (double)timeit) /
2479              (double)CLOCKS_PER_SEC);              (double)CLOCKS_PER_SEC);
2480          }          }
2481        extra = pcre_study(re, study_options, &error);        PCRE_STUDY(extra, re, study_options | force_study_options, &error);
2482        if (error != NULL)        if (error != NULL)
2483          fprintf(outfile, "Failed to study: %s\n", error);          fprintf(outfile, "Failed to study: %s\n", error);
2484        else if (extra != NULL)        else if (extra != NULL)
2485            {
2486          true_study_size = ((pcre_study_data *)(extra->study_data))->size;          true_study_size = ((pcre_study_data *)(extra->study_data))->size;
2487            if (log_store)
2488              {
2489              size_t jitsize;
2490              new_info(re, extra, PCRE_INFO_JITSIZE, &jitsize);
2491              if (jitsize != 0)
2492                fprintf(outfile, "Memory allocation (JIT code): %d\n", jitsize);
2493              }
2494            }
2495        }        }
2496    
2497      /* If /K was present, we set up for handling MARK data. */      /* If /K was present, we set up for handling MARK data. */
# Line 1871  while (!done) Line 2507  while (!done)
2507        extra->flags |= PCRE_EXTRA_MARK;        extra->flags |= PCRE_EXTRA_MARK;
2508        }        }
2509    
2510      /* If the 'F' option was present, we flip the bytes of all the integer      /* Extract and display information from the compiled data if required. */
     fields in the regex data block and the study block. This is to make it  
     possible to test PCRE's handling of byte-flipped patterns, e.g. those  
     compiled on a different architecture. */  
   
     if (do_flip)  
       {  
       real_pcre *rre = (real_pcre *)re;  
       rre->magic_number =  
         byteflip(rre->magic_number, sizeof(rre->magic_number));  
       rre->size = byteflip(rre->size, sizeof(rre->size));  
       rre->options = byteflip(rre->options, sizeof(rre->options));  
       rre->flags = (pcre_uint16)byteflip(rre->flags, sizeof(rre->flags));  
       rre->top_bracket =  
         (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));  
       rre->top_backref =  
         (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));  
       rre->first_byte =  
         (pcre_uint16)byteflip(rre->first_byte, sizeof(rre->first_byte));  
       rre->req_byte =  
         (pcre_uint16)byteflip(rre->req_byte, sizeof(rre->req_byte));  
       rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,  
         sizeof(rre->name_table_offset));  
       rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,  
         sizeof(rre->name_entry_size));  
       rre->name_count = (pcre_uint16)byteflip(rre->name_count,  
         sizeof(rre->name_count));  
   
       if (extra != NULL)  
         {  
         pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);  
         rsd->size = byteflip(rsd->size, sizeof(rsd->size));  
         rsd->flags = byteflip(rsd->flags, sizeof(rsd->flags));  
         rsd->minlength = byteflip(rsd->minlength, sizeof(rsd->minlength));  
         }  
       }  
   
     /* Extract information from the compiled data if required */  
2511    
2512      SHOW_INFO:      SHOW_INFO:
2513    
2514      if (do_debug)      if (do_debug)
2515        {        {
2516        fprintf(outfile, "------------------------------------------------------------------\n");        fprintf(outfile, "------------------------------------------------------------------\n");
2517    #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
2518          if (use_pcre16)
2519            pcre16_printint(re, outfile, debug_lengths);
2520          else
2521            pcre_printint(re, outfile, debug_lengths);
2522    #elif defined SUPPORT_PCRE8
2523        pcre_printint(re, outfile, debug_lengths);        pcre_printint(re, outfile, debug_lengths);
2524    #else
2525          pcre16_printint(re, outfile, debug_lengths);
2526    #endif
2527        }        }
2528    
2529      /* 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 2537  while (!done)
2537        int count, backrefmax, first_char, need_char, okpartial, jchanged,        int count, backrefmax, first_char, need_char, okpartial, jchanged,
2538          hascrorlf;          hascrorlf;
2539        int nameentrysize, namecount;        int nameentrysize, namecount;
2540        const uschar *nametable;        const pcre_uchar *nametable;
2541    
2542        new_info(re, NULL, PCRE_INFO_SIZE, &size);        new_info(re, NULL, PCRE_INFO_SIZE, &size);
2543        new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);        new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);
# Line 1943  while (!done) Line 2551  while (!done)
2551        new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);        new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);
2552        new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);        new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);
2553    
2554          /* The old, obsolete function pcre_info() works only in 8-bit mode. Check
2555          that it gives the same results as the new function. */
2556    
2557  #if !defined NOINFOCHECK  #if !defined NOINFOCHECK
2558        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  
2559          {          {
2560          if (old_count != count) fprintf(outfile,          old_count = pcre_info(re, &old_options, &old_first_char);
2561            "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,          if (count < 0) fprintf(outfile,
2562              old_count);            "Error %d from pcre_info()\n", count);
2563            else
2564          if (old_first_char != first_char) fprintf(outfile,            {
2565            "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",            if (old_count != count) fprintf(outfile,
2566              first_char, old_first_char);              "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,
2567                  old_count);
2568          if (old_options != (int)get_options) fprintf(outfile,  
2569            "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",            if (old_first_char != first_char) fprintf(outfile,
2570              get_options, old_options);              "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",
2571                  first_char, old_first_char);
2572    
2573              if (old_options != (int)get_options) fprintf(outfile,
2574                "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",
2575                  get_options, old_options);
2576              }
2577          }          }
2578  #endif  #endif
2579    
# Line 1987  while (!done) Line 2601  while (!done)
2601        if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n");        if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n");
2602    
2603        all_options = ((real_pcre *)re)->options;        all_options = ((real_pcre *)re)->options;
2604        if (do_flip) all_options = byteflip(all_options, sizeof(all_options));        if (do_flip) all_options = swap_uint32(all_options);
2605    
2606        if (get_options == 0) fprintf(outfile, "No options\n");        if (get_options == 0) fprintf(outfile, "No options\n");
2607          else fprintf(outfile, "Options:%s%s%s%s%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%s%s\n",
# Line 2003  while (!done) Line 2617  while (!done)
2617            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",
2618            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
2619            ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",            ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",
2620            ((get_options & PCRE_UTF8) != 0)? " utf8" : "",            ((get_options & PCRE_UTF8) != 0)? " utf" : "",
2621            ((get_options & PCRE_UCP) != 0)? " ucp" : "",            ((get_options & PCRE_UCP) != 0)? " ucp" : "",
2622            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf_check" : "",
2623            ((get_options & PCRE_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "",            ((get_options & PCRE_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "",
2624            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");
2625    
# Line 2047  while (!done) Line 2661  while (!done)
2661          }          }
2662        else        else
2663          {          {
2664          int ch = first_char & 255;          const char *caseless =
2665          const char *caseless = ((first_char & REQ_CASELESS) == 0)?            ((((real_pcre *)re)->flags & PCRE_FCH_CASELESS) == 0)?
2666            "" : " (caseless)";            "" : " (caseless)";
2667          if (PRINTHEX(ch))  
2668            fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless);          if (PRINTOK(first_char))
2669              fprintf(outfile, "First char = \'%c\'%s\n", first_char, caseless);
2670          else          else
2671            fprintf(outfile, "First char = %d%s\n", ch, caseless);            {
2672              fprintf(outfile, "First char = ");
2673              pchar(first_char, outfile);
2674              fprintf(outfile, "%s\n", caseless);
2675              }
2676          }          }
2677    
2678        if (need_char < 0)        if (need_char < 0)
# Line 2062  while (!done) Line 2681  while (!done)
2681          }          }
2682        else        else
2683          {          {
2684          int ch = need_char & 255;          const char *caseless =
2685          const char *caseless = ((need_char & REQ_CASELESS) == 0)?            ((((real_pcre *)re)->flags & PCRE_RCH_CASELESS) == 0)?
2686            "" : " (caseless)";            "" : " (caseless)";
2687          if (PRINTHEX(ch))  
2688            fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless);          if (PRINTOK(need_char))
2689              fprintf(outfile, "Need char = \'%c\'%s\n", need_char, caseless);
2690          else          else
2691            fprintf(outfile, "Need char = %d%s\n", ch, caseless);            fprintf(outfile, "Need char = %d%s\n", need_char, caseless);
2692          }          }
2693    
2694        /* 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 2699  while (!done)
2699        when auto-callouts are involved, the output from runs with and without        when auto-callouts are involved, the output from runs with and without
2700        -s should be identical. */        -s should be identical. */
2701    
2702        if (do_study || (force_study && showinfo && !no_force_study))        if (do_study || (force_study >= 0 && showinfo && !no_force_study))
2703          {          {
2704          if (extra == NULL)          if (extra == NULL)
2705            fprintf(outfile, "Study returned NULL\n");            fprintf(outfile, "Study returned NULL\n");
2706          else          else
2707            {            {
2708            uschar *start_bits = NULL;            pcre_uint8 *start_bits = NULL;
2709            int minlength;            int minlength;
2710    
2711            new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength);            new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength);
# Line 2108  while (!done) Line 2728  while (!done)
2728                    fprintf(outfile, "\n  ");                    fprintf(outfile, "\n  ");
2729                    c = 2;                    c = 2;
2730                    }                    }
2731                  if (PRINTHEX(i) && i != ' ')                  if (PRINTOK(i) && i != ' ')
2732                    {                    {
2733                    fprintf(outfile, "%c ", i);                    fprintf(outfile, "%c ", i);
2734                    c += 2;                    c += 2;
# Line 2123  while (!done) Line 2743  while (!done)
2743              fprintf(outfile, "\n");              fprintf(outfile, "\n");
2744              }              }
2745            }            }
2746    
2747            /* Show this only if the JIT was set by /S, not by -s. */
2748    
2749            if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0)
2750              {
2751              int jit;
2752              new_info(re, extra, PCRE_INFO_JIT, &jit);
2753              if (jit)
2754                fprintf(outfile, "JIT study was successful\n");
2755              else
2756    #ifdef SUPPORT_JIT
2757                fprintf(outfile, "JIT study was not successful\n");
2758    #else
2759                fprintf(outfile, "JIT support is not available in this version of PCRE\n");
2760    #endif
2761              }
2762          }          }
2763        }        }
2764    
# Line 2139  while (!done) Line 2775  while (!done)
2775          }          }
2776        else        else
2777          {          {
2778          uschar sbuf[8];          pcre_uint8 sbuf[8];
2779          sbuf[0] = (uschar)((true_size >> 24) & 255);  
2780          sbuf[1] = (uschar)((true_size >> 16) & 255);          if (do_flip) regexflip(re, extra);
2781          sbuf[2] = (uschar)((true_size >>  8) & 255);          sbuf[0] = (pcre_uint8)((true_size >> 24) & 255);
2782          sbuf[3] = (uschar)((true_size) & 255);          sbuf[1] = (pcre_uint8)((true_size >> 16) & 255);
2783            sbuf[2] = (pcre_uint8)((true_size >>  8) & 255);
2784          sbuf[4] = (uschar)((true_study_size >> 24) & 255);          sbuf[3] = (pcre_uint8)((true_size) & 255);
2785          sbuf[5] = (uschar)((true_study_size >> 16) & 255);          sbuf[4] = (pcre_uint8)((true_study_size >> 24) & 255);
2786          sbuf[6] = (uschar)((true_study_size >>  8) & 255);          sbuf[5] = (pcre_uint8)((true_study_size >> 16) & 255);
2787          sbuf[7] = (uschar)((true_study_size) & 255);          sbuf[6] = (pcre_uint8)((true_study_size >>  8) & 255);
2788            sbuf[7] = (pcre_uint8)((true_study_size) & 255);
2789    
2790          if (fwrite(sbuf, 1, 8, f) < 8 ||          if (fwrite(sbuf, 1, 8, f) < 8 ||
2791              fwrite(re, 1, true_size, f) < true_size)              fwrite(re, 1, true_size, f) < true_size)
# Line 2176  while (!done) Line 2813  while (!done)
2813          }          }
2814    
2815        new_free(re);        new_free(re);
2816        if (extra != NULL) new_free(extra);        if (extra != NULL)
2817            {
2818            PCRE_FREE_STUDY(extra);
2819            }
2820        if (locale_set)        if (locale_set)
2821          {          {
2822          new_free((void *)tables);          new_free((void *)tables);
# Line 2191  while (!done) Line 2831  while (!done)
2831    
2832    for (;;)    for (;;)
2833      {      {
2834      uschar *q;      pcre_uint8 *q;
2835      uschar *bptr;      pcre_uint8 *bptr;
2836      int *use_offsets = offsets;      int *use_offsets = offsets;
2837      int use_size_offsets = size_offsets;      int use_size_offsets = size_offsets;
2838      int callout_data = 0;      int callout_data = 0;
# Line 2277  while (!done) Line 2917  while (!done)
2917            c = c * 8 + *p++ - '0';            c = c * 8 + *p++ - '0';
2918    
2919  #if !defined NOUTF8  #if !defined NOUTF8
2920          if (use_utf8 && c > 255)          if (use_utf && c > 255)
2921            {            {
2922            unsigned char buff8[8];            pcre_uint8 buff8[8];
2923            int ii, utn;            int ii, utn;
2924            utn = ord2utf8(c, buff8);            utn = ord2utf8(c, buff8);
2925            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 2935  while (!done)
2935  #if !defined NOUTF8  #if !defined NOUTF8
2936          if (*p == '{')          if (*p == '{')
2937            {            {
2938            unsigned char *pt = p;            pcre_uint8 *pt = p;
2939            c = 0;            c = 0;
2940            while (isxdigit(*(++pt)))  
2941              c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W');            /* We used to have "while (isxdigit(*(++pt)))" here, but it fails
2942              when isxdigit() is a macro that refers to its argument more than
2943              once. This is banned by the C Standard, but apparently happens in at
2944              least one MacOS environment. */
2945    
2946              for (pt++; isxdigit(*pt); pt++)
2947                c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'a' - 10);
2948            if (*pt == '}')            if (*pt == '}')
2949              {              {
2950              unsigned char buff8[8];              pcre_uint8 buff8[8];
2951              int ii, utn;              int ii, utn;
2952              if (use_utf8)              if (use_utf)
2953                {                {
2954                utn = ord2utf8(c, buff8);                utn = ord2utf8(c, buff8);
2955                for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];                for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
# Line 2328  while (!done) Line 2974  while (!done)
2974          c = 0;          c = 0;
2975          while (i++ < 2 && isxdigit(*p))          while (i++ < 2 && isxdigit(*p))
2976            {            {
2977            c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W');            c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10);
2978            p++;            p++;
2979            }            }
2980          break;          break;
# Line 2363  while (!done) Line 3009  while (!done)
3009            }            }
3010          else if (isalnum(*p))          else if (isalnum(*p))
3011            {            {
3012            uschar *npp = copynamesptr;            pcre_uchar *npp = copynamesptr;
3013            while (isalnum(*p)) *npp++ = *p++;            while (isalnum(*p)) *npp++ = *p++;
3014            *npp++ = 0;            *npp++ = 0;
3015            *npp = 0;            *npp = 0;
# Line 2433  while (!done) Line 3079  while (!done)
3079            }            }
3080          else if (isalnum(*p))          else if (isalnum(*p))
3081            {            {
3082            uschar *npp = getnamesptr;            pcre_uchar *npp = getnamesptr;
3083            while (isalnum(*p)) *npp++ = *p++;            while (isalnum(*p)) *npp++ = *p++;
3084            *npp++ = 0;            *npp++ = 0;
3085            *npp = 0;            *npp = 0;
# Line 2444  while (!done) Line 3090  while (!done)
3090            }            }
3091          continue;          continue;
3092    
3093            case 'J':
3094            while(isdigit(*p)) n = n * 10 + *p++ - '0';
3095            if (extra != NULL
3096                && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0
3097                && extra->executable_jit != NULL)
3098              {
3099              if (jit_stack != NULL) pcre_jit_stack_free(jit_stack);
3100              jit_stack = pcre_jit_stack_alloc(1, n * 1024);
3101              pcre_assign_jit_stack(extra, jit_callback, jit_stack);
3102              }
3103            continue;
3104    
3105          case 'L':          case 'L':
3106          getlist = 1;          getlist = 1;
3107          continue;          continue;
# Line 2599  while (!done) Line 3257  while (!done)
3257            if (pmatch[i].rm_so >= 0)            if (pmatch[i].rm_so >= 0)
3258              {              {
3259              fprintf(outfile, "%2d: ", (int)i);              fprintf(outfile, "%2d: ", (int)i);
3260              (void)pchars(dbuffer + pmatch[i].rm_so,              PCHARSV(dbuffer + pmatch[i].rm_so,
3261                pmatch[i].rm_eo - pmatch[i].rm_so, outfile);                pmatch[i].rm_eo - pmatch[i].rm_so, outfile);
3262              fprintf(outfile, "\n");              fprintf(outfile, "\n");
3263              if (do_showcaprest || (i == 0 && do_showrest))              if (do_showcaprest || (i == 0 && do_showrest))
3264                {                {
3265                fprintf(outfile, "%2d+ ", (int)i);                fprintf(outfile, "%2d+ ", (int)i);
3266                (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo,                PCHARSV(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo,
3267                  outfile);                  outfile);
3268                fprintf(outfile, "\n");                fprintf(outfile, "\n");
3269                }                }
# Line 2613  while (!done) Line 3271  while (!done)
3271            }            }
3272          }          }
3273        free(pmatch);        free(pmatch);
3274          goto NEXT_DATA;
3275        }        }
3276    
3277    #endif  /* !defined NOPOSIX */
3278    
3279      /* Handle matching via the native interface - repeats for /g and /G */      /* Handle matching via the native interface - repeats for /g and /G */
3280    
3281      else  #ifdef SUPPORT_PCRE16
3282  #endif  /* !defined NOPOSIX */      if (use_pcre16)
3283          {
3284          len = to16(bptr, (((real_pcre *)re)->options) & PCRE_UTF8, len);
3285          if (len < 0)
3286            {
3287            fprintf(outfile, "**Failed: invalid UTF-8 string cannot be "
3288              "converted to UTF-16\n");
3289            goto NEXT_DATA;
3290            }
3291          bptr = (pcre_uint8 *)buffer16;
3292          }
3293    #endif
3294    
3295      for (;; gmatched++)    /* Loop for /g or /G */      for (;; gmatched++)    /* Loop for /g or /G */
3296        {        {
# Line 2643  while (!done) Line 3315  while (!done)
3315  #endif  #endif
3316    
3317          for (i = 0; i < timeitm; i++)          for (i = 0; i < timeitm; i++)
3318            count = pcre_exec(re, extra, (char *)bptr, len,            {
3319              PCRE_EXEC(count, re, extra, bptr, len,
3320              start_offset, options | g_notempty, use_offsets, use_size_offsets);              start_offset, options | g_notempty, use_offsets, use_size_offsets);
3321              }
3322          time_taken = clock() - start_time;          time_taken = clock() - start_time;
3323          fprintf(outfile, "Execute time %.4f milliseconds\n",          fprintf(outfile, "Execute time %.4f milliseconds\n",
3324            (((double)time_taken * 1000.0) / (double)timeitm) /            (((double)time_taken * 1000.0) / (double)timeitm) /
# Line 2654  while (!done) Line 3327  while (!done)
3327    
3328        /* 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
3329        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
3330        for the recursion limit. */        for the recursion limit. The match limits are relevant only to the normal
3331          running of pcre_exec(), so disable the JIT optimization. This makes it
3332          possible to run the same set of tests with and without JIT externally
3333          requested. */
3334    
3335        if (find_match_limit)        if (find_match_limit)
3336          {          {
# Line 2663  while (!done) Line 3339  while (!done)
3339            extra = (pcre_extra *)malloc(sizeof(pcre_extra));            extra = (pcre_extra *)malloc(sizeof(pcre_extra));
3340            extra->flags = 0;            extra->flags = 0;
3341            }            }
3342            else extra->flags &= ~PCRE_EXTRA_EXECUTABLE_JIT;
3343    
3344          (void)check_match_limit(re, extra, bptr, len, start_offset,          (void)check_match_limit(re, extra, bptr, len, start_offset,
3345            options|g_notempty, use_offsets, use_size_offsets,            options|g_notempty, use_offsets, use_size_offsets,
# Line 2686  while (!done) Line 3363  while (!done)
3363            }            }
3364          extra->flags |= PCRE_EXTRA_CALLOUT_DATA;          extra->flags |= PCRE_EXTRA_CALLOUT_DATA;
3365          extra->callout_data = &callout_data;          extra->callout_data = &callout_data;
3366          count = pcre_exec(re, extra, (char *)bptr, len, start_offset,          PCRE_EXEC(count, re, extra, bptr, len, start_offset,
3367            options | g_notempty, use_offsets, use_size_offsets);            options | g_notempty, use_offsets, use_size_offsets);
3368          extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;          extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;
3369          }          }
# Line 2711  while (!done) Line 3388  while (!done)
3388    
3389        else        else
3390          {          {
3391          count = pcre_exec(re, extra, (char *)bptr, len,          PCRE_EXEC(count, re, extra, bptr, len, start_offset,
3392            start_offset, options | g_notempty, use_offsets, use_size_offsets);            options | g_notempty, use_offsets, use_size_offsets);
3393          if (count == 0)          if (count == 0)
3394            {            {
3395            fprintf(outfile, "Matched, but too many substrings\n");            fprintf(outfile, "Matched, but too many substrings\n");
# Line 2773  while (!done) Line 3450  while (!done)
3450            else            else
3451              {              {
3452              fprintf(outfile, "%2d: ", i/2);              fprintf(outfile, "%2d: ", i/2);
3453              (void)pchars(bptr + use_offsets[i],              PCHARSV(bptr + use_offsets[i],
3454                use_offsets[i+1] - use_offsets[i], outfile);                use_offsets[i+1] - use_offsets[i], outfile);
3455              fprintf(outfile, "\n");              fprintf(outfile, "\n");
3456              if (do_showcaprest || (i == 0 && do_showrest))              if (do_showcaprest || (i == 0 && do_showrest))
3457                {                {
3458                fprintf(outfile, "%2d+ ", i/2);                fprintf(outfile, "%2d+ ", i/2);
3459                (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1],                PCHARSV(bptr + use_offsets[i+1], len - use_offsets[i+1],
3460                  outfile);                  outfile);
3461                fprintf(outfile, "\n");                fprintf(outfile, "\n");
3462                }                }
# Line 2861  while (!done) Line 3538  while (!done)
3538                fprintf(outfile, "%2dL %s\n", i, stringlist[i]);                fprintf(outfile, "%2dL %s\n", i, stringlist[i]);
3539              if (stringlist[i] != NULL)              if (stringlist[i] != NULL)
3540                fprintf(outfile, "string list not terminated by NULL\n");                fprintf(outfile, "string list not terminated by NULL\n");
             /* free((void *)stringlist); */  
3541              pcre_free_substring_list(stringlist);              pcre_free_substring_list(stringlist);
3542              }              }
3543            }            }
# Line 2876  while (!done) Line 3552  while (!done)
3552          if (use_size_offsets > 1)          if (use_size_offsets > 1)
3553            {            {
3554            fprintf(outfile, ": ");            fprintf(outfile, ": ");
3555            pchars(bptr + use_offsets[0], use_offsets[1] - use_offsets[0],            PCHARSV(bptr + use_offsets[0], use_offsets[1] - use_offsets[0],
3556              outfile);              outfile);
3557            }            }
3558          fprintf(outfile, "\n");          fprintf(outfile, "\n");
# Line 2926  while (!done) Line 3602  while (!done)
3602                bptr[start_offset] == '\r' &&                bptr[start_offset] == '\r' &&
3603                bptr[start_offset+1] == '\n')                bptr[start_offset+1] == '\n')
3604              onechar++;              onechar++;
3605            else if (use_utf8)            else if (use_utf)
3606              {              {
3607              while (start_offset + onechar < len)              while (start_offset + onechar < len)
3608                {                {
# Line 3012  while (!done) Line 3688  while (!done)
3688  #endif  #endif
3689    
3690    if (re != NULL) new_free(re);    if (re != NULL) new_free(re);
3691    if (extra != NULL) new_free(extra);    if (extra != NULL)
3692        {
3693        PCRE_FREE_STUDY(extra);
3694        }
3695    if (locale_set)    if (locale_set)
3696      {      {
3697      new_free((void *)tables);      new_free((void *)tables);
3698      setlocale(LC_CTYPE, "C");      setlocale(LC_CTYPE, "C");
3699      locale_set = 0;      locale_set = 0;
3700      }      }
3701      if (jit_stack != NULL)
3702        {
3703        pcre_jit_stack_free(jit_stack);
3704        jit_stack = NULL;
3705        }
3706    }    }
3707    
3708  if (infile == stdin) fprintf(outfile, "\n");  if (infile == stdin) fprintf(outfile, "\n");
# Line 3033  free(dbuffer); Line 3717  free(dbuffer);
3717  free(pbuffer);  free(pbuffer);
3718  free(offsets);  free(offsets);
3719    
3720    #ifdef SUPPORT_PCRE16
3721    if (buffer16 != NULL) free(buffer16);
3722    #endif
3723    
3724  return yield;  return yield;
3725  }  }
3726    

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

  ViewVC Help
Powered by ViewVC 1.1.5