/[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 411 by ph10, Fri Apr 10 15:40:21 2009 UTC code/branches/pcre16/pcretest.c revision 808 by ph10, Sun Dec 18 11:11:48 2011 UTC
# Line 4  Line 4 
4    
5  /* This program was hacked up as a tester for PCRE. I really should have  /* This program was hacked up as a tester for PCRE. I really should have
6  written it more tidily in the first place. Will I ever learn? It has grown and  written it more tidily in the first place. Will I ever learn? It has grown and
7  been extended and consequently is now rather, er, *very* untidy in places.  been extended and consequently is now rather, er, *very* untidy in places. The
8    addition of 16-bit support has made it even worse. :-(
9    
10  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
11  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 79  input mode under Windows. */ Line 80  input mode under Windows. */
80  #define fileno _fileno  #define fileno _fileno
81  #endif  #endif
82    
83    /* A user sent this fix for Borland Builder 5 under Windows. */
84    
85    #ifdef __BORLANDC__
86    #define _setmode(handle, mode) setmode(handle, mode)
87    #endif
88    
89    /* Not Windows */
90    
91  #else  #else
92  #include <sys/time.h>          /* These two includes are needed */  #include <sys/time.h>          /* These two includes are needed */
93  #include <sys/resource.h>      /* for setrlimit(). */  #include <sys/resource.h>      /* for setrlimit(). */
# Line 99  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 116  external symbols to prevent clashes. */ Line 138  external symbols to prevent clashes. */
138    
139  #include "pcre_tables.c"  #include "pcre_tables.c"
140    
141  /* We also need the pcre_printint() function for printing out compiled  /* The definition of the macro PRINTABLE, which determines whether to print an
 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.  
   
 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 this file. We uses it here also, in cases when the locale has not  the same as in the printint.src file. We uses it here in cases when the locale
144  been explicitly changed, so as to get consistent output from systems that  has not been explicitly changed, so as to get consistent output from systems
145  differ in their output from isprint() even in the "C" locale. */  that differ in their output from isprint() even in the "C" locale. */
   
 #include "pcre_printint.src"  
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 139  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 151  UTF8 support if PCRE is built without it Line 172  UTF8 support if PCRE is built without it
172  #endif  #endif
173  #endif  #endif
174    
175    /* To make the code a bit tidier for 8-bit and 16-bit support, we define macros
176    for all the pcre[16]_xxx functions (except pcre16_fullinfo, which is called
177    only from one place and is handled differently). I couldn't dream up any way of
178    using a single macro to do this in a generic way, because of the many different
179    argument requirements. We know that at least one of SUPPORT_PCRE8 and
180    SUPPORT_PCRE16 must be set. First define macros for each individual mode; then
181    use these in the definitions of generic macros. */
182    
183    #ifdef SUPPORT_PCRE8
184    #define PCHARS8(lv, p, len, f) \
185      lv = pchars((pcre_uint8 *)p, len, f)
186    
187    #define PCHARSV8(p, len, f) \
188      (void)pchars((pcre_uint8 *)p, len, f)
189    
190    #define PCRE_COMPILE8(re, pat, options, error, erroffset, tables) \
191      re = pcre_compile((char *)pat, options, error, erroffset, tables)
192    
193    #define PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
194        offsets, size_offsets) \
195      count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, \
196        offsets, size_offsets)
197    
198    #define PCRE_STUDY8(extra, re, options, error) \
199      extra = pcre_study(re, options, error)
200    #endif
201    
202    
203    #ifdef SUPPORT_PCRE16
204    #define PCHARS16(lv, p, len, f) \
205      lv = pchars16((PCRE_SPTR16)p, len, f)
206    
207    #define PCHARSV16(p, len, f) \
208      (void)pchars16((PCRE_SPTR16)p, len, f)
209    
210    #define PCRE_COMPILE16(re, pat, options, error, erroffset, tables) \
211      re = pcre16_compile((PCRE_SPTR16)pat, options, error, erroffset, tables)
212    
213    #define PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
214        offsets, size_offsets) \
215      count = pcre16_exec(re, extra, (PCRE_SPTR16)bptr, len, start_offset, \
216        options, offsets, size_offsets)
217    
218    #define PCRE_STUDY16(extra, re, options, error) \
219      extra = pcre16_study(re, options, error)
220    #endif
221    
222    
223    /* ----- Both modes are supported; a runtime test is needed ----- */
224    
225    #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
226    
227    #define PCHARS(lv, p, len, f) \
228      if (use_pcre16) \
229        PCHARS16(lv, p, len, f); \
230      else \
231        PCHARS8(lv, p, len, f)
232    
233    #define PCHARSV(p, len, f) \
234      if (use_pcre16) \
235        PCHARSV16(p, len, f); \
236      else \
237        PCHARSV8(p, len, f)
238    
239    #define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \
240      if (use_pcre16) \
241        PCRE_COMPILE16(re, pat, options, error, erroffset, tables); \
242      else \
243        PCRE_COMPILE8(re, pat, options, error, erroffset, tables)
244    
245    #define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \
246        offsets, size_offsets) \
247      if (use_pcre16) \
248        PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
249          offsets, size_offsets); \
250      else \
251        PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
252          offsets, size_offsets)
253    
254    #define PCRE_STUDY(extra, re, options, error) \
255      if (use_pcre16) \
256        PCRE_STUDY16(extra, re, options, error); \
257      else \
258        PCRE_STUDY8(extra, re, options, error)
259    
260    /* ----- Only 8-bit mode is supported ----- */
261    
262    #elif defined SUPPORT_PCRE8
263    #define PCHARS       PCHARS8
264    #define PCHARSV      PCHARSV8
265    #define PCRE_COMPILE PCRE_COMPILE8
266    #define PCRE_EXEC    PCRE_EXEC8
267    #define PCRE_STUDY   PCRE_STUDY8
268    
269    /* ----- Only 16-bit mode is supported ----- */
270    
271    #else
272    #define PCHARS       PCHARS16
273    #define PCHARSV      PCHARSV16
274    #define PCRE_COMPILE PCRE_COMPILE16
275    #define PCRE_EXEC    PCRE_EXEC16
276    #define PCRE_STUDY   PCRE_STUDY16
277    #endif
278    
279    /* ----- End of mode-specific function call macros ----- */
280    
281    
282  /* Other parameters */  /* Other parameters */
283    
# Line 180  static int locale_set = 0; Line 307  static int locale_set = 0;
307  static int show_malloc;  static int show_malloc;
308  static int use_utf8;  static int use_utf8;
309  static size_t gotten_store;  static size_t gotten_store;
310    static size_t first_gotten_store = 0;
311    static const unsigned char *last_callout_mark = NULL;
312    
313  /* The buffers grow automatically if very long input lines are encountered. */  /* The buffers grow automatically if very long input lines are encountered. */
314    
315  static int buffer_size = 50000;  static int buffer_size = 50000;
316  static uschar *buffer = NULL;  static pcre_uint8 *buffer = NULL;
317  static uschar *dbuffer = NULL;  static pcre_uint8 *dbuffer = NULL;
318  static uschar *pbuffer = NULL;  static pcre_uint8 *pbuffer = NULL;
319    
320    #ifdef SUPPORT_PCRE16
321    static int buffer16_size = 0;
322    static pcre_uint16 *buffer16 = NULL;
323    #endif
324    
325    /* If we have 8-bit support, default use_pcre16 to false; if there is also
326    16-bit support, it can be changed by an option. If there is no 8-bit support,
327    there must be 16-bit support, so default it to 1. */
328    
329    #ifdef SUPPORT_PCRE8
330    static int use_pcre16 = 0;
331    #else
332    static int use_pcre16 = 1;
333    #endif
334    
335    /* Textual explanations for runtime error codes */
336    
337    static const char *errtexts[] = {
338      NULL,  /* 0 is no error */
339      NULL,  /* NOMATCH is handled specially */
340      "NULL argument passed",
341      "bad option value",
342      "magic number missing",
343      "unknown opcode - pattern overwritten?",
344      "no more memory",
345      NULL,  /* never returned by pcre_exec() or pcre_dfa_exec() */
346      "match limit exceeded",
347      "callout error code",
348      NULL,  /* BADUTF8 is handled specially */
349      "bad UTF-8 offset",
350      NULL,  /* PARTIAL is handled specially */
351      "not used - internal error",
352      "internal error - pattern overwritten?",
353      "bad count value",
354      "item unsupported for DFA matching",
355      "backreference condition or recursion test not supported for DFA matching",
356      "match limit not supported for DFA matching",
357      "workspace size exceeded in DFA matching",
358      "too much recursion for DFA matching",
359      "recursion limit exceeded",
360      "not used - internal error",
361      "invalid combination of newline options",
362      "bad offset value",
363      NULL,  /* SHORTUTF8 is handled specially */
364      "nested recursion at the same subject position",
365      "JIT stack limit reached",
366      "pattern compiled in wrong mode (8-bit/16-bit error)"
367    };
368    
369    
370    /*************************************************
371    *         Alternate character tables             *
372    *************************************************/
373    
374    /* By default, the "tables" pointer when calling PCRE is set to NULL, thereby
375    using the default tables of the library. However, the T option can be used to
376    select alternate sets of tables, for different kinds of testing. Note also that
377    the L (locale) option also adjusts the tables. */
378    
379    /* This is the set of tables distributed as default with PCRE. It recognizes
380    only ASCII characters. */
381    
382    static const pcre_uint8 tables0[] = {
383    
384    /* This table is a lower casing table. */
385    
386        0,  1,  2,  3,  4,  5,  6,  7,
387        8,  9, 10, 11, 12, 13, 14, 15,
388       16, 17, 18, 19, 20, 21, 22, 23,
389       24, 25, 26, 27, 28, 29, 30, 31,
390       32, 33, 34, 35, 36, 37, 38, 39,
391       40, 41, 42, 43, 44, 45, 46, 47,
392       48, 49, 50, 51, 52, 53, 54, 55,
393       56, 57, 58, 59, 60, 61, 62, 63,
394       64, 97, 98, 99,100,101,102,103,
395      104,105,106,107,108,109,110,111,
396      112,113,114,115,116,117,118,119,
397      120,121,122, 91, 92, 93, 94, 95,
398       96, 97, 98, 99,100,101,102,103,
399      104,105,106,107,108,109,110,111,
400      112,113,114,115,116,117,118,119,
401      120,121,122,123,124,125,126,127,
402      128,129,130,131,132,133,134,135,
403      136,137,138,139,140,141,142,143,
404      144,145,146,147,148,149,150,151,
405      152,153,154,155,156,157,158,159,
406      160,161,162,163,164,165,166,167,
407      168,169,170,171,172,173,174,175,
408      176,177,178,179,180,181,182,183,
409      184,185,186,187,188,189,190,191,
410      192,193,194,195,196,197,198,199,
411      200,201,202,203,204,205,206,207,
412      208,209,210,211,212,213,214,215,
413      216,217,218,219,220,221,222,223,
414      224,225,226,227,228,229,230,231,
415      232,233,234,235,236,237,238,239,
416      240,241,242,243,244,245,246,247,
417      248,249,250,251,252,253,254,255,
418    
419    /* This table is a case flipping table. */
420    
421        0,  1,  2,  3,  4,  5,  6,  7,
422        8,  9, 10, 11, 12, 13, 14, 15,
423       16, 17, 18, 19, 20, 21, 22, 23,
424       24, 25, 26, 27, 28, 29, 30, 31,
425       32, 33, 34, 35, 36, 37, 38, 39,
426       40, 41, 42, 43, 44, 45, 46, 47,
427       48, 49, 50, 51, 52, 53, 54, 55,
428       56, 57, 58, 59, 60, 61, 62, 63,
429       64, 97, 98, 99,100,101,102,103,
430      104,105,106,107,108,109,110,111,
431      112,113,114,115,116,117,118,119,
432      120,121,122, 91, 92, 93, 94, 95,
433       96, 65, 66, 67, 68, 69, 70, 71,
434       72, 73, 74, 75, 76, 77, 78, 79,
435       80, 81, 82, 83, 84, 85, 86, 87,
436       88, 89, 90,123,124,125,126,127,
437      128,129,130,131,132,133,134,135,
438      136,137,138,139,140,141,142,143,
439      144,145,146,147,148,149,150,151,
440      152,153,154,155,156,157,158,159,
441      160,161,162,163,164,165,166,167,
442      168,169,170,171,172,173,174,175,
443      176,177,178,179,180,181,182,183,
444      184,185,186,187,188,189,190,191,
445      192,193,194,195,196,197,198,199,
446      200,201,202,203,204,205,206,207,
447      208,209,210,211,212,213,214,215,
448      216,217,218,219,220,221,222,223,
449      224,225,226,227,228,229,230,231,
450      232,233,234,235,236,237,238,239,
451      240,241,242,243,244,245,246,247,
452      248,249,250,251,252,253,254,255,
453    
454    /* This table contains bit maps for various character classes. Each map is 32
455    bytes long and the bits run from the least significant end of each byte. The
456    classes that have their own maps are: space, xdigit, digit, upper, lower, word,
457    graph, print, punct, and cntrl. Other classes are built from combinations. */
458    
459      0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
460      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
461      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
462      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
463    
464      0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
465      0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
466      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
467      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
468    
469      0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
470      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
471      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
472      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
473    
474      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
475      0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
476      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
477      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
478    
479      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
480      0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
481      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
482      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
483    
484      0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
485      0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
486      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
487      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
488    
489      0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
490      0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
491      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
492      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
493    
494      0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
495      0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
496      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
497      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
498    
499      0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
500      0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
501      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
502      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
503    
504      0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
505      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
506      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
507      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
508    
509    /* This table identifies various classes of character by individual bits:
510      0x01   white space character
511      0x02   letter
512      0x04   decimal digit
513      0x08   hexadecimal digit
514      0x10   alphanumeric or '_'
515      0x80   regular expression metacharacter or binary zero
516    */
517    
518      0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*   0-  7 */
519      0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /*   8- 15 */
520      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  16- 23 */
521      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */
522      0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /*    - '  */
523      0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /*  ( - /  */
524      0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /*  0 - 7  */
525      0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /*  8 - ?  */
526      0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  @ - G  */
527      0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  H - O  */
528      0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  P - W  */
529      0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /*  X - _  */
530      0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  ` - g  */
531      0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  h - o  */
532      0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  p - w  */
533      0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /*  x -127 */
534      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
535      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
536      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
537      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
538      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
539      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
540      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
541      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
542      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
543      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
544      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
545      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
546      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
547      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
548      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
549      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
550    
551    /* This is a set of tables that came orginally from a Windows user. It seems to
552    be at least an approximation of ISO 8859. In particular, there are characters
553    greater than 128 that are marked as spaces, letters, etc. */
554    
555    static const pcre_uint8 tables1[] = {
556    0,1,2,3,4,5,6,7,
557    8,9,10,11,12,13,14,15,
558    16,17,18,19,20,21,22,23,
559    24,25,26,27,28,29,30,31,
560    32,33,34,35,36,37,38,39,
561    40,41,42,43,44,45,46,47,
562    48,49,50,51,52,53,54,55,
563    56,57,58,59,60,61,62,63,
564    64,97,98,99,100,101,102,103,
565    104,105,106,107,108,109,110,111,
566    112,113,114,115,116,117,118,119,
567    120,121,122,91,92,93,94,95,
568    96,97,98,99,100,101,102,103,
569    104,105,106,107,108,109,110,111,
570    112,113,114,115,116,117,118,119,
571    120,121,122,123,124,125,126,127,
572    128,129,130,131,132,133,134,135,
573    136,137,138,139,140,141,142,143,
574    144,145,146,147,148,149,150,151,
575    152,153,154,155,156,157,158,159,
576    160,161,162,163,164,165,166,167,
577    168,169,170,171,172,173,174,175,
578    176,177,178,179,180,181,182,183,
579    184,185,186,187,188,189,190,191,
580    224,225,226,227,228,229,230,231,
581    232,233,234,235,236,237,238,239,
582    240,241,242,243,244,245,246,215,
583    248,249,250,251,252,253,254,223,
584    224,225,226,227,228,229,230,231,
585    232,233,234,235,236,237,238,239,
586    240,241,242,243,244,245,246,247,
587    248,249,250,251,252,253,254,255,
588    0,1,2,3,4,5,6,7,
589    8,9,10,11,12,13,14,15,
590    16,17,18,19,20,21,22,23,
591    24,25,26,27,28,29,30,31,
592    32,33,34,35,36,37,38,39,
593    40,41,42,43,44,45,46,47,
594    48,49,50,51,52,53,54,55,
595    56,57,58,59,60,61,62,63,
596    64,97,98,99,100,101,102,103,
597    104,105,106,107,108,109,110,111,
598    112,113,114,115,116,117,118,119,
599    120,121,122,91,92,93,94,95,
600    96,65,66,67,68,69,70,71,
601    72,73,74,75,76,77,78,79,
602    80,81,82,83,84,85,86,87,
603    88,89,90,123,124,125,126,127,
604    128,129,130,131,132,133,134,135,
605    136,137,138,139,140,141,142,143,
606    144,145,146,147,148,149,150,151,
607    152,153,154,155,156,157,158,159,
608    160,161,162,163,164,165,166,167,
609    168,169,170,171,172,173,174,175,
610    176,177,178,179,180,181,182,183,
611    184,185,186,187,188,189,190,191,
612    224,225,226,227,228,229,230,231,
613    232,233,234,235,236,237,238,239,
614    240,241,242,243,244,245,246,215,
615    248,249,250,251,252,253,254,223,
616    192,193,194,195,196,197,198,199,
617    200,201,202,203,204,205,206,207,
618    208,209,210,211,212,213,214,247,
619    216,217,218,219,220,221,222,255,
620    0,62,0,0,1,0,0,0,
621    0,0,0,0,0,0,0,0,
622    32,0,0,0,1,0,0,0,
623    0,0,0,0,0,0,0,0,
624    0,0,0,0,0,0,255,3,
625    126,0,0,0,126,0,0,0,
626    0,0,0,0,0,0,0,0,
627    0,0,0,0,0,0,0,0,
628    0,0,0,0,0,0,255,3,
629    0,0,0,0,0,0,0,0,
630    0,0,0,0,0,0,12,2,
631    0,0,0,0,0,0,0,0,
632    0,0,0,0,0,0,0,0,
633    254,255,255,7,0,0,0,0,
634    0,0,0,0,0,0,0,0,
635    255,255,127,127,0,0,0,0,
636    0,0,0,0,0,0,0,0,
637    0,0,0,0,254,255,255,7,
638    0,0,0,0,0,4,32,4,
639    0,0,0,128,255,255,127,255,
640    0,0,0,0,0,0,255,3,
641    254,255,255,135,254,255,255,7,
642    0,0,0,0,0,4,44,6,
643    255,255,127,255,255,255,127,255,
644    0,0,0,0,254,255,255,255,
645    255,255,255,255,255,255,255,127,
646    0,0,0,0,254,255,255,255,
647    255,255,255,255,255,255,255,255,
648    0,2,0,0,255,255,255,255,
649    255,255,255,255,255,255,255,127,
650    0,0,0,0,255,255,255,255,
651    255,255,255,255,255,255,255,255,
652    0,0,0,0,254,255,0,252,
653    1,0,0,248,1,0,0,120,
654    0,0,0,0,254,255,255,255,
655    0,0,128,0,0,0,128,0,
656    255,255,255,255,0,0,0,0,
657    0,0,0,0,0,0,0,128,
658    255,255,255,255,0,0,0,0,
659    0,0,0,0,0,0,0,0,
660    128,0,0,0,0,0,0,0,
661    0,1,1,0,1,1,0,0,
662    0,0,0,0,0,0,0,0,
663    0,0,0,0,0,0,0,0,
664    1,0,0,0,128,0,0,0,
665    128,128,128,128,0,0,128,0,
666    28,28,28,28,28,28,28,28,
667    28,28,0,0,0,0,0,128,
668    0,26,26,26,26,26,26,18,
669    18,18,18,18,18,18,18,18,
670    18,18,18,18,18,18,18,18,
671    18,18,18,128,128,0,128,16,
672    0,26,26,26,26,26,26,18,
673    18,18,18,18,18,18,18,18,
674    18,18,18,18,18,18,18,18,
675    18,18,18,128,128,0,0,0,
676    0,0,0,0,0,1,0,0,
677    0,0,0,0,0,0,0,0,
678    0,0,0,0,0,0,0,0,
679    0,0,0,0,0,0,0,0,
680    1,0,0,0,0,0,0,0,
681    0,0,18,0,0,0,0,0,
682    0,0,20,20,0,18,0,0,
683    0,20,18,0,0,0,0,0,
684    18,18,18,18,18,18,18,18,
685    18,18,18,18,18,18,18,18,
686    18,18,18,18,18,18,18,0,
687    18,18,18,18,18,18,18,18,
688    18,18,18,18,18,18,18,18,
689    18,18,18,18,18,18,18,18,
690    18,18,18,18,18,18,18,0,
691    18,18,18,18,18,18,18,18
692    };
693    
694    
695    
696    
697    #ifndef HAVE_STRERROR
698    /*************************************************
699    *     Provide strerror() for non-ANSI libraries  *
700    *************************************************/
701    
702    /* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror()
703    in their libraries, but can provide the same facility by this simple
704    alternative function. */
705    
706    extern int   sys_nerr;
707    extern char *sys_errlist[];
708    
709    char *
710    strerror(int n)
711    {
712    if (n < 0 || n >= sys_nerr) return "unknown error number";
713    return sys_errlist[n];
714    }
715    #endif /* HAVE_STRERROR */
716    
717    
718    /*************************************************
719    *         JIT memory callback                    *
720    *************************************************/
721    
722    static pcre_jit_stack* jit_callback(void *arg)
723    {
724    return (pcre_jit_stack *)arg;
725    }
726    
727    
728    /*************************************************
729    *            Convert UTF-8 string to value       *
730    *************************************************/
731    
732    /* This function takes one or more bytes that represents a UTF-8 character,
733    and returns the value of the character.
734    
735    Argument:
736      utf8bytes   a pointer to the byte vector
737      vptr        a pointer to an int to receive the value
738    
739    Returns:      >  0 => the number of bytes consumed
740                  -6 to 0 => malformed UTF-8 character at offset = (-return)
741    */
742    
743    #if !defined NOUTF8
744    
745    static int
746    utf82ord(pcre_uint8 *utf8bytes, int *vptr)
747    {
748    int c = *utf8bytes++;
749    int d = c;
750    int i, j, s;
751    
752    for (i = -1; i < 6; i++)               /* i is number of additional bytes */
753      {
754      if ((d & 0x80) == 0) break;
755      d <<= 1;
756      }
757    
758    if (i == -1) { *vptr = c; return 1; }  /* ascii character */
759    if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */
760    
761    /* i now has a value in the range 1-5 */
762    
763    s = 6*i;
764    d = (c & utf8_table3[i]) << s;
765    
766    for (j = 0; j < i; j++)
767      {
768      c = *utf8bytes++;
769      if ((c & 0xc0) != 0x80) return -(j+1);
770      s -= 6;
771      d |= (c & 0x3f) << s;
772      }
773    
774    /* Check that encoding was the correct unique one */
775    
776    for (j = 0; j < utf8_table1_size; j++)
777      if (d <= utf8_table1[j]) break;
778    if (j != i) return -(i+1);
779    
780    /* Valid value */
781    
782    *vptr = d;
783    return i+1;
784    }
785    
786    #endif
787    
788    
789    
790    /*************************************************
791    *       Convert character value to UTF-8         *
792    *************************************************/
793    
794    /* This function takes an integer value in the range 0 - 0x7fffffff
795    and encodes it as a UTF-8 character in 0 to 6 bytes.
796    
797    Arguments:
798      cvalue     the character value
799      utf8bytes  pointer to buffer for result - at least 6 bytes long
800    
801    Returns:     number of characters placed in the buffer
802    */
803    
804    #if !defined NOUTF8
805    
806    static int
807    ord2utf8(int cvalue, pcre_uint8 *utf8bytes)
808    {
809    register int i, j;
810    for (i = 0; i < utf8_table1_size; i++)
811      if (cvalue <= utf8_table1[i]) break;
812    utf8bytes += i;
813    for (j = i; j > 0; j--)
814     {
815     *utf8bytes-- = 0x80 | (cvalue & 0x3f);
816     cvalue >>= 6;
817     }
818    *utf8bytes = utf8_table2[i] | cvalue;
819    return i + 1;
820    }
821    
822    #endif
823    
824    
825    
826    #ifdef SUPPORT_PCRE16
827    /*************************************************
828    *         Convert a string to 16-bit             *
829    *************************************************/
830    
831    /* In non-UTF mode, the space needed for a 16-bit string is exactly double the
832    8-bit size. For a UTF-8 string, the size needed for UTF-16 is no more than
833    double, because up to 0xffff uses no more than 3 bytes in UTF-8 but possibly 4
834    in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in UTF-16. The
835    result is always left in buffer16. */
836    
837    static int
838    to16(pcre_uint8 *p, int utf, int len)
839    {
840    pcre_uint16 *pp;
841    
842    if (buffer16_size < 2*len + 2)
843      {
844      if (buffer16 != NULL) free(buffer16);
845      buffer16_size = 2*len + 2;
846      buffer16 = (pcre_uint16 *)malloc(buffer16_size);
847      if (buffer16 == NULL)
848        {
849        fprintf(stderr, "pcretest: malloc(%d) failed for buffer16\n", buffer16_size);
850        exit(1);
851        }
852      }
853    
854    pp = buffer16;
855    
856    if (!utf)
857      {
858      while (len-- > 0) *pp++ = *p++;
859      }
860    
861    else
862      {
863      int c;
864      while (len > 0)
865        {
866        int chlen = utf82ord(p, &c);
867        p += chlen;
868        len -= chlen;
869        if (c < 0x10000) *pp++ = c; else
870          {
871          c -= 0x10000;
872          *pp++ = 0xD800 | (c >> 10);
873          *pp++ = 0xDC00 | (c & 0x3ff);
874          }
875        }
876      }
877    
878    *pp = 0;
879    return pp - buffer16;
880    }
881    #endif
882    
883    
884  /*************************************************  /*************************************************
885  *        Read or extend an input line            *  *        Read or extend an input line            *
886  *************************************************/  *************************************************/
# Line 213  Returns:       pointer to the start of n Line 904  Returns:       pointer to the start of n
904                 NULL if no data read and EOF reached                 NULL if no data read and EOF reached
905  */  */
906    
907  static uschar *  static pcre_uint8 *
908  extend_inputline(FILE *f, uschar *start, const char *prompt)  extend_inputline(FILE *f, pcre_uint8 *start, const char *prompt)
909  {  {
910  uschar *here = start;  pcre_uint8 *here = start;
911    
912  for (;;)  for (;;)
913    {    {
914    int rlen = buffer_size - (here - buffer);    int rlen = (int)(buffer_size - (here - buffer));
915    
916    if (rlen > 1000)    if (rlen > 1000)
917      {      {
# Line 250  for (;;) Line 941  for (;;)
941      /* Read the next line by normal means, prompting if the file is stdin. */      /* Read the next line by normal means, prompting if the file is stdin. */
942    
943        {        {
944        if (f == stdin) printf(prompt);        if (f == stdin) printf("%s", prompt);
945        if (fgets((char *)here, rlen,  f) == NULL)        if (fgets((char *)here, rlen,  f) == NULL)
946          return (here == start)? NULL : start;          return (here == start)? NULL : start;
947        }        }
# Line 263  for (;;) Line 954  for (;;)
954    else    else
955      {      {
956      int new_buffer_size = 2*buffer_size;      int new_buffer_size = 2*buffer_size;
957      uschar *new_buffer = (unsigned char *)malloc(new_buffer_size);      pcre_uint8 *new_buffer = (pcre_uint8 *)malloc(new_buffer_size);
958      uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size);      pcre_uint8 *new_dbuffer = (pcre_uint8 *)malloc(new_buffer_size);
959      uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size);      pcre_uint8 *new_pbuffer = (pcre_uint8 *)malloc(new_buffer_size);
960    
961      if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)      if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)
962        {        {
# Line 296  return NULL;  /* Control never gets here Line 987  return NULL;  /* Control never gets here
987    
988    
989    
   
   
   
   
990  /*************************************************  /*************************************************
991  *          Read number from string               *  *          Read number from string               *
992  *************************************************/  *************************************************/
# Line 316  Returns:        the unsigned long Line 1003  Returns:        the unsigned long
1003  */  */
1004    
1005  static int  static int
1006  get_value(unsigned char *str, unsigned char **endptr)  get_value(pcre_uint8 *str, pcre_uint8 **endptr)
1007  {  {
1008  int result = 0;  int result = 0;
1009  while(*str != 0 && isspace(*str)) str++;  while(*str != 0 && isspace(*str)) str++;
# Line 327  return(result); Line 1014  return(result);
1014    
1015    
1016    
1017    #ifdef SUPPORT_PCRE8
1018  /*************************************************  /*************************************************
1019  *            Convert UTF-8 string to value       *  *         Print 8-bit character string           *
1020  *************************************************/  *************************************************/
1021    
1022  /* This function takes one or more bytes that represents a UTF-8 character,  /* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed.
1023  and returns the value of the character.  If handed a NULL file, just counts chars without printing. */
   
 Argument:  
   utf8bytes   a pointer to the byte vector  
   vptr        a pointer to an int to receive the value  
1024    
1025  Returns:      >  0 => the number of bytes consumed  static int pchars(pcre_uint8 *p, int length, FILE *f)
               -6 to 0 => malformed UTF-8 character at offset = (-return)  
 */  
   
 #if !defined NOUTF8  
   
 static int  
 utf82ord(unsigned char *utf8bytes, int *vptr)  
 {  
 int c = *utf8bytes++;  
 int d = c;  
 int i, j, s;  
   
 for (i = -1; i < 6; i++)               /* i is number of additional bytes */  
   {  
   if ((d & 0x80) == 0) break;  
   d <<= 1;  
   }  
   
 if (i == -1) { *vptr = c; return 1; }  /* ascii character */  
 if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */  
   
 /* i now has a value in the range 1-5 */  
   
 s = 6*i;  
 d = (c & utf8_table3[i]) << s;  
   
 for (j = 0; j < i; j++)  
   {  
   c = *utf8bytes++;  
   if ((c & 0xc0) != 0x80) return -(j+1);  
   s -= 6;  
   d |= (c & 0x3f) << s;  
   }  
   
 /* Check that encoding was the correct unique one */  
   
 for (j = 0; j < utf8_table1_size; j++)  
   if (d <= utf8_table1[j]) break;  
 if (j != i) return -(i+1);  
   
 /* Valid value */  
   
 *vptr = d;  
 return i+1;  
 }  
   
 #endif  
   
   
   
 /*************************************************  
 *       Convert character value to UTF-8         *  
 *************************************************/  
   
 /* This function takes an integer value in the range 0 - 0x7fffffff  
 and encodes it as a UTF-8 character in 0 to 6 bytes.  
   
 Arguments:  
   cvalue     the character value  
   utf8bytes  pointer to buffer for result - at least 6 bytes long  
   
 Returns:     number of characters placed in the buffer  
 */  
   
 #if !defined NOUTF8  
   
 static int  
 ord2utf8(int cvalue, uschar *utf8bytes)  
 {  
 register int i, j;  
 for (i = 0; i < utf8_table1_size; i++)  
   if (cvalue <= utf8_table1[i]) break;  
 utf8bytes += i;  
 for (j = i; j > 0; j--)  
  {  
  *utf8bytes-- = 0x80 | (cvalue & 0x3f);  
  cvalue >>= 6;  
  }  
 *utf8bytes = utf8_table2[i] | cvalue;  
 return i + 1;  
 }  
   
 #endif  
   
   
   
 /*************************************************  
 *             Print character string             *  
 *************************************************/  
   
 /* Character string printing function. Must handle UTF-8 strings in utf8  
 mode. Yields number of characters printed. If handed a NULL file, just counts  
 chars without printing. */  
   
 static int pchars(unsigned char *p, int length, FILE *f)  
1026  {  {
1027  int c = 0;  int c = 0;
1028  int yield = 0;  int yield = 0;
# Line 450  while (length-- > 0) Line 1038  while (length-- > 0)
1038        {        {
1039        length -= rc - 1;        length -= rc - 1;
1040        p += rc;        p += rc;
1041        if (PRINTHEX(c))        if (PRINTOK(c))
1042          {          {
1043          if (f != NULL) fprintf(f, "%c", c);          if (f != NULL) fprintf(f, "%c", c);
1044          yield++;          yield++;
# Line 472  while (length-- > 0) Line 1060  while (length-- > 0)
1060     /* Not UTF-8, or malformed UTF-8  */     /* Not UTF-8, or malformed UTF-8  */
1061    
1062    c = *p++;    c = *p++;
1063    if (PRINTHEX(c))    if (PRINTOK(c))
1064      {      {
1065      if (f != NULL) fprintf(f, "%c", c);      if (f != NULL) fprintf(f, "%c", c);
1066      yield++;      yield++;
# Line 486  while (length-- > 0) Line 1074  while (length-- > 0)
1074    
1075  return yield;  return yield;
1076  }  }
1077    #endif
1078    
1079    
1080    
1081    #ifdef SUPPORT_PCRE16
1082    /*************************************************
1083    *           Print 16-bit character string        *
1084    *************************************************/
1085    
1086    /* Must handle UTF-16 strings in utf mode. Yields number of characters printed.
1087    If handed a NULL file, just counts chars without printing. */
1088    
1089    static int pchars16(PCRE_SPTR16 p, int length, FILE *f)
1090    {
1091    int yield = 0;
1092    
1093    while (length-- > 0)
1094      {
1095      int c = *p++ & 0xffff;
1096    
1097    #if !defined NOUTF8
1098      if (use_utf8 && c >= 0xD800 && c < 0xDC00 && length > 0)
1099        {
1100        int d = *p & 0xffff;
1101        if (d >= 0xDC00 && d < 0xDFFF)
1102          {
1103          c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000;
1104          length--;
1105          p++;
1106          }
1107        }
1108    #endif
1109    
1110      if (PRINTOK(c))
1111        {
1112        if (f != NULL) fprintf(f, "%c", c);
1113        yield++;
1114        }
1115      else
1116        {
1117        yield += 4;
1118        if (c < 0x100)
1119          {
1120          if (f != NULL) fprintf(f, "\\x%02x", c);
1121          }
1122        else
1123          {
1124          if (f != NULL) fprintf(f, "\\x{%02x}", c);
1125          yield += (c <= 0x000000ff)? 2 :
1126                   (c <= 0x00000fff)? 3 :
1127                   (c <= 0x0000ffff)? 4 :
1128                   (c <= 0x000fffff)? 5 : 6;
1129          }
1130        }
1131      }
1132    
1133    return yield;
1134    }
1135    #endif
1136    
1137    
1138    
# Line 514  if (callout_extra) Line 1161  if (callout_extra)
1161      else      else
1162        {        {
1163        fprintf(f, "%2d: ", i/2);        fprintf(f, "%2d: ", i/2);
1164        (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i],        PCHARSV(cb->subject + cb->offset_vector[i],
1165          cb->offset_vector[i+1] - cb->offset_vector[i], f);          cb->offset_vector[i+1] - cb->offset_vector[i], f);
1166        fprintf(f, "\n");        fprintf(f, "\n");
1167        }        }
# Line 527  printed lengths of the substrings. */ Line 1174  printed lengths of the substrings. */
1174    
1175  if (f != NULL) fprintf(f, "--->");  if (f != NULL) fprintf(f, "--->");
1176    
1177  pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f);  PCHARS(pre_start, cb->subject, cb->start_match, f);
1178  post_start = pchars((unsigned char *)(cb->subject + cb->start_match),  PCHARS(post_start, cb->subject + cb->start_match,
1179    cb->current_position - cb->start_match, f);    cb->current_position - cb->start_match, f);
1180    
1181  subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);  PCHARS(subject_length, cb->subject, cb->subject_length, NULL);
1182    
1183  (void)pchars((unsigned char *)(cb->subject + cb->current_position),  PCHARSV(cb->subject + cb->current_position,
1184    cb->subject_length - cb->current_position, f);    cb->subject_length - cb->current_position, f);
1185    
1186  if (f != NULL) fprintf(f, "\n");  if (f != NULL) fprintf(f, "\n");
# Line 570  fprintf(outfile, "%.*s", (cb->next_item_ Line 1217  fprintf(outfile, "%.*s", (cb->next_item_
1217  fprintf(outfile, "\n");  fprintf(outfile, "\n");
1218  first_callout = 0;  first_callout = 0;
1219    
1220    if (cb->mark != last_callout_mark)
1221      {
1222      fprintf(outfile, "Latest Mark: %s\n",
1223        (cb->mark == NULL)? "<unset>" : (char *)(cb->mark));
1224      last_callout_mark = cb->mark;
1225      }
1226    
1227  if (cb->callout_data != NULL)  if (cb->callout_data != NULL)
1228    {    {
1229    int callout_data = *((int *)(cb->callout_data));    int callout_data = *((int *)(cb->callout_data));
# Line 589  return (cb->callout_number != callout_fa Line 1243  return (cb->callout_number != callout_fa
1243  *            Local malloc functions              *  *            Local malloc functions              *
1244  *************************************************/  *************************************************/
1245    
1246  /* Alternative malloc function, to test functionality and show the size of the  /* Alternative malloc function, to test functionality and save the size of a
1247  compiled re. */  compiled re, which is the first store request that pcre_compile() makes. The
1248    show_malloc variable is set only during matching. */
1249    
1250  static void *new_malloc(size_t size)  static void *new_malloc(size_t size)
1251  {  {
1252  void *block = malloc(size);  void *block = malloc(size);
1253  gotten_store = size;  gotten_store = size;
1254    if (first_gotten_store == 0) first_gotten_store = size;
1255  if (show_malloc)  if (show_malloc)
1256    fprintf(outfile, "malloc       %3d %p\n", (int)size, block);    fprintf(outfile, "malloc       %3d %p\n", (int)size, block);
1257  return block;  return block;
# Line 608  if (show_malloc) Line 1264  if (show_malloc)
1264  free(block);  free(block);
1265  }  }
1266    
   
1267  /* For recursion malloc/free, to test stacking calls */  /* For recursion malloc/free, to test stacking calls */
1268    
1269  static void *stack_malloc(size_t size)  static void *stack_malloc(size_t size)
# Line 631  free(block); Line 1286  free(block);
1286  *          Call pcre_fullinfo()                  *  *          Call pcre_fullinfo()                  *
1287  *************************************************/  *************************************************/
1288    
1289  /* Get one piece of information from the pcre_fullinfo() function */  /* Get one piece of information from the pcre_fullinfo() function. When only
1290    one of 8-bit or 16-bit is supported, use_pcre16 should always have the correct
1291    value, but the code is defensive. */
1292    
1293  static void new_info(pcre *re, pcre_extra *study, int option, void *ptr)  static void new_info(pcre *re, pcre_extra *study, int option, void *ptr)
1294  {  {
1295  int rc;  int rc;
1296  if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)  
1297    fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);  if (use_pcre16)
1298    #ifdef SUPPORT_PCRE16
1299      rc = pcre16_fullinfo(re, study, option, ptr);
1300    #else
1301      rc = PCRE_ERROR_BADMODE;
1302    #endif
1303    else
1304    #ifdef SUPPORT_PCRE8
1305      rc = pcre_fullinfo(re, study, option, ptr);
1306    #else
1307      rc = PCRE_ERROR_BADMODE;
1308    #endif
1309    
1310    if (rc < 0) fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc,
1311      use_pcre16? "16" : "", option);
1312  }  }
1313    
1314    
# Line 664  return ((value & 0x000000ff) << 24) | Line 1335  return ((value & 0x000000ff) << 24) |
1335  *************************************************/  *************************************************/
1336    
1337  static int  static int
1338  check_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len,  check_match_limit(pcre *re, pcre_extra *extra, pcre_uint8 *bptr, int len,
1339    int start_offset, int options, int *use_offsets, int use_size_offsets,    int start_offset, int options, int *use_offsets, int use_size_offsets,
1340    int flag, unsigned long int *limit, int errnumber, const char *msg)    int flag, unsigned long int *limit, int errnumber, const char *msg)
1341  {  {
# Line 679  for (;;) Line 1350  for (;;)
1350    {    {
1351    *limit = mid;    *limit = mid;
1352    
1353    count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options,    PCRE_EXEC(count, re, extra, bptr, len, start_offset, options,
1354      use_offsets, use_size_offsets);      use_offsets, use_size_offsets);
1355    
1356    if (count == errnumber)    if (count == errnumber)
# Line 724  Returns:    < 0, = 0, or > 0, according Line 1395  Returns:    < 0, = 0, or > 0, according
1395  */  */
1396    
1397  static int  static int
1398  strncmpic(uschar *s, uschar *t, int n)  strncmpic(pcre_uint8 *s, pcre_uint8 *t, int n)
1399  {  {
1400  while (n--)  while (n--)
1401    {    {
# Line 740  return 0; Line 1411  return 0;
1411  *         Check newline indicator                *  *         Check newline indicator                *
1412  *************************************************/  *************************************************/
1413    
1414  /* This is used both at compile and run-time to check for <xxx> escapes, where  /* This is used both at compile and run-time to check for <xxx> escapes. Print
1415  xxx is LF, CR, CRLF, ANYCRLF, or ANY. Print a message and return 0 if there is  a message and return 0 if there is no match.
 no match.  
1416    
1417  Arguments:  Arguments:
1418    p           points after the leading '<'    p           points after the leading '<'
# Line 752  Returns:      appropriate PCRE_NEWLINE_x Line 1422  Returns:      appropriate PCRE_NEWLINE_x
1422  */  */
1423    
1424  static int  static int
1425  check_newline(uschar *p, FILE *f)  check_newline(pcre_uint8 *p, FILE *f)
1426  {  {
1427  if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;  if (strncmpic(p, (pcre_uint8 *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
1428  if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;  if (strncmpic(p, (pcre_uint8 *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
1429  if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;  if (strncmpic(p, (pcre_uint8 *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
1430  if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;  if (strncmpic(p, (pcre_uint8 *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
1431  if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;  if (strncmpic(p, (pcre_uint8 *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
1432  if (strncmpic(p, (uschar *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;  if (strncmpic(p, (pcre_uint8 *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;
1433  if (strncmpic(p, (uschar *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;  if (strncmpic(p, (pcre_uint8 *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;
1434  fprintf(f, "Unknown newline type at: <%s\n", p);  fprintf(f, "Unknown newline type at: <%s\n", p);
1435  return 0;  return 0;
1436  }  }
# Line 782  printf("If input is a terminal, readline Line 1452  printf("If input is a terminal, readline
1452  printf("This version of pcretest is not linked with readline().\n");  printf("This version of pcretest is not linked with readline().\n");
1453  #endif  #endif
1454  printf("\nOptions:\n");  printf("\nOptions:\n");
1455    #ifdef SUPPORT_PCRE16
1456    printf("  -16      use 16-bit interface\n");
1457    #endif
1458  printf("  -b       show compiled code (bytecode)\n");  printf("  -b       show compiled code (bytecode)\n");
1459  printf("  -C       show PCRE compile-time options and exit\n");  printf("  -C       show PCRE compile-time options and exit\n");
1460  printf("  -d       debug: show compiled code and information (-b and -i)\n");  printf("  -d       debug: show compiled code and information (-b and -i)\n");
# Line 798  printf("  -p       use POSIX interface\n Line 1471  printf("  -p       use POSIX interface\n
1471  #endif  #endif
1472  printf("  -q       quiet: do not output PCRE version number at start\n");  printf("  -q       quiet: do not output PCRE version number at start\n");
1473  printf("  -S <n>   set stack size to <n> megabytes\n");  printf("  -S <n>   set stack size to <n> megabytes\n");
1474  printf("  -s       output store (memory) used information\n"  printf("  -s       force each pattern to be studied at basic level\n"
1475           "  -s+      force each pattern to be studied, using JIT if available\n"
1476         "  -t       time compilation and execution\n");         "  -t       time compilation and execution\n");
1477  printf("  -t <n>   time compilation and execution, repeating <n> times\n");  printf("  -t <n>   time compilation and execution, repeating <n> times\n");
1478  printf("  -tm      time execution (matching) only\n");  printf("  -tm      time execution (matching) only\n");
# Line 826  int timeit = 0; Line 1500  int timeit = 0;
1500  int timeitm = 0;  int timeitm = 0;
1501  int showinfo = 0;  int showinfo = 0;
1502  int showstore = 0;  int showstore = 0;
1503    int force_study = -1;
1504    int force_study_options = 0;
1505  int quiet = 0;  int quiet = 0;
1506  int size_offsets = 45;  int size_offsets = 45;
1507  int size_offsets_max;  int size_offsets_max;
# Line 839  int all_use_dfa = 0; Line 1515  int all_use_dfa = 0;
1515  int yield = 0;  int yield = 0;
1516  int stack_size;  int stack_size;
1517    
1518    pcre_jit_stack *jit_stack = NULL;
1519    
1520  /* These vectors store, end-to-end, a list of captured substring names. Assume  /* These vectors store, end-to-end, a list of captured substring names. Assume
1521  that 1024 is plenty long enough for the few names we'll be testing. */  that 1024 is plenty long enough for the few names we'll be testing. */
1522    
1523  uschar copynames[1024];  pcre_uchar copynames[1024];
1524  uschar getnames[1024];  pcre_uchar getnames[1024];
   
 uschar *copynamesptr;  
 uschar *getnamesptr;  
1525    
1526  /* Get buffers from malloc() so that Electric Fence will check their misuse  pcre_uchar *copynamesptr;
1527  when I am debugging. They grow automatically when very long lines are read. */  pcre_uchar *getnamesptr;
1528    
1529  buffer = (unsigned char *)malloc(buffer_size);  /* Get buffers from malloc() so that valgrind will check their misuse when
1530  dbuffer = (unsigned char *)malloc(buffer_size);  debugging. They grow automatically when very long lines are read. The 16-bit
1531  pbuffer = (unsigned char *)malloc(buffer_size);  buffer (buffer16) is obtained only if needed. */
1532    
1533    buffer = (pcre_uint8 *)malloc(buffer_size);
1534    dbuffer = (pcre_uint8 *)malloc(buffer_size);
1535    pbuffer = (pcre_uint8 *)malloc(buffer_size);
1536    
1537  /* The outfile variable is static so that new_malloc can use it. */  /* The outfile variable is static so that new_malloc can use it. */
1538    
# Line 872  _setmode( _fileno( stdout ), _O_BINARY ) Line 1551  _setmode( _fileno( stdout ), _O_BINARY )
1551    
1552  while (argc > 1 && argv[op][0] == '-')  while (argc > 1 && argv[op][0] == '-')
1553    {    {
1554    unsigned char *endptr;    pcre_uint8 *endptr;
1555    
1556      if (strcmp(argv[op], "-m") == 0) showstore = 1;
1557      else if (strcmp(argv[op], "-s") == 0) force_study = 0;
1558      else if (strcmp(argv[op], "-s+") == 0)
1559        {
1560        force_study = 1;
1561        force_study_options = PCRE_STUDY_JIT_COMPILE;
1562        }
1563    #ifdef SUPPORT_PCRE16
1564      else if (strcmp(argv[op], "-16") == 0) use_pcre16 = 1;
1565    #endif
1566    
   if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0)  
     showstore = 1;  
1567    else if (strcmp(argv[op], "-q") == 0) quiet = 1;    else if (strcmp(argv[op], "-q") == 0) quiet = 1;
1568    else if (strcmp(argv[op], "-b") == 0) debug = 1;    else if (strcmp(argv[op], "-b") == 0) debug = 1;
1569    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
# Line 885  while (argc > 1 && argv[op][0] == '-') Line 1573  while (argc > 1 && argv[op][0] == '-')
1573    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;
1574  #endif  #endif
1575    else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&    else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&
1576        ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)),        ((size_offsets = get_value((pcre_uint8 *)argv[op+1], &endptr)),
1577          *endptr == 0))          *endptr == 0))
1578      {      {
1579      op++;      op++;
# Line 895  while (argc > 1 && argv[op][0] == '-') Line 1583  while (argc > 1 && argv[op][0] == '-')
1583      {      {
1584      int both = argv[op][2] == 0;      int both = argv[op][2] == 0;
1585      int temp;      int temp;
1586      if (argc > 2 && (temp = get_value((unsigned char *)argv[op+1], &endptr),      if (argc > 2 && (temp = get_value((pcre_uint8 *)argv[op+1], &endptr),
1587                       *endptr == 0))                       *endptr == 0))
1588        {        {
1589        timeitm = temp;        timeitm = temp;
# Line 906  while (argc > 1 && argv[op][0] == '-') Line 1594  while (argc > 1 && argv[op][0] == '-')
1594      if (both) timeit = timeitm;      if (both) timeit = timeitm;
1595      }      }
1596    else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&    else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&
1597        ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)),        ((stack_size = get_value((pcre_uint8 *)argv[op+1], &endptr)),
1598          *endptr == 0))          *endptr == 0))
1599      {      {
1600  #if defined(_WIN32) || defined(WIN32)  #if defined(_WIN32) || defined(WIN32) || defined(__minix)
1601      printf("PCRE: -S not supported on this OS\n");      printf("PCRE: -S not supported on this OS\n");
1602      exit(1);      exit(1);
1603  #else  #else
# Line 936  while (argc > 1 && argv[op][0] == '-') Line 1624  while (argc > 1 && argv[op][0] == '-')
1624      unsigned long int lrc;      unsigned long int lrc;
1625      printf("PCRE version %s\n", pcre_version());      printf("PCRE version %s\n", pcre_version());
1626      printf("Compiled with\n");      printf("Compiled with\n");
1627    
1628    /* At least one of SUPPORT_PCRE8 and SUPPORT_PCRE16 will be set. If both
1629    are set, either both UTFs are supported or both are not supported. */
1630    
1631    #if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
1632        printf("  8-bit and 16-bit support\n");
1633        (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
1634        if (rc)
1635          printf("  UTF-8 and UTF-16 support\n");
1636        else
1637          printf("  No UTF-8 or UTF-16 support\n");
1638    #elif defined SUPPORT_PCRE8
1639        printf("  8-bit support only\n");
1640      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
1641      printf("  %sUTF-8 support\n", rc? "" : "No ");      printf("  %sUTF-8 support\n", rc? "" : "No ");
1642    #else
1643        printf("  16-bit support only\n");
1644        (void)pcre16_config(PCRE_CONFIG_UTF16, &rc);
1645        printf("  %sUTF-16 support\n", rc? "" : "No ");
1646    #endif
1647    
1648      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
1649      printf("  %sUnicode properties support\n", rc? "" : "No ");      printf("  %sUnicode properties support\n", rc? "" : "No ");
1650        (void)pcre_config(PCRE_CONFIG_JIT, &rc);
1651        if (rc)
1652          printf("  Just-in-time compiler support\n");
1653        else
1654          printf("  No just-in-time compiler support\n");
1655      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
1656      /* Note that these values are always the ASCII values, even      /* Note that these values are always the ASCII values, even
1657      in EBCDIC environments. CR is 13 and NL is 10. */      in EBCDIC environments. CR is 13 and NL is 10. */
# Line 1017  if (argc > 2) Line 1729  if (argc > 2)
1729    
1730  /* Set alternative malloc function */  /* Set alternative malloc function */
1731    
1732    #ifdef SUPPORT_PCRE8
1733  pcre_malloc = new_malloc;  pcre_malloc = new_malloc;
1734  pcre_free = new_free;  pcre_free = new_free;
1735  pcre_stack_malloc = stack_malloc;  pcre_stack_malloc = stack_malloc;
1736  pcre_stack_free = stack_free;  pcre_stack_free = stack_free;
1737    #endif
1738    
1739    #ifdef SUPPORT_PCRE16
1740    pcre16_malloc = new_malloc;
1741    pcre16_free = new_free;
1742    pcre16_stack_malloc = stack_malloc;
1743    pcre16_stack_free = stack_free;
1744    #endif
1745    
1746  /* Heading line unless quiet, then prompt for first regex if stdin */  /* Heading line unless quiet, then prompt for first regex if stdin */
1747    
# Line 1039  while (!done) Line 1760  while (!done)
1760  #endif  #endif
1761    
1762    const char *error;    const char *error;
1763    unsigned char *p, *pp, *ppp;    pcre_uint8 *markptr;
1764    unsigned char *to_file = NULL;    pcre_uint8 *p, *pp, *ppp;
1765    const unsigned char *tables = NULL;    pcre_uint8 *to_file = NULL;
1766      const pcre_uint8 *tables = NULL;
1767    unsigned long int true_size, true_study_size = 0;    unsigned long int true_size, true_study_size = 0;
1768    size_t size, regex_gotten_store;    size_t size, regex_gotten_store;
1769      int do_allcaps = 0;
1770      int do_mark = 0;
1771    int do_study = 0;    int do_study = 0;
1772      int no_force_study = 0;
1773    int do_debug = debug;    int do_debug = debug;
1774    int do_G = 0;    int do_G = 0;
1775    int do_g = 0;    int do_g = 0;
1776    int do_showinfo = showinfo;    int do_showinfo = showinfo;
1777    int do_showrest = 0;    int do_showrest = 0;
1778      int do_showcaprest = 0;
1779    int do_flip = 0;    int do_flip = 0;
1780    int erroroffset, len, delimiter, poffset;    int erroroffset, len, delimiter, poffset;
1781    
# Line 1069  while (!done) Line 1795  while (!done)
1795    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)
1796      {      {
1797      unsigned long int magic, get_options;      unsigned long int magic, get_options;
1798      uschar sbuf[8];      pcre_uint8 sbuf[8];
1799      FILE *f;      FILE *f;
1800    
1801      p++;      p++;
# Line 1092  while (!done) Line 1818  while (!done)
1818        (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];        (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];
1819    
1820      re = (real_pcre *)new_malloc(true_size);      re = (real_pcre *)new_malloc(true_size);
1821      regex_gotten_store = gotten_store;      regex_gotten_store = first_gotten_store;
1822    
1823      if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;      if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;
1824    
# Line 1111  while (!done) Line 1837  while (!done)
1837          }          }
1838        }        }
1839    
1840      fprintf(outfile, "Compiled regex%s loaded from %s\n",      fprintf(outfile, "Compiled pattern%s loaded from %s\n",
1841        do_flip? " (byte-inverted)" : "", p);        do_flip? " (byte-inverted)" : "", p);
1842    
1843      /* Need to know if UTF-8 for printing data strings */      /* Need to know if UTF-8 for printing data strings */
# Line 1119  while (!done) Line 1845  while (!done)
1845      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
1846      use_utf8 = (get_options & PCRE_UTF8) != 0;      use_utf8 = (get_options & PCRE_UTF8) != 0;
1847    
1848      /* Now see if there is any following study data */      /* Now see if there is any following study data. */
1849    
1850      if (true_study_size != 0)      if (true_study_size != 0)
1851        {        {
# Line 1135  while (!done) Line 1861  while (!done)
1861          {          {
1862          FAIL_READ:          FAIL_READ:
1863          fprintf(outfile, "Failed to read data from %s\n", p);          fprintf(outfile, "Failed to read data from %s\n", p);
1864          if (extra != NULL) new_free(extra);          if (extra != NULL) pcre_free_study(extra);
1865          if (re != NULL) new_free(re);          if (re != NULL) new_free(re);
1866          fclose(f);          fclose(f);
1867          continue;          continue;
# Line 1161  while (!done) Line 1887  while (!done)
1887      }      }
1888    
1889    pp = p;    pp = p;
1890    poffset = p - buffer;    poffset = (int)(p - buffer);
1891    
1892    for(;;)    for(;;)
1893      {      {
# Line 1215  while (!done) Line 1941  while (!done)
1941        case 's': options |= PCRE_DOTALL; break;        case 's': options |= PCRE_DOTALL; break;
1942        case 'x': options |= PCRE_EXTENDED; break;        case 'x': options |= PCRE_EXTENDED; break;
1943    
1944        case '+': do_showrest = 1; break;        case '+':
1945          if (do_showrest) do_showcaprest = 1; else do_showrest = 1;
1946          break;
1947    
1948          case '=': do_allcaps = 1; break;
1949        case 'A': options |= PCRE_ANCHORED; break;        case 'A': options |= PCRE_ANCHORED; break;
1950        case 'B': do_debug = 1; break;        case 'B': do_debug = 1; break;
1951        case 'C': options |= PCRE_AUTO_CALLOUT; break;        case 'C': options |= PCRE_AUTO_CALLOUT; break;
# Line 1225  while (!done) Line 1955  while (!done)
1955        case 'G': do_G = 1; break;        case 'G': do_G = 1; break;
1956        case 'I': do_showinfo = 1; break;        case 'I': do_showinfo = 1; break;
1957        case 'J': options |= PCRE_DUPNAMES; break;        case 'J': options |= PCRE_DUPNAMES; break;
1958          case 'K': do_mark = 1; break;
1959        case 'M': log_store = 1; break;        case 'M': log_store = 1; break;
1960        case 'N': options |= PCRE_NO_AUTO_CAPTURE; break;        case 'N': options |= PCRE_NO_AUTO_CAPTURE; break;
1961    
# Line 1232  while (!done) Line 1963  while (!done)
1963        case 'P': do_posix = 1; break;        case 'P': do_posix = 1; break;
1964  #endif  #endif
1965    
1966        case 'S': do_study = 1; break;        case 'S':
1967          if (do_study == 0)
1968            {
1969            do_study = 1;
1970            if (*pp == '+')
1971              {
1972              study_options |= PCRE_STUDY_JIT_COMPILE;
1973              pp++;
1974              }
1975            }
1976          else
1977            {
1978            do_study = 0;
1979            no_force_study = 1;
1980            }
1981          break;
1982    
1983        case 'U': options |= PCRE_UNGREEDY; break;        case 'U': options |= PCRE_UNGREEDY; break;
1984          case 'W': options |= PCRE_UCP; break;
1985        case 'X': options |= PCRE_EXTRA; break;        case 'X': options |= PCRE_EXTRA; break;
1986          case 'Y': options |= PCRE_NO_START_OPTIMISE; break;
1987        case 'Z': debug_lengths = 0; break;        case 'Z': debug_lengths = 0; break;
1988        case '8': options |= PCRE_UTF8; use_utf8 = 1; break;        case '8': options |= PCRE_UTF8; use_utf8 = 1; break;
1989        case '?': options |= PCRE_NO_UTF8_CHECK; break;        case '?': options |= PCRE_NO_UTF8_CHECK; break;
1990    
1991          case 'T':
1992          switch (*pp++)
1993            {
1994            case '0': tables = tables0; break;
1995            case '1': tables = tables1; break;
1996    
1997            case '\r':
1998            case '\n':
1999            case ' ':
2000            case 0:
2001            fprintf(outfile, "** Missing table number after /T\n");
2002            goto SKIP_DATA;
2003    
2004            default:
2005            fprintf(outfile, "** Bad table number \"%c\" after /T\n", pp[-1]);
2006            goto SKIP_DATA;
2007            }
2008          break;
2009    
2010        case 'L':        case 'L':
2011        ppp = pp;        ppp = pp;
2012        /* The '\r' test here is so that it works on Windows. */        /* The '\r' test here is so that it works on Windows. */
# Line 1264  while (!done) Line 2032  while (!done)
2032    
2033        case '<':        case '<':
2034          {          {
2035          if (strncmp((char *)pp, "JS>", 3) == 0)          if (strncmpic(pp, (pcre_uint8 *)"JS>", 3) == 0)
2036            {            {
2037            options |= PCRE_JAVASCRIPT_COMPAT;            options |= PCRE_JAVASCRIPT_COMPAT;
2038            pp += 3;            pp += 3;
# Line 1292  while (!done) Line 2060  while (!done)
2060    
2061    /* Handle compiling via the POSIX interface, which doesn't support the    /* Handle compiling via the POSIX interface, which doesn't support the
2062    timing, showing, or debugging options, nor the ability to pass over    timing, showing, or debugging options, nor the ability to pass over
2063    local character tables. */    local character tables. Neither does it have 16-bit support. */
2064    
2065  #if !defined NOPOSIX  #if !defined NOPOSIX
2066    if (posix || do_posix)    if (posix || do_posix)
# Line 1305  while (!done) Line 2073  while (!done)
2073      if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL;      if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL;
2074      if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB;      if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB;
2075      if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8;      if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8;
2076        if ((options & PCRE_UCP) != 0) cflags |= REG_UCP;
2077        if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY;
2078    
2079        first_gotten_store = 0;
2080      rc = regcomp(&preg, (char *)p, cflags);      rc = regcomp(&preg, (char *)p, cflags);
2081    
2082      /* Compilation failed; go back for another re, skipping to blank line      /* Compilation failed; go back for another re, skipping to blank line
# Line 1325  while (!done) Line 2096  while (!done)
2096  #endif  /* !defined NOPOSIX */  #endif  /* !defined NOPOSIX */
2097    
2098      {      {
2099        unsigned long int get_options;
2100    
2101        /* In 16-bit mode, convert the input. */
2102    
2103    #ifdef SUPPORT_PCRE16
2104        if (use_pcre16)
2105          {
2106          (void)to16(p, options & PCRE_UTF8, (int)strlen((char *)p));
2107          p = (pcre_uint8 *)buffer16;
2108          }
2109    #endif
2110    
2111        /* Compile many times when timing */
2112    
2113      if (timeit > 0)      if (timeit > 0)
2114        {        {
2115        register int i;        register int i;
# Line 1332  while (!done) Line 2117  while (!done)
2117        clock_t start_time = clock();        clock_t start_time = clock();
2118        for (i = 0; i < timeit; i++)        for (i = 0; i < timeit; i++)
2119          {          {
2120          re = pcre_compile((char *)p, options, &error, &erroroffset, tables);          PCRE_COMPILE(re, p, options, &error, &erroroffset, tables);
2121          if (re != NULL) free(re);          if (re != NULL) free(re);
2122          }          }
2123        time_taken = clock() - start_time;        time_taken = clock() - start_time;
# Line 1341  while (!done) Line 2126  while (!done)
2126            (double)CLOCKS_PER_SEC);            (double)CLOCKS_PER_SEC);
2127        }        }
2128    
2129      re = pcre_compile((char *)p, options, &error, &erroroffset, tables);      first_gotten_store = 0;
2130        PCRE_COMPILE(re, p, options, &error, &erroroffset, tables);
2131    
2132      /* Compilation failed; go back for another re, skipping to blank line      /* Compilation failed; go back for another re, skipping to blank line
2133      if non-interactive. */      if non-interactive. */
# Line 1368  while (!done) Line 2154  while (!done)
2154        goto CONTINUE;        goto CONTINUE;
2155        }        }
2156    
2157      /* Compilation succeeded; print data if required. There are now two      /* Compilation succeeded. It is now possible to set the UTF-8 option from
2158      info-returning functions. The old one has a limited interface and      within the regex; check for this so that we know how to process the data
2159      returns only limited data. Check that it agrees with the newer one. */      lines. */
2160    
2161      if (log_store)      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
2162        fprintf(outfile, "Memory allocation (code space): %d\n",      if ((get_options & PCRE_UTF8) != 0) use_utf8 = 1;
         (int)(gotten_store -  
               sizeof(real_pcre) -  
               ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));  
2163    
2164      /* Extract the size for possible writing before possibly flipping it,      /* Extract the size for possible writing before possibly flipping it,
2165      and remember the store that was got. */      and remember the store that was got. */
2166    
2167      true_size = ((real_pcre *)re)->size;      true_size = ((real_pcre *)re)->size;
2168      regex_gotten_store = gotten_store;      regex_gotten_store = first_gotten_store;
2169    
2170      /* If /S was present, study the regexp to generate additional info to      /* Output code size information if requested */
2171      help with the matching. */  
2172        if (log_store)
2173          fprintf(outfile, "Memory allocation (code space): %d\n",
2174            (int)(first_gotten_store -
2175                  sizeof(real_pcre) -
2176                  ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));
2177    
2178      if (do_study)      /* If -s or /S was present, study the regex to generate additional info to
2179        help with the matching, unless the pattern has the SS option, which
2180        suppresses the effect of /S (used for a few test patterns where studying is
2181        never sensible). */
2182    
2183        if (do_study || (force_study >= 0 && !no_force_study))
2184        {        {
2185        if (timeit > 0)        if (timeit > 0)
2186          {          {
# Line 1395  while (!done) Line 2188  while (!done)
2188          clock_t time_taken;          clock_t time_taken;
2189          clock_t start_time = clock();          clock_t start_time = clock();
2190          for (i = 0; i < timeit; i++)          for (i = 0; i < timeit; i++)
2191            extra = pcre_study(re, study_options, &error);            {
2192              PCRE_STUDY(extra, re, study_options | force_study_options, &error);
2193              }
2194          time_taken = clock() - start_time;          time_taken = clock() - start_time;
2195          if (extra != NULL) free(extra);          if (extra != NULL) pcre_free_study(extra);
2196          fprintf(outfile, "  Study time %.4f milliseconds\n",          fprintf(outfile, "  Study time %.4f milliseconds\n",
2197            (((double)time_taken * 1000.0) / (double)timeit) /            (((double)time_taken * 1000.0) / (double)timeit) /
2198              (double)CLOCKS_PER_SEC);              (double)CLOCKS_PER_SEC);
2199          }          }
2200        extra = pcre_study(re, study_options, &error);        PCRE_STUDY(extra, re, study_options | force_study_options, &error);
2201        if (error != NULL)        if (error != NULL)
2202          fprintf(outfile, "Failed to study: %s\n", error);          fprintf(outfile, "Failed to study: %s\n", error);
2203        else if (extra != NULL)        else if (extra != NULL)
2204            {
2205          true_study_size = ((pcre_study_data *)(extra->study_data))->size;          true_study_size = ((pcre_study_data *)(extra->study_data))->size;
2206            if (log_store)
2207              {
2208              size_t jitsize;
2209              new_info(re, extra, PCRE_INFO_JITSIZE, &jitsize);
2210              if (jitsize != 0)
2211                fprintf(outfile, "Memory allocation (JIT code): %d\n", jitsize);
2212              }
2213            }
2214          }
2215    
2216        /* If /K was present, we set up for handling MARK data. */
2217    
2218        if (do_mark)
2219          {
2220          if (extra == NULL)
2221            {
2222            extra = (pcre_extra *)malloc(sizeof(pcre_extra));
2223            extra->flags = 0;
2224            }
2225          extra->mark = &markptr;
2226          extra->flags |= PCRE_EXTRA_MARK;
2227        }        }
2228    
2229      /* If the 'F' option was present, we flip the bytes of all the integer      /* If the 'F' option was present, we flip the bytes of all the integer
# Line 1426  while (!done) Line 2243  while (!done)
2243          (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));          (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));
2244        rre->top_backref =        rre->top_backref =
2245          (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));          (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));
2246        rre->first_byte =        rre->first_char =
2247          (pcre_uint16)byteflip(rre->first_byte, sizeof(rre->first_byte));          (pcre_uint16)byteflip(rre->first_char, sizeof(rre->first_char));
2248        rre->req_byte =        rre->req_char =
2249          (pcre_uint16)byteflip(rre->req_byte, sizeof(rre->req_byte));          (pcre_uint16)byteflip(rre->req_char, sizeof(rre->req_char));
2250        rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,        rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,
2251          sizeof(rre->name_table_offset));          sizeof(rre->name_table_offset));
2252        rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,        rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,
# Line 1441  while (!done) Line 2258  while (!done)
2258          {          {
2259          pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);          pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);
2260          rsd->size = byteflip(rsd->size, sizeof(rsd->size));          rsd->size = byteflip(rsd->size, sizeof(rsd->size));
2261          rsd->options = byteflip(rsd->options, sizeof(rsd->options));          rsd->flags = byteflip(rsd->flags, sizeof(rsd->flags));
2262            rsd->minlength = byteflip(rsd->minlength, sizeof(rsd->minlength));
2263          }          }
2264        }        }
2265    
2266      /* Extract information from the compiled data if required */      /* Extract and display information from the compiled data if required. */
2267    
2268      SHOW_INFO:      SHOW_INFO:
2269    
2270      if (do_debug)      if (do_debug)
2271        {        {
2272        fprintf(outfile, "------------------------------------------------------------------\n");        fprintf(outfile, "------------------------------------------------------------------\n");
2273        pcre_printint(re, outfile, debug_lengths);        if (use_pcre16)
2274            pcre16_printint(re, outfile, debug_lengths);
2275          else
2276            pcre_printint(re, outfile, debug_lengths);
2277        }        }
2278    
2279        /* We already have the options in get_options (see above) */
2280    
2281      if (do_showinfo)      if (do_showinfo)
2282        {        {
2283        unsigned long int get_options, all_options;        unsigned long int all_options;
2284  #if !defined NOINFOCHECK  #if !defined NOINFOCHECK
2285        int old_first_char, old_options, old_count;        int old_first_char, old_options, old_count;
2286  #endif  #endif
2287        int count, backrefmax, first_char, need_char, okpartial, jchanged,        int count, backrefmax, first_char, need_char, okpartial, jchanged,
2288          hascrorlf;          hascrorlf;
2289        int nameentrysize, namecount;        int nameentrysize, namecount;
2290        const uschar *nametable;        const pcre_uchar *nametable;
2291    
       new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);  
2292        new_info(re, NULL, PCRE_INFO_SIZE, &size);        new_info(re, NULL, PCRE_INFO_SIZE, &size);
2293        new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);        new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);
2294        new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax);        new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax);
# Line 1479  while (!done) Line 2301  while (!done)
2301        new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);        new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);
2302        new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);        new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);
2303    
2304          /* The old, obsolete function pcre_info() works only in 8-bit mode. Check
2305          that it gives the same results as the new function. */
2306    
2307  #if !defined NOINFOCHECK  #if !defined NOINFOCHECK
2308        old_count = pcre_info(re, &old_options, &old_first_char);        if (!use_pcre16)
       if (count < 0) fprintf(outfile,  
         "Error %d from pcre_info()\n", count);  
       else  
2309          {          {
2310          if (old_count != count) fprintf(outfile,          old_count = pcre_info(re, &old_options, &old_first_char);
2311            "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,          if (count < 0) fprintf(outfile,
2312              old_count);            "Error %d from pcre_info()\n", count);
2313            else
2314          if (old_first_char != first_char) fprintf(outfile,            {
2315            "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",            if (old_count != count) fprintf(outfile,
2316              first_char, old_first_char);              "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,
2317                  old_count);
2318          if (old_options != (int)get_options) fprintf(outfile,  
2319            "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",            if (old_first_char != first_char) fprintf(outfile,
2320              get_options, old_options);              "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",
2321                  first_char, old_first_char);
2322    
2323              if (old_options != (int)get_options) fprintf(outfile,
2324                "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",
2325                  get_options, old_options);
2326              }
2327          }          }
2328  #endif  #endif
2329    
# Line 1526  while (!done) Line 2354  while (!done)
2354        if (do_flip) all_options = byteflip(all_options, sizeof(all_options));        if (do_flip) all_options = byteflip(all_options, sizeof(all_options));
2355    
2356        if (get_options == 0) fprintf(outfile, "No options\n");        if (get_options == 0) fprintf(outfile, "No options\n");
2357          else fprintf(outfile, "Options:%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",
2358            ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",            ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",
2359            ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",            ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",
2360            ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",            ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",
# Line 1540  while (!done) Line 2368  while (!done)
2368            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
2369            ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",            ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",
2370            ((get_options & PCRE_UTF8) != 0)? " utf8" : "",            ((get_options & PCRE_UTF8) != 0)? " utf8" : "",
2371              ((get_options & PCRE_UCP) != 0)? " ucp" : "",
2372            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",
2373              ((get_options & PCRE_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "",
2374            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");
2375    
2376        if (jchanged) fprintf(outfile, "Duplicate name status changes\n");        if (jchanged) fprintf(outfile, "Duplicate name status changes\n");
# Line 1581  while (!done) Line 2411  while (!done)
2411          }          }
2412        else        else
2413          {          {
2414          int ch = first_char & 255;          const char *caseless =
2415          const char *caseless = ((first_char & REQ_CASELESS) == 0)?            ((((real_pcre *)re)->flags & PCRE_FCH_CASELESS) == 0)?
2416            "" : " (caseless)";            "" : " (caseless)";
2417          if (PRINTHEX(ch))  
2418            fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless);          if (PRINTOK(first_char))
2419              fprintf(outfile, "First char = \'%c\'%s\n", first_char, caseless);
2420          else          else
2421            fprintf(outfile, "First char = %d%s\n", ch, caseless);            fprintf(outfile, "First char = %d%s\n", first_char, caseless);
2422          }          }
2423    
2424        if (need_char < 0)        if (need_char < 0)
# Line 1596  while (!done) Line 2427  while (!done)
2427          }          }
2428        else        else
2429          {          {
2430          int ch = need_char & 255;          const char *caseless =
2431          const char *caseless = ((need_char & REQ_CASELESS) == 0)?            ((((real_pcre *)re)->flags & PCRE_RCH_CASELESS) == 0)?
2432            "" : " (caseless)";            "" : " (caseless)";
2433          if (PRINTHEX(ch))  
2434            fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless);          if (PRINTOK(need_char))
2435              fprintf(outfile, "Need char = \'%c\'%s\n", need_char, caseless);
2436          else          else
2437            fprintf(outfile, "Need char = %d%s\n", ch, caseless);            fprintf(outfile, "Need char = %d%s\n", need_char, caseless);
2438          }          }
2439    
2440        /* Don't output study size; at present it is in any case a fixed        /* Don't output study size; at present it is in any case a fixed
2441        value, but it varies, depending on the computer architecture, and        value, but it varies, depending on the computer architecture, and
2442        so messes up the test suite. (And with the /F option, it might be        so messes up the test suite. (And with the /F option, it might be
2443        flipped.) */        flipped.) If study was forced by an external -s, don't show this
2444          information unless -i or -d was also present. This means that, except
2445          when auto-callouts are involved, the output from runs with and without
2446          -s should be identical. */
2447    
2448        if (do_study)        if (do_study || (force_study >= 0 && showinfo && !no_force_study))
2449          {          {
2450          if (extra == NULL)          if (extra == NULL)
2451            fprintf(outfile, "Study returned NULL\n");            fprintf(outfile, "Study returned NULL\n");
2452          else          else
2453            {            {
2454            uschar *start_bits = NULL;            pcre_uint8 *start_bits = NULL;
2455            new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);            int minlength;
2456    
2457              new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength);
2458              fprintf(outfile, "Subject length lower bound = %d\n", minlength);
2459    
2460              new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);
2461            if (start_bits == NULL)            if (start_bits == NULL)
2462              fprintf(outfile, "No starting byte set\n");              fprintf(outfile, "No set of starting bytes\n");
2463            else            else
2464              {              {
2465              int i;              int i;
# Line 1635  while (!done) Line 2474  while (!done)
2474                    fprintf(outfile, "\n  ");                    fprintf(outfile, "\n  ");
2475                    c = 2;                    c = 2;
2476                    }                    }
2477                  if (PRINTHEX(i) && i != ' ')                  if (PRINTOK(i) && i != ' ')
2478                    {                    {
2479                    fprintf(outfile, "%c ", i);                    fprintf(outfile, "%c ", i);
2480                    c += 2;                    c += 2;
# Line 1650  while (!done) Line 2489  while (!done)
2489              fprintf(outfile, "\n");              fprintf(outfile, "\n");
2490              }              }
2491            }            }
2492    
2493            /* Show this only if the JIT was set by /S, not by -s. */
2494    
2495            if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0)
2496              {
2497              int jit;
2498              new_info(re, extra, PCRE_INFO_JIT, &jit);
2499              if (jit)
2500                fprintf(outfile, "JIT study was successful\n");
2501              else
2502    #ifdef SUPPORT_JIT
2503                fprintf(outfile, "JIT study was not successful\n");
2504    #else
2505                fprintf(outfile, "JIT support is not available in this version of PCRE\n");
2506    #endif
2507              }
2508          }          }
2509        }        }
2510    
# Line 1666  while (!done) Line 2521  while (!done)
2521          }          }
2522        else        else
2523          {          {
2524          uschar sbuf[8];          pcre_uint8 sbuf[8];
2525          sbuf[0] = (uschar)((true_size >> 24) & 255);          sbuf[0] = (pcre_uint8)((true_size >> 24) & 255);
2526          sbuf[1] = (uschar)((true_size >> 16) & 255);          sbuf[1] = (pcre_uint8)((true_size >> 16) & 255);
2527          sbuf[2] = (uschar)((true_size >>  8) & 255);          sbuf[2] = (pcre_uint8)((true_size >>  8) & 255);
2528          sbuf[3] = (uschar)((true_size) & 255);          sbuf[3] = (pcre_uint8)((true_size) & 255);
2529    
2530          sbuf[4] = (uschar)((true_study_size >> 24) & 255);          sbuf[4] = (pcre_uint8)((true_study_size >> 24) & 255);
2531          sbuf[5] = (uschar)((true_study_size >> 16) & 255);          sbuf[5] = (pcre_uint8)((true_study_size >> 16) & 255);
2532          sbuf[6] = (uschar)((true_study_size >>  8) & 255);          sbuf[6] = (pcre_uint8)((true_study_size >>  8) & 255);
2533          sbuf[7] = (uschar)((true_study_size) & 255);          sbuf[7] = (pcre_uint8)((true_study_size) & 255);
2534    
2535          if (fwrite(sbuf, 1, 8, f) < 8 ||          if (fwrite(sbuf, 1, 8, f) < 8 ||
2536              fwrite(re, 1, true_size, f) < true_size)              fwrite(re, 1, true_size, f) < true_size)
# Line 1684  while (!done) Line 2539  while (!done)
2539            }            }
2540          else          else
2541            {            {
2542            fprintf(outfile, "Compiled regex written to %s\n", to_file);            fprintf(outfile, "Compiled pattern written to %s\n", to_file);
2543    
2544              /* If there is study data, write it. */
2545    
2546            if (extra != NULL)            if (extra != NULL)
2547              {              {
2548              if (fwrite(extra->study_data, 1, true_study_size, f) <              if (fwrite(extra->study_data, 1, true_study_size, f) <
# Line 1694  while (!done) Line 2552  while (!done)
2552                  strerror(errno));                  strerror(errno));
2553                }                }
2554              else fprintf(outfile, "Study data written to %s\n", to_file);              else fprintf(outfile, "Study data written to %s\n", to_file);
   
2555              }              }
2556            }            }
2557          fclose(f);          fclose(f);
2558          }          }
2559    
2560        new_free(re);        new_free(re);
2561        if (extra != NULL) new_free(extra);        if (extra != NULL) pcre_free_study(extra);
2562        if (tables != NULL) new_free((void *)tables);        if (locale_set)
2563            {
2564            new_free((void *)tables);
2565            setlocale(LC_CTYPE, "C");
2566            locale_set = 0;
2567            }
2568        continue;  /* With next regex */        continue;  /* With next regex */
2569        }        }
2570      }        /* End of non-POSIX compile */      }        /* End of non-POSIX compile */
# Line 1711  while (!done) Line 2573  while (!done)
2573    
2574    for (;;)    for (;;)
2575      {      {
2576      uschar *q;      pcre_uint8 *q;
2577      uschar *bptr;      pcre_uint8 *bptr;
2578      int *use_offsets = offsets;      int *use_offsets = offsets;
2579      int use_size_offsets = size_offsets;      int use_size_offsets = size_offsets;
2580      int callout_data = 0;      int callout_data = 0;
# Line 1724  while (!done) Line 2586  while (!done)
2586      int getlist = 0;      int getlist = 0;
2587      int gmatched = 0;      int gmatched = 0;
2588      int start_offset = 0;      int start_offset = 0;
2589        int start_offset_sign = 1;
2590      int g_notempty = 0;      int g_notempty = 0;
2591      int use_dfa = 0;      int use_dfa = 0;
2592    
# Line 1737  while (!done) Line 2600  while (!done)
2600    
2601      pcre_callout = callout;      pcre_callout = callout;
2602      first_callout = 1;      first_callout = 1;
2603        last_callout_mark = NULL;
2604      callout_extra = 0;      callout_extra = 0;
2605      callout_count = 0;      callout_count = 0;
2606      callout_fail_count = 999999;      callout_fail_count = 999999;
# Line 1751  while (!done) Line 2615  while (!done)
2615        {        {
2616        if (extend_inputline(infile, buffer + len, "data> ") == NULL)        if (extend_inputline(infile, buffer + len, "data> ") == NULL)
2617          {          {
2618          if (len > 0) break;          if (len > 0)    /* Reached EOF without hitting a newline */
2619              {
2620              fprintf(outfile, "\n");
2621              break;
2622              }
2623          done = 1;          done = 1;
2624          goto CONTINUE;          goto CONTINUE;
2625          }          }
# Line 1793  while (!done) Line 2661  while (!done)
2661  #if !defined NOUTF8  #if !defined NOUTF8
2662          if (use_utf8 && c > 255)          if (use_utf8 && c > 255)
2663            {            {
2664            unsigned char buff8[8];            pcre_uint8 buff8[8];
2665            int ii, utn;            int ii, utn;
2666            utn = ord2utf8(c, buff8);            utn = ord2utf8(c, buff8);
2667            for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];            for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
# Line 1809  while (!done) Line 2677  while (!done)
2677  #if !defined NOUTF8  #if !defined NOUTF8
2678          if (*p == '{')          if (*p == '{')
2679            {            {
2680            unsigned char *pt = p;            pcre_uint8 *pt = p;
2681            c = 0;            c = 0;
2682            while (isxdigit(*(++pt)))  
2683              c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W');            /* We used to have "while (isxdigit(*(++pt)))" here, but it fails
2684              when isxdigit() is a macro that refers to its argument more than
2685              once. This is banned by the C Standard, but apparently happens in at
2686              least one MacOS environment. */
2687    
2688              for (pt++; isxdigit(*pt); pt++)
2689                c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'a' - 10);
2690            if (*pt == '}')            if (*pt == '}')
2691              {              {
2692              unsigned char buff8[8];              pcre_uint8 buff8[8];
2693              int ii, utn;              int ii, utn;
2694              if (use_utf8)              if (use_utf8)
2695                {                {
# Line 1842  while (!done) Line 2716  while (!done)
2716          c = 0;          c = 0;
2717          while (i++ < 2 && isxdigit(*p))          while (i++ < 2 && isxdigit(*p))
2718            {            {
2719            c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W');            c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10);
2720            p++;            p++;
2721            }            }
2722          break;          break;
# Line 1852  while (!done) Line 2726  while (!done)
2726          continue;          continue;
2727    
2728          case '>':          case '>':
2729            if (*p == '-')
2730              {
2731              start_offset_sign = -1;
2732              p++;
2733              }
2734          while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0';          while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0';
2735            start_offset *= start_offset_sign;
2736          continue;          continue;
2737    
2738          case 'A':  /* Option setting */          case 'A':  /* Option setting */
# Line 1871  while (!done) Line 2751  while (!done)
2751            }            }
2752          else if (isalnum(*p))          else if (isalnum(*p))
2753            {            {
2754            uschar *npp = copynamesptr;            pcre_uchar *npp = copynamesptr;
2755            while (isalnum(*p)) *npp++ = *p++;            while (isalnum(*p)) *npp++ = *p++;
2756            *npp++ = 0;            *npp++ = 0;
2757            *npp = 0;            *npp = 0;
# Line 1925  while (!done) Line 2805  while (!done)
2805  #endif  #endif
2806            use_dfa = 1;            use_dfa = 1;
2807          continue;          continue;
2808    #endif
2809    
2810    #if !defined NODFA
2811          case 'F':          case 'F':
2812          options |= PCRE_DFA_SHORTEST;          options |= PCRE_DFA_SHORTEST;
2813          continue;          continue;
# Line 1939  while (!done) Line 2821  while (!done)
2821            }            }
2822          else if (isalnum(*p))          else if (isalnum(*p))
2823            {            {
2824            uschar *npp = getnamesptr;            pcre_uchar *npp = getnamesptr;
2825            while (isalnum(*p)) *npp++ = *p++;            while (isalnum(*p)) *npp++ = *p++;
2826            *npp++ = 0;            *npp++ = 0;
2827            *npp = 0;            *npp = 0;
# Line 1950  while (!done) Line 2832  while (!done)
2832            }            }
2833          continue;          continue;
2834    
2835            case 'J':
2836            while(isdigit(*p)) n = n * 10 + *p++ - '0';
2837            if (extra != NULL
2838                && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0
2839                && extra->executable_jit != NULL)
2840              {
2841              if (jit_stack != NULL) pcre_jit_stack_free(jit_stack);
2842              jit_stack = pcre_jit_stack_alloc(1, n * 1024);
2843              pcre_assign_jit_stack(extra, jit_callback, jit_stack);
2844              }
2845            continue;
2846    
2847          case 'L':          case 'L':
2848          getlist = 1;          getlist = 1;
2849          continue;          continue;
# Line 1959  while (!done) Line 2853  while (!done)
2853          continue;          continue;
2854    
2855          case 'N':          case 'N':
2856          options |= PCRE_NOTEMPTY;          if ((options & PCRE_NOTEMPTY) != 0)
2857              options = (options & ~PCRE_NOTEMPTY) | PCRE_NOTEMPTY_ATSTART;
2858            else
2859              options |= PCRE_NOTEMPTY;
2860          continue;          continue;
2861    
2862          case 'O':          case 'O':
# Line 1982  while (!done) Line 2879  while (!done)
2879          continue;          continue;
2880    
2881          case 'P':          case 'P':
2882          options |= PCRE_PARTIAL;          options |= ((options & PCRE_PARTIAL_SOFT) == 0)?
2883              PCRE_PARTIAL_SOFT : PCRE_PARTIAL_HARD;
2884          continue;          continue;
2885    
2886          case 'Q':          case 'Q':
# Line 2041  while (!done) Line 2939  while (!done)
2939        *q++ = c;        *q++ = c;
2940        }        }
2941      *q = 0;      *q = 0;
2942      len = q - dbuffer;      len = (int)(q - dbuffer);
2943    
2944      /* Move the data to the end of the buffer so that a read over the end of      /* Move the data to the end of the buffer so that a read over the end of
2945      the buffer will be seen by valgrind, even if it doesn't cause a crash. If      the buffer will be seen by valgrind, even if it doesn't cause a crash. If
# Line 2101  while (!done) Line 2999  while (!done)
2999            if (pmatch[i].rm_so >= 0)            if (pmatch[i].rm_so >= 0)
3000              {              {
3001              fprintf(outfile, "%2d: ", (int)i);              fprintf(outfile, "%2d: ", (int)i);
3002              (void)pchars(dbuffer + pmatch[i].rm_so,              PCHARSV(dbuffer + pmatch[i].rm_so,
3003                pmatch[i].rm_eo - pmatch[i].rm_so, outfile);                pmatch[i].rm_eo - pmatch[i].rm_so, outfile);
3004              fprintf(outfile, "\n");              fprintf(outfile, "\n");
3005              if (i == 0 && do_showrest)              if (do_showcaprest || (i == 0 && do_showrest))
3006                {                {
3007                fprintf(outfile, " 0+ ");                fprintf(outfile, "%2d+ ", (int)i);
3008                (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo,                PCHARSV(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo,
3009                  outfile);                  outfile);
3010                fprintf(outfile, "\n");                fprintf(outfile, "\n");
3011                }                }
# Line 2115  while (!done) Line 3013  while (!done)
3013            }            }
3014          }          }
3015        free(pmatch);        free(pmatch);
3016          goto NEXT_DATA;
3017        }        }
3018    
3019    #endif  /* !defined NOPOSIX */
3020    
3021      /* Handle matching via the native interface - repeats for /g and /G */      /* Handle matching via the native interface - repeats for /g and /G */
3022    
3023      else  #ifdef SUPPORT_PCRE16
3024  #endif  /* !defined NOPOSIX */      if (use_pcre16)
3025          {
3026          len = to16(bptr, (((real_pcre *)re)->options) & PCRE_UTF8, len);
3027          bptr = (pcre_uint8 *)buffer16;
3028          }
3029    #endif
3030    
3031      for (;; gmatched++)    /* Loop for /g or /G */      for (;; gmatched++)    /* Loop for /g or /G */
3032        {        {
3033          markptr = NULL;
3034    
3035        if (timeitm > 0)        if (timeitm > 0)
3036          {          {
3037          register int i;          register int i;
# Line 2135  while (!done) Line 3043  while (!done)
3043            {            {
3044            int workspace[1000];            int workspace[1000];
3045            for (i = 0; i < timeitm; i++)            for (i = 0; i < timeitm; i++)
3046              count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset,              count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset,
3047                options | g_notempty, use_offsets, use_size_offsets, workspace,                options | g_notempty, use_offsets, use_size_offsets, workspace,
3048                sizeof(workspace)/sizeof(int));                sizeof(workspace)/sizeof(int));
3049            }            }
# Line 2143  while (!done) Line 3051  while (!done)
3051  #endif  #endif
3052    
3053          for (i = 0; i < timeitm; i++)          for (i = 0; i < timeitm; i++)
3054            count = pcre_exec(re, extra, (char *)bptr, len,            {
3055              PCRE_EXEC(count, re, extra, bptr, len,
3056              start_offset, options | g_notempty, use_offsets, use_size_offsets);              start_offset, options | g_notempty, use_offsets, use_size_offsets);
3057              }
3058          time_taken = clock() - start_time;          time_taken = clock() - start_time;
3059          fprintf(outfile, "Execute time %.4f milliseconds\n",          fprintf(outfile, "Execute time %.4f milliseconds\n",
3060            (((double)time_taken * 1000.0) / (double)timeitm) /            (((double)time_taken * 1000.0) / (double)timeitm) /
# Line 2154  while (!done) Line 3063  while (!done)
3063    
3064        /* If find_match_limit is set, we want to do repeated matches with        /* If find_match_limit is set, we want to do repeated matches with
3065        varying limits in order to find the minimum value for the match limit and        varying limits in order to find the minimum value for the match limit and
3066        for the recursion limit. */        for the recursion limit. The match limits are relevant only to the normal
3067          running of pcre_exec(), so disable the JIT optimization. This makes it
3068          possible to run the same set of tests with and without JIT externally
3069          requested. */
3070    
3071        if (find_match_limit)        if (find_match_limit)
3072          {          {
# Line 2163  while (!done) Line 3075  while (!done)
3075            extra = (pcre_extra *)malloc(sizeof(pcre_extra));            extra = (pcre_extra *)malloc(sizeof(pcre_extra));
3076            extra->flags = 0;            extra->flags = 0;
3077            }            }
3078            else extra->flags &= ~PCRE_EXTRA_EXECUTABLE_JIT;
3079    
3080          (void)check_match_limit(re, extra, bptr, len, start_offset,          (void)check_match_limit(re, extra, bptr, len, start_offset,
3081            options|g_notempty, use_offsets, use_size_offsets,            options|g_notempty, use_offsets, use_size_offsets,
# Line 2186  while (!done) Line 3099  while (!done)
3099            }            }
3100          extra->flags |= PCRE_EXTRA_CALLOUT_DATA;          extra->flags |= PCRE_EXTRA_CALLOUT_DATA;
3101          extra->callout_data = &callout_data;          extra->callout_data = &callout_data;
3102          count = pcre_exec(re, extra, (char *)bptr, len, start_offset,          PCRE_EXEC(count, re, extra, bptr, len, start_offset,
3103            options | g_notempty, use_offsets, use_size_offsets);            options | g_notempty, use_offsets, use_size_offsets);
3104          extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;          extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;
3105          }          }
# Line 2198  while (!done) Line 3111  while (!done)
3111        else if (all_use_dfa || use_dfa)        else if (all_use_dfa || use_dfa)
3112          {          {
3113          int workspace[1000];          int workspace[1000];
3114          count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset,          count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset,
3115            options | g_notempty, use_offsets, use_size_offsets, workspace,            options | g_notempty, use_offsets, use_size_offsets, workspace,
3116            sizeof(workspace)/sizeof(int));            sizeof(workspace)/sizeof(int));
3117          if (count == 0)          if (count == 0)
# Line 2211  while (!done) Line 3124  while (!done)
3124    
3125        else        else
3126          {          {
3127          count = pcre_exec(re, extra, (char *)bptr, len,          PCRE_EXEC(count, re, extra, bptr, len, start_offset,
3128            start_offset, options | g_notempty, use_offsets, use_size_offsets);            options | g_notempty, use_offsets, use_size_offsets);
3129          if (count == 0)          if (count == 0)
3130            {            {
3131            fprintf(outfile, "Matched, but too many substrings\n");            fprintf(outfile, "Matched, but too many substrings\n");
# Line 2246  while (!done) Line 3159  while (!done)
3159              }              }
3160            }            }
3161    
3162            /* do_allcaps requests showing of all captures in the pattern, to check
3163            unset ones at the end. */
3164    
3165            if (do_allcaps)
3166              {
3167              new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);
3168              count++;   /* Allow for full match */
3169              if (count * 2 > use_size_offsets) count = use_size_offsets/2;
3170              }
3171    
3172            /* Output the captured substrings */
3173    
3174          for (i = 0; i < count * 2; i += 2)          for (i = 0; i < count * 2; i += 2)
3175            {            {
3176            if (use_offsets[i] < 0)            if (use_offsets[i] < 0)
3177                {
3178                if (use_offsets[i] != -1)
3179                  fprintf(outfile, "ERROR: bad negative value %d for offset %d\n",
3180                    use_offsets[i], i);
3181                if (use_offsets[i+1] != -1)
3182                  fprintf(outfile, "ERROR: bad negative value %d for offset %d\n",
3183                    use_offsets[i+1], i+1);
3184              fprintf(outfile, "%2d: <unset>\n", i/2);              fprintf(outfile, "%2d: <unset>\n", i/2);
3185                }
3186            else            else
3187              {              {
3188              fprintf(outfile, "%2d: ", i/2);              fprintf(outfile, "%2d: ", i/2);
3189              (void)pchars(bptr + use_offsets[i],              PCHARSV(bptr + use_offsets[i],
3190                use_offsets[i+1] - use_offsets[i], outfile);                use_offsets[i+1] - use_offsets[i], outfile);
3191              fprintf(outfile, "\n");              fprintf(outfile, "\n");
3192              if (i == 0)              if (do_showcaprest || (i == 0 && do_showrest))
3193                {                {
3194                if (do_showrest)                fprintf(outfile, "%2d+ ", i/2);
3195                  {                PCHARSV(bptr + use_offsets[i+1], len - use_offsets[i+1],
3196                  fprintf(outfile, " 0+ ");                  outfile);
3197                  (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1],                fprintf(outfile, "\n");
                   outfile);  
                 fprintf(outfile, "\n");  
                 }  
3198                }                }
3199              }              }
3200            }            }
3201    
3202            if (markptr != NULL) fprintf(outfile, "MK: %s\n", markptr);
3203    
3204          for (i = 0; i < 32; i++)          for (i = 0; i < 32; i++)
3205            {            {
3206            if ((copystrings & (1 << i)) != 0)            if ((copystrings & (1 << i)) != 0)
# Line 2342  while (!done) Line 3274  while (!done)
3274                fprintf(outfile, "%2dL %s\n", i, stringlist[i]);                fprintf(outfile, "%2dL %s\n", i, stringlist[i]);
3275              if (stringlist[i] != NULL)              if (stringlist[i] != NULL)
3276                fprintf(outfile, "string list not terminated by NULL\n");                fprintf(outfile, "string list not terminated by NULL\n");
             /* free((void *)stringlist); */  
3277              pcre_free_substring_list(stringlist);              pcre_free_substring_list(stringlist);
3278              }              }
3279            }            }
# Line 2352  while (!done) Line 3283  while (!done)
3283    
3284        else if (count == PCRE_ERROR_PARTIAL)        else if (count == PCRE_ERROR_PARTIAL)
3285          {          {
3286          fprintf(outfile, "Partial match");          if (markptr == NULL) fprintf(outfile, "Partial match");
3287  #if !defined NODFA            else fprintf(outfile, "Partial match, mark=%s", markptr);
3288          if ((all_use_dfa || use_dfa) && use_size_offsets > 2)          if (use_size_offsets > 1)
3289            fprintf(outfile, ": %.*s", use_offsets[1] - use_offsets[0],            {
3290              bptr + use_offsets[0]);            fprintf(outfile, ": ");
3291  #endif            PCHARSV(bptr + use_offsets[0], use_offsets[1] - use_offsets[0],
3292                outfile);
3293              }
3294          fprintf(outfile, "\n");          fprintf(outfile, "\n");
3295          break;  /* Out of the /g loop */          break;  /* Out of the /g loop */
3296          }          }
# Line 2367  while (!done) Line 3300  while (!done)
3300        to advance the start offset, and continue. We won't be at the end of the        to advance the start offset, and continue. We won't be at the end of the
3301        string - that was checked before setting g_notempty.        string - that was checked before setting g_notempty.
3302    
3303        Complication arises in the case when the newline option is "any" or        Complication arises in the case when the newline convention is "any",
3304        "anycrlf". If the previous match was at the end of a line terminated by        "crlf", or "anycrlf". If the previous match was at the end of a line
3305        CRLF, an advance of one character just passes the \r, whereas we should        terminated by CRLF, an advance of one character just passes the \r,
3306        prefer the longer newline sequence, as does the code in pcre_exec().        whereas we should prefer the longer newline sequence, as does the code in
3307        Fudge the offset value to achieve this.        pcre_exec(). Fudge the offset value to achieve this. We check for a
3308          newline setting in the pattern; if none was set, use pcre_config() to
3309          find the default.
3310    
3311        Otherwise, in the case of UTF-8 matching, the advance must be one        Otherwise, in the case of UTF-8 matching, the advance must be one
3312        character, not one byte. */        character, not one byte. */
# Line 2396  while (!done) Line 3331  while (!done)
3331                      (d == -1)? PCRE_NEWLINE_ANY : 0;                      (d == -1)? PCRE_NEWLINE_ANY : 0;
3332              }              }
3333            if (((obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANY ||            if (((obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANY ||
3334                   (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_CRLF ||
3335                 (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANYCRLF)                 (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANYCRLF)
3336                &&                &&
3337                start_offset < len - 1 &&                start_offset < len - 1 &&
# Line 2406  while (!done) Line 3342  while (!done)
3342              {              {
3343              while (start_offset + onechar < len)              while (start_offset + onechar < len)
3344                {                {
3345                int tb = bptr[start_offset+onechar];                if ((bptr[start_offset+onechar] & 0xc0) != 0x80) break;
3346                if (tb <= 127) break;                onechar++;
               tb &= 0xc0;  
               if (tb != 0 && tb != 0xc0) onechar++;  
3347                }                }
3348              }              }
3349            use_offsets[1] = start_offset + onechar;            use_offsets[1] = start_offset + onechar;
3350            }            }
3351          else          else
3352            {            {
3353            if (count == PCRE_ERROR_NOMATCH)            switch(count)
3354              {              {
3355              if (gmatched == 0) fprintf(outfile, "No match\n");              case PCRE_ERROR_NOMATCH:
3356                if (gmatched == 0)
3357                  {
3358                  if (markptr == NULL) fprintf(outfile, "No match\n");
3359                    else fprintf(outfile, "No match, mark = %s\n", markptr);
3360                  }
3361                break;
3362    
3363                case PCRE_ERROR_BADUTF8:
3364                case PCRE_ERROR_SHORTUTF8:
3365                fprintf(outfile, "Error %d (%s UTF-8 string)", count,
3366                  (count == PCRE_ERROR_BADUTF8)? "bad" : "short");
3367                if (use_size_offsets >= 2)
3368                  fprintf(outfile, " offset=%d reason=%d", use_offsets[0],
3369                    use_offsets[1]);
3370                fprintf(outfile, "\n");
3371                break;
3372    
3373                default:
3374                if (count < 0 && (-count) < sizeof(errtexts)/sizeof(const char *))
3375                  fprintf(outfile, "Error %d (%s)\n", count, errtexts[-count]);
3376                else
3377                  fprintf(outfile, "Error %d (Unexpected value)\n", count);
3378                break;
3379              }              }
3380            else fprintf(outfile, "Error %d\n", count);  
3381            break;  /* Out of the /g loop */            break;  /* Out of the /g loop */
3382            }            }
3383          }          }
# Line 2430  while (!done) Line 3387  while (!done)
3387        if (!do_g && !do_G) break;        if (!do_g && !do_G) break;
3388    
3389        /* If we have matched an empty string, first check to see if we are at        /* If we have matched an empty string, first check to see if we are at
3390        the end of the subject. If so, the /g loop is over. Otherwise, mimic        the end of the subject. If so, the /g loop is over. Otherwise, mimic what
3391        what Perl's /g options does. This turns out to be rather cunning. First        Perl's /g options does. This turns out to be rather cunning. First we set
3392        we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the        PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED and try the match again at the
3393        same point. If this fails (picked up above) we advance to the next        same point. If this fails (picked up above) we advance to the next
3394        character. */        character. */
3395    
# Line 2441  while (!done) Line 3398  while (!done)
3398        if (use_offsets[0] == use_offsets[1])        if (use_offsets[0] == use_offsets[1])
3399          {          {
3400          if (use_offsets[0] == len) break;          if (use_offsets[0] == len) break;
3401          g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED;          g_notempty = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED;
3402          }          }
3403    
3404        /* For /g, update the start offset, leaving the rest alone */        /* For /g, update the start offset, leaving the rest alone */
# Line 2467  while (!done) Line 3424  while (!done)
3424  #endif  #endif
3425    
3426    if (re != NULL) new_free(re);    if (re != NULL) new_free(re);
3427    if (extra != NULL) new_free(extra);    if (extra != NULL) pcre_free_study(extra);
3428    if (tables != NULL)    if (locale_set)
3429      {      {
3430      new_free((void *)tables);      new_free((void *)tables);
3431      setlocale(LC_CTYPE, "C");      setlocale(LC_CTYPE, "C");
3432      locale_set = 0;      locale_set = 0;
3433      }      }
3434      if (jit_stack != NULL)
3435        {
3436        pcre_jit_stack_free(jit_stack);
3437        jit_stack = NULL;
3438        }
3439    }    }
3440    
3441  if (infile == stdin) fprintf(outfile, "\n");  if (infile == stdin) fprintf(outfile, "\n");
# Line 2488  free(dbuffer); Line 3450  free(dbuffer);
3450  free(pbuffer);  free(pbuffer);
3451  free(offsets);  free(offsets);
3452    
3453    #ifdef SUPPORT_PCRE16
3454    if (buffer16 != NULL) free(buffer16);
3455    #endif
3456    
3457  return yield;  return yield;
3458  }  }
3459    

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

  ViewVC Help
Powered by ViewVC 1.1.5