/[pcre]/code/trunk/pcretest.c
ViewVC logotype

Diff of /code/trunk/pcretest.c

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

revision 689 by ph10, Fri Sep 9 10:34:57 2011 UTC revision 1126 by chpe, Thu Oct 18 18:35:01 2012 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 35  POSSIBILITY OF SUCH DAMAGE. Line 36  POSSIBILITY OF SUCH DAMAGE.
36  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
37  */  */
38    
39    /* This program now supports the testing of both the 8-bit and 16-bit PCRE
40    libraries in a single program. This is different from the modules such as
41    pcre_compile.c in the library itself, which are compiled separately for each
42    mode. If both modes are enabled, for example, pcre_compile.c is compiled twice
43    (the second time with COMPILE_PCRE16 defined). By contrast, pcretest.c is
44    compiled only once. Therefore, it must not make use of any of the macros from
45    pcre_internal.h that depend on COMPILE_PCRE8 or COMPILE_PCRE16. It does,
46    however, make use of SUPPORT_PCRE8 and SUPPORT_PCRE16 to ensure that it calls
47    only supported library functions. */
48    
49  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
50  #include "config.h"  #include "config.h"
# Line 48  POSSIBILITY OF SUCH DAMAGE. Line 58  POSSIBILITY OF SUCH DAMAGE.
58  #include <locale.h>  #include <locale.h>
59  #include <errno.h>  #include <errno.h>
60    
61  #ifdef SUPPORT_LIBREADLINE  /* Both libreadline and libedit are optionally supported. The user-supplied
62    original patch uses readline/readline.h for libedit, but in at least one system
63    it is installed as editline/readline.h, so the configuration code now looks for
64    that first, falling back to readline/readline.h. */
65    
66    #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
67  #ifdef HAVE_UNISTD_H  #ifdef HAVE_UNISTD_H
68  #include <unistd.h>  #include <unistd.h>
69  #endif  #endif
70    #if defined(SUPPORT_LIBREADLINE)
71  #include <readline/readline.h>  #include <readline/readline.h>
72  #include <readline/history.h>  #include <readline/history.h>
73    #else
74    #if defined(HAVE_EDITLINE_READLINE_H)
75    #include <editline/readline.h>
76    #else
77    #include <readline/readline.h>
78    #endif
79    #endif
80  #endif  #endif
   
81    
82  /* A number of things vary for Windows builds. Originally, pcretest opened its  /* A number of things vary for Windows builds. Originally, pcretest opened its
83  input and output without "b"; then I was told that "b" was needed in some  input and output without "b"; then I was told that "b" was needed in some
# Line 90  input mode under Windows. */ Line 112  input mode under Windows. */
112  #else  #else
113  #include <sys/time.h>          /* These two includes are needed */  #include <sys/time.h>          /* These two includes are needed */
114  #include <sys/resource.h>      /* for setrlimit(). */  #include <sys/resource.h>      /* for setrlimit(). */
115    #if defined NATIVE_ZOS         /* z/OS uses non-binary I/O */
116    #define INPUT_MODE   "r"
117    #define OUTPUT_MODE  "w"
118    #else
119  #define INPUT_MODE   "rb"  #define INPUT_MODE   "rb"
120  #define OUTPUT_MODE  "wb"  #define OUTPUT_MODE  "wb"
121  #endif  #endif
122    #endif
123    
124    #define PRIV(name) name
125    
126  /* We have to include pcre_internal.h because we need the internal info for  /* We have to include pcre_internal.h because we need the internal info for
127  displaying the results of pcre_study() and we also need to know about the  displaying the results of pcre_study() and we also need to know about the
# Line 105  here before pcre_internal.h so that the Line 133  here before pcre_internal.h so that the
133  appropriately for an application, not for building PCRE. */  appropriately for an application, not for building PCRE. */
134    
135  #include "pcre.h"  #include "pcre.h"
136    
137    #if defined SUPPORT_PCRE32 && !defined SUPPORT_PCRE8 && !defined SUPPORT_PCRE16
138    /* Configure internal macros to 32 bit mode. */
139    #define COMPILE_PCRE32
140    #endif
141    #if defined SUPPORT_PCRE16 && !defined SUPPORT_PCRE8 && !defined SUPPORT_PCRE32
142    /* Configure internal macros to 16 bit mode. */
143    #define COMPILE_PCRE16
144    #endif
145    #if defined SUPPORT_PCRE8 && !defined SUPPORT_PCRE16 && !defined SUPPORT_PCRE32
146    /* Configure internal macros to 16 bit mode. */
147    #define COMPILE_PCRE8
148    #endif
149    
150  #include "pcre_internal.h"  #include "pcre_internal.h"
151    
152    /* The pcre_printint() function, which prints the internal form of a compiled
153    regex, is held in a separate file so that (a) it can be compiled in either
154    8-, 16- or 32-bit mode, and (b) it can be #included directly in pcre_compile.c
155    when that is compiled in debug mode. */
156    
157    #ifdef SUPPORT_PCRE8
158    void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
159    #endif
160    #ifdef SUPPORT_PCRE16
161    void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths);
162    #endif
163    #ifdef SUPPORT_PCRE32
164    void pcre32_printint(pcre *external_re, FILE *f, BOOL print_lengths);
165    #endif
166    
167  /* 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
168  to keep two copies, we include the source file here, changing the names of the  to keep two copies, we include the source files here, changing the names of the
169  external symbols to prevent clashes. */  external symbols to prevent clashes. */
170    
171  #define _pcre_ucp_gentype      ucp_gentype  #define PCRE_INCLUDED
 #define _pcre_ucp_typerange    ucp_typerange  
 #define _pcre_utf8_table1      utf8_table1  
 #define _pcre_utf8_table1_size utf8_table1_size  
 #define _pcre_utf8_table2      utf8_table2  
 #define _pcre_utf8_table3      utf8_table3  
 #define _pcre_utf8_table4      utf8_table4  
 #define _pcre_utf8_char_sizes  utf8_char_sizes  
 #define _pcre_utt              utt  
 #define _pcre_utt_size         utt_size  
 #define _pcre_utt_names        utt_names  
 #define _pcre_OP_lengths       OP_lengths  
172    
173  #include "pcre_tables.c"  #include "pcre_tables.c"
174    #include "pcre_ucd.c"
 /* We also need the pcre_printint() function for printing out compiled  
 patterns. This function is in a separate file so that it can be included in  
 pcre_compile.c when that module is compiled with debugging enabled. It needs to  
 know which case is being compiled. */  
   
 #define COMPILING_PCRETEST  
 #include "pcre_printint.src"  
175    
176  /* The definition of the macro PRINTABLE, which determines whether to print an  /* The definition of the macro PRINTABLE, which determines whether to print an
177  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
178  contained in the printint.src file. We uses it here also, in cases when the  the same as in the printint.src file. We uses it here in cases when the locale
179  locale has not been explicitly changed, so as to get consistent output from  has not been explicitly changed, so as to get consistent output from systems
180  systems that differ in their output from isprint() even in the "C" locale. */  that differ in their output from isprint() even in the "C" locale. */
181    
182    #ifdef EBCDIC
183    #define PRINTABLE(c) ((c) >= 64 && (c) < 255)
184    #else
185    #define PRINTABLE(c) ((c) >= 32 && (c) < 127)
186    #endif
187    
188    #define PRINTOK(c) (locale_set? isprint(c) : PRINTABLE(c))
189    
190  #define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c))  /* Posix support is disabled in 16 or 32 bit only mode. */
191    #if !defined SUPPORT_PCRE8 && !defined NOPOSIX
192    #define NOPOSIX
193    #endif
194    
195  /* It is possible to compile this test program without including support for  /* It is possible to compile this test program without including support for
196  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 150  Makefile. */ Line 200  Makefile. */
200  #include "pcreposix.h"  #include "pcreposix.h"
201  #endif  #endif
202    
203  /* 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
204  Exim, to build pcretest without support for UTF8 (define NOUTF8), without the  imported into Exim, to build pcretest without support for UTF8 or UTF16 (define
205  interface to the DFA matcher (NODFA), and without the doublecheck of the old  NOUTF), without the interface to the DFA matcher (NODFA). In fact, we
206  "info" function (define NOINFOCHECK). In fact, we automatically cut out the  automatically cut out the UTF support if PCRE is built without it. */
207  UTF8 support if PCRE is built without it. */  
208    #ifndef SUPPORT_UTF
209  #ifndef SUPPORT_UTF8  #ifndef NOUTF
210  #ifndef NOUTF8  #define NOUTF
211  #define NOUTF8  #endif
212    #endif
213    
214    /* To make the code a bit tidier for 8/16/32-bit support, we define macros
215    for all the pcre[16]_xxx functions (except pcre16_fullinfo, which is called
216    only from one place and is handled differently). I couldn't dream up any way of
217    using a single macro to do this in a generic way, because of the many different
218    argument requirements. We know that at least one of SUPPORT_PCRE8 and
219    SUPPORT_PCRE16 must be set. First define macros for each individual mode; then
220    use these in the definitions of generic macros.
221    
222    **** Special note about the PCHARSxxx macros: the address of the string to be
223    printed is always given as two arguments: a base address followed by an offset.
224    The base address is cast to the correct data size for 8 or 16 bit data; the
225    offset is in units of this size. If the string were given as base+offset in one
226    argument, the casting might be incorrectly applied. */
227    
228    #ifdef SUPPORT_PCRE8
229    
230    #define PCHARS8(lv, p, offset, len, f) \
231      lv = pchars((pcre_uint8 *)(p) + offset, len, f)
232    
233    #define PCHARSV8(p, offset, len, f) \
234      (void)pchars((pcre_uint8 *)(p) + offset, len, f)
235    
236    #define READ_CAPTURE_NAME8(p, cn8, cn16, cn32, re) \
237      p = read_capture_name8(p, cn8, re)
238    
239    #define STRLEN8(p) ((int)strlen((char *)p))
240    
241    #define SET_PCRE_CALLOUT8(callout) \
242      pcre_callout = callout
243    
244    #define PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata) \
245       pcre_assign_jit_stack(extra, callback, userdata)
246    
247    #define PCRE_COMPILE8(re, pat, options, error, erroffset, tables) \
248      re = pcre_compile((char *)pat, options, error, erroffset, tables)
249    
250    #define PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
251        namesptr, cbuffer, size) \
252      rc = pcre_copy_named_substring(re, (char *)bptr, offsets, count, \
253        (char *)namesptr, cbuffer, size)
254    
255    #define PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size) \
256      rc = pcre_copy_substring((char *)bptr, offsets, count, i, cbuffer, size)
257    
258    #define PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \
259        offsets, size_offsets, workspace, size_workspace) \
260      count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset, options, \
261        offsets, size_offsets, workspace, size_workspace)
262    
263    #define PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
264        offsets, size_offsets) \
265      count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, \
266        offsets, size_offsets)
267    
268    #define PCRE_FREE_STUDY8(extra) \
269      pcre_free_study(extra)
270    
271    #define PCRE_FREE_SUBSTRING8(substring) \
272      pcre_free_substring(substring)
273    
274    #define PCRE_FREE_SUBSTRING_LIST8(listptr) \
275      pcre_free_substring_list(listptr)
276    
277    #define PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
278        getnamesptr, subsptr) \
279      rc = pcre_get_named_substring(re, (char *)bptr, offsets, count, \
280        (char *)getnamesptr, subsptr)
281    
282    #define PCRE_GET_STRINGNUMBER8(n, rc, ptr) \
283      n = pcre_get_stringnumber(re, (char *)ptr)
284    
285    #define PCRE_GET_SUBSTRING8(rc, bptr, offsets, count, i, subsptr) \
286      rc = pcre_get_substring((char *)bptr, offsets, count, i, subsptr)
287    
288    #define PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr) \
289      rc = pcre_get_substring_list((const char *)bptr, offsets, count, listptr)
290    
291    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables) \
292      rc = pcre_pattern_to_host_byte_order(re, extra, tables)
293    
294    #define PCRE_PRINTINT8(re, outfile, debug_lengths) \
295      pcre_printint(re, outfile, debug_lengths)
296    
297    #define PCRE_STUDY8(extra, re, options, error) \
298      extra = pcre_study(re, options, error)
299    
300    #define PCRE_JIT_STACK_ALLOC8(startsize, maxsize) \
301      pcre_jit_stack_alloc(startsize, maxsize)
302    
303    #define PCRE_JIT_STACK_FREE8(stack) \
304      pcre_jit_stack_free(stack)
305    
306    #endif /* SUPPORT_PCRE8 */
307    
308    /* -----------------------------------------------------------*/
309    
310    #ifdef SUPPORT_PCRE16
311    
312    #define PCHARS16(lv, p, offset, len, f) \
313      lv = pchars16((PCRE_SPTR16)(p) + offset, len, f)
314    
315    #define PCHARSV16(p, offset, len, f) \
316      (void)pchars16((PCRE_SPTR16)(p) + offset, len, f)
317    
318    #define READ_CAPTURE_NAME16(p, cn8, cn16, cn32, re) \
319      p = read_capture_name16(p, cn16, re)
320    
321    #define STRLEN16(p) ((int)strlen16((PCRE_SPTR16)p))
322    
323    #define SET_PCRE_CALLOUT16(callout) \
324      pcre16_callout = (int (*)(pcre16_callout_block *))callout
325    
326    #define PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata) \
327      pcre16_assign_jit_stack((pcre16_extra *)extra, \
328        (pcre16_jit_callback)callback, userdata)
329    
330    #define PCRE_COMPILE16(re, pat, options, error, erroffset, tables) \
331      re = (pcre *)pcre16_compile((PCRE_SPTR16)pat, options, error, erroffset, \
332        tables)
333    
334    #define PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
335        namesptr, cbuffer, size) \
336      rc = pcre16_copy_named_substring((pcre16 *)re, (PCRE_SPTR16)bptr, offsets, \
337        count, (PCRE_SPTR16)namesptr, (PCRE_UCHAR16 *)cbuffer, size/2)
338    
339    #define PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size) \
340      rc = pcre16_copy_substring((PCRE_SPTR16)bptr, offsets, count, i, \
341        (PCRE_UCHAR16 *)cbuffer, size/2)
342    
343    #define PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \
344        offsets, size_offsets, workspace, size_workspace) \
345      count = pcre16_dfa_exec((pcre16 *)re, (pcre16_extra *)extra, \
346        (PCRE_SPTR16)bptr, len, start_offset, options, offsets, size_offsets, \
347        workspace, size_workspace)
348    
349    #define PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
350        offsets, size_offsets) \
351      count = pcre16_exec((pcre16 *)re, (pcre16_extra *)extra, (PCRE_SPTR16)bptr, \
352        len, start_offset, options, offsets, size_offsets)
353    
354    #define PCRE_FREE_STUDY16(extra) \
355      pcre16_free_study((pcre16_extra *)extra)
356    
357    #define PCRE_FREE_SUBSTRING16(substring) \
358      pcre16_free_substring((PCRE_SPTR16)substring)
359    
360    #define PCRE_FREE_SUBSTRING_LIST16(listptr) \
361      pcre16_free_substring_list((PCRE_SPTR16 *)listptr)
362    
363    #define PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
364        getnamesptr, subsptr) \
365      rc = pcre16_get_named_substring((pcre16 *)re, (PCRE_SPTR16)bptr, offsets, \
366        count, (PCRE_SPTR16)getnamesptr, (PCRE_SPTR16 *)(void*)subsptr)
367    
368    #define PCRE_GET_STRINGNUMBER16(n, rc, ptr) \
369      n = pcre16_get_stringnumber(re, (PCRE_SPTR16)ptr)
370    
371    #define PCRE_GET_SUBSTRING16(rc, bptr, offsets, count, i, subsptr) \
372      rc = pcre16_get_substring((PCRE_SPTR16)bptr, offsets, count, i, \
373        (PCRE_SPTR16 *)(void*)subsptr)
374    
375    #define PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr) \
376      rc = pcre16_get_substring_list((PCRE_SPTR16)bptr, offsets, count, \
377        (PCRE_SPTR16 **)(void*)listptr)
378    
379    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables) \
380      rc = pcre16_pattern_to_host_byte_order((pcre16 *)re, (pcre16_extra *)extra, \
381        tables)
382    
383    #define PCRE_PRINTINT16(re, outfile, debug_lengths) \
384      pcre16_printint(re, outfile, debug_lengths)
385    
386    #define PCRE_STUDY16(extra, re, options, error) \
387      extra = (pcre_extra *)pcre16_study((pcre16 *)re, options, error)
388    
389    #define PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \
390      (pcre_jit_stack *)pcre16_jit_stack_alloc(startsize, maxsize)
391    
392    #define PCRE_JIT_STACK_FREE16(stack) \
393      pcre16_jit_stack_free((pcre16_jit_stack *)stack)
394    
395    #endif /* SUPPORT_PCRE16 */
396    
397    /* -----------------------------------------------------------*/
398    
399    #ifdef SUPPORT_PCRE32
400    
401    #define PCHARS32(lv, p, offset, len, f) \
402      lv = pchars32((PCRE_SPTR32)(p) + offset, len, use_utf, f)
403    
404    #define PCHARSV32(p, offset, len, f)                \
405      (void)pchars32((PCRE_SPTR32)(p) + offset, len, use_utf, f)
406    
407    #define READ_CAPTURE_NAME32(p, cn8, cn16, cn32, re) \
408      p = read_capture_name32(p, cn32, re)
409    
410    #define STRLEN32(p) ((int)strlen32((PCRE_SPTR32)p))
411    
412    #define SET_PCRE_CALLOUT32(callout) \
413      pcre32_callout = (int (*)(pcre32_callout_block *))callout
414    
415    #define PCRE_ASSIGN_JIT_STACK32(extra, callback, userdata) \
416      pcre32_assign_jit_stack((pcre32_extra *)extra, \
417        (pcre32_jit_callback)callback, userdata)
418    
419    #define PCRE_COMPILE32(re, pat, options, error, erroffset, tables) \
420      re = (pcre *)pcre32_compile((PCRE_SPTR32)pat, options, error, erroffset, \
421        tables)
422    
423    #define PCRE_COPY_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \
424        namesptr, cbuffer, size) \
425      rc = pcre32_copy_named_substring((pcre32 *)re, (PCRE_SPTR32)bptr, offsets, \
426        count, (PCRE_SPTR32)namesptr, (PCRE_UCHAR32 *)cbuffer, size/2)
427    
428    #define PCRE_COPY_SUBSTRING32(rc, bptr, offsets, count, i, cbuffer, size) \
429      rc = pcre32_copy_substring((PCRE_SPTR32)bptr, offsets, count, i, \
430        (PCRE_UCHAR32 *)cbuffer, size/2)
431    
432    #define PCRE_DFA_EXEC32(count, re, extra, bptr, len, start_offset, options, \
433        offsets, size_offsets, workspace, size_workspace) \
434      count = pcre32_dfa_exec((pcre32 *)re, (pcre32_extra *)extra, \
435        (PCRE_SPTR32)bptr, len, start_offset, options, offsets, size_offsets, \
436        workspace, size_workspace)
437    
438    #define PCRE_EXEC32(count, re, extra, bptr, len, start_offset, options, \
439        offsets, size_offsets) \
440      count = pcre32_exec((pcre32 *)re, (pcre32_extra *)extra, (PCRE_SPTR32)bptr, \
441        len, start_offset, options, offsets, size_offsets)
442    
443    #define PCRE_FREE_STUDY32(extra) \
444      pcre32_free_study((pcre32_extra *)extra)
445    
446    #define PCRE_FREE_SUBSTRING32(substring) \
447      pcre32_free_substring((PCRE_SPTR32)substring)
448    
449    #define PCRE_FREE_SUBSTRING_LIST32(listptr) \
450      pcre32_free_substring_list((PCRE_SPTR32 *)listptr)
451    
452    #define PCRE_GET_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \
453        getnamesptr, subsptr) \
454      rc = pcre32_get_named_substring((pcre32 *)re, (PCRE_SPTR32)bptr, offsets, \
455        count, (PCRE_SPTR32)getnamesptr, (PCRE_SPTR32 *)(void*)subsptr)
456    
457    #define PCRE_GET_STRINGNUMBER32(n, rc, ptr) \
458      n = pcre32_get_stringnumber(re, (PCRE_SPTR32)ptr)
459    
460    #define PCRE_GET_SUBSTRING32(rc, bptr, offsets, count, i, subsptr) \
461      rc = pcre32_get_substring((PCRE_SPTR32)bptr, offsets, count, i, \
462        (PCRE_SPTR32 *)(void*)subsptr)
463    
464    #define PCRE_GET_SUBSTRING_LIST32(rc, bptr, offsets, count, listptr) \
465      rc = pcre32_get_substring_list((PCRE_SPTR32)bptr, offsets, count, \
466        (PCRE_SPTR32 **)(void*)listptr)
467    
468    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER32(rc, re, extra, tables) \
469      rc = pcre32_pattern_to_host_byte_order((pcre32 *)re, (pcre32_extra *)extra, \
470        tables)
471    
472    #define PCRE_PRINTINT32(re, outfile, debug_lengths) \
473      pcre32_printint(re, outfile, debug_lengths)
474    
475    #define PCRE_STUDY32(extra, re, options, error) \
476      extra = (pcre_extra *)pcre32_study((pcre32 *)re, options, error)
477    
478    #define PCRE_JIT_STACK_ALLOC32(startsize, maxsize) \
479      (pcre_jit_stack *)pcre32_jit_stack_alloc(startsize, maxsize)
480    
481    #define PCRE_JIT_STACK_FREE32(stack) \
482      pcre32_jit_stack_free((pcre32_jit_stack *)stack)
483    
484    #endif /* SUPPORT_PCRE32 */
485    
486    
487    /* ----- More than one mode is supported; a runtime test is needed, except for
488    pcre_config(), and the JIT stack functions, when it doesn't matter which
489    version is called. ----- */
490    
491    enum {
492      PCRE8_MODE,
493      PCRE16_MODE,
494      PCRE32_MODE
495    };
496    
497    #if (defined (SUPPORT_PCRE8) + defined (SUPPORT_PCRE16) + \
498         defined (SUPPORT_PCRE32)) >= 2
499    
500    #define CHAR_SIZE (1 << pcre_mode)
501    
502    /* There doesn't seem to be an easy way of writing these macros that can cope
503    with the 3 pairs of bit sizes plus all three bit sizes. So just handle all the
504    cases separately. */
505    
506    /* ----- All three modes supported ----- */
507    
508    #if defined(SUPPORT_PCRE8) && defined(SUPPORT_PCRE16) && defined(SUPPORT_PCRE32)
509    
510    #define PCHARS(lv, p, offset, len, f) \
511      if (pcre_mode == PCRE32_MODE) \
512        PCHARS32(lv, p, offset, len, f); \
513      else if (pcre_mode == PCRE16_MODE) \
514        PCHARS16(lv, p, offset, len, f); \
515      else \
516        PCHARS8(lv, p, offset, len, f)
517    
518    #define PCHARSV(p, offset, len, f) \
519      if (pcre_mode == PCRE32_MODE) \
520        PCHARSV32(p, offset, len, f); \
521      else if (pcre_mode == PCRE16_MODE) \
522        PCHARSV16(p, offset, len, f); \
523      else \
524        PCHARSV8(p, offset, len, f)
525    
526    #define READ_CAPTURE_NAME(p, cn8, cn16, cn32, re) \
527      if (pcre_mode == PCRE32_MODE) \
528        READ_CAPTURE_NAME32(p, cn8, cn16, cn32, re); \
529      else if (pcre_mode == PCRE16_MODE) \
530        READ_CAPTURE_NAME16(p, cn8, cn16, cn32, re); \
531      else \
532        READ_CAPTURE_NAME8(p, cn8, cn16, cn32, re)
533    
534    #define SET_PCRE_CALLOUT(callout) \
535      if (pcre_mode == PCRE32_MODE) \
536        SET_PCRE_CALLOUT32(callout); \
537      else if (pcre_mode == PCRE16_MODE) \
538        SET_PCRE_CALLOUT16(callout); \
539      else \
540        SET_PCRE_CALLOUT8(callout)
541    
542    #define STRLEN(p) (pcre_mode == PCRE32_MODE ? STRLEN32(p) : pcre_mode == PCRE16_MODE ? STRLEN16(p) : STRLEN8(p))
543    
544    #define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \
545      if (pcre_mode == PCRE32_MODE) \
546        PCRE_ASSIGN_JIT_STACK32(extra, callback, userdata); \
547      else if (pcre_mode == PCRE16_MODE) \
548        PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata); \
549      else \
550        PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata)
551    
552    #define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \
553      if (pcre_mode == PCRE32_MODE) \
554        PCRE_COMPILE32(re, pat, options, error, erroffset, tables); \
555      else if (pcre_mode == PCRE16_MODE) \
556        PCRE_COMPILE16(re, pat, options, error, erroffset, tables); \
557      else \
558        PCRE_COMPILE8(re, pat, options, error, erroffset, tables)
559    
560    #define PCRE_CONFIG pcre_config
561    
562    #define PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
563        namesptr, cbuffer, size) \
564      if (pcre_mode == PCRE32_MODE) \
565        PCRE_COPY_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \
566          namesptr, cbuffer, size); \
567      else if (pcre_mode == PCRE16_MODE) \
568        PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
569          namesptr, cbuffer, size); \
570      else \
571        PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
572          namesptr, cbuffer, size)
573    
574    #define PCRE_COPY_SUBSTRING(rc, bptr, offsets, count, i, cbuffer, size) \
575      if (pcre_mode == PCRE32_MODE) \
576        PCRE_COPY_SUBSTRING32(rc, bptr, offsets, count, i, cbuffer, size); \
577      else if (pcre_mode == PCRE16_MODE) \
578        PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size); \
579      else \
580        PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size)
581    
582    #define PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, options, \
583        offsets, size_offsets, workspace, size_workspace) \
584      if (pcre_mode == PCRE32_MODE) \
585        PCRE_DFA_EXEC32(count, re, extra, bptr, len, start_offset, options, \
586          offsets, size_offsets, workspace, size_workspace); \
587      else if (pcre_mode == PCRE16_MODE) \
588        PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \
589          offsets, size_offsets, workspace, size_workspace); \
590      else \
591        PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \
592          offsets, size_offsets, workspace, size_workspace)
593    
594    #define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \
595        offsets, size_offsets) \
596      if (pcre_mode == PCRE32_MODE) \
597        PCRE_EXEC32(count, re, extra, bptr, len, start_offset, options, \
598          offsets, size_offsets); \
599      else if (pcre_mode == PCRE16_MODE) \
600        PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
601          offsets, size_offsets); \
602      else \
603        PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
604          offsets, size_offsets)
605    
606    #define PCRE_FREE_STUDY(extra) \
607      if (pcre_mode == PCRE32_MODE) \
608        PCRE_FREE_STUDY32(extra); \
609      else if (pcre_mode == PCRE16_MODE) \
610        PCRE_FREE_STUDY16(extra); \
611      else \
612        PCRE_FREE_STUDY8(extra)
613    
614    #define PCRE_FREE_SUBSTRING(substring) \
615      if (pcre_mode == PCRE32_MODE) \
616        PCRE_FREE_SUBSTRING32(substring); \
617      else if (pcre_mode == PCRE16_MODE) \
618        PCRE_FREE_SUBSTRING16(substring); \
619      else \
620        PCRE_FREE_SUBSTRING8(substring)
621    
622    #define PCRE_FREE_SUBSTRING_LIST(listptr) \
623      if (pcre_mode == PCRE32_MODE) \
624        PCRE_FREE_SUBSTRING_LIST32(listptr); \
625      else if (pcre_mode == PCRE16_MODE) \
626        PCRE_FREE_SUBSTRING_LIST16(listptr); \
627      else \
628        PCRE_FREE_SUBSTRING_LIST8(listptr)
629    
630    #define PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
631        getnamesptr, subsptr) \
632      if (pcre_mode == PCRE32_MODE) \
633        PCRE_GET_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \
634          getnamesptr, subsptr); \
635      else if (pcre_mode == PCRE16_MODE) \
636        PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
637          getnamesptr, subsptr); \
638      else \
639        PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
640          getnamesptr, subsptr)
641    
642    #define PCRE_GET_STRINGNUMBER(n, rc, ptr) \
643      if (pcre_mode == PCRE32_MODE) \
644        PCRE_GET_STRINGNUMBER32(n, rc, ptr); \
645      else if (pcre_mode == PCRE16_MODE) \
646        PCRE_GET_STRINGNUMBER16(n, rc, ptr); \
647      else \
648        PCRE_GET_STRINGNUMBER8(n, rc, ptr)
649    
650    #define PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, subsptr) \
651      if (pcre_mode == PCRE32_MODE) \
652        PCRE_GET_SUBSTRING32(rc, bptr, use_offsets, count, i, subsptr); \
653      else if (pcre_mode == PCRE16_MODE) \
654        PCRE_GET_SUBSTRING16(rc, bptr, use_offsets, count, i, subsptr); \
655      else \
656        PCRE_GET_SUBSTRING8(rc, bptr, use_offsets, count, i, subsptr)
657    
658    #define PCRE_GET_SUBSTRING_LIST(rc, bptr, offsets, count, listptr) \
659      if (pcre_mode == PCRE32_MODE) \
660        PCRE_GET_SUBSTRING_LIST32(rc, bptr, offsets, count, listptr); \
661      else if (pcre_mode == PCRE16_MODE) \
662        PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr); \
663      else \
664        PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr)
665    
666    #define PCRE_JIT_STACK_ALLOC(startsize, maxsize) \
667      (pcre_mode == PCRE32_MODE ? \
668         PCRE_JIT_STACK_ALLOC32(startsize, maxsize) \
669        : pcre_mode == PCRE16_MODE ? \
670          PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \
671          : PCRE_JIT_STACK_ALLOC8(startsize, maxsize))
672    
673    #define PCRE_JIT_STACK_FREE(stack) \
674      if (pcre_mode == PCRE32_MODE) \
675        PCRE_JIT_STACK_FREE32(stack); \
676      else if (pcre_mode == PCRE16_MODE) \
677        PCRE_JIT_STACK_FREE16(stack); \
678      else \
679        PCRE_JIT_STACK_FREE8(stack)
680    
681    #define PCRE_MAKETABLES \
682      (pcre_mode == PCRE32_MODE ? pcre32_maketables() : pcre_mode == PCRE16_MODE ? pcre16_maketables() : pcre_maketables())
683    
684    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, tables) \
685      if (pcre_mode == PCRE32_MODE) \
686        PCRE_PATTERN_TO_HOST_BYTE_ORDER32(rc, re, extra, tables); \
687      else if (pcre_mode == PCRE16_MODE) \
688        PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables); \
689      else \
690        PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables)
691    
692    #define PCRE_PRINTINT(re, outfile, debug_lengths) \
693      if (pcre_mode == PCRE32_MODE) \
694        PCRE_PRINTINT32(re, outfile, debug_lengths); \
695      else if (pcre_mode == PCRE16_MODE) \
696        PCRE_PRINTINT16(re, outfile, debug_lengths); \
697      else \
698        PCRE_PRINTINT8(re, outfile, debug_lengths)
699    
700    #define PCRE_STUDY(extra, re, options, error) \
701      if (pcre_mode == PCRE32_MODE) \
702        PCRE_STUDY32(extra, re, options, error); \
703      else if (pcre_mode == PCRE16_MODE) \
704        PCRE_STUDY16(extra, re, options, error); \
705      else \
706        PCRE_STUDY8(extra, re, options, error)
707    
708    
709    /* ----- 32-bit and 16-bit but not 8-bit supported ----- */
710    
711    #elif defined(SUPPORT_PCRE32) && defined(SUPPORT_PCRE16)
712    #define PCHARS(lv, p, offset, len, f) \
713      if (pcre_mode == PCRE32_MODE) \
714        PCHARS32(lv, p, offset, len, f); \
715      else \
716        PCHARS16(lv, p, offset, len, f)
717    
718    #define PCHARSV(p, offset, len, f) \
719      if (pcre_mode == PCRE32_MODE) \
720        PCHARSV32(p, offset, len, f); \
721      else \
722        PCHARSV16(p, offset, len, f)
723    
724    #define READ_CAPTURE_NAME(p, cn8, cn16, cn32, re) \
725      if (pcre_mode == PCRE32_MODE) \
726        READ_CAPTURE_NAME32(p, cn8, cn16, cn32, re); \
727      else \
728        READ_CAPTURE_NAME16(p, cn8, cn16, cn32, re)
729    
730    #define SET_PCRE_CALLOUT(callout) \
731      if (pcre_mode == PCRE32_MODE) \
732        SET_PCRE_CALLOUT32(callout); \
733      else \
734        SET_PCRE_CALLOUT16(callout)
735    
736    #define STRLEN(p) (pcre_mode == PCRE32_MODE ? STRLEN32(p) : STRLEN16(p)
737    
738    #define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \
739      if (pcre_mode == PCRE32_MODE) \
740        PCRE_ASSIGN_JIT_STACK32(extra, callback, userdata); \
741      else \
742        PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata)
743    
744    #define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \
745      if (pcre_mode == PCRE32_MODE) \
746        PCRE_COMPILE32(re, pat, options, error, erroffset, tables); \
747      else \
748        PCRE_COMPILE16(re, pat, options, error, erroffset, tables)
749    
750    #define PCRE_CONFIG pcre_config
751    
752    #define PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
753        namesptr, cbuffer, size) \
754      if (pcre_mode == PCRE32_MODE) \
755        PCRE_COPY_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \
756          namesptr, cbuffer, size); \
757      else \
758        PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
759          namesptr, cbuffer, size)
760    
761    #define PCRE_COPY_SUBSTRING(rc, bptr, offsets, count, i, cbuffer, size) \
762      if (pcre_mode == PCRE32_MODE) \
763        PCRE_COPY_SUBSTRING32(rc, bptr, offsets, count, i, cbuffer, size); \
764      else \
765        PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size)
766    
767    #define PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, options, \
768        offsets, size_offsets, workspace, size_workspace) \
769      if (pcre_mode == PCRE32_MODE) \
770        PCRE_DFA_EXEC32(count, re, extra, bptr, len, start_offset, options, \
771          offsets, size_offsets, workspace, size_workspace); \
772      else \
773        PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \
774          offsets, size_offsets, workspace, size_workspace)
775    
776    #define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \
777        offsets, size_offsets) \
778      if (pcre_mode == PCRE32_MODE) \
779        PCRE_EXEC32(count, re, extra, bptr, len, start_offset, options, \
780          offsets, size_offsets); \
781      else \
782        PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
783          offsets, size_offsets)
784    
785    #define PCRE_FREE_STUDY(extra) \
786      if (pcre_mode == PCRE32_MODE) \
787        PCRE_FREE_STUDY32(extra); \
788      else \
789        PCRE_FREE_STUDY16(extra)
790    
791    #define PCRE_FREE_SUBSTRING(substring) \
792      if (pcre_mode == PCRE32_MODE) \
793        PCRE_FREE_SUBSTRING32(substring); \
794      else \
795        PCRE_FREE_SUBSTRING16(substring)
796    
797    #define PCRE_FREE_SUBSTRING_LIST(listptr) \
798      if (pcre_mode == PCRE32_MODE) \
799        PCRE_FREE_SUBSTRING_LIST32(listptr); \
800      else \
801        PCRE_FREE_SUBSTRING_LIST16(listptr)
802    
803    #define PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
804        getnamesptr, subsptr) \
805      if (pcre_mode == PCRE32_MODE) \
806        PCRE_GET_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \
807          getnamesptr, subsptr); \
808      else \
809        PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
810          getnamesptr, subsptr)
811    
812    #define PCRE_GET_STRINGNUMBER(n, rc, ptr) \
813      if (pcre_mode == PCRE32_MODE) \
814        PCRE_GET_STRINGNUMBER32(n, rc, ptr); \
815      else \
816        PCRE_GET_STRINGNUMBER16(n, rc, ptr)
817    
818    #define PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, subsptr) \
819      if (pcre_mode == PCRE32_MODE) \
820        PCRE_GET_SUBSTRING32(rc, bptr, use_offsets, count, i, subsptr); \
821      else \
822        PCRE_GET_SUBSTRING16(rc, bptr, use_offsets, count, i, subsptr)
823    
824    #define PCRE_GET_SUBSTRING_LIST(rc, bptr, offsets, count, listptr) \
825      if (pcre_mode == PCRE32_MODE) \
826        PCRE_GET_SUBSTRING_LIST32(rc, bptr, offsets, count, listptr); \
827      else \
828        PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr)
829    
830    #define PCRE_JIT_STACK_ALLOC(startsize, maxsize) \
831      (pcre_mode == PCRE32_MODE ? \
832         PCRE_JIT_STACK_ALLOC32(startsize, maxsize) \
833        : PCRE_JIT_STACK_ALLOC16(startsize, maxsize)
834    
835    #define PCRE_JIT_STACK_FREE(stack) \
836      if (pcre_mode == PCRE32_MODE) \
837        PCRE_JIT_STACK_FREE32(stack); \
838      else \
839        PCRE_JIT_STACK_FREE16(stack)
840    
841    #define PCRE_MAKETABLES \
842      (pcre_mode == PCRE32_MODE ? pcre32_maketables() : pcre16_maketables())
843    
844    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, tables) \
845      if (pcre_mode == PCRE32_MODE) \
846        PCRE_PATTERN_TO_HOST_BYTE_ORDER32(rc, re, extra, tables); \
847      else \
848        PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables)
849    
850    #define PCRE_PRINTINT(re, outfile, debug_lengths) \
851      if (pcre_mode == PCRE32_MODE) \
852        PCRE_PRINTINT32(re, outfile, debug_lengths); \
853      else \
854        PCRE_PRINTINT16(re, outfile, debug_lengths)
855    
856    #define PCRE_STUDY(extra, re, options, error) \
857      if (pcre_mode == PCRE32_MODE) \
858        PCRE_STUDY32(extra, re, options, error); \
859      else \
860        PCRE_STUDY16(extra, re, options, error)
861    
862    
863    /* ----- 32-bit and 8-bit but not 16-bit supported ----- */
864    
865    #elif defined(SUPPORT_PCRE32) && defined(SUPPORT_PCRE8)
866    
867    #define PCHARS(lv, p, offset, len, f) \
868      if (pcre_mode == PCRE32_MODE) \
869        PCHARS32(lv, p, offset, len, f); \
870      else \
871        PCHARS8(lv, p, offset, len, f)
872    
873    #define PCHARSV(p, offset, len, f) \
874      if (pcre_mode == PCRE32_MODE) \
875        PCHARSV32(p, offset, len, f); \
876      else \
877        PCHARSV8(p, offset, len, f)
878    
879    #define READ_CAPTURE_NAME(p, cn8, cn16, cn32, re) \
880      if (pcre_mode == PCRE32_MODE) \
881        READ_CAPTURE_NAME32(p, cn8, cn16, cn32, re); \
882      else \
883        READ_CAPTURE_NAME8(p, cn8, cn16, cn32, re)
884    
885    #define SET_PCRE_CALLOUT(callout) \
886      if (pcre_mode == PCRE32_MODE) \
887        SET_PCRE_CALLOUT32(callout); \
888      else \
889        SET_PCRE_CALLOUT8(callout)
890    
891    #define STRLEN(p) (pcre_mode == PCRE32_MODE ? STRLEN32(p) : STRLEN8(p))
892    
893    #define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \
894      if (pcre_mode == PCRE32_MODE) \
895        PCRE_ASSIGN_JIT_STACK32(extra, callback, userdata); \
896      else \
897        PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata)
898    
899    #define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \
900      if (pcre_mode == PCRE32_MODE) \
901        PCRE_COMPILE32(re, pat, options, error, erroffset, tables); \
902      else \
903        PCRE_COMPILE8(re, pat, options, error, erroffset, tables)
904    
905    #define PCRE_CONFIG pcre_config
906    
907    #define PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
908        namesptr, cbuffer, size) \
909      if (pcre_mode == PCRE32_MODE) \
910        PCRE_COPY_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \
911          namesptr, cbuffer, size); \
912      else \
913        PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
914          namesptr, cbuffer, size)
915    
916    #define PCRE_COPY_SUBSTRING(rc, bptr, offsets, count, i, cbuffer, size) \
917      if (pcre_mode == PCRE32_MODE) \
918        PCRE_COPY_SUBSTRING32(rc, bptr, offsets, count, i, cbuffer, size); \
919      else \
920        PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size)
921    
922    #define PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, options, \
923        offsets, size_offsets, workspace, size_workspace) \
924      if (pcre_mode == PCRE32_MODE) \
925        PCRE_DFA_EXEC32(count, re, extra, bptr, len, start_offset, options, \
926          offsets, size_offsets, workspace, size_workspace); \
927      else \
928        PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \
929          offsets, size_offsets, workspace, size_workspace)
930    
931    #define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \
932        offsets, size_offsets) \
933      if (pcre_mode == PCRE32_MODE) \
934        PCRE_EXEC32(count, re, extra, bptr, len, start_offset, options, \
935          offsets, size_offsets); \
936      else \
937        PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
938          offsets, size_offsets)
939    
940    #define PCRE_FREE_STUDY(extra) \
941      if (pcre_mode == PCRE32_MODE) \
942        PCRE_FREE_STUDY32(extra); \
943      else \
944        PCRE_FREE_STUDY8(extra)
945    
946    #define PCRE_FREE_SUBSTRING(substring) \
947      if (pcre_mode == PCRE32_MODE) \
948        PCRE_FREE_SUBSTRING32(substring); \
949      else \
950        PCRE_FREE_SUBSTRING8(substring)
951    
952    #define PCRE_FREE_SUBSTRING_LIST(listptr) \
953      if (pcre_mode == PCRE32_MODE) \
954        PCRE_FREE_SUBSTRING_LIST32(listptr); \
955      else \
956        PCRE_FREE_SUBSTRING_LIST8(listptr)
957    
958    #define PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
959        getnamesptr, subsptr) \
960      if (pcre_mode == PCRE32_MODE) \
961        PCRE_GET_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \
962          getnamesptr, subsptr); \
963      else \
964        PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
965          getnamesptr, subsptr)
966    
967    #define PCRE_GET_STRINGNUMBER(n, rc, ptr) \
968      if (pcre_mode == PCRE32_MODE) \
969        PCRE_GET_STRINGNUMBER32(n, rc, ptr); \
970      else \
971        PCRE_GET_STRINGNUMBER8(n, rc, ptr)
972    
973    #define PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, subsptr) \
974      if (pcre_mode == PCRE32_MODE) \
975        PCRE_GET_SUBSTRING32(rc, bptr, use_offsets, count, i, subsptr); \
976      else \
977        PCRE_GET_SUBSTRING8(rc, bptr, use_offsets, count, i, subsptr)
978    
979    #define PCRE_GET_SUBSTRING_LIST(rc, bptr, offsets, count, listptr) \
980      if (pcre_mode == PCRE32_MODE) \
981        PCRE_GET_SUBSTRING_LIST32(rc, bptr, offsets, count, listptr); \
982      else \
983        PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr)
984    
985    #define PCRE_JIT_STACK_ALLOC(startsize, maxsize) \
986      (pcre_mode == PCRE32_MODE ? \
987         PCRE_JIT_STACK_ALLOC32(startsize, maxsize) \
988          : PCRE_JIT_STACK_ALLOC8(startsize, maxsize))
989    
990    #define PCRE_JIT_STACK_FREE(stack) \
991      if (pcre_mode == PCRE32_MODE) \
992        PCRE_JIT_STACK_FREE32(stack); \
993      else \
994        PCRE_JIT_STACK_FREE8(stack)
995    
996    #define PCRE_MAKETABLES \
997      (pcre_mode == PCRE32_MODE ? pcre32_maketables() : pcre_maketables())
998    
999    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, tables) \
1000      if (pcre_mode == PCRE32_MODE) \
1001        PCRE_PATTERN_TO_HOST_BYTE_ORDER32(rc, re, extra, tables); \
1002      else \
1003        PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables)
1004    
1005    #define PCRE_PRINTINT(re, outfile, debug_lengths) \
1006      if (pcre_mode == PCRE32_MODE) \
1007        PCRE_PRINTINT32(re, outfile, debug_lengths); \
1008      else \
1009        PCRE_PRINTINT8(re, outfile, debug_lengths)
1010    
1011    #define PCRE_STUDY(extra, re, options, error) \
1012      if (pcre_mode == PCRE32_MODE) \
1013        PCRE_STUDY32(extra, re, options, error); \
1014      else \
1015        PCRE_STUDY8(extra, re, options, error)
1016    
1017    
1018    /* ----- 16-bit and 8-bit but not 32-bit supported ----- */
1019    
1020    #else
1021    #define PCHARS(lv, p, offset, len, f) \
1022      if (pcre_mode == PCRE16_MODE) \
1023        PCHARS16(lv, p, offset, len, f); \
1024      else \
1025        PCHARS8(lv, p, offset, len, f)
1026    
1027    #define PCHARSV(p, offset, len, f) \
1028      if (pcre_mode == PCRE16_MODE) \
1029        PCHARSV16(p, offset, len, f); \
1030      else \
1031        PCHARSV8(p, offset, len, f)
1032    
1033    #define READ_CAPTURE_NAME(p, cn8, cn16, cn32, re) \
1034      if (pcre_mode == PCRE16_MODE) \
1035        READ_CAPTURE_NAME16(p, cn8, cn16, cn32, re); \
1036      else \
1037        READ_CAPTURE_NAME8(p, cn8, cn16, cn32, re)
1038    
1039    #define SET_PCRE_CALLOUT(callout) \
1040      if (pcre_mode == PCRE16_MODE) \
1041        SET_PCRE_CALLOUT16(callout); \
1042      else \
1043        SET_PCRE_CALLOUT8(callout)
1044    
1045    #define STRLEN(p) (pcre_mode == PCRE16_MODE ? STRLEN16(p) : STRLEN8(p))
1046    
1047    #define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \
1048      if (pcre_mode == PCRE16_MODE) \
1049        PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata); \
1050      else \
1051        PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata)
1052    
1053    #define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \
1054      if (pcre_mode == PCRE16_MODE) \
1055        PCRE_COMPILE16(re, pat, options, error, erroffset, tables); \
1056      else \
1057        PCRE_COMPILE8(re, pat, options, error, erroffset, tables)
1058    
1059    #define PCRE_CONFIG pcre_config
1060    
1061    #define PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
1062        namesptr, cbuffer, size) \
1063      if (pcre_mode == PCRE16_MODE) \
1064        PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
1065          namesptr, cbuffer, size); \
1066      else \
1067        PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
1068          namesptr, cbuffer, size)
1069    
1070    #define PCRE_COPY_SUBSTRING(rc, bptr, offsets, count, i, cbuffer, size) \
1071      if (pcre_mode == PCRE16_MODE) \
1072        PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size); \
1073      else \
1074        PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size)
1075    
1076    #define PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, options, \
1077        offsets, size_offsets, workspace, size_workspace) \
1078      if (pcre_mode == PCRE16_MODE) \
1079        PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \
1080          offsets, size_offsets, workspace, size_workspace); \
1081      else \
1082        PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \
1083          offsets, size_offsets, workspace, size_workspace)
1084    
1085    #define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \
1086        offsets, size_offsets) \
1087      if (pcre_mode == PCRE16_MODE) \
1088        PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
1089          offsets, size_offsets); \
1090      else \
1091        PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
1092          offsets, size_offsets)
1093    
1094    #define PCRE_FREE_STUDY(extra) \
1095      if (pcre_mode == PCRE16_MODE) \
1096        PCRE_FREE_STUDY16(extra); \
1097      else \
1098        PCRE_FREE_STUDY8(extra)
1099    
1100    #define PCRE_FREE_SUBSTRING(substring) \
1101      if (pcre_mode == PCRE16_MODE) \
1102        PCRE_FREE_SUBSTRING16(substring); \
1103      else \
1104        PCRE_FREE_SUBSTRING8(substring)
1105    
1106    #define PCRE_FREE_SUBSTRING_LIST(listptr) \
1107      if (pcre_mode == PCRE16_MODE) \
1108        PCRE_FREE_SUBSTRING_LIST16(listptr); \
1109      else \
1110        PCRE_FREE_SUBSTRING_LIST8(listptr)
1111    
1112    #define PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
1113        getnamesptr, subsptr) \
1114      if (pcre_mode == PCRE16_MODE) \
1115        PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
1116          getnamesptr, subsptr); \
1117      else \
1118        PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
1119          getnamesptr, subsptr)
1120    
1121    #define PCRE_GET_STRINGNUMBER(n, rc, ptr) \
1122      if (pcre_mode == PCRE16_MODE) \
1123        PCRE_GET_STRINGNUMBER16(n, rc, ptr); \
1124      else \
1125        PCRE_GET_STRINGNUMBER8(n, rc, ptr)
1126    
1127    #define PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, subsptr) \
1128      if (pcre_mode == PCRE16_MODE) \
1129        PCRE_GET_SUBSTRING16(rc, bptr, use_offsets, count, i, subsptr); \
1130      else \
1131        PCRE_GET_SUBSTRING8(rc, bptr, use_offsets, count, i, subsptr)
1132    
1133    #define PCRE_GET_SUBSTRING_LIST(rc, bptr, offsets, count, listptr) \
1134      if (pcre_mode == PCRE16_MODE) \
1135        PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr); \
1136      else \
1137        PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr)
1138    
1139    #define PCRE_JIT_STACK_ALLOC(startsize, maxsize) \
1140      (pcre_mode == PCRE16_MODE ? \
1141          PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \
1142          : PCRE_JIT_STACK_ALLOC8(startsize, maxsize))
1143    
1144    #define PCRE_JIT_STACK_FREE(stack) \
1145      if (pcre_mode == PCRE16_MODE) \
1146        PCRE_JIT_STACK_FREE16(stack); \
1147      else \
1148        PCRE_JIT_STACK_FREE8(stack)
1149    
1150    #define PCRE_MAKETABLES \
1151      (pcre_mode == PCRE16_MODE ? pcre16_maketables() : pcre_maketables())
1152    
1153    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, tables) \
1154      if (pcre_mode == PCRE16_MODE) \
1155        PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables); \
1156      else \
1157        PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables)
1158    
1159    #define PCRE_PRINTINT(re, outfile, debug_lengths) \
1160      if (pcre_mode == PCRE16_MODE) \
1161        PCRE_PRINTINT16(re, outfile, debug_lengths); \
1162      else \
1163        PCRE_PRINTINT8(re, outfile, debug_lengths)
1164    
1165    #define PCRE_STUDY(extra, re, options, error) \
1166      if (pcre_mode == PCRE16_MODE) \
1167        PCRE_STUDY16(extra, re, options, error); \
1168      else \
1169        PCRE_STUDY8(extra, re, options, error)
1170    
1171  #endif  #endif
1172    
1173    /* ----- End of cases where more than one mode is supported ----- */
1174    
1175    
1176    /* ----- Only 8-bit mode is supported ----- */
1177    
1178    #elif defined SUPPORT_PCRE8
1179    #define CHAR_SIZE                 1
1180    #define PCHARS                    PCHARS8
1181    #define PCHARSV                   PCHARSV8
1182    #define READ_CAPTURE_NAME         READ_CAPTURE_NAME8
1183    #define SET_PCRE_CALLOUT          SET_PCRE_CALLOUT8
1184    #define STRLEN                    STRLEN8
1185    #define PCRE_ASSIGN_JIT_STACK     PCRE_ASSIGN_JIT_STACK8
1186    #define PCRE_COMPILE              PCRE_COMPILE8
1187    #define PCRE_CONFIG               pcre_config
1188    #define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING8
1189    #define PCRE_COPY_SUBSTRING       PCRE_COPY_SUBSTRING8
1190    #define PCRE_DFA_EXEC             PCRE_DFA_EXEC8
1191    #define PCRE_EXEC                 PCRE_EXEC8
1192    #define PCRE_FREE_STUDY           PCRE_FREE_STUDY8
1193    #define PCRE_FREE_SUBSTRING       PCRE_FREE_SUBSTRING8
1194    #define PCRE_FREE_SUBSTRING_LIST  PCRE_FREE_SUBSTRING_LIST8
1195    #define PCRE_GET_NAMED_SUBSTRING  PCRE_GET_NAMED_SUBSTRING8
1196    #define PCRE_GET_STRINGNUMBER     PCRE_GET_STRINGNUMBER8
1197    #define PCRE_GET_SUBSTRING        PCRE_GET_SUBSTRING8
1198    #define PCRE_GET_SUBSTRING_LIST   PCRE_GET_SUBSTRING_LIST8
1199    #define PCRE_JIT_STACK_ALLOC      PCRE_JIT_STACK_ALLOC8
1200    #define PCRE_JIT_STACK_FREE       PCRE_JIT_STACK_FREE8
1201    #define PCRE_MAKETABLES           pcre_maketables()
1202    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER8
1203    #define PCRE_PRINTINT             PCRE_PRINTINT8
1204    #define PCRE_STUDY                PCRE_STUDY8
1205    
1206    /* ----- Only 16-bit mode is supported ----- */
1207    
1208    #elif defined SUPPORT_PCRE16
1209    #define CHAR_SIZE                 2
1210    #define PCHARS                    PCHARS16
1211    #define PCHARSV                   PCHARSV16
1212    #define READ_CAPTURE_NAME         READ_CAPTURE_NAME16
1213    #define SET_PCRE_CALLOUT          SET_PCRE_CALLOUT16
1214    #define STRLEN                    STRLEN16
1215    #define PCRE_ASSIGN_JIT_STACK     PCRE_ASSIGN_JIT_STACK16
1216    #define PCRE_COMPILE              PCRE_COMPILE16
1217    #define PCRE_CONFIG               pcre16_config
1218    #define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING16
1219    #define PCRE_COPY_SUBSTRING       PCRE_COPY_SUBSTRING16
1220    #define PCRE_DFA_EXEC             PCRE_DFA_EXEC16
1221    #define PCRE_EXEC                 PCRE_EXEC16
1222    #define PCRE_FREE_STUDY           PCRE_FREE_STUDY16
1223    #define PCRE_FREE_SUBSTRING       PCRE_FREE_SUBSTRING16
1224    #define PCRE_FREE_SUBSTRING_LIST  PCRE_FREE_SUBSTRING_LIST16
1225    #define PCRE_GET_NAMED_SUBSTRING  PCRE_GET_NAMED_SUBSTRING16
1226    #define PCRE_GET_STRINGNUMBER     PCRE_GET_STRINGNUMBER16
1227    #define PCRE_GET_SUBSTRING        PCRE_GET_SUBSTRING16
1228    #define PCRE_GET_SUBSTRING_LIST   PCRE_GET_SUBSTRING_LIST16
1229    #define PCRE_JIT_STACK_ALLOC      PCRE_JIT_STACK_ALLOC16
1230    #define PCRE_JIT_STACK_FREE       PCRE_JIT_STACK_FREE16
1231    #define PCRE_MAKETABLES           pcre16_maketables()
1232    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER16
1233    #define PCRE_PRINTINT             PCRE_PRINTINT16
1234    #define PCRE_STUDY                PCRE_STUDY16
1235    
1236    /* ----- Only 32-bit mode is supported ----- */
1237    
1238    #elif defined SUPPORT_PCRE32
1239    #define CHAR_SIZE                 4
1240    #define PCHARS                    PCHARS32
1241    #define PCHARSV                   PCHARSV32
1242    #define READ_CAPTURE_NAME         READ_CAPTURE_NAME32
1243    #define SET_PCRE_CALLOUT          SET_PCRE_CALLOUT32
1244    #define STRLEN                    STRLEN32
1245    #define PCRE_ASSIGN_JIT_STACK     PCRE_ASSIGN_JIT_STACK32
1246    #define PCRE_COMPILE              PCRE_COMPILE32
1247    #define PCRE_CONFIG               pcre32_config
1248    #define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING32
1249    #define PCRE_COPY_SUBSTRING       PCRE_COPY_SUBSTRING32
1250    #define PCRE_DFA_EXEC             PCRE_DFA_EXEC32
1251    #define PCRE_EXEC                 PCRE_EXEC32
1252    #define PCRE_FREE_STUDY           PCRE_FREE_STUDY32
1253    #define PCRE_FREE_SUBSTRING       PCRE_FREE_SUBSTRING32
1254    #define PCRE_FREE_SUBSTRING_LIST  PCRE_FREE_SUBSTRING_LIST32
1255    #define PCRE_GET_NAMED_SUBSTRING  PCRE_GET_NAMED_SUBSTRING32
1256    #define PCRE_GET_STRINGNUMBER     PCRE_GET_STRINGNUMBER32
1257    #define PCRE_GET_SUBSTRING        PCRE_GET_SUBSTRING32
1258    #define PCRE_GET_SUBSTRING_LIST   PCRE_GET_SUBSTRING_LIST32
1259    #define PCRE_JIT_STACK_ALLOC      PCRE_JIT_STACK_ALLOC32
1260    #define PCRE_JIT_STACK_FREE       PCRE_JIT_STACK_FREE32
1261    #define PCRE_MAKETABLES           pcre32_maketables()
1262    #define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER32
1263    #define PCRE_PRINTINT             PCRE_PRINTINT32
1264    #define PCRE_STUDY                PCRE_STUDY32
1265    
1266  #endif  #endif
1267    
1268    /* ----- End of mode-specific function call macros ----- */
1269    
1270    
1271  /* Other parameters */  /* Other parameters */
1272    
# Line 173  UTF8 support if PCRE is built without it Line 1278  UTF8 support if PCRE is built without it
1278  #endif  #endif
1279  #endif  #endif
1280    
1281    #if !defined NODFA
1282    #define DFA_WS_DIMENSION 1000
1283    #endif
1284    
1285  /* This is the default loop count for timing. */  /* This is the default loop count for timing. */
1286    
1287  #define LOOPREPEAT 500000  #define LOOPREPEAT 500000
# Line 187  static int callout_fail_count; Line 1296  static int callout_fail_count;
1296  static int callout_fail_id;  static int callout_fail_id;
1297  static int debug_lengths;  static int debug_lengths;
1298  static int first_callout;  static int first_callout;
1299    static int jit_was_used;
1300  static int locale_set = 0;  static int locale_set = 0;
1301  static int show_malloc;  static int show_malloc;
1302  static int use_utf8;  static int use_utf;
1303  static size_t gotten_store;  static size_t gotten_store;
1304    static size_t first_gotten_store = 0;
1305  static const unsigned char *last_callout_mark = NULL;  static const unsigned char *last_callout_mark = NULL;
1306    
1307  /* The buffers grow automatically if very long input lines are encountered. */  /* The buffers grow automatically if very long input lines are encountered. */
1308    
1309  static int buffer_size = 50000;  static int buffer_size = 50000;
1310  static uschar *buffer = NULL;  static pcre_uint8 *buffer = NULL;
1311  static uschar *dbuffer = NULL;  static pcre_uint8 *pbuffer = NULL;
1312  static uschar *pbuffer = NULL;  
1313    /* Another buffer is needed translation to 16/32-bit character strings. It will
1314    obtained and extended as required. */
1315    
1316    #if defined SUPPORT_PCRE8 && (defined SUPPORT_PCRE16 || defined SUPPORT_PCRE32)
1317    
1318    /* We need the table of operator lengths that is used for 16/32-bit compiling, in
1319    order to swap bytes in a pattern for saving/reloading testing. Luckily, the
1320    data is defined as a macro. However, we must ensure that LINK_SIZE is adjusted
1321    appropriately for the 16/32-bit world. Just as a safety check, make sure that
1322    COMPILE_PCRE[16|32] is *not* set. */
1323    
1324    #ifdef COMPILE_PCRE16
1325    #error COMPILE_PCRE16 must not be set when compiling pcretest.c
1326    #endif
1327    
1328    #ifdef COMPILE_PCRE32
1329    #error COMPILE_PCRE32 must not be set when compiling pcretest.c
1330    #endif
1331    
1332    #if LINK_SIZE == 2
1333    #undef LINK_SIZE
1334    #define LINK_SIZE 1
1335    #elif LINK_SIZE == 3 || LINK_SIZE == 4
1336    #undef LINK_SIZE
1337    #define LINK_SIZE 2
1338    #else
1339    #error LINK_SIZE must be either 2, 3, or 4
1340    #endif
1341    
1342    #undef IMM2_SIZE
1343    #define IMM2_SIZE 1
1344    
1345    #endif /* SUPPORT_PCRE8 && (SUPPORT_PCRE16 || SUPPORT_PCRE32) */
1346    
1347    #ifdef SUPPORT_PCRE16
1348    static int buffer16_size = 0;
1349    static pcre_uint16 *buffer16 = NULL;
1350    static const pcre_uint16 OP_lengths16[] = { OP_LENGTHS };
1351    #endif  /* SUPPORT_PCRE16 */
1352    
1353    #ifdef SUPPORT_PCRE32
1354    static int buffer32_size = 0;
1355    static pcre_uint32 *buffer32 = NULL;
1356    static const pcre_uint32 OP_lengths32[] = { OP_LENGTHS };
1357    #endif  /* SUPPORT_PCRE32 */
1358    
1359    /* If we have 8-bit support, default to it; if there is also
1360    16-or 32-bit support, it can be changed by an option. If there is no 8-bit support,
1361    there must be 16-or 32-bit support, so default it to 1. */
1362    
1363    #if defined SUPPORT_PCRE8
1364    static int pcre_mode = PCRE8_MODE;
1365    #elif defined SUPPORT_PCRE16
1366    static int pcre_mode = PCRE16_MODE;
1367    #elif defined SUPPORT_PCRE32
1368    static int pcre_mode = PCRE32_MODE;
1369    #endif
1370    
1371    /* JIT study options for -s+n and /S+n where '1' <= n <= '7'. */
1372    
1373    static int jit_study_bits[] =
1374      {
1375      PCRE_STUDY_JIT_COMPILE,
1376      PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE,
1377      PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE,
1378      PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE,
1379      PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE,
1380      PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE,
1381      PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE +
1382        PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
1383    };
1384    
1385    #define PCRE_STUDY_ALLJIT (PCRE_STUDY_JIT_COMPILE | \
1386      PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE | PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)
1387    
1388  /* Textual explanations for runtime error codes */  /* Textual explanations for runtime error codes */
1389    
# Line 213  static const char *errtexts[] = { Line 1398  static const char *errtexts[] = {
1398    NULL,  /* never returned by pcre_exec() or pcre_dfa_exec() */    NULL,  /* never returned by pcre_exec() or pcre_dfa_exec() */
1399    "match limit exceeded",    "match limit exceeded",
1400    "callout error code",    "callout error code",
1401    NULL,  /* BADUTF8 is handled specially */    NULL,  /* BADUTF8/16 is handled specially */
1402    "bad UTF-8 offset",    NULL,  /* BADUTF8/16 offset is handled specially */
1403    NULL,  /* PARTIAL is handled specially */    NULL,  /* PARTIAL is handled specially */
1404    "not used - internal error",    "not used - internal error",
1405    "internal error - pattern overwritten?",    "internal error - pattern overwritten?",
# Line 228  static const char *errtexts[] = { Line 1413  static const char *errtexts[] = {
1413    "not used - internal error",    "not used - internal error",
1414    "invalid combination of newline options",    "invalid combination of newline options",
1415    "bad offset value",    "bad offset value",
1416    NULL,  /* SHORTUTF8 is handled specially */    NULL,  /* SHORTUTF8/16 is handled specially */
1417    "nested recursion at the same subject position",    "nested recursion at the same subject position",
1418    "JIT stack limit reached"    "JIT stack limit reached",
1419      "pattern compiled in wrong mode: 8-bit/16-bit error",
1420      "pattern compiled with other endianness",
1421      "invalid data in workspace for DFA restart"
1422  };  };
1423    
1424    
# Line 246  the L (locale) option also adjusts the t Line 1434  the L (locale) option also adjusts the t
1434  /* This is the set of tables distributed as default with PCRE. It recognizes  /* This is the set of tables distributed as default with PCRE. It recognizes
1435  only ASCII characters. */  only ASCII characters. */
1436    
1437  static const unsigned char tables0[] = {  static const pcre_uint8 tables0[] = {
1438    
1439  /* This table is a lower casing table. */  /* This table is a lower casing table. */
1440    
# Line 419  graph, print, punct, and cntrl. Other cl Line 1607  graph, print, punct, and cntrl. Other cl
1607  be at least an approximation of ISO 8859. In particular, there are characters  be at least an approximation of ISO 8859. In particular, there are characters
1608  greater than 128 that are marked as spaces, letters, etc. */  greater than 128 that are marked as spaces, letters, etc. */
1609    
1610  static const unsigned char tables1[] = {  static const pcre_uint8 tables1[] = {
1611  0,1,2,3,4,5,6,7,  0,1,2,3,4,5,6,7,
1612  8,9,10,11,12,13,14,15,  8,9,10,11,12,13,14,15,
1613  16,17,18,19,20,21,22,23,  16,17,18,19,20,21,22,23,
# Line 582  return sys_errlist[n]; Line 1770  return sys_errlist[n];
1770  #endif /* HAVE_STRERROR */  #endif /* HAVE_STRERROR */
1771    
1772    
1773    
1774    /*************************************************
1775    *       Print newline configuration              *
1776    *************************************************/
1777    
1778    /*
1779    Arguments:
1780      rc         the return code from PCRE_CONFIG_NEWLINE
1781      isc        TRUE if called from "-C newline"
1782    Returns:     nothing
1783    */
1784    
1785    static void
1786    print_newline_config(int rc, BOOL isc)
1787    {
1788    const char *s = NULL;
1789    if (!isc) printf("  Newline sequence is ");
1790    switch(rc)
1791      {
1792      case CHAR_CR: s = "CR"; break;
1793      case CHAR_LF: s = "LF"; break;
1794      case (CHAR_CR<<8 | CHAR_LF): s = "CRLF"; break;
1795      case -1: s = "ANY"; break;
1796      case -2: s = "ANYCRLF"; break;
1797    
1798      default:
1799      printf("a non-standard value: 0x%04x\n", rc);
1800      return;
1801      }
1802    
1803    printf("%s\n", s);
1804    }
1805    
1806    
1807    
1808  /*************************************************  /*************************************************
1809  *         JIT memory callback                    *  *         JIT memory callback                    *
1810  *************************************************/  *************************************************/
1811    
1812  static pcre_jit_stack* jit_callback(void *arg)  static pcre_jit_stack* jit_callback(void *arg)
1813  {  {
1814    jit_was_used = TRUE;
1815  return (pcre_jit_stack *)arg;  return (pcre_jit_stack *)arg;
1816  }  }
1817    
1818    
1819    #if !defined NOUTF || defined SUPPORT_PCRE16 || defined SUPPORT_PCRE32
1820  /*************************************************  /*************************************************
1821  *        Read or extend an input line            *  *            Convert UTF-8 string to value       *
1822  *************************************************/  *************************************************/
1823    
1824  /* Input lines are read into buffer, but both patterns and data lines can be  /* This function takes one or more bytes that represents a UTF-8 character,
1825  continued over multiple input lines. In addition, if the buffer fills up, we  and returns the value of the character.
 want to automatically expand it so as to be able to handle extremely large  
 lines that are needed for certain stress tests. When the input buffer is  
 expanded, the other two buffers must also be expanded likewise, and the  
 contents of pbuffer, which are a copy of the input for callouts, must be  
 preserved (for when expansion happens for a data line). This is not the most  
 optimal way of handling this, but hey, this is just a test program!  
1826    
1827  Arguments:  Argument:
1828    f            the file to read    utf8bytes   a pointer to the byte vector
1829    start        where in buffer to start (this *must* be within buffer)    vptr        a pointer to an int to receive the value
   prompt       for stdin or readline()  
1830    
1831  Returns:       pointer to the start of new data  Returns:      >  0 => the number of bytes consumed
1832                 could be a copy of start, or could be moved                -6 to 0 => malformed UTF-8 character at offset = (-return)
                NULL if no data read and EOF reached  
1833  */  */
1834    
1835  static uschar *  static int
1836  extend_inputline(FILE *f, uschar *start, const char *prompt)  utf82ord(pcre_uint8 *utf8bytes, pcre_uint32 *vptr)
1837  {  {
1838  uschar *here = start;  pcre_uint32 c = *utf8bytes++;
1839    pcre_uint32 d = c;
1840    int i, j, s;
1841    
1842  for (;;)  for (i = -1; i < 6; i++)               /* i is number of additional bytes */
1843    {    {
1844    int rlen = (int)(buffer_size - (here - buffer));    if ((d & 0x80) == 0) break;
1845      d <<= 1;
1846    if (rlen > 1000)    }
     {  
     int dlen;  
1847    
1848      /* If libreadline support is required, use readline() to read a line if the  if (i == -1) { *vptr = c; return 1; }  /* ascii character */
1849      input is a terminal. Note that readline() removes the trailing newline, so  if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */
     we must put it back again, to be compatible with fgets(). */  
1850    
1851  #ifdef SUPPORT_LIBREADLINE  /* i now has a value in the range 1-5 */
     if (isatty(fileno(f)))  
       {  
       size_t len;  
       char *s = readline(prompt);  
       if (s == NULL) return (here == start)? NULL : start;  
       len = strlen(s);  
       if (len > 0) add_history(s);  
       if (len > rlen - 1) len = rlen - 1;  
       memcpy(here, s, len);  
       here[len] = '\n';  
       here[len+1] = 0;  
       free(s);  
       }  
     else  
 #endif  
1852    
1853      /* Read the next line by normal means, prompting if the file is stdin. */  s = 6*i;
1854    d = (c & utf8_table3[i]) << s;
1855    
1856        {  for (j = 0; j < i; j++)
1857        if (f == stdin) printf("%s", prompt);    {
1858        if (fgets((char *)here, rlen,  f) == NULL)    c = *utf8bytes++;
1859          return (here == start)? NULL : start;    if ((c & 0xc0) != 0x80) return -(j+1);
1860        }    s -= 6;
1861      d |= (c & 0x3f) << s;
1862      }
1863    
1864      dlen = (int)strlen((char *)here);  /* Check that encoding was the correct unique one */
     if (dlen > 0 && here[dlen - 1] == '\n') return start;  
     here += dlen;  
     }  
1865    
1866    else  for (j = 0; j < utf8_table1_size; j++)
1867      {    if (d <= (pcre_uint32)utf8_table1[j]) break;
1868      int new_buffer_size = 2*buffer_size;  if (j != i) return -(i+1);
     uschar *new_buffer = (unsigned char *)malloc(new_buffer_size);  
     uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size);  
     uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size);  
1869    
1870      if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)  /* Valid value */
       {  
       fprintf(stderr, "pcretest: malloc(%d) failed\n", new_buffer_size);  
       exit(1);  
       }  
1871    
1872      memcpy(new_buffer, buffer, buffer_size);  *vptr = d;
1873      memcpy(new_pbuffer, pbuffer, buffer_size);  return i+1;
1874    }
1875    #endif /* NOUTF || SUPPORT_PCRE16 */
1876    
     buffer_size = new_buffer_size;  
1877    
1878      start = new_buffer + (start - buffer);  
1879      here = new_buffer + (here - buffer);  #if !defined NOUTF || defined SUPPORT_PCRE16 || defined SUPPORT_PCRE32
1880    /*************************************************
1881    *       Convert character value to UTF-8         *
1882    *************************************************/
1883    
1884    /* This function takes an integer value in the range 0 - 0x7fffffff
1885    and encodes it as a UTF-8 character in 0 to 6 bytes.
1886    
1887    Arguments:
1888      cvalue     the character value
1889      utf8bytes  pointer to buffer for result - at least 6 bytes long
1890    
1891    Returns:     number of characters placed in the buffer
1892    */
1893    
1894    static int
1895    ord2utf8(pcre_uint32 cvalue, pcre_uint8 *utf8bytes)
1896    {
1897    register int i, j;
1898    if (cvalue > 0x7fffffffu)
1899      return -1;
1900    for (i = 0; i < utf8_table1_size; i++)
1901      if (cvalue <= (pcre_uint32)utf8_table1[i]) break;
1902    utf8bytes += i;
1903    for (j = i; j > 0; j--)
1904     {
1905     *utf8bytes-- = 0x80 | (cvalue & 0x3f);
1906     cvalue >>= 6;
1907     }
1908    *utf8bytes = utf8_table2[i] | cvalue;
1909    return i + 1;
1910    }
1911    #endif
1912    
1913    
1914    #ifdef SUPPORT_PCRE16
1915    /*************************************************
1916    *         Convert a string to 16-bit             *
1917    *************************************************/
1918    
1919    /* In non-UTF mode, the space needed for a 16-bit string is exactly double the
1920    8-bit size. For a UTF-8 string, the size needed for UTF-16 is no more than
1921    double, because up to 0xffff uses no more than 3 bytes in UTF-8 but possibly 4
1922    in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in UTF-16. The
1923    result is always left in buffer16.
1924    
1925    Note that this function does not object to surrogate values. This is
1926    deliberate; it makes it possible to construct UTF-16 strings that are invalid,
1927    for the purpose of testing that they are correctly faulted.
1928    
1929    Patterns to be converted are either plain ASCII or UTF-8; data lines are always
1930    in UTF-8 so that values greater than 255 can be handled.
1931    
1932    Arguments:
1933      data       TRUE if converting a data line; FALSE for a regex
1934      p          points to a byte string
1935      utf        true if UTF-8 (to be converted to UTF-16)
1936      len        number of bytes in the string (excluding trailing zero)
1937    
1938    Returns:     number of 16-bit data items used (excluding trailing zero)
1939                 OR -1 if a UTF-8 string is malformed
1940                 OR -2 if a value > 0x10ffff is encountered
1941                 OR -3 if a value > 0xffff is encountered when not in UTF mode
1942    */
1943    
1944    static int
1945    to16(int data, pcre_uint8 *p, int utf, int len)
1946    {
1947    pcre_uint16 *pp;
1948    
1949    if (buffer16_size < 2*len + 2)
1950      {
1951      if (buffer16 != NULL) free(buffer16);
1952      buffer16_size = 2*len + 2;
1953      buffer16 = (pcre_uint16 *)malloc(buffer16_size);
1954      if (buffer16 == NULL)
1955        {
1956        fprintf(stderr, "pcretest: malloc(%d) failed for buffer16\n", buffer16_size);
1957        exit(1);
1958        }
1959      }
1960    
1961    pp = buffer16;
1962    
1963    if (!utf && !data)
1964      {
1965      while (len-- > 0) *pp++ = *p++;
1966      }
1967    
1968    else
1969      {
1970      pcre_uint32 c = 0;
1971      while (len > 0)
1972        {
1973        int chlen = utf82ord(p, &c);
1974        if (chlen <= 0) return -1;
1975        if (c > 0x10ffff) return -2;
1976        p += chlen;
1977        len -= chlen;
1978        if (c < 0x10000) *pp++ = c; else
1979          {
1980          if (!utf) return -3;
1981          c -= 0x10000;
1982          *pp++ = 0xD800 | (c >> 10);
1983          *pp++ = 0xDC00 | (c & 0x3ff);
1984          }
1985        }
1986      }
1987    
1988    *pp = 0;
1989    return pp - buffer16;
1990    }
1991    #endif
1992    
1993    #ifdef SUPPORT_PCRE32
1994    /*************************************************
1995    *         Convert a string to 32-bit             *
1996    *************************************************/
1997    
1998    /* In non-UTF mode, the space needed for a 32-bit string is exactly four times the
1999    8-bit size. For a UTF-8 string, the size needed for UTF-32 is no more than four
2000    times, because up to 0xffff uses no more than 3 bytes in UTF-8 but possibly 4
2001    in UTF-32. Higher values use 4 bytes in UTF-8 and up to 4 bytes in UTF-32. The
2002    result is always left in buffer32.
2003    
2004    Note that this function does not object to surrogate values. This is
2005    deliberate; it makes it possible to construct UTF-32 strings that are invalid,
2006    for the purpose of testing that they are correctly faulted.
2007    
2008    Patterns to be converted are either plain ASCII or UTF-8; data lines are always
2009    in UTF-8 so that values greater than 255 can be handled.
2010    
2011    Arguments:
2012      data       TRUE if converting a data line; FALSE for a regex
2013      p          points to a byte string
2014      utf        true if UTF-8 (to be converted to UTF-32)
2015      len        number of bytes in the string (excluding trailing zero)
2016    
2017    Returns:     number of 32-bit data items used (excluding trailing zero)
2018                 OR -1 if a UTF-8 string is malformed
2019                 OR -2 if a value > 0x10ffff is encountered
2020                 OR -3 if an ill-formed value is encountered (i.e. a surrogate)
2021    */
2022    
2023    static int
2024    to32(int data, pcre_uint8 *p, int utf, int len)
2025    {
2026    pcre_uint32 *pp;
2027    
2028    if (buffer32_size < 4*len + 4)
2029      {
2030      if (buffer32 != NULL) free(buffer32);
2031      buffer32_size = 4*len + 4;
2032      buffer32 = (pcre_uint32 *)malloc(buffer32_size);
2033      if (buffer32 == NULL)
2034        {
2035        fprintf(stderr, "pcretest: malloc(%d) failed for buffer32\n", buffer32_size);
2036        exit(1);
2037        }
2038      }
2039    
2040    pp = buffer32;
2041    
2042    if (!utf && !data)
2043      {
2044      while (len-- > 0) *pp++ = *p++;
2045      }
2046    
2047    else
2048      {
2049      pcre_uint32 c = 0;
2050      while (len > 0)
2051        {
2052        int chlen = utf82ord(p, &c);
2053        if (chlen <= 0) return -1;
2054        if (utf)
2055          {
2056          if (c > 0x10ffff) return -2;
2057          if (!data && (c & 0xfffff800u) == 0xd800u) return -3;
2058          }
2059    
2060        p += chlen;
2061        len -= chlen;
2062        *pp++ = c;
2063        }
2064      }
2065    
2066    *pp = 0;
2067    return pp - buffer32;
2068    }
2069    
2070    /* Check that a 32-bit character string is valid UTF-32.
2071    
2072    Arguments:
2073      string       points to the string
2074      length       length of string, or -1 if the string is zero-terminated
2075    
2076    Returns:       TRUE  if the string is a valid UTF-32 string
2077                   FALSE otherwise
2078    */
2079    
2080    #ifdef SUPPORT_UTF
2081    static BOOL
2082    valid_utf32(pcre_uint32 *string, int length)
2083    {
2084    register pcre_uint32 *p;
2085    register pcre_uint32 c;
2086    
2087    for (p = string; length-- > 0; p++)
2088      {
2089      c = *p;
2090    
2091      if (c > 0x10ffffu)
2092        return FALSE;
2093    
2094      /* A surrogate */
2095      if ((c & 0xfffff800u) == 0xd800u)
2096        return FALSE;
2097    
2098      /* Non-character */
2099      if ((c & 0xfffeu) == 0xfffeu || (c >= 0xfdd0u && c <= 0xfdefu))
2100        return FALSE;
2101      }
2102    
2103    return TRUE;
2104    }
2105    #endif /* SUPPORT_UTF */
2106    
2107    #endif
2108    
2109    /*************************************************
2110    *        Read or extend an input line            *
2111    *************************************************/
2112    
2113    /* Input lines are read into buffer, but both patterns and data lines can be
2114    continued over multiple input lines. In addition, if the buffer fills up, we
2115    want to automatically expand it so as to be able to handle extremely large
2116    lines that are needed for certain stress tests. When the input buffer is
2117    expanded, the other two buffers must also be expanded likewise, and the
2118    contents of pbuffer, which are a copy of the input for callouts, must be
2119    preserved (for when expansion happens for a data line). This is not the most
2120    optimal way of handling this, but hey, this is just a test program!
2121    
2122    Arguments:
2123      f            the file to read
2124      start        where in buffer to start (this *must* be within buffer)
2125      prompt       for stdin or readline()
2126    
2127    Returns:       pointer to the start of new data
2128                   could be a copy of start, or could be moved
2129                   NULL if no data read and EOF reached
2130    */
2131    
2132    static pcre_uint8 *
2133    extend_inputline(FILE *f, pcre_uint8 *start, const char *prompt)
2134    {
2135    pcre_uint8 *here = start;
2136    
2137    for (;;)
2138      {
2139      size_t rlen = (size_t)(buffer_size - (here - buffer));
2140    
2141      if (rlen > 1000)
2142        {
2143        int dlen;
2144    
2145        /* If libreadline or libedit support is required, use readline() to read a
2146        line if the input is a terminal. Note that readline() removes the trailing
2147        newline, so we must put it back again, to be compatible with fgets(). */
2148    
2149    #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
2150        if (isatty(fileno(f)))
2151          {
2152          size_t len;
2153          char *s = readline(prompt);
2154          if (s == NULL) return (here == start)? NULL : start;
2155          len = strlen(s);
2156          if (len > 0) add_history(s);
2157          if (len > rlen - 1) len = rlen - 1;
2158          memcpy(here, s, len);
2159          here[len] = '\n';
2160          here[len+1] = 0;
2161          free(s);
2162          }
2163        else
2164    #endif
2165    
2166        /* Read the next line by normal means, prompting if the file is stdin. */
2167    
2168          {
2169          if (f == stdin) printf("%s", prompt);
2170          if (fgets((char *)here, rlen,  f) == NULL)
2171            return (here == start)? NULL : start;
2172          }
2173    
2174        dlen = (int)strlen((char *)here);
2175        if (dlen > 0 && here[dlen - 1] == '\n') return start;
2176        here += dlen;
2177        }
2178    
2179      else
2180        {
2181        int new_buffer_size = 2*buffer_size;
2182        pcre_uint8 *new_buffer = (pcre_uint8 *)malloc(new_buffer_size);
2183        pcre_uint8 *new_pbuffer = (pcre_uint8 *)malloc(new_buffer_size);
2184    
2185        if (new_buffer == NULL || new_pbuffer == NULL)
2186          {
2187          fprintf(stderr, "pcretest: malloc(%d) failed\n", new_buffer_size);
2188          exit(1);
2189          }
2190    
2191        memcpy(new_buffer, buffer, buffer_size);
2192        memcpy(new_pbuffer, pbuffer, buffer_size);
2193    
2194        buffer_size = new_buffer_size;
2195    
2196        start = new_buffer + (start - buffer);
2197        here = new_buffer + (here - buffer);
2198    
2199      free(buffer);      free(buffer);
     free(dbuffer);  
2200      free(pbuffer);      free(pbuffer);
2201    
2202      buffer = new_buffer;      buffer = new_buffer;
     dbuffer = new_dbuffer;  
2203      pbuffer = new_pbuffer;      pbuffer = new_pbuffer;
2204      }      }
2205    }    }
# Line 698  return NULL;  /* Control never gets here Line 2209  return NULL;  /* Control never gets here
2209    
2210    
2211    
   
   
   
   
2212  /*************************************************  /*************************************************
2213  *          Read number from string               *  *          Read number from string               *
2214  *************************************************/  *************************************************/
# Line 718  Returns:        the unsigned long Line 2225  Returns:        the unsigned long
2225  */  */
2226    
2227  static int  static int
2228  get_value(unsigned char *str, unsigned char **endptr)  get_value(pcre_uint8 *str, pcre_uint8 **endptr)
2229  {  {
2230  int result = 0;  int result = 0;
2231  while(*str != 0 && isspace(*str)) str++;  while(*str != 0 && isspace(*str)) str++;
# Line 729  return(result); Line 2236  return(result);
2236    
2237    
2238    
   
2239  /*************************************************  /*************************************************
2240  *            Convert UTF-8 string to value       *  *             Print one character                *
2241  *************************************************/  *************************************************/
2242    
2243  /* This function takes one or more bytes that represents a UTF-8 character,  /* Print a single character either literally, or as a hex escape. */
 and returns the value of the character.  
   
 Argument:  
   utf8bytes   a pointer to the byte vector  
   vptr        a pointer to an int to receive the value  
   
 Returns:      >  0 => the number of bytes consumed  
               -6 to 0 => malformed UTF-8 character at offset = (-return)  
 */  
   
 #if !defined NOUTF8  
2244    
2245  static int  static int pchar(pcre_uint32 c, FILE *f)
 utf82ord(unsigned char *utf8bytes, int *vptr)  
2246  {  {
2247  int c = *utf8bytes++;  int n = 0;
2248  int d = c;  if (PRINTOK(c))
2249  int i, j, s;    {
2250      if (f != NULL) fprintf(f, "%c", c);
2251      return 1;
2252      }
2253    
2254  for (i = -1; i < 6; i++)               /* i is number of additional bytes */  if (c < 0x100)
2255    {    {
2256    if ((d & 0x80) == 0) break;    if (use_utf)
2257    d <<= 1;      {
2258        if (f != NULL) fprintf(f, "\\x{%02x}", c);
2259        return 6;
2260        }
2261      else
2262        {
2263        if (f != NULL) fprintf(f, "\\x%02x", c);
2264        return 4;
2265        }
2266    }    }
2267    
2268  if (i == -1) { *vptr = c; return 1; }  /* ascii character */  if (f != NULL) n = fprintf(f, "\\x{%02x}", c);
2269  if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */  return n >= 0 ? n : 0;
2270    }
2271    
 /* i now has a value in the range 1-5 */  
2272    
 s = 6*i;  
 d = (c & utf8_table3[i]) << s;  
2273    
2274  for (j = 0; j < i; j++)  #ifdef SUPPORT_PCRE8
2275    {  /*************************************************
2276    c = *utf8bytes++;  *         Print 8-bit character string           *
2277    if ((c & 0xc0) != 0x80) return -(j+1);  *************************************************/
   s -= 6;  
   d |= (c & 0x3f) << s;  
   }  
2278    
2279  /* Check that encoding was the correct unique one */  /* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed.
2280    If handed a NULL file, just counts chars without printing. */
2281    
2282  for (j = 0; j < utf8_table1_size; j++)  static int pchars(pcre_uint8 *p, int length, FILE *f)
2283    if (d <= utf8_table1[j]) break;  {
2284  if (j != i) return -(i+1);  pcre_uint32 c = 0;
2285    int yield = 0;
2286    
2287  /* Valid value */  if (length < 0)
2288      length = strlen((char *)p);
2289    
2290  *vptr = d;  while (length-- > 0)
2291  return i+1;    {
2292  }  #if !defined NOUTF
2293      if (use_utf)
2294        {
2295        int rc = utf82ord(p, &c);
2296        if (rc > 0 && rc <= length + 1)   /* Mustn't run over the end */
2297          {
2298          length -= rc - 1;
2299          p += rc;
2300          yield += pchar(c, f);
2301          continue;
2302          }
2303        }
2304    #endif
2305      c = *p++;
2306      yield += pchar(c, f);
2307      }
2308    
2309    return yield;
2310    }
2311  #endif  #endif
2312    
2313    
2314    
2315    #ifdef SUPPORT_PCRE16
2316  /*************************************************  /*************************************************
2317  *       Convert character value to UTF-8         *  *    Find length of 0-terminated 16-bit string   *
2318  *************************************************/  *************************************************/
2319    
2320  /* This function takes an integer value in the range 0 - 0x7fffffff  static int strlen16(PCRE_SPTR16 p)
2321  and encodes it as a UTF-8 character in 0 to 6 bytes.  {
2322    int len = 0;
2323    while (*p++ != 0) len++;
2324    return len;
2325    }
2326    #endif  /* SUPPORT_PCRE16 */
2327    
 Arguments:  
   cvalue     the character value  
   utf8bytes  pointer to buffer for result - at least 6 bytes long  
2328    
 Returns:     number of characters placed in the buffer  
 */  
2329    
2330  #if !defined NOUTF8  #ifdef SUPPORT_PCRE32
2331    /*************************************************
2332    *    Find length of 0-terminated 32-bit string   *
2333    *************************************************/
2334    
2335  static int  static int strlen32(PCRE_SPTR32 p)
 ord2utf8(int cvalue, uschar *utf8bytes)  
2336  {  {
2337  register int i, j;  int len = 0;
2338  for (i = 0; i < utf8_table1_size; i++)  while (*p++ != 0) len++;
2339    if (cvalue <= utf8_table1[i]) break;  return len;
 utf8bytes += i;  
 for (j = i; j > 0; j--)  
  {  
  *utf8bytes-- = 0x80 | (cvalue & 0x3f);  
  cvalue >>= 6;  
  }  
 *utf8bytes = utf8_table2[i] | cvalue;  
 return i + 1;  
2340  }  }
2341    #endif  /* SUPPORT_PCRE32 */
 #endif  
2342    
2343    
2344    
2345    #ifdef SUPPORT_PCRE16
2346  /*************************************************  /*************************************************
2347  *             Print character string             *  *           Print 16-bit character string        *
2348  *************************************************/  *************************************************/
2349    
2350  /* Character string printing function. Must handle UTF-8 strings in utf8  /* Must handle UTF-16 strings in utf mode. Yields number of characters printed.
2351  mode. Yields number of characters printed. If handed a NULL file, just counts  If handed a NULL file, just counts chars without printing. */
 chars without printing. */  
2352    
2353  static int pchars(unsigned char *p, int length, FILE *f)  static int pchars16(PCRE_SPTR16 p, int length, FILE *f)
2354  {  {
 int c = 0;  
2355  int yield = 0;  int yield = 0;
2356    
2357    if (length < 0)
2358      length = strlen16(p);
2359    
2360  while (length-- > 0)  while (length-- > 0)
2361    {    {
2362  #if !defined NOUTF8    pcre_uint32 c = *p++ & 0xffff;
2363    if (use_utf8)  #if !defined NOUTF
2364      if (use_utf && c >= 0xD800 && c < 0xDC00 && length > 0)
2365      {      {
2366      int rc = utf82ord(p, &c);      int d = *p & 0xffff;
2367        if (d >= 0xDC00 && d < 0xDFFF)
     if (rc > 0 && rc <= length + 1)   /* Mustn't run over the end */  
2368        {        {
2369        length -= rc - 1;        c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000;
2370        p += rc;        length--;
2371        if (PRINTHEX(c))        p++;
         {  
         if (f != NULL) fprintf(f, "%c", c);  
         yield++;  
         }  
       else  
         {  
         int n = 4;  
         if (f != NULL) fprintf(f, "\\x{%02x}", c);  
         yield += (n <= 0x000000ff)? 2 :  
                  (n <= 0x00000fff)? 3 :  
                  (n <= 0x0000ffff)? 4 :  
                  (n <= 0x000fffff)? 5 : 6;  
         }  
       continue;  
2372        }        }
2373      }      }
2374  #endif  #endif
2375      yield += pchar(c, f);
2376      }
2377    
2378     /* Not UTF-8, or malformed UTF-8  */  return yield;
2379    }
2380    #endif  /* SUPPORT_PCRE16 */
2381    
2382    c = *p++;  
2383    if (PRINTHEX(c))  
2384      {  #ifdef SUPPORT_PCRE32
2385      if (f != NULL) fprintf(f, "%c", c);  /*************************************************
2386      yield++;  *           Print 32-bit character string        *
2387      }  *************************************************/
2388    else  
2389      {  /* Must handle UTF-32 strings in utf mode. Yields number of characters printed.
2390      if (f != NULL) fprintf(f, "\\x%02x", c);  If handed a NULL file, just counts chars without printing. */
2391      yield += 4;  
2392      }  #define UTF32_MASK (0x1fffffu)
2393    
2394    static int pchars32(PCRE_SPTR32 p, int length, BOOL utf, FILE *f)
2395    {
2396    int yield = 0;
2397    
2398    if (length < 0)
2399      length = strlen32(p);
2400    
2401    while (length-- > 0)
2402      {
2403      pcre_uint32 c = *p++;
2404      if (utf) c &= UTF32_MASK;
2405      yield += pchar(c, f);
2406    }    }
2407    
2408  return yield;  return yield;
2409  }  }
2410    #endif  /* SUPPORT_PCRE32 */
2411    
2412    
2413    
2414    #ifdef SUPPORT_PCRE8
2415    /*************************************************
2416    *     Read a capture name (8-bit) and check it   *
2417    *************************************************/
2418    
2419    static pcre_uint8 *
2420    read_capture_name8(pcre_uint8 *p, pcre_uint8 **pp, pcre *re)
2421    {
2422    pcre_uint8 *npp = *pp;
2423    while (isalnum(*p)) *npp++ = *p++;
2424    *npp++ = 0;
2425    *npp = 0;
2426    if (pcre_get_stringnumber(re, (char *)(*pp)) < 0)
2427      {
2428      fprintf(outfile, "no parentheses with name \"");
2429      PCHARSV(*pp, 0, -1, outfile);
2430      fprintf(outfile, "\"\n");
2431      }
2432    
2433    *pp = npp;
2434    return p;
2435    }
2436    #endif  /* SUPPORT_PCRE8 */
2437    
2438    
2439    
2440    #ifdef SUPPORT_PCRE16
2441    /*************************************************
2442    *     Read a capture name (16-bit) and check it  *
2443    *************************************************/
2444    
2445    /* Note that the text being read is 8-bit. */
2446    
2447    static pcre_uint8 *
2448    read_capture_name16(pcre_uint8 *p, pcre_uint16 **pp, pcre *re)
2449    {
2450    pcre_uint16 *npp = *pp;
2451    while (isalnum(*p)) *npp++ = *p++;
2452    *npp++ = 0;
2453    *npp = 0;
2454    if (pcre16_get_stringnumber((pcre16 *)re, (PCRE_SPTR16)(*pp)) < 0)
2455      {
2456      fprintf(outfile, "no parentheses with name \"");
2457      PCHARSV(*pp, 0, -1, outfile);
2458      fprintf(outfile, "\"\n");
2459      }
2460    *pp = npp;
2461    return p;
2462    }
2463    #endif  /* SUPPORT_PCRE16 */
2464    
2465    
2466    
2467    #ifdef SUPPORT_PCRE32
2468    /*************************************************
2469    *     Read a capture name (32-bit) and check it  *
2470    *************************************************/
2471    
2472    /* Note that the text being read is 8-bit. */
2473    
2474    static pcre_uint8 *
2475    read_capture_name32(pcre_uint8 *p, pcre_uint32 **pp, pcre *re)
2476    {
2477    pcre_uint32 *npp = *pp;
2478    while (isalnum(*p)) *npp++ = *p++;
2479    *npp++ = 0;
2480    *npp = 0;
2481    if (pcre32_get_stringnumber((pcre32 *)re, (PCRE_SPTR32)(*pp)) < 0)
2482      {
2483      fprintf(outfile, "no parentheses with name \"");
2484      PCHARSV(*pp, 0, -1, outfile);
2485      fprintf(outfile, "\"\n");
2486      }
2487    *pp = npp;
2488    return p;
2489    }
2490    #endif  /* SUPPORT_PCRE32 */
2491    
2492    
2493    
# Line 916  if (callout_extra) Line 2516  if (callout_extra)
2516      else      else
2517        {        {
2518        fprintf(f, "%2d: ", i/2);        fprintf(f, "%2d: ", i/2);
2519        (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i],        PCHARSV(cb->subject, cb->offset_vector[i],
2520          cb->offset_vector[i+1] - cb->offset_vector[i], f);          cb->offset_vector[i+1] - cb->offset_vector[i], f);
2521        fprintf(f, "\n");        fprintf(f, "\n");
2522        }        }
# Line 929  printed lengths of the substrings. */ Line 2529  printed lengths of the substrings. */
2529    
2530  if (f != NULL) fprintf(f, "--->");  if (f != NULL) fprintf(f, "--->");
2531    
2532  pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f);  PCHARS(pre_start, cb->subject, 0, cb->start_match, f);
2533  post_start = pchars((unsigned char *)(cb->subject + cb->start_match),  PCHARS(post_start, cb->subject, cb->start_match,
2534    cb->current_position - cb->start_match, f);    cb->current_position - cb->start_match, f);
2535    
2536  subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);  PCHARS(subject_length, cb->subject, 0, cb->subject_length, NULL);
2537    
2538  (void)pchars((unsigned char *)(cb->subject + cb->current_position),  PCHARSV(cb->subject, cb->current_position,
2539    cb->subject_length - cb->current_position, f);    cb->subject_length - cb->current_position, f);
2540    
2541  if (f != NULL) fprintf(f, "\n");  if (f != NULL) fprintf(f, "\n");
# Line 969  for (i = 0; i < subject_length - pre_sta Line 2569  for (i = 0; i < subject_length - pre_sta
2569  fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length,  fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length,
2570    pbuffer + cb->pattern_position);    pbuffer + cb->pattern_position);
2571    
2572  fprintf(outfile, "\n");  fprintf(outfile, "\n");
2573  first_callout = 0;  first_callout = 0;
2574    
2575    if (cb->mark != last_callout_mark)
2576      {
2577      if (cb->mark == NULL)
2578        fprintf(outfile, "Latest Mark: <unset>\n");
2579      else
2580        {
2581        fprintf(outfile, "Latest Mark: ");
2582        PCHARSV(cb->mark, 0, -1, outfile);
2583        putc('\n', outfile);
2584        }
2585      last_callout_mark = cb->mark;
2586      }
2587    
2588    if (cb->callout_data != NULL)
2589      {
2590      int callout_data = *((int *)(cb->callout_data));
2591      if (callout_data != 0)
2592        {
2593        fprintf(outfile, "Callout data = %d\n", callout_data);
2594        return callout_data;
2595        }
2596      }
2597    
2598    return (cb->callout_number != callout_fail_id)? 0 :
2599           (++callout_count >= callout_fail_count)? 1 : 0;
2600    }
2601    
2602    
2603    /*************************************************
2604    *            Local malloc functions              *
2605    *************************************************/
2606    
2607    /* Alternative malloc function, to test functionality and save the size of a
2608    compiled re, which is the first store request that pcre_compile() makes. The
2609    show_malloc variable is set only during matching. */
2610    
2611    static void *new_malloc(size_t size)
2612    {
2613    void *block = malloc(size);
2614    gotten_store = size;
2615    if (first_gotten_store == 0) first_gotten_store = size;
2616    if (show_malloc)
2617      fprintf(outfile, "malloc       %3d %p\n", (int)size, block);
2618    return block;
2619    }
2620    
2621    static void new_free(void *block)
2622    {
2623    if (show_malloc)
2624      fprintf(outfile, "free             %p\n", block);
2625    free(block);
2626    }
2627    
2628    /* For recursion malloc/free, to test stacking calls */
2629    
2630    static void *stack_malloc(size_t size)
2631    {
2632    void *block = malloc(size);
2633    if (show_malloc)
2634      fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block);
2635    return block;
2636    }
2637    
2638    static void stack_free(void *block)
2639    {
2640    if (show_malloc)
2641      fprintf(outfile, "stack_free       %p\n", block);
2642    free(block);
2643    }
2644    
2645    
2646    /*************************************************
2647    *          Call pcre_fullinfo()                  *
2648    *************************************************/
2649    
2650    /* Get one piece of information from the pcre_fullinfo() function. When only
2651    one of 8-, 16- or 32-bit is supported, pcre_mode should always have the correct
2652    value, but the code is defensive.
2653    
2654    Arguments:
2655      re        compiled regex
2656      study     study data
2657      option    PCRE_INFO_xxx option
2658      ptr       where to put the data
2659    
2660    Returns:    0 when OK, < 0 on error
2661    */
2662    
2663    static int
2664    new_info(pcre *re, pcre_extra *study, int option, void *ptr)
2665    {
2666    int rc;
2667    
2668    if (pcre_mode == PCRE32_MODE)
2669    #ifdef SUPPORT_PCRE32
2670      rc = pcre32_fullinfo((pcre32 *)re, (pcre32_extra *)study, option, ptr);
2671    #else
2672      rc = PCRE_ERROR_BADMODE;
2673    #endif
2674    else if (pcre_mode == PCRE16_MODE)
2675    #ifdef SUPPORT_PCRE16
2676      rc = pcre16_fullinfo((pcre16 *)re, (pcre16_extra *)study, option, ptr);
2677    #else
2678      rc = PCRE_ERROR_BADMODE;
2679    #endif
2680    else
2681    #ifdef SUPPORT_PCRE8
2682      rc = pcre_fullinfo(re, study, option, ptr);
2683    #else
2684      rc = PCRE_ERROR_BADMODE;
2685    #endif
2686    
2687    if (rc < 0)
2688      {
2689      fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc,
2690        pcre_mode == PCRE32_MODE ? "32" : pcre_mode == PCRE16_MODE ? "16" : "", option);
2691      if (rc == PCRE_ERROR_BADMODE)
2692        fprintf(outfile, "Running in %d-bit mode but pattern was compiled in "
2693          "%d-bit mode\n", 8 * CHAR_SIZE,
2694          8 * (REAL_PCRE_FLAGS(re) & PCRE_MODE_MASK));
2695      }
2696    
2697    return rc;
2698    }
2699    
2700    
2701    
2702    /*************************************************
2703    *             Swap byte functions                *
2704    *************************************************/
2705    
2706    /* The following functions swap the bytes of a pcre_uint16 and pcre_uint32
2707    value, respectively.
2708    
2709    Arguments:
2710      value        any number
2711    
2712    Returns:       the byte swapped value
2713    */
2714    
2715    static pcre_uint32
2716    swap_uint32(pcre_uint32 value)
2717    {
2718    return ((value & 0x000000ff) << 24) |
2719           ((value & 0x0000ff00) <<  8) |
2720           ((value & 0x00ff0000) >>  8) |
2721           (value >> 24);
2722    }
2723    
2724    static pcre_uint16
2725    swap_uint16(pcre_uint16 value)
2726    {
2727    return (value >> 8) | (value << 8);
2728    }
2729    
2730    
2731    
2732    /*************************************************
2733    *        Flip bytes in a compiled pattern        *
2734    *************************************************/
2735    
2736    /* This function is called if the 'F' option was present on a pattern that is
2737    to be written to a file. We flip the bytes of all the integer fields in the
2738    regex data block and the study block. In 16-bit mode this also flips relevant
2739    bytes in the pattern itself. This is to make it possible to test PCRE's
2740    ability to reload byte-flipped patterns, e.g. those compiled on a different
2741    architecture. */
2742    
2743    #if defined SUPPORT_PCRE8 || defined SUPPORT_PCRE16
2744    static void
2745    regexflip8_or_16(pcre *ere, pcre_extra *extra)
2746    {
2747    real_pcre8_or_16 *re = (real_pcre8_or_16 *)ere;
2748    #ifdef SUPPORT_PCRE16
2749    int op;
2750    pcre_uint16 *ptr = (pcre_uint16 *)re + re->name_table_offset;
2751    int length = re->name_count * re->name_entry_size;
2752    #ifdef SUPPORT_UTF
2753    BOOL utf = (re->options & PCRE_UTF16) != 0;
2754    BOOL utf16_char = FALSE;
2755    #endif /* SUPPORT_UTF */
2756    #endif /* SUPPORT_PCRE16 */
2757    
2758    /* Always flip the bytes in the main data block and study blocks. */
2759    
2760    re->magic_number = REVERSED_MAGIC_NUMBER;
2761    re->size = swap_uint32(re->size);
2762    re->options = swap_uint32(re->options);
2763    re->flags = swap_uint16(re->flags);
2764    re->top_bracket = swap_uint16(re->top_bracket);
2765    re->top_backref = swap_uint16(re->top_backref);
2766    re->first_char = swap_uint16(re->first_char);
2767    re->req_char = swap_uint16(re->req_char);
2768    re->name_table_offset = swap_uint16(re->name_table_offset);
2769    re->name_entry_size = swap_uint16(re->name_entry_size);
2770    re->name_count = swap_uint16(re->name_count);
2771    
2772  if (cb->mark != last_callout_mark)  if (extra != NULL)
2773    {    {
2774    fprintf(outfile, "Latest Mark: %s\n",    pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);
2775      (cb->mark == NULL)? "<unset>" : (char *)(cb->mark));    rsd->size = swap_uint32(rsd->size);
2776    last_callout_mark = cb->mark;    rsd->flags = swap_uint32(rsd->flags);
2777      rsd->minlength = swap_uint32(rsd->minlength);
2778    }    }
2779    
2780  if (cb->callout_data != NULL)  /* In 8-bit mode, that is all we need to do. In 16-bit mode we must swap bytes
2781    in the name table, if present, and then in the pattern itself. */
2782    
2783    #ifdef SUPPORT_PCRE16
2784    if (pcre_mode != PCRE16_MODE) return;
2785    
2786    while(TRUE)
2787    {    {
2788    int callout_data = *((int *)(cb->callout_data));    /* Swap previous characters. */
2789    if (callout_data != 0)    while (length-- > 0)
2790      {      {
2791      fprintf(outfile, "Callout data = %d\n", callout_data);      *ptr = swap_uint16(*ptr);
2792      return callout_data;      ptr++;
2793      }      }
2794    }  #ifdef SUPPORT_UTF
2795      if (utf16_char)
2796        {
2797        if ((ptr[-1] & 0xfc00) == 0xd800)
2798          {
2799          /* We know that there is only one extra character in UTF-16. */
2800          *ptr = swap_uint16(*ptr);
2801          ptr++;
2802          }
2803        }
2804      utf16_char = FALSE;
2805    #endif /* SUPPORT_UTF */
2806    
2807  return (cb->callout_number != callout_fail_id)? 0 :    /* Get next opcode. */
        (++callout_count >= callout_fail_count)? 1 : 0;  
 }  
2808    
2809      length = 0;
2810      op = *ptr;
2811      *ptr++ = swap_uint16(op);
2812    
2813  /*************************************************    switch (op)
2814  *            Local malloc functions              *      {
2815  *************************************************/      case OP_END:
2816        return;
2817    
2818  /* Alternative malloc function, to test functionality and save the size of a  #ifdef SUPPORT_UTF
2819  compiled re. The show_malloc variable is set only during matching. */      case OP_CHAR:
2820        case OP_CHARI:
2821        case OP_NOT:
2822        case OP_NOTI:
2823        case OP_STAR:
2824        case OP_MINSTAR:
2825        case OP_PLUS:
2826        case OP_MINPLUS:
2827        case OP_QUERY:
2828        case OP_MINQUERY:
2829        case OP_UPTO:
2830        case OP_MINUPTO:
2831        case OP_EXACT:
2832        case OP_POSSTAR:
2833        case OP_POSPLUS:
2834        case OP_POSQUERY:
2835        case OP_POSUPTO:
2836        case OP_STARI:
2837        case OP_MINSTARI:
2838        case OP_PLUSI:
2839        case OP_MINPLUSI:
2840        case OP_QUERYI:
2841        case OP_MINQUERYI:
2842        case OP_UPTOI:
2843        case OP_MINUPTOI:
2844        case OP_EXACTI:
2845        case OP_POSSTARI:
2846        case OP_POSPLUSI:
2847        case OP_POSQUERYI:
2848        case OP_POSUPTOI:
2849        case OP_NOTSTAR:
2850        case OP_NOTMINSTAR:
2851        case OP_NOTPLUS:
2852        case OP_NOTMINPLUS:
2853        case OP_NOTQUERY:
2854        case OP_NOTMINQUERY:
2855        case OP_NOTUPTO:
2856        case OP_NOTMINUPTO:
2857        case OP_NOTEXACT:
2858        case OP_NOTPOSSTAR:
2859        case OP_NOTPOSPLUS:
2860        case OP_NOTPOSQUERY:
2861        case OP_NOTPOSUPTO:
2862        case OP_NOTSTARI:
2863        case OP_NOTMINSTARI:
2864        case OP_NOTPLUSI:
2865        case OP_NOTMINPLUSI:
2866        case OP_NOTQUERYI:
2867        case OP_NOTMINQUERYI:
2868        case OP_NOTUPTOI:
2869        case OP_NOTMINUPTOI:
2870        case OP_NOTEXACTI:
2871        case OP_NOTPOSSTARI:
2872        case OP_NOTPOSPLUSI:
2873        case OP_NOTPOSQUERYI:
2874        case OP_NOTPOSUPTOI:
2875        if (utf) utf16_char = TRUE;
2876    #endif
2877        /* Fall through. */
2878    
2879  static void *new_malloc(size_t size)      default:
2880  {      length = OP_lengths16[op] - 1;
2881  void *block = malloc(size);      break;
2882  gotten_store = size;  
2883  if (show_malloc)      case OP_CLASS:
2884    fprintf(outfile, "malloc       %3d %p\n", (int)size, block);      case OP_NCLASS:
2885  return block;      /* Skip the character bit map. */
2886  }      ptr += 32/sizeof(pcre_uint16);
2887        length = 0;
2888        break;
2889    
2890        case OP_XCLASS:
2891        /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
2892        if (LINK_SIZE > 1)
2893          length = (int)((((unsigned int)(ptr[0]) << 16) | (unsigned int)(ptr[1]))
2894            - (1 + LINK_SIZE + 1));
2895        else
2896          length = (int)((unsigned int)(ptr[0]) - (1 + LINK_SIZE + 1));
2897    
2898  static void new_free(void *block)      /* Reverse the size of the XCLASS instance. */
2899  {      *ptr = swap_uint16(*ptr);
2900  if (show_malloc)      ptr++;
2901    fprintf(outfile, "free             %p\n", block);      if (LINK_SIZE > 1)
2902  free(block);        {
2903          *ptr = swap_uint16(*ptr);
2904          ptr++;
2905          }
2906    
2907        op = *ptr;
2908        *ptr = swap_uint16(op);
2909        ptr++;
2910        if ((op & XCL_MAP) != 0)
2911          {
2912          /* Skip the character bit map. */
2913          ptr += 32/sizeof(pcre_uint16);
2914          length -= 32/sizeof(pcre_uint16);
2915          }
2916        break;
2917        }
2918      }
2919    /* Control should never reach here in 16 bit mode. */
2920    #endif /* SUPPORT_PCRE16 */
2921  }  }
2922    #endif /* SUPPORT_PCRE[8|16] */
2923    
 /* For recursion malloc/free, to test stacking calls */  
2924    
 static void *stack_malloc(size_t size)  
 {  
 void *block = malloc(size);  
 if (show_malloc)  
   fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block);  
 return block;  
 }  
2925    
2926  static void stack_free(void *block)  #if defined SUPPORT_PCRE32
2927    static void
2928    regexflip_32(pcre *ere, pcre_extra *extra)
2929  {  {
2930  if (show_malloc)  real_pcre32 *re = (real_pcre32 *)ere;
2931    fprintf(outfile, "stack_free       %p\n", block);  int op;
2932  free(block);  pcre_uint32 *ptr = (pcre_uint32 *)re + re->name_table_offset;
2933  }  int length = re->name_count * re->name_entry_size;
2934    #ifdef SUPPORT_UTF
2935    BOOL utf = (re->options & PCRE_UTF32) != 0;
2936    #endif /* SUPPORT_UTF */
2937    
2938    /* Always flip the bytes in the main data block and study blocks. */
2939    
2940    re->magic_number = REVERSED_MAGIC_NUMBER;
2941    re->size = swap_uint32(re->size);
2942    re->options = swap_uint32(re->options);
2943    re->flags = swap_uint16(re->flags);
2944    re->top_bracket = swap_uint16(re->top_bracket);
2945    re->top_backref = swap_uint16(re->top_backref);
2946    re->first_char = swap_uint32(re->first_char);
2947    re->req_char = swap_uint32(re->req_char);
2948    re->name_table_offset = swap_uint16(re->name_table_offset);
2949    re->name_entry_size = swap_uint16(re->name_entry_size);
2950    re->name_count = swap_uint16(re->name_count);
2951    
2952    if (extra != NULL)
2953      {
2954      pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);
2955      rsd->size = swap_uint32(rsd->size);
2956      rsd->flags = swap_uint32(rsd->flags);
2957      rsd->minlength = swap_uint32(rsd->minlength);
2958      }
2959    
2960    /* In 32-bit mode we must swap bytes
2961    in the name table, if present, and then in the pattern itself. */
2962    
2963  /*************************************************  while(TRUE)
2964  *          Call pcre_fullinfo()                  *    {
2965  *************************************************/    /* Swap previous characters. */
2966      while (length-- > 0)
2967        {
2968        *ptr = swap_uint32(*ptr);
2969        ptr++;
2970        }
2971    
2972  /* Get one piece of information from the pcre_fullinfo() function */    /* Get next opcode. */
2973    
2974  static void new_info(pcre *re, pcre_extra *study, int option, void *ptr)    length = 0;
2975  {    op = *ptr;
2976  int rc;    *ptr++ = swap_uint32(op);
2977  if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)  
2978    fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);    switch (op)
2979        {
2980        case OP_END:
2981        return;
2982    
2983        default:
2984        length = OP_lengths32[op] - 1;
2985        break;
2986    
2987        case OP_CLASS:
2988        case OP_NCLASS:
2989        /* Skip the character bit map. */
2990        ptr += 32/sizeof(pcre_uint32);
2991        length = 0;
2992        break;
2993    
2994        case OP_XCLASS:
2995        /* LINK_SIZE can only be 1 in 32-bit mode. */
2996        length = (int)((unsigned int)(ptr[0]) - (1 + LINK_SIZE + 1));
2997    
2998        /* Reverse the size of the XCLASS instance. */
2999        *ptr = swap_uint32(*ptr);
3000        ptr++;
3001    
3002        op = *ptr;
3003        *ptr = swap_uint32(op);
3004        ptr++;
3005        if ((op & XCL_MAP) != 0)
3006          {
3007          /* Skip the character bit map. */
3008          ptr += 32/sizeof(pcre_uint32);
3009          length -= 32/sizeof(pcre_uint32);
3010          }
3011        break;
3012        }
3013      }
3014    /* Control should never reach here in 32 bit mode. */
3015  }  }
3016    
3017    #endif /* SUPPORT_PCRE32 */
3018    
3019    
 /*************************************************  
 *         Byte flipping function                 *  
 *************************************************/  
3020    
3021  static unsigned long int  static void
3022  byteflip(unsigned long int value, int n)  regexflip(pcre *ere, pcre_extra *extra)
3023  {  {
3024  if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);  #if defined SUPPORT_PCRE32
3025  return ((value & 0x000000ff) << 24) |    if (REAL_PCRE_FLAGS(ere) & PCRE_MODE32)
3026         ((value & 0x0000ff00) <<  8) |      regexflip_32(ere, extra);
3027         ((value & 0x00ff0000) >>  8) |  #endif
3028         ((value & 0xff000000) >> 24);  #if defined SUPPORT_PCRE8 || defined SUPPORT_PCRE16
3029      if (REAL_PCRE_FLAGS(ere) & (PCRE_MODE8 | PCRE_MODE16))
3030        regexflip8_or_16(ere, extra);
3031    #endif
3032  }  }
3033    
3034    
3035    
   
3036  /*************************************************  /*************************************************
3037  *        Check match or recursion limit          *  *        Check match or recursion limit          *
3038  *************************************************/  *************************************************/
3039    
3040  static int  static int
3041  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,
3042    int start_offset, int options, int *use_offsets, int use_size_offsets,    int start_offset, int options, int *use_offsets, int use_size_offsets,
3043    int flag, unsigned long int *limit, int errnumber, const char *msg)    int flag, unsigned long int *limit, int errnumber, const char *msg)
3044  {  {
# Line 1087  for (;;) Line 3053  for (;;)
3053    {    {
3054    *limit = mid;    *limit = mid;
3055    
3056    count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options,    PCRE_EXEC(count, re, extra, bptr, len, start_offset, options,
3057      use_offsets, use_size_offsets);      use_offsets, use_size_offsets);
3058    
3059    if (count == errnumber)    if (count == errnumber)
# Line 1132  Returns:    < 0, = 0, or > 0, according Line 3098  Returns:    < 0, = 0, or > 0, according
3098  */  */
3099    
3100  static int  static int
3101  strncmpic(uschar *s, uschar *t, int n)  strncmpic(pcre_uint8 *s, pcre_uint8 *t, int n)
3102  {  {
3103  while (n--)  while (n--)
3104    {    {
# Line 1159  Returns:      appropriate PCRE_NEWLINE_x Line 3125  Returns:      appropriate PCRE_NEWLINE_x
3125  */  */
3126    
3127  static int  static int
3128  check_newline(uschar *p, FILE *f)  check_newline(pcre_uint8 *p, FILE *f)
3129  {  {
3130  if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;  if (strncmpic(p, (pcre_uint8 *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
3131  if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;  if (strncmpic(p, (pcre_uint8 *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
3132  if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;  if (strncmpic(p, (pcre_uint8 *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
3133  if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;  if (strncmpic(p, (pcre_uint8 *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
3134  if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;  if (strncmpic(p, (pcre_uint8 *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
3135  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;
3136  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;
3137  fprintf(f, "Unknown newline type at: <%s\n", p);  fprintf(f, "Unknown newline type at: <%s\n", p);
3138  return 0;  return 0;
3139  }  }
# Line 1183  usage(void) Line 3149  usage(void)
3149  {  {
3150  printf("Usage:     pcretest [options] [<input file> [<output file>]]\n\n");  printf("Usage:     pcretest [options] [<input file> [<output file>]]\n\n");
3151  printf("Input and output default to stdin and stdout.\n");  printf("Input and output default to stdin and stdout.\n");
3152  #ifdef SUPPORT_LIBREADLINE  #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
3153  printf("If input is a terminal, readline() is used to read from it.\n");  printf("If input is a terminal, readline() is used to read from it.\n");
3154  #else  #else
3155  printf("This version of pcretest is not linked with readline().\n");  printf("This version of pcretest is not linked with readline().\n");
3156  #endif  #endif
3157  printf("\nOptions:\n");  printf("\nOptions:\n");
3158  printf("  -b       show compiled code (bytecode)\n");  #ifdef SUPPORT_PCRE16
3159    printf("  -16      use the 16-bit library\n");
3160    #endif
3161    #ifdef SUPPORT_PCRE32
3162    printf("  -32      use the 32-bit library\n");
3163    #endif
3164    printf("  -b       show compiled code\n");
3165  printf("  -C       show PCRE compile-time options and exit\n");  printf("  -C       show PCRE compile-time options and exit\n");
3166    printf("  -C arg   show a specific compile-time option\n");
3167    printf("           and exit with its value. The arg can be:\n");
3168    printf("     linksize     internal link size [2, 3, 4]\n");
3169    printf("     pcre8        8 bit library support enabled [0, 1]\n");
3170    printf("     pcre16       16 bit library support enabled [0, 1]\n");
3171    printf("     pcre32       32 bit library support enabled [0, 1]\n");
3172    printf("     utf          Unicode Transformation Format supported [0, 1]\n");
3173    printf("     ucp          Unicode Properties supported [0, 1]\n");
3174    printf("     jit          Just-in-time compiler supported [0, 1]\n");
3175    printf("     newline      Newline type [CR, LF, CRLF, ANYCRLF, ANY, ???]\n");
3176  printf("  -d       debug: show compiled code and information (-b and -i)\n");  printf("  -d       debug: show compiled code and information (-b and -i)\n");
3177  #if !defined NODFA  #if !defined NODFA
3178  printf("  -dfa     force DFA matching for all subjects\n");  printf("  -dfa     force DFA matching for all subjects\n");
# Line 1207  printf("  -q       quiet: do not output Line 3189  printf("  -q       quiet: do not output
3189  printf("  -S <n>   set stack size to <n> megabytes\n");  printf("  -S <n>   set stack size to <n> megabytes\n");
3190  printf("  -s       force each pattern to be studied at basic level\n"  printf("  -s       force each pattern to be studied at basic level\n"
3191         "  -s+      force each pattern to be studied, using JIT if available\n"         "  -s+      force each pattern to be studied, using JIT if available\n"
3192           "  -s++     ditto, verifying when JIT was actually used\n"
3193           "  -s+n     force each pattern to be studied, using JIT if available,\n"
3194           "             where 1 <= n <= 7 selects JIT options\n"
3195           "  -s++n    ditto, verifying when JIT was actually used\n"
3196         "  -t       time compilation and execution\n");         "  -t       time compilation and execution\n");
3197  printf("  -t <n>   time compilation and execution, repeating <n> times\n");  printf("  -t <n>   time compilation and execution, repeating <n> times\n");
3198  printf("  -tm      time execution (matching) only\n");  printf("  -tm      time execution (matching) only\n");
# Line 1226  options, followed by a set of test data, Line 3212  options, followed by a set of test data,
3212  int main(int argc, char **argv)  int main(int argc, char **argv)
3213  {  {
3214  FILE *infile = stdin;  FILE *infile = stdin;
3215    const char *version;
3216  int options = 0;  int options = 0;
3217  int study_options = 0;  int study_options = 0;
3218  int default_find_match_limit = FALSE;  int default_find_match_limit = FALSE;
# Line 1240  int quiet = 0; Line 3227  int quiet = 0;
3227  int size_offsets = 45;  int size_offsets = 45;
3228  int size_offsets_max;  int size_offsets_max;
3229  int *offsets = NULL;  int *offsets = NULL;
 #if !defined NOPOSIX  
 int posix = 0;  
 #endif  
3230  int debug = 0;  int debug = 0;
3231  int done = 0;  int done = 0;
3232  int all_use_dfa = 0;  int all_use_dfa = 0;
3233    int verify_jit = 0;
3234  int yield = 0;  int yield = 0;
3235    #ifdef SUPPORT_PCRE32
3236    int mask_utf32 = 0;
3237    #endif
3238  int stack_size;  int stack_size;
3239    pcre_uint8 *dbuffer = NULL;
3240    size_t dbuffer_size = 1u << 14;
3241    
3242  pcre_jit_stack *jit_stack = NULL;  #if !defined NOPOSIX
3243    int posix = 0;
3244    #endif
3245    #if !defined NODFA
3246    int *dfa_workspace = NULL;
3247    #endif
3248    
3249    pcre_jit_stack *jit_stack = NULL;
3250    
3251  /* These vectors store, end-to-end, a list of captured substring names. Assume  /* These vectors store, end-to-end, a list of zero-terminated captured
3252  that 1024 is plenty long enough for the few names we'll be testing. */  substring names, each list itself being terminated by an empty name. Assume
3253    that 1024 is plenty long enough for the few names we'll be testing. It is
3254    easiest to keep separate 8-, 16- and 32-bit versions, using the 32-bit version
3255    for the actual memory, to ensure alignment. */
3256    
3257    pcre_uint32 copynames[1024];
3258    pcre_uint32 getnames[1024];
3259    
3260    #ifdef SUPPORT_PCRE32
3261    pcre_uint32 *cn32ptr;
3262    pcre_uint32 *gn32ptr;
3263    #endif
3264    
3265  uschar copynames[1024];  #ifdef SUPPORT_PCRE16
3266  uschar getnames[1024];  pcre_uint16 *copynames16 = (pcre_uint16 *)copynames;
3267    pcre_uint16 *getnames16 = (pcre_uint16 *)getnames;
3268    pcre_uint16 *cn16ptr;
3269    pcre_uint16 *gn16ptr;
3270    #endif
3271    
3272  uschar *copynamesptr;  #ifdef SUPPORT_PCRE8
3273  uschar *getnamesptr;  pcre_uint8 *copynames8 = (pcre_uint8 *)copynames;
3274    pcre_uint8 *getnames8 = (pcre_uint8 *)getnames;
3275    pcre_uint8 *cn8ptr;
3276    pcre_uint8 *gn8ptr;
3277    #endif
3278    
3279  /* Get buffers from malloc() so that Electric Fence will check their misuse  /* Get buffers from malloc() so that valgrind will check their misuse when
3280  when I am debugging. They grow automatically when very long lines are read. */  debugging. They grow automatically when very long lines are read. The 16-
3281    and 32-bit buffers (buffer16, buffer32) are obtained only if needed. */
3282    
3283  buffer = (unsigned char *)malloc(buffer_size);  buffer = (pcre_uint8 *)malloc(buffer_size);
3284  dbuffer = (unsigned char *)malloc(buffer_size);  pbuffer = (pcre_uint8 *)malloc(buffer_size);
 pbuffer = (unsigned char *)malloc(buffer_size);  
3285    
3286  /* The outfile variable is static so that new_malloc can use it. */  /* The outfile variable is static so that new_malloc can use it. */
3287    
# Line 1281  it set 0x8000, but then I was advised th Line 3296  it set 0x8000, but then I was advised th
3296  _setmode( _fileno( stdout ), _O_BINARY );  _setmode( _fileno( stdout ), _O_BINARY );
3297  #endif  #endif
3298    
3299    /* Get the version number: both pcre_version() and pcre16_version() give the
3300    same answer. We just need to ensure that we call one that is available. */
3301    
3302    #if defined SUPPORT_PCRE8
3303    version = pcre_version();
3304    #elif defined SUPPORT_PCRE16
3305    version = pcre16_version();
3306    #elif defined SUPPORT_PCRE32
3307    version = pcre32_version();
3308    #endif
3309    
3310  /* Scan options */  /* Scan options */
3311    
3312  while (argc > 1 && argv[op][0] == '-')  while (argc > 1 && argv[op][0] == '-')
3313    {    {
3314    unsigned char *endptr;    pcre_uint8 *endptr;
3315      char *arg = argv[op];
3316    
3317    if (strcmp(argv[op], "-m") == 0) showstore = 1;    if (strcmp(arg, "-m") == 0) showstore = 1;
3318    else if (strcmp(argv[op], "-s") == 0) force_study = 0;    else if (strcmp(arg, "-s") == 0) force_study = 0;
3319    else if (strcmp(argv[op], "-s+") == 0)  
3320      else if (strncmp(arg, "-s+", 3) == 0)
3321      {      {
3322        arg += 3;
3323        if (*arg == '+') { arg++; verify_jit = TRUE; }
3324      force_study = 1;      force_study = 1;
3325      force_study_options = PCRE_STUDY_JIT_COMPILE;      if (*arg == 0)
3326      }        force_study_options = jit_study_bits[6];
3327    else if (strcmp(argv[op], "-q") == 0) quiet = 1;      else if (*arg >= '1' && *arg <= '7')
3328    else if (strcmp(argv[op], "-b") == 0) debug = 1;        force_study_options = jit_study_bits[*arg - '1'];
3329    else if (strcmp(argv[op], "-i") == 0) showinfo = 1;      else goto BAD_ARG;
3330    else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;      }
3331    else if (strcmp(argv[op], "-M") == 0) default_find_match_limit = TRUE;    else if (strcmp(arg, "-8") == 0)
3332        {
3333    #ifdef SUPPORT_PCRE8
3334        pcre_mode = PCRE8_MODE;
3335    #else
3336        printf("** This version of PCRE was built without 8-bit support\n");
3337        exit(1);
3338    #endif
3339        }
3340      else if (strcmp(arg, "-16") == 0)
3341        {
3342    #ifdef SUPPORT_PCRE16
3343        pcre_mode = PCRE16_MODE;
3344    #else
3345        printf("** This version of PCRE was built without 16-bit support\n");
3346        exit(1);
3347    #endif
3348        }
3349      else if (strcmp(arg, "-32") == 0 || strcmp(arg, "-32+") == 0)
3350        {
3351    #ifdef SUPPORT_PCRE32
3352        pcre_mode = PCRE32_MODE;
3353        mask_utf32 = (strcmp(arg, "-32+") == 0);
3354    #else
3355        printf("** This version of PCRE was built without 32-bit support\n");
3356        exit(1);
3357    #endif
3358        }
3359      else if (strcmp(arg, "-q") == 0) quiet = 1;
3360      else if (strcmp(arg, "-b") == 0) debug = 1;
3361      else if (strcmp(arg, "-i") == 0) showinfo = 1;
3362      else if (strcmp(arg, "-d") == 0) showinfo = debug = 1;
3363      else if (strcmp(arg, "-M") == 0) default_find_match_limit = TRUE;
3364  #if !defined NODFA  #if !defined NODFA
3365    else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;    else if (strcmp(arg, "-dfa") == 0) all_use_dfa = 1;
3366  #endif  #endif
3367    else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&    else if (strcmp(arg, "-o") == 0 && argc > 2 &&
3368        ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)),        ((size_offsets = get_value((pcre_uint8 *)argv[op+1], &endptr)),
3369          *endptr == 0))          *endptr == 0))
3370      {      {
3371      op++;      op++;
3372      argc--;      argc--;
3373      }      }
3374    else if (strcmp(argv[op], "-t") == 0 || strcmp(argv[op], "-tm") == 0)    else if (strcmp(arg, "-t") == 0 || strcmp(arg, "-tm") == 0)
3375      {      {
3376      int both = argv[op][2] == 0;      int both = arg[2] == 0;
3377      int temp;      int temp;
3378      if (argc > 2 && (temp = get_value((unsigned char *)argv[op+1], &endptr),      if (argc > 2 && (temp = get_value((pcre_uint8 *)argv[op+1], &endptr),
3379                       *endptr == 0))                       *endptr == 0))
3380        {        {
3381        timeitm = temp;        timeitm = temp;
# Line 1323  while (argc > 1 && argv[op][0] == '-') Line 3385  while (argc > 1 && argv[op][0] == '-')
3385      else timeitm = LOOPREPEAT;      else timeitm = LOOPREPEAT;
3386      if (both) timeit = timeitm;      if (both) timeit = timeitm;
3387      }      }
3388    else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&    else if (strcmp(arg, "-S") == 0 && argc > 2 &&
3389        ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)),        ((stack_size = get_value((pcre_uint8 *)argv[op+1], &endptr)),
3390          *endptr == 0))          *endptr == 0))
3391      {      {
3392  #if defined(_WIN32) || defined(WIN32) || defined(__minix)  #if defined(_WIN32) || defined(WIN32) || defined(__minix) || defined(NATIVE_ZOS)
3393      printf("PCRE: -S not supported on this OS\n");      printf("PCRE: -S not supported on this OS\n");
3394      exit(1);      exit(1);
3395  #else  #else
# Line 1346  while (argc > 1 && argv[op][0] == '-') Line 3408  while (argc > 1 && argv[op][0] == '-')
3408  #endif  #endif
3409      }      }
3410  #if !defined NOPOSIX  #if !defined NOPOSIX
3411    else if (strcmp(argv[op], "-p") == 0) posix = 1;    else if (strcmp(arg, "-p") == 0) posix = 1;
3412  #endif  #endif
3413    else if (strcmp(argv[op], "-C") == 0)    else if (strcmp(arg, "-C") == 0)
3414      {      {
3415      int rc;      int rc;
3416      unsigned long int lrc;      unsigned long int lrc;
3417      printf("PCRE version %s\n", pcre_version());  
3418        if (argc > 2)
3419          {
3420          if (strcmp(argv[op + 1], "linksize") == 0)
3421            {
3422            (void)PCRE_CONFIG(PCRE_CONFIG_LINK_SIZE, &rc);
3423            printf("%d\n", rc);
3424            yield = rc;
3425            }
3426          else if (strcmp(argv[op + 1], "pcre8") == 0)
3427            {
3428    #ifdef SUPPORT_PCRE8
3429            printf("1\n");
3430            yield = 1;
3431    #else
3432            printf("0\n");
3433            yield = 0;
3434    #endif
3435            }
3436          else if (strcmp(argv[op + 1], "pcre16") == 0)
3437            {
3438    #ifdef SUPPORT_PCRE16
3439            printf("1\n");
3440            yield = 1;
3441    #else
3442            printf("0\n");
3443            yield = 0;
3444    #endif
3445            }
3446          else if (strcmp(argv[op + 1], "pcre32") == 0)
3447            {
3448    #ifdef SUPPORT_PCRE32
3449            printf("1\n");
3450            yield = 1;
3451    #else
3452            printf("0\n");
3453            yield = 0;
3454    #endif
3455            goto EXIT;
3456            }
3457          if (strcmp(argv[op + 1], "utf") == 0)
3458            {
3459    #ifdef SUPPORT_PCRE8
3460            if (pcre_mode == PCRE8_MODE)
3461              (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
3462    #endif
3463    #ifdef SUPPORT_PCRE16
3464            if (pcre_mode == PCRE16_MODE)
3465              (void)pcre16_config(PCRE_CONFIG_UTF16, &rc);
3466    #endif
3467    #ifdef SUPPORT_PCRE32
3468            if (pcre_mode == PCRE32_MODE)
3469              (void)pcre32_config(PCRE_CONFIG_UTF32, &rc);
3470    #endif
3471            printf("%d\n", rc);
3472            yield = rc;
3473            goto EXIT;
3474            }
3475          else if (strcmp(argv[op + 1], "ucp") == 0)
3476            {
3477            (void)PCRE_CONFIG(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
3478            printf("%d\n", rc);
3479            yield = rc;
3480            }
3481          else if (strcmp(argv[op + 1], "jit") == 0)
3482            {
3483            (void)PCRE_CONFIG(PCRE_CONFIG_JIT, &rc);
3484            printf("%d\n", rc);
3485            yield = rc;
3486            }
3487          else if (strcmp(argv[op + 1], "newline") == 0)
3488            {
3489            (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &rc);
3490            print_newline_config(rc, TRUE);
3491            }
3492          else if (strcmp(argv[op + 1], "ebcdic") == 0)
3493            {
3494    #ifdef EBCDIC
3495            printf("1\n");
3496            yield = 1;
3497    #else
3498            printf("0\n");
3499    #endif
3500            }
3501          else if (strcmp(argv[op + 1], "ebcdic-nl") == 0)
3502            {
3503    #ifdef EBCDIC
3504            printf("0x%02x\n", CHAR_LF);
3505    #else
3506            printf("0\n");
3507    #endif
3508            }
3509          else
3510            {
3511            printf("Unknown -C option: %s\n", argv[op + 1]);
3512            }
3513          goto EXIT;
3514          }
3515    
3516        /* No argument for -C: output all configuration information. */
3517    
3518        printf("PCRE version %s\n", version);
3519      printf("Compiled with\n");      printf("Compiled with\n");
3520    
3521    #ifdef EBCDIC
3522        printf("  EBCDIC code support: LF is 0x%02x\n", CHAR_LF);
3523    #endif
3524    
3525    /* At least one of SUPPORT_PCRE8 and SUPPORT_PCRE16 will be set. If both
3526    are set, either both UTFs are supported or both are not supported. */
3527    
3528    #ifdef SUPPORT_PCRE8
3529        printf("  8-bit support\n");
3530      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);      (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
3531      printf("  %sUTF-8 support\n", rc? "" : "No ");        printf ("  %sUTF-8 support\n", rc ? "" : "No ");
3532      (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);  #endif
3533    #ifdef SUPPORT_PCRE16
3534        printf("  16-bit support\n");
3535        (void)pcre16_config(PCRE_CONFIG_UTF16, &rc);
3536        printf ("  %sUTF-16 support\n", rc ? "" : "No ");
3537    #endif
3538    #ifdef SUPPORT_PCRE32
3539        printf("  32-bit support\n");
3540        (void)pcre32_config(PCRE_CONFIG_UTF32, &rc);
3541        printf ("  %sUTF-32 support\n", rc ? "" : "No ");
3542    #endif
3543    
3544        (void)PCRE_CONFIG(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
3545      printf("  %sUnicode properties support\n", rc? "" : "No ");      printf("  %sUnicode properties support\n", rc? "" : "No ");
3546      (void)pcre_config(PCRE_CONFIG_JIT, &rc);      (void)PCRE_CONFIG(PCRE_CONFIG_JIT, &rc);
3547      if (rc)      if (rc)
3548        printf("  Just-in-time compiler support\n");        {
3549          const char *arch;
3550          (void)PCRE_CONFIG(PCRE_CONFIG_JITTARGET, (void *)(&arch));
3551          printf("  Just-in-time compiler support: %s\n", arch);
3552          }
3553      else      else
3554        printf("  No just-in-time compiler support\n");        printf("  No just-in-time compiler support\n");
3555      (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);      (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &rc);
3556      /* Note that these values are always the ASCII values, even      print_newline_config(rc, FALSE);
3557      in EBCDIC environments. CR is 13 and NL is 10. */      (void)PCRE_CONFIG(PCRE_CONFIG_BSR, &rc);
     printf("  Newline sequence is %s\n", (rc == 13)? "CR" :  
       (rc == 10)? "LF" : (rc == (13<<8 | 10))? "CRLF" :  
       (rc == -2)? "ANYCRLF" :  
       (rc == -1)? "ANY" : "???");  
     (void)pcre_config(PCRE_CONFIG_BSR, &rc);  
3558      printf("  \\R matches %s\n", rc? "CR, LF, or CRLF only" :      printf("  \\R matches %s\n", rc? "CR, LF, or CRLF only" :
3559                                       "all Unicode newlines");                                       "all Unicode newlines");
3560      (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);      (void)PCRE_CONFIG(PCRE_CONFIG_LINK_SIZE, &rc);
3561      printf("  Internal link size = %d\n", rc);      printf("  Internal link size = %d\n", rc);
3562      (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);      (void)PCRE_CONFIG(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);
3563      printf("  POSIX malloc threshold = %d\n", rc);      printf("  POSIX malloc threshold = %d\n", rc);
3564      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &lrc);      (void)PCRE_CONFIG(PCRE_CONFIG_MATCH_LIMIT, &lrc);
3565      printf("  Default match limit = %ld\n", lrc);      printf("  Default match limit = %ld\n", lrc);
3566      (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &lrc);      (void)PCRE_CONFIG(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &lrc);
3567      printf("  Default recursion depth limit = %ld\n", lrc);      printf("  Default recursion depth limit = %ld\n", lrc);
3568      (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc);      (void)PCRE_CONFIG(PCRE_CONFIG_STACKRECURSE, &rc);
3569      printf("  Match recursion uses %s\n", rc? "stack" : "heap");      printf("  Match recursion uses %s", rc? "stack" : "heap");
3570        if (showstore)
3571          {
3572          PCRE_EXEC(stack_size, NULL, NULL, NULL, -999, -999, 0, NULL, 0);
3573          printf(": %sframe size = %d bytes", rc? "approximate " : "", -stack_size);
3574          }
3575        printf("\n");
3576      goto EXIT;      goto EXIT;
3577      }      }
3578    else if (strcmp(argv[op], "-help") == 0 ||    else if (strcmp(arg, "-help") == 0 ||
3579             strcmp(argv[op], "--help") == 0)             strcmp(arg, "--help") == 0)
3580      {      {
3581      usage();      usage();
3582      goto EXIT;      goto EXIT;
3583      }      }
3584    else    else
3585      {      {
3586      printf("** Unknown or malformed option %s\n", argv[op]);      BAD_ARG:
3587        printf("** Unknown or malformed option %s\n", arg);
3588      usage();      usage();
3589      yield = 1;      yield = 1;
3590      goto EXIT;      goto EXIT;
# Line 1440  if (argc > 2) Line 3631  if (argc > 2)
3631    
3632  /* Set alternative malloc function */  /* Set alternative malloc function */
3633    
3634    #ifdef SUPPORT_PCRE8
3635  pcre_malloc = new_malloc;  pcre_malloc = new_malloc;
3636  pcre_free = new_free;  pcre_free = new_free;
3637  pcre_stack_malloc = stack_malloc;  pcre_stack_malloc = stack_malloc;
3638  pcre_stack_free = stack_free;  pcre_stack_free = stack_free;
3639    #endif
3640    
3641    #ifdef SUPPORT_PCRE16
3642    pcre16_malloc = new_malloc;
3643    pcre16_free = new_free;
3644    pcre16_stack_malloc = stack_malloc;
3645    pcre16_stack_free = stack_free;
3646    #endif
3647    
3648    #ifdef SUPPORT_PCRE32
3649    pcre32_malloc = new_malloc;
3650    pcre32_free = new_free;
3651    pcre32_stack_malloc = stack_malloc;
3652    pcre32_stack_free = stack_free;
3653    #endif
3654    
3655  /* Heading line unless quiet, then prompt for first regex if stdin */  /* Heading line unless quiet, then prompt for first regex if stdin */
3656    
3657  if (!quiet) fprintf(outfile, "PCRE version %s\n\n", pcre_version());  if (!quiet) fprintf(outfile, "PCRE version %s\n\n", version);
3658    
3659  /* Main loop */  /* Main loop */
3660    
# Line 1462  while (!done) Line 3669  while (!done)
3669  #endif  #endif
3670    
3671    const char *error;    const char *error;
3672    unsigned char *markptr;    pcre_uint8 *markptr;
3673    unsigned char *p, *pp, *ppp;    pcre_uint8 *p, *pp, *ppp;
3674    unsigned char *to_file = NULL;    pcre_uint8 *to_file = NULL;
3675    const unsigned char *tables = NULL;    const pcre_uint8 *tables = NULL;
3676      unsigned long int get_options;
3677    unsigned long int true_size, true_study_size = 0;    unsigned long int true_size, true_study_size = 0;
3678    size_t size, regex_gotten_store;    size_t size, regex_gotten_store;
3679    int do_allcaps = 0;    int do_allcaps = 0;
# Line 1481  while (!done) Line 3689  while (!done)
3689    int do_flip = 0;    int do_flip = 0;
3690    int erroroffset, len, delimiter, poffset;    int erroroffset, len, delimiter, poffset;
3691    
3692    use_utf8 = 0;  #if !defined NODFA
3693      int dfa_matched = 0;
3694    #endif
3695    
3696      use_utf = 0;
3697    debug_lengths = 1;    debug_lengths = 1;
3698    
3699    if (extend_inputline(infile, buffer, "  re> ") == NULL) break;    if (extend_inputline(infile, buffer, "  re> ") == NULL) break;
# Line 1496  while (!done) Line 3708  while (!done)
3708    
3709    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)    if (*p == '<' && strchr((char *)(p+1), '<') == NULL)
3710      {      {
3711      unsigned long int magic, get_options;      pcre_uint32 magic;
3712      uschar sbuf[8];      pcre_uint8 sbuf[8];
3713      FILE *f;      FILE *f;
3714    
3715      p++;      p++;
3716        if (*p == '!')
3717          {
3718          do_debug = TRUE;
3719          do_showinfo = TRUE;
3720          p++;
3721          }
3722    
3723      pp = p + (int)strlen((char *)p);      pp = p + (int)strlen((char *)p);
3724      while (isspace(pp[-1])) pp--;      while (isspace(pp[-1])) pp--;
3725      *pp = 0;      *pp = 0;
# Line 1512  while (!done) Line 3731  while (!done)
3731        continue;        continue;
3732        }        }
3733    
3734        first_gotten_store = 0;
3735      if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ;      if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ;
3736    
3737      true_size =      true_size =
# Line 1519  while (!done) Line 3739  while (!done)
3739      true_study_size =      true_study_size =
3740        (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];        (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];
3741    
3742      re = (real_pcre *)new_malloc(true_size);      re = (pcre *)new_malloc(true_size);
3743      regex_gotten_store = gotten_store;      if (re == NULL)
3744          {
3745          printf("** Failed to get %d bytes of memory for pcre object\n",
3746            (int)true_size);
3747          yield = 1;
3748          goto EXIT;
3749          }
3750        regex_gotten_store = first_gotten_store;
3751    
3752      if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;      if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;
3753    
3754      magic = ((real_pcre *)re)->magic_number;      magic = REAL_PCRE_MAGIC(re);
3755      if (magic != MAGIC_NUMBER)      if (magic != MAGIC_NUMBER)
3756        {        {
3757        if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER)        if (swap_uint32(magic) == MAGIC_NUMBER)
3758          {          {
3759          do_flip = 1;          do_flip = 1;
3760          }          }
3761        else        else
3762          {          {
3763          fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p);          fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p);
3764            new_free(re);
3765          fclose(f);          fclose(f);
3766          continue;          continue;
3767          }          }
3768        }        }
3769    
3770        /* We hide the byte-invert info for little and big endian tests. */
3771      fprintf(outfile, "Compiled pattern%s loaded from %s\n",      fprintf(outfile, "Compiled pattern%s loaded from %s\n",
3772        do_flip? " (byte-inverted)" : "", p);        do_flip && (p[-1] == '<') ? " (byte-inverted)" : "", p);
   
     /* Need to know if UTF-8 for printing data strings */  
   
     new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);  
     use_utf8 = (get_options & PCRE_UTF8) != 0;  
3773    
3774      /* Now see if there is any following study data. */      /* Now see if there is any following study data. */
3775    
# Line 1563  while (!done) Line 3787  while (!done)
3787          {          {
3788          FAIL_READ:          FAIL_READ:
3789          fprintf(outfile, "Failed to read data from %s\n", p);          fprintf(outfile, "Failed to read data from %s\n", p);
3790          if (extra != NULL) pcre_free_study(extra);          if (extra != NULL)
3791          if (re != NULL) new_free(re);            {
3792              PCRE_FREE_STUDY(extra);
3793              }
3794            new_free(re);
3795          fclose(f);          fclose(f);
3796          continue;          continue;
3797          }          }
# Line 1573  while (!done) Line 3800  while (!done)
3800        }        }
3801      else fprintf(outfile, "No study data\n");      else fprintf(outfile, "No study data\n");
3802    
3803        /* Flip the necessary bytes. */
3804        if (do_flip)
3805          {
3806          int rc;
3807          PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, NULL);
3808          if (rc == PCRE_ERROR_BADMODE)
3809            {
3810            /* Simulate the result of the function call below. */
3811            fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc,
3812              pcre_mode == PCRE32_MODE ? "32" : pcre_mode == PCRE16_MODE ? "16" : "",
3813              PCRE_INFO_OPTIONS);
3814            fprintf(outfile, "Running in %d-bit mode but pattern was compiled in "
3815              "%d-bit mode\n", 8 * CHAR_SIZE,
3816              8 * (REAL_PCRE_FLAGS(re) & PCRE_MODE_MASK));
3817            new_free(re);
3818            fclose(f);
3819            continue;
3820            }
3821          }
3822    
3823        /* Need to know if UTF-8 for printing data strings. */
3824    
3825        if (new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options) < 0)
3826          {
3827          new_free(re);
3828          fclose(f);
3829          continue;
3830          }
3831        use_utf = (get_options & PCRE_UTF8) != 0;
3832    
3833      fclose(f);      fclose(f);
3834      goto SHOW_INFO;      goto SHOW_INFO;
3835      }      }
3836    
3837    /* In-line pattern (the usual case). Get the delimiter and seek the end of    /* In-line pattern (the usual case). Get the delimiter and seek the end of
3838    the pattern; if is isn't complete, read more. */    the pattern; if it isn't complete, read more. */
3839    
3840    delimiter = *p++;    delimiter = *p++;
3841    
# Line 1629  while (!done) Line 3886  while (!done)
3886    /* Look for options after final delimiter */    /* Look for options after final delimiter */
3887    
3888    options = 0;    options = 0;
3889      study_options = force_study_options;
3890    log_store = showstore;  /* default from command line */    log_store = showstore;  /* default from command line */
3891    
3892    while (*pp != 0)    while (*pp != 0)
# Line 1665  while (!done) Line 3923  while (!done)
3923  #endif  #endif
3924    
3925        case 'S':        case 'S':
3926        if (do_study == 0)        do_study = 1;
3927          for (;;)
3928          {          {
3929          do_study = 1;          switch (*pp++)
         if (*pp == '+')  
3930            {            {
3931            study_options |= PCRE_STUDY_JIT_COMPILE;            case 'S':
3932            pp++;            do_study = 0;
3933            }            no_force_study = 1;
3934          }            break;
3935        else  
3936          {            case '!':
3937          do_study = 0;            study_options |= PCRE_STUDY_EXTRA_NEEDED;
3938          no_force_study = 1;            break;
3939    
3940              case '+':
3941              if (*pp == '+')
3942                {
3943                verify_jit = TRUE;
3944                pp++;
3945                }
3946              if (*pp >= '1' && *pp <= '7')
3947                study_options |= jit_study_bits[*pp++ - '1'];
3948              else
3949                study_options |= jit_study_bits[6];
3950              break;
3951    
3952              case '-':
3953              study_options &= ~PCRE_STUDY_ALLJIT;
3954              break;
3955    
3956              default:
3957              pp--;
3958              goto ENDLOOP;
3959              }
3960          }          }
3961          ENDLOOP:
3962        break;        break;
3963    
3964        case 'U': options |= PCRE_UNGREEDY; break;        case 'U': options |= PCRE_UNGREEDY; break;
# Line 1686  while (!done) Line 3966  while (!done)
3966        case 'X': options |= PCRE_EXTRA; break;        case 'X': options |= PCRE_EXTRA; break;
3967        case 'Y': options |= PCRE_NO_START_OPTIMISE; break;        case 'Y': options |= PCRE_NO_START_OPTIMISE; break;
3968        case 'Z': debug_lengths = 0; break;        case 'Z': debug_lengths = 0; break;
3969        case '8': options |= PCRE_UTF8; use_utf8 = 1; break;        case '8': options |= PCRE_UTF8; use_utf = 1; break;
3970        case '?': options |= PCRE_NO_UTF8_CHECK; break;        case '?': options |= PCRE_NO_UTF8_CHECK; break;
3971    
3972        case 'T':        case 'T':
# Line 1720  while (!done) Line 4000  while (!done)
4000          goto SKIP_DATA;          goto SKIP_DATA;
4001          }          }
4002        locale_set = 1;        locale_set = 1;
4003        tables = pcre_maketables();        tables = PCRE_MAKETABLES;
4004        pp = ppp;        pp = ppp;
4005        break;        break;
4006    
# Line 1733  while (!done) Line 4013  while (!done)
4013    
4014        case '<':        case '<':
4015          {          {
4016          if (strncmpic(pp, (uschar *)"JS>", 3) == 0)          if (strncmpic(pp, (pcre_uint8 *)"JS>", 3) == 0)
4017            {            {
4018            options |= PCRE_JAVASCRIPT_COMPAT;            options |= PCRE_JAVASCRIPT_COMPAT;
4019            pp += 3;            pp += 3;
# Line 1761  while (!done) Line 4041  while (!done)
4041    
4042    /* Handle compiling via the POSIX interface, which doesn't support the    /* Handle compiling via the POSIX interface, which doesn't support the
4043    timing, showing, or debugging options, nor the ability to pass over    timing, showing, or debugging options, nor the ability to pass over
4044    local character tables. */    local character tables. Neither does it have 16-bit support. */
4045    
4046  #if !defined NOPOSIX  #if !defined NOPOSIX
4047    if (posix || do_posix)    if (posix || do_posix)
# Line 1777  while (!done) Line 4057  while (!done)
4057      if ((options & PCRE_UCP) != 0) cflags |= REG_UCP;      if ((options & PCRE_UCP) != 0) cflags |= REG_UCP;
4058      if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY;      if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY;
4059    
4060        first_gotten_store = 0;
4061      rc = regcomp(&preg, (char *)p, cflags);      rc = regcomp(&preg, (char *)p, cflags);
4062    
4063      /* Compilation failed; go back for another re, skipping to blank line      /* Compilation failed; go back for another re, skipping to blank line
# Line 1796  while (!done) Line 4077  while (!done)
4077  #endif  /* !defined NOPOSIX */  #endif  /* !defined NOPOSIX */
4078    
4079      {      {
4080      unsigned long int get_options;      /* In 16- or 32-bit mode, convert the input. */
4081    
4082    #ifdef SUPPORT_PCRE16
4083        if (pcre_mode == PCRE16_MODE)
4084          {
4085          switch(to16(FALSE, p, options & PCRE_UTF8, (int)strlen((char *)p)))
4086            {
4087            case -1:
4088            fprintf(outfile, "**Failed: invalid UTF-8 string cannot be "
4089              "converted to UTF-16\n");
4090            goto SKIP_DATA;
4091    
4092            case -2:
4093            fprintf(outfile, "**Failed: character value greater than 0x10ffff "
4094              "cannot be converted to UTF-16\n");
4095            goto SKIP_DATA;
4096    
4097            case -3: /* "Impossible error" when to16 is called arg1 FALSE */
4098            fprintf(outfile, "**Failed: character value greater than 0xffff "
4099              "cannot be converted to 16-bit in non-UTF mode\n");
4100            goto SKIP_DATA;
4101    
4102            default:
4103            break;
4104            }
4105          p = (pcre_uint8 *)buffer16;
4106          }
4107    #endif
4108    
4109    #ifdef SUPPORT_PCRE32
4110        if (pcre_mode == PCRE32_MODE)
4111          {
4112          switch(to32(FALSE, p, options & PCRE_UTF32, (int)strlen((char *)p)))
4113            {
4114            case -1:
4115            fprintf(outfile, "**Failed: invalid UTF-8 string cannot be "
4116              "converted to UTF-32\n");
4117            goto SKIP_DATA;
4118    
4119            case -2:
4120            fprintf(outfile, "**Failed: character value greater than 0x10ffff "
4121              "cannot be converted to UTF-32\n");
4122            goto SKIP_DATA;
4123    
4124            case -3:
4125            fprintf(outfile, "**Failed: character value is ill-formed UTF-32\n");
4126            goto SKIP_DATA;
4127    
4128            default:
4129            break;
4130            }
4131          p = (pcre_uint8 *)buffer32;
4132          }
4133    #endif
4134    
4135        /* Compile many times when timing */
4136    
4137      if (timeit > 0)      if (timeit > 0)
4138        {        {
# Line 1805  while (!done) Line 4141  while (!done)
4141        clock_t start_time = clock();        clock_t start_time = clock();
4142        for (i = 0; i < timeit; i++)        for (i = 0; i < timeit; i++)
4143          {          {
4144          re = pcre_compile((char *)p, options, &error, &erroroffset, tables);          PCRE_COMPILE(re, p, options, &error, &erroroffset, tables);
4145          if (re != NULL) free(re);          if (re != NULL) free(re);
4146          }          }
4147        time_taken = clock() - start_time;        time_taken = clock() - start_time;
# Line 1814  while (!done) Line 4150  while (!done)
4150            (double)CLOCKS_PER_SEC);            (double)CLOCKS_PER_SEC);
4151        }        }
4152    
4153      re = pcre_compile((char *)p, options, &error, &erroroffset, tables);      first_gotten_store = 0;
4154        PCRE_COMPILE(re, p, options, &error, &erroroffset, tables);
4155    
4156      /* Compilation failed; go back for another re, skipping to blank line      /* Compilation failed; go back for another re, skipping to blank line
4157      if non-interactive. */      if non-interactive. */
# Line 1845  while (!done) Line 4182  while (!done)
4182      within the regex; check for this so that we know how to process the data      within the regex; check for this so that we know how to process the data
4183      lines. */      lines. */
4184    
4185      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);      if (new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options) < 0)
4186      if ((get_options & PCRE_UTF8) != 0) use_utf8 = 1;        goto SKIP_DATA;
4187        if ((get_options & PCRE_UTF8) != 0) use_utf = 1;
     /* Print information if required. There are now two info-returning  
     functions. The old one has a limited interface and returns only limited  
     data. Check that it agrees with the newer one. */  
   
     if (log_store)  
       fprintf(outfile, "Memory allocation (code space): %d\n",  
         (int)(gotten_store -  
               sizeof(real_pcre) -  
               ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));  
4188    
4189      /* Extract the size for possible writing before possibly flipping it,      /* Extract the size for possible writing before possibly flipping it,
4190      and remember the store that was got. */      and remember the store that was got. */
4191    
4192      true_size = ((real_pcre *)re)->size;      true_size = REAL_PCRE_SIZE(re);
4193      regex_gotten_store = gotten_store;      regex_gotten_store = first_gotten_store;
4194    
4195        /* Output code size information if requested */
4196    
4197        if (log_store)
4198          {
4199          int name_count, name_entry_size, real_pcre_size;
4200    
4201          new_info(re, NULL, PCRE_INFO_NAMECOUNT, &name_count);
4202          new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size);
4203          real_pcre_size = 0;
4204    #ifdef SUPPORT_PCRE8
4205          if (REAL_PCRE_FLAGS(re) & PCRE_MODE8)
4206            real_pcre_size = sizeof(real_pcre);
4207    #endif
4208    #ifdef SUPPORT_PCRE16
4209          if (REAL_PCRE_FLAGS(re) & PCRE_MODE16)
4210            real_pcre_size = sizeof(real_pcre16);
4211    #endif
4212    #ifdef SUPPORT_PCRE32
4213          if (REAL_PCRE_FLAGS(re) & PCRE_MODE32)
4214            real_pcre_size = sizeof(real_pcre32);
4215    #endif
4216          fprintf(outfile, "Memory allocation (code space): %d\n",
4217            (int)(first_gotten_store - real_pcre_size - name_count * name_entry_size));
4218          }
4219    
4220      /* If -s or /S was present, study the regex to generate additional info to      /* If -s or /S was present, study the regex to generate additional info to
4221      help with the matching, unless the pattern has the SS option, which      help with the matching, unless the pattern has the SS option, which
# Line 1877  while (!done) Line 4230  while (!done)
4230          clock_t time_taken;          clock_t time_taken;
4231          clock_t start_time = clock();          clock_t start_time = clock();
4232          for (i = 0; i < timeit; i++)          for (i = 0; i < timeit; i++)
4233            extra = pcre_study(re, study_options | force_study_options, &error);            {
4234              PCRE_STUDY(extra, re, study_options, &error);
4235              }
4236          time_taken = clock() - start_time;          time_taken = clock() - start_time;
4237          if (extra != NULL) pcre_free_study(extra);          if (extra != NULL)
4238              {
4239              PCRE_FREE_STUDY(extra);
4240              }
4241          fprintf(outfile, "  Study time %.4f milliseconds\n",          fprintf(outfile, "  Study time %.4f milliseconds\n",
4242            (((double)time_taken * 1000.0) / (double)timeit) /            (((double)time_taken * 1000.0) / (double)timeit) /
4243              (double)CLOCKS_PER_SEC);              (double)CLOCKS_PER_SEC);
4244          }          }
4245        extra = pcre_study(re, study_options | force_study_options, &error);        PCRE_STUDY(extra, re, study_options, &error);
4246        if (error != NULL)        if (error != NULL)
4247          fprintf(outfile, "Failed to study: %s\n", error);          fprintf(outfile, "Failed to study: %s\n", error);
4248        else if (extra != NULL)        else if (extra != NULL)
4249            {
4250          true_study_size = ((pcre_study_data *)(extra->study_data))->size;          true_study_size = ((pcre_study_data *)(extra->study_data))->size;
4251            if (log_store)
4252              {
4253              size_t jitsize;
4254              if (new_info(re, extra, PCRE_INFO_JITSIZE, &jitsize) == 0 &&
4255                  jitsize != 0)
4256                fprintf(outfile, "Memory allocation (JIT code): %d\n", (int)jitsize);
4257              }
4258            }
4259        }        }
4260    
4261      /* If /K was present, we set up for handling MARK data. */      /* If /K was present, we set up for handling MARK data. */
# Line 1904  while (!done) Line 4271  while (!done)
4271        extra->flags |= PCRE_EXTRA_MARK;        extra->flags |= PCRE_EXTRA_MARK;
4272        }        }
4273    
4274      /* If the 'F' option was present, we flip the bytes of all the integer      /* Extract and display information from the compiled data if required. */
     fields in the regex data block and the study block. This is to make it  
     possible to test PCRE's handling of byte-flipped patterns, e.g. those  
     compiled on a different architecture. */  
   
     if (do_flip)  
       {  
       real_pcre *rre = (real_pcre *)re;  
       rre->magic_number =  
         byteflip(rre->magic_number, sizeof(rre->magic_number));  
       rre->size = byteflip(rre->size, sizeof(rre->size));  
       rre->options = byteflip(rre->options, sizeof(rre->options));  
       rre->flags = (pcre_uint16)byteflip(rre->flags, sizeof(rre->flags));  
       rre->top_bracket =  
         (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));  
       rre->top_backref =  
         (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));  
       rre->first_byte =  
         (pcre_uint16)byteflip(rre->first_byte, sizeof(rre->first_byte));  
       rre->req_byte =  
         (pcre_uint16)byteflip(rre->req_byte, sizeof(rre->req_byte));  
       rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,  
         sizeof(rre->name_table_offset));  
       rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,  
         sizeof(rre->name_entry_size));  
       rre->name_count = (pcre_uint16)byteflip(rre->name_count,  
         sizeof(rre->name_count));  
   
       if (extra != NULL)  
         {  
         pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);  
         rsd->size = byteflip(rsd->size, sizeof(rsd->size));  
         rsd->flags = byteflip(rsd->flags, sizeof(rsd->flags));  
         rsd->minlength = byteflip(rsd->minlength, sizeof(rsd->minlength));  
         }  
       }  
   
     /* Extract information from the compiled data if required */  
4275    
4276      SHOW_INFO:      SHOW_INFO:
4277    
4278      if (do_debug)      if (do_debug)
4279        {        {
4280        fprintf(outfile, "------------------------------------------------------------------\n");        fprintf(outfile, "------------------------------------------------------------------\n");
4281        pcre_printint(re, outfile, debug_lengths);        PCRE_PRINTINT(re, outfile, debug_lengths);
4282        }        }
4283    
4284      /* We already have the options in get_options (see above) */      /* We already have the options in get_options (see above) */
# Line 1956  while (!done) Line 4286  while (!done)
4286      if (do_showinfo)      if (do_showinfo)
4287        {        {
4288        unsigned long int all_options;        unsigned long int all_options;
4289  #if !defined NOINFOCHECK        pcre_uint32 first_char, need_char;
4290        int old_first_char, old_options, old_count;        int count, backrefmax, first_char_set, need_char_set, okpartial, jchanged,
4291  #endif          hascrorlf, maxlookbehind;
       int count, backrefmax, first_char, need_char, okpartial, jchanged,  
         hascrorlf;  
4292        int nameentrysize, namecount;        int nameentrysize, namecount;
4293        const uschar *nametable;        const pcre_uint8 *nametable;
4294    
4295        new_info(re, NULL, PCRE_INFO_SIZE, &size);        if (new_info(re, NULL, PCRE_INFO_SIZE, &size) +
4296        new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);            new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count) +
4297        new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax);            new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax) +
4298        new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char);            new_info(re, NULL, PCRE_INFO_FIRSTCHARACTER, &first_char) +
4299        new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char);            new_info(re, NULL, PCRE_INFO_FIRSTCHARACTERFLAGS, &first_char_set) +
4300        new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);            new_info(re, NULL, PCRE_INFO_REQUIREDCHAR, &need_char) +
4301        new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount);            new_info(re, NULL, PCRE_INFO_REQUIREDCHARFLAGS, &need_char_set) +
4302        new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable);            new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize) +
4303        new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial);            new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount) +
4304        new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);            new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable) +
4305        new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);            new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial) +
4306              new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged) +
4307  #if !defined NOINFOCHECK            new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf) +
4308        old_count = pcre_info(re, &old_options, &old_first_char);            new_info(re, NULL, PCRE_INFO_MAXLOOKBEHIND, &maxlookbehind)
4309        if (count < 0) fprintf(outfile,            != 0)
4310          "Error %d from pcre_info()\n", count);          goto SKIP_DATA;
       else  
         {  
         if (old_count != count) fprintf(outfile,  
           "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,  
             old_count);  
   
         if (old_first_char != first_char) fprintf(outfile,  
           "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",  
             first_char, old_first_char);  
   
         if (old_options != (int)get_options) fprintf(outfile,  
           "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",  
             get_options, old_options);  
         }  
 #endif  
4311    
4312        if (size != regex_gotten_store) fprintf(outfile,        if (size != regex_gotten_store) fprintf(outfile,
4313          "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n",          "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n",
# Line 2009  while (!done) Line 4322  while (!done)
4322          fprintf(outfile, "Named capturing subpatterns:\n");          fprintf(outfile, "Named capturing subpatterns:\n");
4323          while (namecount-- > 0)          while (namecount-- > 0)
4324            {            {
4325            fprintf(outfile, "  %s %*s%3d\n", nametable + 2,            int imm2_size = pcre_mode == PCRE8_MODE ? 2 : 1;
4326              nameentrysize - 3 - (int)strlen((char *)nametable + 2), "",            int length = (int)STRLEN(nametable + imm2_size);
4327              GET2(nametable, 0));            fprintf(outfile, "  ");
4328            nametable += nameentrysize;            PCHARSV(nametable, imm2_size, length, outfile);
4329              while (length++ < nameentrysize - imm2_size) putc(' ', outfile);
4330    #ifdef SUPPORT_PCRE32
4331              if (pcre_mode == PCRE32_MODE)
4332                fprintf(outfile, "%3d\n", (int)(((PCRE_SPTR32)nametable)[0]));
4333    #endif
4334    #ifdef SUPPORT_PCRE16
4335              if (pcre_mode == PCRE16_MODE)
4336                fprintf(outfile, "%3d\n", (int)(((PCRE_SPTR16)nametable)[0]));
4337    #endif
4338    #ifdef SUPPORT_PCRE8
4339              if (pcre_mode == PCRE8_MODE)
4340                fprintf(outfile, "%3d\n", ((int)nametable[0] << 8) | (int)nametable[1]);
4341    #endif
4342              nametable += nameentrysize * CHAR_SIZE;
4343            }            }
4344          }          }
4345    
4346        if (!okpartial) fprintf(outfile, "Partial matching not supported\n");        if (!okpartial) fprintf(outfile, "Partial matching not supported\n");
4347        if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n");        if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n");
4348    
4349        all_options = ((real_pcre *)re)->options;        all_options = REAL_PCRE_OPTIONS(re);
4350        if (do_flip) all_options = byteflip(all_options, sizeof(all_options));        if (do_flip) all_options = swap_uint32(all_options);
4351    
4352        if (get_options == 0) fprintf(outfile, "No options\n");        if (get_options == 0) fprintf(outfile, "No options\n");
4353          else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",          else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
# Line 2036  while (!done) Line 4363  while (!done)
4363            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",            ((get_options & PCRE_EXTRA) != 0)? " extra" : "",
4364            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",            ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
4365            ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",            ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",
4366            ((get_options & PCRE_UTF8) != 0)? " utf8" : "",            ((get_options & PCRE_UTF8) != 0)? " utf" : "",
4367            ((get_options & PCRE_UCP) != 0)? " ucp" : "",            ((get_options & PCRE_UCP) != 0)? " ucp" : "",
4368            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",            ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf_check" : "",
4369            ((get_options & PCRE_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "",            ((get_options & PCRE_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "",
4370            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");            ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");
4371    
# Line 2070  while (!done) Line 4397  while (!done)
4397          break;          break;
4398          }          }
4399    
4400        if (first_char == -1)        if (first_char_set == 2)
4401          {          {
4402          fprintf(outfile, "First char at start or follows newline\n");          fprintf(outfile, "First char at start or follows newline\n");
4403          }          }
4404        else if (first_char < 0)        else if (first_char_set == 1)
4405          {          {
4406          fprintf(outfile, "No first char\n");          const char *caseless =
4407              ((REAL_PCRE_FLAGS(re) & PCRE_FCH_CASELESS) == 0)?
4408              "" : " (caseless)";
4409    
4410            if (PRINTOK(first_char))
4411              fprintf(outfile, "First char = \'%c\'%s\n", first_char, caseless);
4412            else
4413              {
4414              fprintf(outfile, "First char = ");
4415              pchar(first_char, outfile);
4416              fprintf(outfile, "%s\n", caseless);
4417              }
4418          }          }
4419        else        else
4420          {          {
4421          int ch = first_char & 255;          fprintf(outfile, "No first char\n");
         const char *caseless = ((first_char & REQ_CASELESS) == 0)?  
           "" : " (caseless)";  
         if (PRINTHEX(ch))  
           fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless);  
         else  
           fprintf(outfile, "First char = %d%s\n", ch, caseless);  
4422          }          }
4423    
4424        if (need_char < 0)        if (need_char_set == 0)
4425          {          {
4426          fprintf(outfile, "No need char\n");          fprintf(outfile, "No need char\n");
4427          }          }
4428        else        else
4429          {          {
4430          int ch = need_char & 255;          const char *caseless =
4431          const char *caseless = ((need_char & REQ_CASELESS) == 0)?            ((REAL_PCRE_FLAGS(re) & PCRE_RCH_CASELESS) == 0)?
4432            "" : " (caseless)";            "" : " (caseless)";
4433          if (PRINTHEX(ch))  
4434            fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless);          if (PRINTOK(need_char))
4435              fprintf(outfile, "Need char = \'%c\'%s\n", need_char, caseless);