xref: /aosp_15_r20/external/pcre/src/pcre2test.c (revision 22dc650d8ae982c6770746019a6f94af92b0f024)
1*22dc650dSSadaf Ebrahimi /*************************************************
2*22dc650dSSadaf Ebrahimi *             PCRE2 testing program              *
3*22dc650dSSadaf Ebrahimi *************************************************/
4*22dc650dSSadaf Ebrahimi 
5*22dc650dSSadaf Ebrahimi /* PCRE2 is a library of functions to support regular expressions whose syntax
6*22dc650dSSadaf Ebrahimi and semantics are as close as possible to those of the Perl 5 language. In 2014
7*22dc650dSSadaf Ebrahimi the API was completely revised and '2' was added to the name, because the old
8*22dc650dSSadaf Ebrahimi API, which had lasted for 16 years, could not accommodate new requirements. At
9*22dc650dSSadaf Ebrahimi the same time, this testing program was re-designed because its original
10*22dc650dSSadaf Ebrahimi hacked-up (non-) design had also run out of steam.
11*22dc650dSSadaf Ebrahimi 
12*22dc650dSSadaf Ebrahimi                        Written by Philip Hazel
13*22dc650dSSadaf Ebrahimi      Original code Copyright (c) 1997-2012 University of Cambridge
14*22dc650dSSadaf Ebrahimi     Rewritten code Copyright (c) 2016-2024 University of Cambridge
15*22dc650dSSadaf Ebrahimi 
16*22dc650dSSadaf Ebrahimi -----------------------------------------------------------------------------
17*22dc650dSSadaf Ebrahimi Redistribution and use in source and binary forms, with or without
18*22dc650dSSadaf Ebrahimi modification, are permitted provided that the following conditions are met:
19*22dc650dSSadaf Ebrahimi 
20*22dc650dSSadaf Ebrahimi     * Redistributions of source code must retain the above copyright notice,
21*22dc650dSSadaf Ebrahimi       this list of conditions and the following disclaimer.
22*22dc650dSSadaf Ebrahimi 
23*22dc650dSSadaf Ebrahimi     * Redistributions in binary form must reproduce the above copyright
24*22dc650dSSadaf Ebrahimi       notice, this list of conditions and the following disclaimer in the
25*22dc650dSSadaf Ebrahimi       documentation and/or other materials provided with the distribution.
26*22dc650dSSadaf Ebrahimi 
27*22dc650dSSadaf Ebrahimi     * Neither the name of the University of Cambridge nor the names of its
28*22dc650dSSadaf Ebrahimi       contributors may be used to endorse or promote products derived from
29*22dc650dSSadaf Ebrahimi       this software without specific prior written permission.
30*22dc650dSSadaf Ebrahimi 
31*22dc650dSSadaf Ebrahimi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32*22dc650dSSadaf Ebrahimi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33*22dc650dSSadaf Ebrahimi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34*22dc650dSSadaf Ebrahimi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35*22dc650dSSadaf Ebrahimi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36*22dc650dSSadaf Ebrahimi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37*22dc650dSSadaf Ebrahimi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38*22dc650dSSadaf Ebrahimi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39*22dc650dSSadaf Ebrahimi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40*22dc650dSSadaf Ebrahimi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*22dc650dSSadaf Ebrahimi POSSIBILITY OF SUCH DAMAGE.
42*22dc650dSSadaf Ebrahimi -----------------------------------------------------------------------------
43*22dc650dSSadaf Ebrahimi */
44*22dc650dSSadaf Ebrahimi 
45*22dc650dSSadaf Ebrahimi 
46*22dc650dSSadaf Ebrahimi /* This program supports testing of the 8-bit, 16-bit, and 32-bit PCRE2
47*22dc650dSSadaf Ebrahimi libraries in a single program, though its input and output are always 8-bit.
48*22dc650dSSadaf Ebrahimi It is different from modules such as pcre2_compile.c in the library itself,
49*22dc650dSSadaf Ebrahimi which are compiled separately for each code unit width. If two widths are
50*22dc650dSSadaf Ebrahimi enabled, for example, pcre2_compile.c is compiled twice. In contrast,
51*22dc650dSSadaf Ebrahimi pcre2test.c is compiled only once, and linked with all the enabled libraries.
52*22dc650dSSadaf Ebrahimi Therefore, it must not make use of any of the macros from pcre2.h or
53*22dc650dSSadaf Ebrahimi pcre2_internal.h that depend on PCRE2_CODE_UNIT_WIDTH. It does, however, make
54*22dc650dSSadaf Ebrahimi use of SUPPORT_PCRE2_8, SUPPORT_PCRE2_16, and SUPPORT_PCRE2_32, to ensure that
55*22dc650dSSadaf Ebrahimi it references only the enabled library functions. */
56*22dc650dSSadaf Ebrahimi 
57*22dc650dSSadaf Ebrahimi #ifdef HAVE_CONFIG_H
58*22dc650dSSadaf Ebrahimi #include "config.h"
59*22dc650dSSadaf Ebrahimi #endif
60*22dc650dSSadaf Ebrahimi 
61*22dc650dSSadaf Ebrahimi #include <ctype.h>
62*22dc650dSSadaf Ebrahimi #include <stdio.h>
63*22dc650dSSadaf Ebrahimi #include <string.h>
64*22dc650dSSadaf Ebrahimi #include <stdlib.h>
65*22dc650dSSadaf Ebrahimi #include <time.h>
66*22dc650dSSadaf Ebrahimi #include <locale.h>
67*22dc650dSSadaf Ebrahimi #include <errno.h>
68*22dc650dSSadaf Ebrahimi 
69*22dc650dSSadaf Ebrahimi #if defined NATIVE_ZOS
70*22dc650dSSadaf Ebrahimi #include "pcrzoscs.h"
71*22dc650dSSadaf Ebrahimi /* That header is not included in the main PCRE2 distribution because other
72*22dc650dSSadaf Ebrahimi apparatus is needed to compile pcre2test for z/OS. The header can be found in
73*22dc650dSSadaf Ebrahimi the special z/OS distribution, which is available from www.zaconsultants.net or
74*22dc650dSSadaf Ebrahimi from www.cbttape.org. */
75*22dc650dSSadaf Ebrahimi #endif
76*22dc650dSSadaf Ebrahimi 
77*22dc650dSSadaf Ebrahimi #ifdef HAVE_UNISTD_H
78*22dc650dSSadaf Ebrahimi #include <unistd.h>
79*22dc650dSSadaf Ebrahimi #endif
80*22dc650dSSadaf Ebrahimi 
81*22dc650dSSadaf Ebrahimi /* Debugging code enabler */
82*22dc650dSSadaf Ebrahimi 
83*22dc650dSSadaf Ebrahimi /* #define DEBUG_SHOW_MALLOC_ADDRESSES */
84*22dc650dSSadaf Ebrahimi 
85*22dc650dSSadaf Ebrahimi /* Both libreadline and libedit are optionally supported */
86*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
87*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE)
88*22dc650dSSadaf Ebrahimi #include <readline/readline.h>
89*22dc650dSSadaf Ebrahimi #include <readline/history.h>
90*22dc650dSSadaf Ebrahimi #else
91*22dc650dSSadaf Ebrahimi #if defined(HAVE_EDITLINE_READLINE_H)
92*22dc650dSSadaf Ebrahimi #include <editline/readline.h>
93*22dc650dSSadaf Ebrahimi #elif defined(HAVE_EDIT_READLINE_READLINE_H)
94*22dc650dSSadaf Ebrahimi #include <edit/readline/readline.h>
95*22dc650dSSadaf Ebrahimi #else
96*22dc650dSSadaf Ebrahimi #include <readline.h>
97*22dc650dSSadaf Ebrahimi /* GNU readline defines this macro but libedit doesn't, if that ever changes
98*22dc650dSSadaf Ebrahimi this needs to be updated or the build could break */
99*22dc650dSSadaf Ebrahimi #ifdef RL_VERSION_MAJOR
100*22dc650dSSadaf Ebrahimi #include <history.h>
101*22dc650dSSadaf Ebrahimi #endif
102*22dc650dSSadaf Ebrahimi #endif
103*22dc650dSSadaf Ebrahimi #endif
104*22dc650dSSadaf Ebrahimi #endif
105*22dc650dSSadaf Ebrahimi 
106*22dc650dSSadaf Ebrahimi /* Put the test for interactive input into a macro so that it can be changed if
107*22dc650dSSadaf Ebrahimi required for different environments. */
108*22dc650dSSadaf Ebrahimi 
109*22dc650dSSadaf Ebrahimi #define INTERACTIVE(f) isatty(fileno(f))
110*22dc650dSSadaf Ebrahimi 
111*22dc650dSSadaf Ebrahimi 
112*22dc650dSSadaf Ebrahimi /* ---------------------- System-specific definitions ---------------------- */
113*22dc650dSSadaf Ebrahimi 
114*22dc650dSSadaf Ebrahimi /* A number of things vary for Windows builds. Originally, pcretest opened its
115*22dc650dSSadaf Ebrahimi input and output without "b"; then I was told that "b" was needed in some
116*22dc650dSSadaf Ebrahimi environments, so it was added for release 5.0 to both the input and output. (It
117*22dc650dSSadaf Ebrahimi makes no difference on Unix-like systems.) Later I was told that it is wrong
118*22dc650dSSadaf Ebrahimi for the input on Windows. I've now abstracted the modes into macros that are
119*22dc650dSSadaf Ebrahimi set here, to make it easier to fiddle with them, and removed "b" from the input
120*22dc650dSSadaf Ebrahimi mode under Windows. The BINARY versions are used when saving/restoring compiled
121*22dc650dSSadaf Ebrahimi patterns. */
122*22dc650dSSadaf Ebrahimi 
123*22dc650dSSadaf Ebrahimi #if defined(_WIN32) || defined(WIN32)
124*22dc650dSSadaf Ebrahimi #include <io.h>                /* For _setmode() */
125*22dc650dSSadaf Ebrahimi #include <fcntl.h>             /* For _O_BINARY */
126*22dc650dSSadaf Ebrahimi #define INPUT_MODE          "r"
127*22dc650dSSadaf Ebrahimi #define OUTPUT_MODE         "wb"
128*22dc650dSSadaf Ebrahimi #define BINARY_INPUT_MODE   "rb"
129*22dc650dSSadaf Ebrahimi #define BINARY_OUTPUT_MODE  "wb"
130*22dc650dSSadaf Ebrahimi 
131*22dc650dSSadaf Ebrahimi #ifndef isatty
132*22dc650dSSadaf Ebrahimi #define isatty _isatty         /* This is what Windows calls them, I'm told, */
133*22dc650dSSadaf Ebrahimi #endif                         /* though in some environments they seem to   */
134*22dc650dSSadaf Ebrahimi                                /* be already defined, hence the #ifndefs.    */
135*22dc650dSSadaf Ebrahimi #ifndef fileno
136*22dc650dSSadaf Ebrahimi #define fileno _fileno
137*22dc650dSSadaf Ebrahimi #endif
138*22dc650dSSadaf Ebrahimi 
139*22dc650dSSadaf Ebrahimi /* A user sent this fix for Borland Builder 5 under Windows. */
140*22dc650dSSadaf Ebrahimi 
141*22dc650dSSadaf Ebrahimi #ifdef __BORLANDC__
142*22dc650dSSadaf Ebrahimi #define _setmode(handle, mode) setmode(handle, mode)
143*22dc650dSSadaf Ebrahimi #endif
144*22dc650dSSadaf Ebrahimi 
145*22dc650dSSadaf Ebrahimi /* Not Windows */
146*22dc650dSSadaf Ebrahimi 
147*22dc650dSSadaf Ebrahimi #else
148*22dc650dSSadaf Ebrahimi #include <sys/time.h>          /* These two includes are needed */
149*22dc650dSSadaf Ebrahimi #include <sys/resource.h>      /* for setrlimit(). */
150*22dc650dSSadaf Ebrahimi #if defined NATIVE_ZOS         /* z/OS uses non-binary I/O */
151*22dc650dSSadaf Ebrahimi #define INPUT_MODE   "r"
152*22dc650dSSadaf Ebrahimi #define OUTPUT_MODE  "w"
153*22dc650dSSadaf Ebrahimi #define BINARY_INPUT_MODE   "rb"
154*22dc650dSSadaf Ebrahimi #define BINARY_OUTPUT_MODE  "wb"
155*22dc650dSSadaf Ebrahimi #else
156*22dc650dSSadaf Ebrahimi #define INPUT_MODE          "rb"
157*22dc650dSSadaf Ebrahimi #define OUTPUT_MODE         "wb"
158*22dc650dSSadaf Ebrahimi #define BINARY_INPUT_MODE   "rb"
159*22dc650dSSadaf Ebrahimi #define BINARY_OUTPUT_MODE  "wb"
160*22dc650dSSadaf Ebrahimi #endif
161*22dc650dSSadaf Ebrahimi #endif
162*22dc650dSSadaf Ebrahimi 
163*22dc650dSSadaf Ebrahimi /* VMS-specific code was included as suggested by a VMS user [1]. Another VMS
164*22dc650dSSadaf Ebrahimi user [2] provided alternative code which worked better for him. I have
165*22dc650dSSadaf Ebrahimi commented out the original, but kept it around just in case. */
166*22dc650dSSadaf Ebrahimi 
167*22dc650dSSadaf Ebrahimi #ifdef __VMS
168*22dc650dSSadaf Ebrahimi #include <ssdef.h>
169*22dc650dSSadaf Ebrahimi /* These two includes came from [2]. */
170*22dc650dSSadaf Ebrahimi #include descrip
171*22dc650dSSadaf Ebrahimi #include lib$routines
172*22dc650dSSadaf Ebrahimi /* void vms_setsymbol( char *, char *, int ); Original code from [1]. */
173*22dc650dSSadaf Ebrahimi #endif
174*22dc650dSSadaf Ebrahimi 
175*22dc650dSSadaf Ebrahimi /* old VC and older compilers don't support %td or %zu, and even some that
176*22dc650dSSadaf Ebrahimi claim to be C99 don't support it (hence DISABLE_PERCENT_ZT). */
177*22dc650dSSadaf Ebrahimi 
178*22dc650dSSadaf Ebrahimi #if defined(DISABLE_PERCENT_ZT) || (defined(_MSC_VER) && (_MSC_VER < 1800)) || \
179*22dc650dSSadaf Ebrahimi   (!defined(_MSC_VER) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)))
180*22dc650dSSadaf Ebrahimi #ifdef _WIN64
181*22dc650dSSadaf Ebrahimi #define PTR_FORM "lld"
182*22dc650dSSadaf Ebrahimi #define SIZ_FORM "llu"
183*22dc650dSSadaf Ebrahimi #else
184*22dc650dSSadaf Ebrahimi #define PTR_FORM "ld"
185*22dc650dSSadaf Ebrahimi #define SIZ_FORM "lu"
186*22dc650dSSadaf Ebrahimi #endif
187*22dc650dSSadaf Ebrahimi #else
188*22dc650dSSadaf Ebrahimi #define PTR_FORM "td"
189*22dc650dSSadaf Ebrahimi #define SIZ_FORM "zu"
190*22dc650dSSadaf Ebrahimi #endif
191*22dc650dSSadaf Ebrahimi 
192*22dc650dSSadaf Ebrahimi /* ------------------End of system-specific definitions -------------------- */
193*22dc650dSSadaf Ebrahimi 
194*22dc650dSSadaf Ebrahimi /* Glueing macros that are used in several places below. */
195*22dc650dSSadaf Ebrahimi 
196*22dc650dSSadaf Ebrahimi #define glue(a,b) a##b
197*22dc650dSSadaf Ebrahimi #define G(a,b) glue(a,b)
198*22dc650dSSadaf Ebrahimi 
199*22dc650dSSadaf Ebrahimi /* Miscellaneous parameters and manifests */
200*22dc650dSSadaf Ebrahimi 
201*22dc650dSSadaf Ebrahimi #ifndef CLOCKS_PER_SEC
202*22dc650dSSadaf Ebrahimi #ifdef CLK_TCK
203*22dc650dSSadaf Ebrahimi #define CLOCKS_PER_SEC CLK_TCK
204*22dc650dSSadaf Ebrahimi #else
205*22dc650dSSadaf Ebrahimi #define CLOCKS_PER_SEC 100
206*22dc650dSSadaf Ebrahimi #endif
207*22dc650dSSadaf Ebrahimi #endif
208*22dc650dSSadaf Ebrahimi 
209*22dc650dSSadaf Ebrahimi #define CFORE_UNSET UINT32_MAX    /* Unset value for startend/cfail/cerror fields */
210*22dc650dSSadaf Ebrahimi #define CONVERT_UNSET UINT32_MAX  /* Unset value for convert_type field */
211*22dc650dSSadaf Ebrahimi #define DFA_WS_DIMENSION 1000     /* Size of DFA workspace */
212*22dc650dSSadaf Ebrahimi #define DEFAULT_OVECCOUNT 15      /* Default ovector count */
213*22dc650dSSadaf Ebrahimi #define JUNK_OFFSET 0xdeadbeef    /* For initializing ovector */
214*22dc650dSSadaf Ebrahimi #define LOCALESIZE 32             /* Size of locale name */
215*22dc650dSSadaf Ebrahimi #define LOOPREPEAT 500000         /* Default loop count for timing */
216*22dc650dSSadaf Ebrahimi #define MALLOCLISTSIZE 20         /* For remembering mallocs */
217*22dc650dSSadaf Ebrahimi #define PARENS_NEST_DEFAULT 220   /* Default parentheses nest limit */
218*22dc650dSSadaf Ebrahimi #define PATSTACKSIZE 20           /* Pattern stack for save/restore testing */
219*22dc650dSSadaf Ebrahimi #define REPLACE_MODSIZE 100       /* Field for reading 8-bit replacement */
220*22dc650dSSadaf Ebrahimi #define VERSION_SIZE 64           /* Size of buffer for the version strings */
221*22dc650dSSadaf Ebrahimi 
222*22dc650dSSadaf Ebrahimi /* Default JIT compile options */
223*22dc650dSSadaf Ebrahimi 
224*22dc650dSSadaf Ebrahimi #define JIT_DEFAULT (PCRE2_JIT_COMPLETE|\
225*22dc650dSSadaf Ebrahimi                      PCRE2_JIT_PARTIAL_SOFT|\
226*22dc650dSSadaf Ebrahimi                      PCRE2_JIT_PARTIAL_HARD)
227*22dc650dSSadaf Ebrahimi 
228*22dc650dSSadaf Ebrahimi /* Make sure the buffer into which replacement strings are copied is big enough
229*22dc650dSSadaf Ebrahimi to hold them as 32-bit code units. */
230*22dc650dSSadaf Ebrahimi 
231*22dc650dSSadaf Ebrahimi #define REPLACE_BUFFSIZE 1024   /* This is a byte value */
232*22dc650dSSadaf Ebrahimi 
233*22dc650dSSadaf Ebrahimi /* Execution modes */
234*22dc650dSSadaf Ebrahimi 
235*22dc650dSSadaf Ebrahimi #define PCRE8_MODE   8
236*22dc650dSSadaf Ebrahimi #define PCRE16_MODE 16
237*22dc650dSSadaf Ebrahimi #define PCRE32_MODE 32
238*22dc650dSSadaf Ebrahimi 
239*22dc650dSSadaf Ebrahimi /* Processing returns */
240*22dc650dSSadaf Ebrahimi 
241*22dc650dSSadaf Ebrahimi enum { PR_OK, PR_SKIP, PR_ABEND };
242*22dc650dSSadaf Ebrahimi 
243*22dc650dSSadaf Ebrahimi /* The macro PRINTABLE determines whether to print an output character as-is or
244*22dc650dSSadaf Ebrahimi as a hex value when showing compiled patterns. is We use it in cases when the
245*22dc650dSSadaf Ebrahimi locale has not been explicitly changed, so as to get consistent output from
246*22dc650dSSadaf Ebrahimi systems that differ in their output from isprint() even in the "C" locale. */
247*22dc650dSSadaf Ebrahimi 
248*22dc650dSSadaf Ebrahimi #ifdef EBCDIC
249*22dc650dSSadaf Ebrahimi #define PRINTABLE(c) ((c) >= 64 && (c) < 255)
250*22dc650dSSadaf Ebrahimi #else
251*22dc650dSSadaf Ebrahimi #define PRINTABLE(c) ((c) >= 32 && (c) < 127)
252*22dc650dSSadaf Ebrahimi #endif
253*22dc650dSSadaf Ebrahimi 
254*22dc650dSSadaf Ebrahimi #define PRINTOK(c) ((use_tables != NULL && c < 256)? isprint(c) : PRINTABLE(c))
255*22dc650dSSadaf Ebrahimi 
256*22dc650dSSadaf Ebrahimi /* We have to include some of the library source files because we need
257*22dc650dSSadaf Ebrahimi to use some of the macros, internal structure definitions, and other internal
258*22dc650dSSadaf Ebrahimi values - pcre2test has "inside information" compared to an application program
259*22dc650dSSadaf Ebrahimi that strictly follows the PCRE2 API.
260*22dc650dSSadaf Ebrahimi 
261*22dc650dSSadaf Ebrahimi Before including pcre2_internal.h we define PRIV so that it does not get
262*22dc650dSSadaf Ebrahimi defined therein. This ensures that PRIV names in the included files do not
263*22dc650dSSadaf Ebrahimi clash with those in the libraries. Also, although pcre2_internal.h does itself
264*22dc650dSSadaf Ebrahimi include pcre2.h, we explicitly include it beforehand, along with pcre2posix.h,
265*22dc650dSSadaf Ebrahimi so that the PCRE2_EXP_xxx macros get set appropriately for an application, not
266*22dc650dSSadaf Ebrahimi for building the library.
267*22dc650dSSadaf Ebrahimi 
268*22dc650dSSadaf Ebrahimi Setting PCRE2_CODE_UNIT_WIDTH to zero cuts out all the width-specific settings
269*22dc650dSSadaf Ebrahimi in pcre2.h and pcre2_internal.h. Defining PCRE2_BUILDING_PCRE2TEST cuts out the
270*22dc650dSSadaf Ebrahimi check in pcre2_internal.h that ensures PCRE2_CODE_UNIT_WIDTH is 8, 16, or 32
271*22dc650dSSadaf Ebrahimi (which it needs to be when compiling one of the libraries). */
272*22dc650dSSadaf Ebrahimi 
273*22dc650dSSadaf Ebrahimi #define PRIV(name) name
274*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_UNIT_WIDTH 0
275*22dc650dSSadaf Ebrahimi #define PCRE2_BUILDING_PCRE2TEST
276*22dc650dSSadaf Ebrahimi #include "pcre2.h"
277*22dc650dSSadaf Ebrahimi #include "pcre2posix.h"
278*22dc650dSSadaf Ebrahimi #include "pcre2_internal.h"
279*22dc650dSSadaf Ebrahimi 
280*22dc650dSSadaf Ebrahimi /* We need access to some of the data tables that PCRE2 uses. Defining
281*22dc650dSSadaf Ebrahimi PCRE2_PCRE2TEST makes some minor changes in the files. The previous definition
282*22dc650dSSadaf Ebrahimi of PRIV avoids name clashes. */
283*22dc650dSSadaf Ebrahimi 
284*22dc650dSSadaf Ebrahimi #define PCRE2_PCRE2TEST
285*22dc650dSSadaf Ebrahimi #include "pcre2_tables.c"
286*22dc650dSSadaf Ebrahimi #include "pcre2_ucd.c"
287*22dc650dSSadaf Ebrahimi 
288*22dc650dSSadaf Ebrahimi /* 32-bit integer values in the input are read by strtoul() or strtol(). The
289*22dc650dSSadaf Ebrahimi check needed for overflow depends on whether long ints are in fact longer than
290*22dc650dSSadaf Ebrahimi ints. They are defined not to be shorter. */
291*22dc650dSSadaf Ebrahimi 
292*22dc650dSSadaf Ebrahimi #if ULONG_MAX > UINT32_MAX
293*22dc650dSSadaf Ebrahimi #define U32OVERFLOW(x) (x > UINT32_MAX)
294*22dc650dSSadaf Ebrahimi #else
295*22dc650dSSadaf Ebrahimi #define U32OVERFLOW(x) (x == UINT32_MAX)
296*22dc650dSSadaf Ebrahimi #endif
297*22dc650dSSadaf Ebrahimi 
298*22dc650dSSadaf Ebrahimi #if LONG_MAX > INT32_MAX
299*22dc650dSSadaf Ebrahimi #define S32OVERFLOW(x) (x > INT32_MAX || x < INT32_MIN)
300*22dc650dSSadaf Ebrahimi #else
301*22dc650dSSadaf Ebrahimi #define S32OVERFLOW(x) (x == INT32_MAX || x == INT32_MIN)
302*22dc650dSSadaf Ebrahimi #endif
303*22dc650dSSadaf Ebrahimi 
304*22dc650dSSadaf Ebrahimi /* When PCRE2_CODE_UNIT_WIDTH is zero, pcre2_internal.h does not include
305*22dc650dSSadaf Ebrahimi pcre2_intmodedep.h, which is where mode-dependent macros and structures are
306*22dc650dSSadaf Ebrahimi defined. We can now include it for each supported code unit width. Because
307*22dc650dSSadaf Ebrahimi PCRE2_CODE_UNIT_WIDTH was defined as zero before including pcre2.h, it will
308*22dc650dSSadaf Ebrahimi have left PCRE2_SUFFIX defined as a no-op. We must re-define it appropriately
309*22dc650dSSadaf Ebrahimi while including these files, and then restore it to a no-op. Because LINK_SIZE
310*22dc650dSSadaf Ebrahimi may be changed in 16-bit mode and forced to 1 in 32-bit mode, the order of
311*22dc650dSSadaf Ebrahimi these inclusions should not be changed. */
312*22dc650dSSadaf Ebrahimi 
313*22dc650dSSadaf Ebrahimi #undef PCRE2_SUFFIX
314*22dc650dSSadaf Ebrahimi #undef PCRE2_CODE_UNIT_WIDTH
315*22dc650dSSadaf Ebrahimi 
316*22dc650dSSadaf Ebrahimi #ifdef   SUPPORT_PCRE2_8
317*22dc650dSSadaf Ebrahimi #define  PCRE2_CODE_UNIT_WIDTH 8
318*22dc650dSSadaf Ebrahimi #define  PCRE2_SUFFIX(a) G(a,8)
319*22dc650dSSadaf Ebrahimi #include "pcre2_intmodedep.h"
320*22dc650dSSadaf Ebrahimi #include "pcre2_printint.c"
321*22dc650dSSadaf Ebrahimi #undef   PCRE2_CODE_UNIT_WIDTH
322*22dc650dSSadaf Ebrahimi #undef   PCRE2_SUFFIX
323*22dc650dSSadaf Ebrahimi #endif   /* SUPPORT_PCRE2_8 */
324*22dc650dSSadaf Ebrahimi 
325*22dc650dSSadaf Ebrahimi #ifdef   SUPPORT_PCRE2_16
326*22dc650dSSadaf Ebrahimi #define  PCRE2_CODE_UNIT_WIDTH 16
327*22dc650dSSadaf Ebrahimi #define  PCRE2_SUFFIX(a) G(a,16)
328*22dc650dSSadaf Ebrahimi #include "pcre2_intmodedep.h"
329*22dc650dSSadaf Ebrahimi #include "pcre2_printint.c"
330*22dc650dSSadaf Ebrahimi #undef   PCRE2_CODE_UNIT_WIDTH
331*22dc650dSSadaf Ebrahimi #undef   PCRE2_SUFFIX
332*22dc650dSSadaf Ebrahimi #endif   /* SUPPORT_PCRE2_16 */
333*22dc650dSSadaf Ebrahimi 
334*22dc650dSSadaf Ebrahimi #ifdef   SUPPORT_PCRE2_32
335*22dc650dSSadaf Ebrahimi #define  PCRE2_CODE_UNIT_WIDTH 32
336*22dc650dSSadaf Ebrahimi #define  PCRE2_SUFFIX(a) G(a,32)
337*22dc650dSSadaf Ebrahimi #include "pcre2_intmodedep.h"
338*22dc650dSSadaf Ebrahimi #include "pcre2_printint.c"
339*22dc650dSSadaf Ebrahimi #undef   PCRE2_CODE_UNIT_WIDTH
340*22dc650dSSadaf Ebrahimi #undef   PCRE2_SUFFIX
341*22dc650dSSadaf Ebrahimi #endif   /* SUPPORT_PCRE2_32 */
342*22dc650dSSadaf Ebrahimi 
343*22dc650dSSadaf Ebrahimi #define PCRE2_SUFFIX(a) a
344*22dc650dSSadaf Ebrahimi 
345*22dc650dSSadaf Ebrahimi #include "pcre2_chkdint.c"
346*22dc650dSSadaf Ebrahimi 
347*22dc650dSSadaf Ebrahimi /* We need to be able to check input text for UTF-8 validity, whatever code
348*22dc650dSSadaf Ebrahimi widths are actually available, because the input to pcre2test is always in
349*22dc650dSSadaf Ebrahimi 8-bit code units. So we include the UTF validity checking function for 8-bit
350*22dc650dSSadaf Ebrahimi code units. */
351*22dc650dSSadaf Ebrahimi 
352*22dc650dSSadaf Ebrahimi extern int valid_utf(PCRE2_SPTR8, PCRE2_SIZE, PCRE2_SIZE *);
353*22dc650dSSadaf Ebrahimi 
354*22dc650dSSadaf Ebrahimi #define  PCRE2_CODE_UNIT_WIDTH 8
355*22dc650dSSadaf Ebrahimi #undef   PCRE2_SPTR
356*22dc650dSSadaf Ebrahimi #define  PCRE2_SPTR PCRE2_SPTR8
357*22dc650dSSadaf Ebrahimi #include "pcre2_valid_utf.c"
358*22dc650dSSadaf Ebrahimi #undef   PCRE2_CODE_UNIT_WIDTH
359*22dc650dSSadaf Ebrahimi #undef   PCRE2_SPTR
360*22dc650dSSadaf Ebrahimi 
361*22dc650dSSadaf Ebrahimi /* If we have 8-bit support, default to it; if there is also 16-or 32-bit
362*22dc650dSSadaf Ebrahimi support, it can be selected by a command-line option. If there is no 8-bit
363*22dc650dSSadaf Ebrahimi support, there must be 16-bit or 32-bit support, so default to one of them. The
364*22dc650dSSadaf Ebrahimi config function, JIT stack, contexts, and version string are the same in all
365*22dc650dSSadaf Ebrahimi modes, so use the form of the first that is available. */
366*22dc650dSSadaf Ebrahimi 
367*22dc650dSSadaf Ebrahimi #if defined SUPPORT_PCRE2_8
368*22dc650dSSadaf Ebrahimi #define DEFAULT_TEST_MODE PCRE8_MODE
369*22dc650dSSadaf Ebrahimi #define VERSION_TYPE PCRE2_UCHAR8
370*22dc650dSSadaf Ebrahimi #define PCRE2_CONFIG pcre2_config_8
371*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK pcre2_jit_stack_8
372*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_8
373*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_8
374*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_CONVERT_CONTEXT pcre2_real_convert_context_8
375*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_8
376*22dc650dSSadaf Ebrahimi 
377*22dc650dSSadaf Ebrahimi #elif defined SUPPORT_PCRE2_16
378*22dc650dSSadaf Ebrahimi #define DEFAULT_TEST_MODE PCRE16_MODE
379*22dc650dSSadaf Ebrahimi #define VERSION_TYPE PCRE2_UCHAR16
380*22dc650dSSadaf Ebrahimi #define PCRE2_CONFIG pcre2_config_16
381*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK pcre2_jit_stack_16
382*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_16
383*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_16
384*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_CONVERT_CONTEXT pcre2_real_convert_context_16
385*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_16
386*22dc650dSSadaf Ebrahimi 
387*22dc650dSSadaf Ebrahimi #elif defined SUPPORT_PCRE2_32
388*22dc650dSSadaf Ebrahimi #define DEFAULT_TEST_MODE PCRE32_MODE
389*22dc650dSSadaf Ebrahimi #define VERSION_TYPE PCRE2_UCHAR32
390*22dc650dSSadaf Ebrahimi #define PCRE2_CONFIG pcre2_config_32
391*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK pcre2_jit_stack_32
392*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_32
393*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_32
394*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_CONVERT_CONTEXT pcre2_real_convert_context_32
395*22dc650dSSadaf Ebrahimi #define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_32
396*22dc650dSSadaf Ebrahimi #endif
397*22dc650dSSadaf Ebrahimi 
398*22dc650dSSadaf Ebrahimi /* ------------- Structure and table for handling #-commands ------------- */
399*22dc650dSSadaf Ebrahimi 
400*22dc650dSSadaf Ebrahimi typedef struct cmdstruct {
401*22dc650dSSadaf Ebrahimi   const char *name;
402*22dc650dSSadaf Ebrahimi   int  value;
403*22dc650dSSadaf Ebrahimi } cmdstruct;
404*22dc650dSSadaf Ebrahimi 
405*22dc650dSSadaf Ebrahimi enum { CMD_FORBID_UTF, CMD_LOAD, CMD_LOADTABLES, CMD_NEWLINE_DEFAULT,
406*22dc650dSSadaf Ebrahimi   CMD_PATTERN, CMD_PERLTEST, CMD_POP, CMD_POPCOPY, CMD_SAVE, CMD_SUBJECT,
407*22dc650dSSadaf Ebrahimi   CMD_UNKNOWN };
408*22dc650dSSadaf Ebrahimi 
409*22dc650dSSadaf Ebrahimi static cmdstruct cmdlist[] = {
410*22dc650dSSadaf Ebrahimi   { "forbid_utf",      CMD_FORBID_UTF },
411*22dc650dSSadaf Ebrahimi   { "load",            CMD_LOAD },
412*22dc650dSSadaf Ebrahimi   { "loadtables",      CMD_LOADTABLES },
413*22dc650dSSadaf Ebrahimi   { "newline_default", CMD_NEWLINE_DEFAULT },
414*22dc650dSSadaf Ebrahimi   { "pattern",         CMD_PATTERN },
415*22dc650dSSadaf Ebrahimi   { "perltest",        CMD_PERLTEST },
416*22dc650dSSadaf Ebrahimi   { "pop",             CMD_POP },
417*22dc650dSSadaf Ebrahimi   { "popcopy",         CMD_POPCOPY },
418*22dc650dSSadaf Ebrahimi   { "save",            CMD_SAVE },
419*22dc650dSSadaf Ebrahimi   { "subject",         CMD_SUBJECT }};
420*22dc650dSSadaf Ebrahimi 
421*22dc650dSSadaf Ebrahimi #define cmdlistcount (sizeof(cmdlist)/sizeof(cmdstruct))
422*22dc650dSSadaf Ebrahimi 
423*22dc650dSSadaf Ebrahimi /* ------------- Structures and tables for handling modifiers -------------- */
424*22dc650dSSadaf Ebrahimi 
425*22dc650dSSadaf Ebrahimi /* Table of names for newline types. Must be kept in step with the definitions
426*22dc650dSSadaf Ebrahimi of PCRE2_NEWLINE_xx in pcre2.h. */
427*22dc650dSSadaf Ebrahimi 
428*22dc650dSSadaf Ebrahimi static const char *newlines[] = {
429*22dc650dSSadaf Ebrahimi   "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF", "NUL" };
430*22dc650dSSadaf Ebrahimi 
431*22dc650dSSadaf Ebrahimi /* Structure and table for handling pattern conversion types. */
432*22dc650dSSadaf Ebrahimi 
433*22dc650dSSadaf Ebrahimi typedef struct convertstruct {
434*22dc650dSSadaf Ebrahimi   const char *name;
435*22dc650dSSadaf Ebrahimi   uint32_t option;
436*22dc650dSSadaf Ebrahimi } convertstruct;
437*22dc650dSSadaf Ebrahimi 
438*22dc650dSSadaf Ebrahimi static convertstruct convertlist[] = {
439*22dc650dSSadaf Ebrahimi   { "glob",                   PCRE2_CONVERT_GLOB },
440*22dc650dSSadaf Ebrahimi   { "glob_no_starstar",       PCRE2_CONVERT_GLOB_NO_STARSTAR },
441*22dc650dSSadaf Ebrahimi   { "glob_no_wild_separator", PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR },
442*22dc650dSSadaf Ebrahimi   { "posix_basic",            PCRE2_CONVERT_POSIX_BASIC },
443*22dc650dSSadaf Ebrahimi   { "posix_extended",         PCRE2_CONVERT_POSIX_EXTENDED },
444*22dc650dSSadaf Ebrahimi   { "unset",                  CONVERT_UNSET }};
445*22dc650dSSadaf Ebrahimi 
446*22dc650dSSadaf Ebrahimi #define convertlistcount (sizeof(convertlist)/sizeof(convertstruct))
447*22dc650dSSadaf Ebrahimi 
448*22dc650dSSadaf Ebrahimi /* Modifier types and applicability */
449*22dc650dSSadaf Ebrahimi 
450*22dc650dSSadaf Ebrahimi enum { MOD_CTC,    /* Applies to a compile context */
451*22dc650dSSadaf Ebrahimi        MOD_CTM,    /* Applies to a match context */
452*22dc650dSSadaf Ebrahimi        MOD_PAT,    /* Applies to a pattern */
453*22dc650dSSadaf Ebrahimi        MOD_PATP,   /* Ditto, OK for Perl test */
454*22dc650dSSadaf Ebrahimi        MOD_DAT,    /* Applies to a data line */
455*22dc650dSSadaf Ebrahimi        MOD_DATP,   /* Ditto, OK for Perl test */
456*22dc650dSSadaf Ebrahimi        MOD_PD,     /* Applies to a pattern or a data line */
457*22dc650dSSadaf Ebrahimi        MOD_PDP,    /* As MOD_PD, OK for Perl test */
458*22dc650dSSadaf Ebrahimi        MOD_PND,    /* As MOD_PD, but not for a default pattern */
459*22dc650dSSadaf Ebrahimi        MOD_PNDP,   /* As MOD_PND, OK for Perl test */
460*22dc650dSSadaf Ebrahimi        MOD_CHR,    /* Is a single character */
461*22dc650dSSadaf Ebrahimi        MOD_CON,    /* Is a "convert" type/options list */
462*22dc650dSSadaf Ebrahimi        MOD_CTL,    /* Is a control bit */
463*22dc650dSSadaf Ebrahimi        MOD_BSR,    /* Is a BSR value */
464*22dc650dSSadaf Ebrahimi        MOD_IN2,    /* Is one or two unsigned integers */
465*22dc650dSSadaf Ebrahimi        MOD_INS,    /* Is a signed integer */
466*22dc650dSSadaf Ebrahimi        MOD_INT,    /* Is an unsigned integer */
467*22dc650dSSadaf Ebrahimi        MOD_IND,    /* Is an unsigned integer, but no value => default */
468*22dc650dSSadaf Ebrahimi        MOD_NL,     /* Is a newline value */
469*22dc650dSSadaf Ebrahimi        MOD_NN,     /* Is a number or a name; more than one may occur */
470*22dc650dSSadaf Ebrahimi        MOD_OPT,    /* Is an option bit */
471*22dc650dSSadaf Ebrahimi        MOD_SIZ,    /* Is a PCRE2_SIZE value */
472*22dc650dSSadaf Ebrahimi        MOD_STR };  /* Is a string */
473*22dc650dSSadaf Ebrahimi 
474*22dc650dSSadaf Ebrahimi /* Control bits. Some apply to compiling, some to matching, but some can be set
475*22dc650dSSadaf Ebrahimi either on a pattern or a data line, so they must all be distinct. There are now
476*22dc650dSSadaf Ebrahimi so many of them that they are split into two fields. */
477*22dc650dSSadaf Ebrahimi 
478*22dc650dSSadaf Ebrahimi #define CTL_AFTERTEXT                    0x00000001u
479*22dc650dSSadaf Ebrahimi #define CTL_ALLAFTERTEXT                 0x00000002u
480*22dc650dSSadaf Ebrahimi #define CTL_ALLCAPTURES                  0x00000004u
481*22dc650dSSadaf Ebrahimi #define CTL_ALLUSEDTEXT                  0x00000008u
482*22dc650dSSadaf Ebrahimi #define CTL_ALTGLOBAL                    0x00000010u
483*22dc650dSSadaf Ebrahimi #define CTL_BINCODE                      0x00000020u
484*22dc650dSSadaf Ebrahimi #define CTL_CALLOUT_CAPTURE              0x00000040u
485*22dc650dSSadaf Ebrahimi #define CTL_CALLOUT_INFO                 0x00000080u
486*22dc650dSSadaf Ebrahimi #define CTL_CALLOUT_NONE                 0x00000100u
487*22dc650dSSadaf Ebrahimi #define CTL_DFA                          0x00000200u
488*22dc650dSSadaf Ebrahimi #define CTL_EXPAND                       0x00000400u
489*22dc650dSSadaf Ebrahimi #define CTL_FINDLIMITS                   0x00000800u
490*22dc650dSSadaf Ebrahimi #define CTL_FINDLIMITS_NOHEAP            0x00001000u
491*22dc650dSSadaf Ebrahimi #define CTL_FULLBINCODE                  0x00002000u
492*22dc650dSSadaf Ebrahimi #define CTL_GETALL                       0x00004000u
493*22dc650dSSadaf Ebrahimi #define CTL_GLOBAL                       0x00008000u
494*22dc650dSSadaf Ebrahimi #define CTL_HEXPAT                       0x00010000u  /* Same word as USE_LENGTH */
495*22dc650dSSadaf Ebrahimi #define CTL_INFO                         0x00020000u
496*22dc650dSSadaf Ebrahimi #define CTL_JITFAST                      0x00040000u
497*22dc650dSSadaf Ebrahimi #define CTL_JITVERIFY                    0x00080000u
498*22dc650dSSadaf Ebrahimi #define CTL_MARK                         0x00100000u
499*22dc650dSSadaf Ebrahimi #define CTL_MEMORY                       0x00200000u
500*22dc650dSSadaf Ebrahimi #define CTL_NULLCONTEXT                  0x00400000u
501*22dc650dSSadaf Ebrahimi #define CTL_POSIX                        0x00800000u
502*22dc650dSSadaf Ebrahimi #define CTL_POSIX_NOSUB                  0x01000000u
503*22dc650dSSadaf Ebrahimi #define CTL_PUSH                         0x02000000u  /* These three must be */
504*22dc650dSSadaf Ebrahimi #define CTL_PUSHCOPY                     0x04000000u  /*   all in the same */
505*22dc650dSSadaf Ebrahimi #define CTL_PUSHTABLESCOPY               0x08000000u  /*     word. */
506*22dc650dSSadaf Ebrahimi #define CTL_STARTCHAR                    0x10000000u
507*22dc650dSSadaf Ebrahimi #define CTL_USE_LENGTH                   0x20000000u  /* Same word as HEXPAT */
508*22dc650dSSadaf Ebrahimi #define CTL_UTF8_INPUT                   0x40000000u
509*22dc650dSSadaf Ebrahimi #define CTL_ZERO_TERMINATE               0x80000000u
510*22dc650dSSadaf Ebrahimi 
511*22dc650dSSadaf Ebrahimi /* Combinations */
512*22dc650dSSadaf Ebrahimi 
513*22dc650dSSadaf Ebrahimi #define CTL_DEBUG            (CTL_FULLBINCODE|CTL_INFO)  /* For setting */
514*22dc650dSSadaf Ebrahimi #define CTL_ANYINFO          (CTL_DEBUG|CTL_BINCODE|CTL_CALLOUT_INFO)
515*22dc650dSSadaf Ebrahimi #define CTL_ANYGLOB          (CTL_ALTGLOBAL|CTL_GLOBAL)
516*22dc650dSSadaf Ebrahimi 
517*22dc650dSSadaf Ebrahimi /* Second control word */
518*22dc650dSSadaf Ebrahimi 
519*22dc650dSSadaf Ebrahimi #define CTL2_SUBSTITUTE_CALLOUT          0x00000001u
520*22dc650dSSadaf Ebrahimi #define CTL2_SUBSTITUTE_EXTENDED         0x00000002u
521*22dc650dSSadaf Ebrahimi #define CTL2_SUBSTITUTE_LITERAL          0x00000004u
522*22dc650dSSadaf Ebrahimi #define CTL2_SUBSTITUTE_MATCHED          0x00000008u
523*22dc650dSSadaf Ebrahimi #define CTL2_SUBSTITUTE_OVERFLOW_LENGTH  0x00000010u
524*22dc650dSSadaf Ebrahimi #define CTL2_SUBSTITUTE_REPLACEMENT_ONLY 0x00000020u
525*22dc650dSSadaf Ebrahimi #define CTL2_SUBSTITUTE_UNKNOWN_UNSET    0x00000040u
526*22dc650dSSadaf Ebrahimi #define CTL2_SUBSTITUTE_UNSET_EMPTY      0x00000080u
527*22dc650dSSadaf Ebrahimi #define CTL2_SUBJECT_LITERAL             0x00000100u
528*22dc650dSSadaf Ebrahimi #define CTL2_CALLOUT_NO_WHERE            0x00000200u
529*22dc650dSSadaf Ebrahimi #define CTL2_CALLOUT_EXTRA               0x00000400u
530*22dc650dSSadaf Ebrahimi #define CTL2_ALLVECTOR                   0x00000800u
531*22dc650dSSadaf Ebrahimi #define CTL2_NULL_PATTERN                0x00001000u
532*22dc650dSSadaf Ebrahimi #define CTL2_NULL_SUBJECT                0x00002000u
533*22dc650dSSadaf Ebrahimi #define CTL2_NULL_REPLACEMENT            0x00004000u
534*22dc650dSSadaf Ebrahimi #define CTL2_FRAMESIZE                   0x00008000u
535*22dc650dSSadaf Ebrahimi 
536*22dc650dSSadaf Ebrahimi #define CTL2_HEAPFRAMES_SIZE             0x20000000u  /* Informational */
537*22dc650dSSadaf Ebrahimi #define CTL2_NL_SET                      0x40000000u  /* Informational */
538*22dc650dSSadaf Ebrahimi #define CTL2_BSR_SET                     0x80000000u  /* Informational */
539*22dc650dSSadaf Ebrahimi 
540*22dc650dSSadaf Ebrahimi /* These are the matching controls that may be set either on a pattern or on a
541*22dc650dSSadaf Ebrahimi data line. They are copied from the pattern controls as initial settings for
542*22dc650dSSadaf Ebrahimi data line controls. Note that CTL_MEMORY is not included here, because it does
543*22dc650dSSadaf Ebrahimi different things in the two cases. */
544*22dc650dSSadaf Ebrahimi 
545*22dc650dSSadaf Ebrahimi #define CTL_ALLPD  (CTL_AFTERTEXT|\
546*22dc650dSSadaf Ebrahimi                     CTL_ALLAFTERTEXT|\
547*22dc650dSSadaf Ebrahimi                     CTL_ALLCAPTURES|\
548*22dc650dSSadaf Ebrahimi                     CTL_ALLUSEDTEXT|\
549*22dc650dSSadaf Ebrahimi                     CTL_ALTGLOBAL|\
550*22dc650dSSadaf Ebrahimi                     CTL_GLOBAL|\
551*22dc650dSSadaf Ebrahimi                     CTL_MARK|\
552*22dc650dSSadaf Ebrahimi                     CTL_STARTCHAR|\
553*22dc650dSSadaf Ebrahimi                     CTL_UTF8_INPUT)
554*22dc650dSSadaf Ebrahimi 
555*22dc650dSSadaf Ebrahimi #define CTL2_ALLPD (CTL2_SUBSTITUTE_CALLOUT|\
556*22dc650dSSadaf Ebrahimi                     CTL2_SUBSTITUTE_EXTENDED|\
557*22dc650dSSadaf Ebrahimi                     CTL2_SUBSTITUTE_LITERAL|\
558*22dc650dSSadaf Ebrahimi                     CTL2_SUBSTITUTE_MATCHED|\
559*22dc650dSSadaf Ebrahimi                     CTL2_SUBSTITUTE_OVERFLOW_LENGTH|\
560*22dc650dSSadaf Ebrahimi                     CTL2_SUBSTITUTE_REPLACEMENT_ONLY|\
561*22dc650dSSadaf Ebrahimi                     CTL2_SUBSTITUTE_UNKNOWN_UNSET|\
562*22dc650dSSadaf Ebrahimi                     CTL2_SUBSTITUTE_UNSET_EMPTY|\
563*22dc650dSSadaf Ebrahimi                     CTL2_ALLVECTOR|\
564*22dc650dSSadaf Ebrahimi                     CTL2_HEAPFRAMES_SIZE)
565*22dc650dSSadaf Ebrahimi 
566*22dc650dSSadaf Ebrahimi /* Structures for holding modifier information for patterns and subject strings
567*22dc650dSSadaf Ebrahimi (data). Fields containing modifiers that can be set either for a pattern or a
568*22dc650dSSadaf Ebrahimi subject must be at the start and in the same order in both cases so that the
569*22dc650dSSadaf Ebrahimi same offset in the big table below works for both. */
570*22dc650dSSadaf Ebrahimi 
571*22dc650dSSadaf Ebrahimi typedef struct patctl {       /* Structure for pattern modifiers. */
572*22dc650dSSadaf Ebrahimi   uint32_t  options;          /* Must be in same position as datctl */
573*22dc650dSSadaf Ebrahimi   uint32_t  control;          /* Must be in same position as datctl */
574*22dc650dSSadaf Ebrahimi   uint32_t  control2;         /* Must be in same position as datctl */
575*22dc650dSSadaf Ebrahimi   uint32_t  jitstack;         /* Must be in same position as datctl */
576*22dc650dSSadaf Ebrahimi    uint8_t  replacement[REPLACE_MODSIZE];  /* So must this */
577*22dc650dSSadaf Ebrahimi   uint32_t  substitute_skip;  /* Must be in same position as patctl */
578*22dc650dSSadaf Ebrahimi   uint32_t  substitute_stop;  /* Must be in same position as patctl */
579*22dc650dSSadaf Ebrahimi   uint32_t  jit;
580*22dc650dSSadaf Ebrahimi   uint32_t  stackguard_test;
581*22dc650dSSadaf Ebrahimi   uint32_t  tables_id;
582*22dc650dSSadaf Ebrahimi   uint32_t  convert_type;
583*22dc650dSSadaf Ebrahimi   uint32_t  convert_length;
584*22dc650dSSadaf Ebrahimi   uint32_t  convert_glob_escape;
585*22dc650dSSadaf Ebrahimi   uint32_t  convert_glob_separator;
586*22dc650dSSadaf Ebrahimi   uint32_t  regerror_buffsize;
587*22dc650dSSadaf Ebrahimi    uint8_t  locale[LOCALESIZE];
588*22dc650dSSadaf Ebrahimi } patctl;
589*22dc650dSSadaf Ebrahimi 
590*22dc650dSSadaf Ebrahimi #define MAXCPYGET 10
591*22dc650dSSadaf Ebrahimi #define LENCPYGET 64
592*22dc650dSSadaf Ebrahimi 
593*22dc650dSSadaf Ebrahimi typedef struct datctl {       /* Structure for data line modifiers. */
594*22dc650dSSadaf Ebrahimi   uint32_t  options;          /* Must be in same position as patctl */
595*22dc650dSSadaf Ebrahimi   uint32_t  control;          /* Must be in same position as patctl */
596*22dc650dSSadaf Ebrahimi   uint32_t  control2;         /* Must be in same position as patctl */
597*22dc650dSSadaf Ebrahimi   uint32_t  jitstack;         /* Must be in same position as patctl */
598*22dc650dSSadaf Ebrahimi    uint8_t  replacement[REPLACE_MODSIZE];  /* So must this */
599*22dc650dSSadaf Ebrahimi   uint32_t  substitute_skip;  /* Must be in same position as patctl */
600*22dc650dSSadaf Ebrahimi   uint32_t  substitute_stop;  /* Must be in same position as patctl */
601*22dc650dSSadaf Ebrahimi   uint32_t  startend[2];
602*22dc650dSSadaf Ebrahimi   uint32_t  cerror[2];
603*22dc650dSSadaf Ebrahimi   uint32_t  cfail[2];
604*22dc650dSSadaf Ebrahimi    int32_t  callout_data;
605*22dc650dSSadaf Ebrahimi    int32_t  copy_numbers[MAXCPYGET];
606*22dc650dSSadaf Ebrahimi    int32_t  get_numbers[MAXCPYGET];
607*22dc650dSSadaf Ebrahimi   uint32_t  oveccount;
608*22dc650dSSadaf Ebrahimi   uint32_t  offset;
609*22dc650dSSadaf Ebrahimi   uint8_t   copy_names[LENCPYGET];
610*22dc650dSSadaf Ebrahimi   uint8_t   get_names[LENCPYGET];
611*22dc650dSSadaf Ebrahimi } datctl;
612*22dc650dSSadaf Ebrahimi 
613*22dc650dSSadaf Ebrahimi /* Ids for which context to modify. */
614*22dc650dSSadaf Ebrahimi 
615*22dc650dSSadaf Ebrahimi enum { CTX_PAT,            /* Active pattern context */
616*22dc650dSSadaf Ebrahimi        CTX_POPPAT,         /* Ditto, for a popped pattern */
617*22dc650dSSadaf Ebrahimi        CTX_DEFPAT,         /* Default pattern context */
618*22dc650dSSadaf Ebrahimi        CTX_DAT,            /* Active data (match) context */
619*22dc650dSSadaf Ebrahimi        CTX_DEFDAT };       /* Default data (match) context */
620*22dc650dSSadaf Ebrahimi 
621*22dc650dSSadaf Ebrahimi /* Macros to simplify the big table below. */
622*22dc650dSSadaf Ebrahimi 
623*22dc650dSSadaf Ebrahimi #define CO(name) offsetof(PCRE2_REAL_COMPILE_CONTEXT, name)
624*22dc650dSSadaf Ebrahimi #define MO(name) offsetof(PCRE2_REAL_MATCH_CONTEXT, name)
625*22dc650dSSadaf Ebrahimi #define PO(name) offsetof(patctl, name)
626*22dc650dSSadaf Ebrahimi #define PD(name) PO(name)
627*22dc650dSSadaf Ebrahimi #define DO(name) offsetof(datctl, name)
628*22dc650dSSadaf Ebrahimi 
629*22dc650dSSadaf Ebrahimi /* Table of all long-form modifiers. Must be in collating sequence of modifier
630*22dc650dSSadaf Ebrahimi name because it is searched by binary chop. */
631*22dc650dSSadaf Ebrahimi 
632*22dc650dSSadaf Ebrahimi typedef struct modstruct {
633*22dc650dSSadaf Ebrahimi   const char   *name;
634*22dc650dSSadaf Ebrahimi   uint16_t      which;
635*22dc650dSSadaf Ebrahimi   uint16_t      type;
636*22dc650dSSadaf Ebrahimi   uint32_t      value;
637*22dc650dSSadaf Ebrahimi   PCRE2_SIZE    offset;
638*22dc650dSSadaf Ebrahimi } modstruct;
639*22dc650dSSadaf Ebrahimi 
640*22dc650dSSadaf Ebrahimi #define PCRE2_EXTRA_ASCII_ALL (PCRE2_EXTRA_ASCII_BSD|PCRE2_EXTRA_ASCII_BSS| \
641*22dc650dSSadaf Ebrahimi   PCRE2_EXTRA_ASCII_BSW|PCRE2_EXTRA_ASCII_POSIX)
642*22dc650dSSadaf Ebrahimi 
643*22dc650dSSadaf Ebrahimi static modstruct modlist[] = {
644*22dc650dSSadaf Ebrahimi   { "aftertext",                   MOD_PNDP, MOD_CTL, CTL_AFTERTEXT,              PO(control) },
645*22dc650dSSadaf Ebrahimi   { "allaftertext",                MOD_PNDP, MOD_CTL, CTL_ALLAFTERTEXT,           PO(control) },
646*22dc650dSSadaf Ebrahimi   { "allcaptures",                 MOD_PND,  MOD_CTL, CTL_ALLCAPTURES,            PO(control) },
647*22dc650dSSadaf Ebrahimi   { "allow_empty_class",           MOD_PAT,  MOD_OPT, PCRE2_ALLOW_EMPTY_CLASS,    PO(options) },
648*22dc650dSSadaf Ebrahimi   { "allow_lookaround_bsk",        MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK, CO(extra_options) },
649*22dc650dSSadaf Ebrahimi   { "allow_surrogate_escapes",     MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES, CO(extra_options) },
650*22dc650dSSadaf Ebrahimi   { "allusedtext",                 MOD_PNDP, MOD_CTL, CTL_ALLUSEDTEXT,            PO(control) },
651*22dc650dSSadaf Ebrahimi   { "allvector",                   MOD_PND,  MOD_CTL, CTL2_ALLVECTOR,             PO(control2) },
652*22dc650dSSadaf Ebrahimi   { "alt_bsux",                    MOD_PAT,  MOD_OPT, PCRE2_ALT_BSUX,             PO(options) },
653*22dc650dSSadaf Ebrahimi   { "alt_circumflex",              MOD_PAT,  MOD_OPT, PCRE2_ALT_CIRCUMFLEX,       PO(options) },
654*22dc650dSSadaf Ebrahimi   { "alt_verbnames",               MOD_PAT,  MOD_OPT, PCRE2_ALT_VERBNAMES,        PO(options) },
655*22dc650dSSadaf Ebrahimi   { "altglobal",                   MOD_PND,  MOD_CTL, CTL_ALTGLOBAL,              PO(control) },
656*22dc650dSSadaf Ebrahimi   { "anchored",                    MOD_PD,   MOD_OPT, PCRE2_ANCHORED,             PD(options) },
657*22dc650dSSadaf Ebrahimi   { "ascii_all",                   MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ASCII_ALL,      CO(extra_options) },
658*22dc650dSSadaf Ebrahimi   { "ascii_bsd",                   MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ASCII_BSD,      CO(extra_options) },
659*22dc650dSSadaf Ebrahimi   { "ascii_bss",                   MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ASCII_BSS,      CO(extra_options) },
660*22dc650dSSadaf Ebrahimi   { "ascii_bsw",                   MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ASCII_BSW,      CO(extra_options) },
661*22dc650dSSadaf Ebrahimi   { "ascii_digit",                 MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ASCII_DIGIT,    CO(extra_options) },
662*22dc650dSSadaf Ebrahimi   { "ascii_posix",                 MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ASCII_POSIX,    CO(extra_options) },
663*22dc650dSSadaf Ebrahimi   { "auto_callout",                MOD_PAT,  MOD_OPT, PCRE2_AUTO_CALLOUT,         PO(options) },
664*22dc650dSSadaf Ebrahimi   { "bad_escape_is_literal",       MOD_CTC,  MOD_OPT, PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL, CO(extra_options) },
665*22dc650dSSadaf Ebrahimi   { "bincode",                     MOD_PAT,  MOD_CTL, CTL_BINCODE,                PO(control) },
666*22dc650dSSadaf Ebrahimi   { "bsr",                         MOD_CTC,  MOD_BSR, 0,                          CO(bsr_convention) },
667*22dc650dSSadaf Ebrahimi   { "callout_capture",             MOD_DAT,  MOD_CTL, CTL_CALLOUT_CAPTURE,        DO(control) },
668*22dc650dSSadaf Ebrahimi   { "callout_data",                MOD_DAT,  MOD_INS, 0,                          DO(callout_data) },
669*22dc650dSSadaf Ebrahimi   { "callout_error",               MOD_DAT,  MOD_IN2, 0,                          DO(cerror) },
670*22dc650dSSadaf Ebrahimi   { "callout_extra",               MOD_DAT,  MOD_CTL, CTL2_CALLOUT_EXTRA,         DO(control2) },
671*22dc650dSSadaf Ebrahimi   { "callout_fail",                MOD_DAT,  MOD_IN2, 0,                          DO(cfail) },
672*22dc650dSSadaf Ebrahimi   { "callout_info",                MOD_PAT,  MOD_CTL, CTL_CALLOUT_INFO,           PO(control) },
673*22dc650dSSadaf Ebrahimi   { "callout_no_where",            MOD_DAT,  MOD_CTL, CTL2_CALLOUT_NO_WHERE,      DO(control2) },
674*22dc650dSSadaf Ebrahimi   { "callout_none",                MOD_DAT,  MOD_CTL, CTL_CALLOUT_NONE,           DO(control) },
675*22dc650dSSadaf Ebrahimi   { "caseless",                    MOD_PATP, MOD_OPT, PCRE2_CASELESS,             PO(options) },
676*22dc650dSSadaf Ebrahimi   { "caseless_restrict",           MOD_CTC,  MOD_OPT, PCRE2_EXTRA_CASELESS_RESTRICT, CO(extra_options) },
677*22dc650dSSadaf Ebrahimi   { "convert",                     MOD_PAT,  MOD_CON, 0,                          PO(convert_type) },
678*22dc650dSSadaf Ebrahimi   { "convert_glob_escape",         MOD_PAT,  MOD_CHR, 0,                          PO(convert_glob_escape) },
679*22dc650dSSadaf Ebrahimi   { "convert_glob_separator",      MOD_PAT,  MOD_CHR, 0,                          PO(convert_glob_separator) },
680*22dc650dSSadaf Ebrahimi   { "convert_length",              MOD_PAT,  MOD_INT, 0,                          PO(convert_length) },
681*22dc650dSSadaf Ebrahimi   { "copy",                        MOD_DAT,  MOD_NN,  DO(copy_numbers),           DO(copy_names) },
682*22dc650dSSadaf Ebrahimi   { "copy_matched_subject",        MOD_DAT,  MOD_OPT, PCRE2_COPY_MATCHED_SUBJECT, DO(options) },
683*22dc650dSSadaf Ebrahimi   { "debug",                       MOD_PAT,  MOD_CTL, CTL_DEBUG,                  PO(control) },
684*22dc650dSSadaf Ebrahimi   { "depth_limit",                 MOD_CTM,  MOD_INT, 0,                          MO(depth_limit) },
685*22dc650dSSadaf Ebrahimi   { "dfa",                         MOD_DAT,  MOD_CTL, CTL_DFA,                    DO(control) },
686*22dc650dSSadaf Ebrahimi   { "dfa_restart",                 MOD_DAT,  MOD_OPT, PCRE2_DFA_RESTART,          DO(options) },
687*22dc650dSSadaf Ebrahimi   { "dfa_shortest",                MOD_DAT,  MOD_OPT, PCRE2_DFA_SHORTEST,         DO(options) },
688*22dc650dSSadaf Ebrahimi   { "disable_recurseloop_check",   MOD_DAT,  MOD_OPT, PCRE2_DISABLE_RECURSELOOP_CHECK, DO(options) },
689*22dc650dSSadaf Ebrahimi   { "dollar_endonly",              MOD_PAT,  MOD_OPT, PCRE2_DOLLAR_ENDONLY,       PO(options) },
690*22dc650dSSadaf Ebrahimi   { "dotall",                      MOD_PATP, MOD_OPT, PCRE2_DOTALL,               PO(options) },
691*22dc650dSSadaf Ebrahimi   { "dupnames",                    MOD_PATP, MOD_OPT, PCRE2_DUPNAMES,             PO(options) },
692*22dc650dSSadaf Ebrahimi   { "endanchored",                 MOD_PD,   MOD_OPT, PCRE2_ENDANCHORED,          PD(options) },
693*22dc650dSSadaf Ebrahimi   { "escaped_cr_is_lf",            MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ESCAPED_CR_IS_LF, CO(extra_options) },
694*22dc650dSSadaf Ebrahimi   { "expand",                      MOD_PAT,  MOD_CTL, CTL_EXPAND,                 PO(control) },
695*22dc650dSSadaf Ebrahimi   { "extended",                    MOD_PATP, MOD_OPT, PCRE2_EXTENDED,             PO(options) },
696*22dc650dSSadaf Ebrahimi   { "extended_more",               MOD_PATP, MOD_OPT, PCRE2_EXTENDED_MORE,        PO(options) },
697*22dc650dSSadaf Ebrahimi   { "extra_alt_bsux",              MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ALT_BSUX,       CO(extra_options) },
698*22dc650dSSadaf Ebrahimi   { "find_limits",                 MOD_DAT,  MOD_CTL, CTL_FINDLIMITS,             DO(control) },
699*22dc650dSSadaf Ebrahimi   { "find_limits_noheap",          MOD_DAT,  MOD_CTL, CTL_FINDLIMITS_NOHEAP,      DO(control) },
700*22dc650dSSadaf Ebrahimi   { "firstline",                   MOD_PAT,  MOD_OPT, PCRE2_FIRSTLINE,            PO(options) },
701*22dc650dSSadaf Ebrahimi   { "framesize",                   MOD_PAT,  MOD_CTL, CTL2_FRAMESIZE,             PO(control2) },
702*22dc650dSSadaf Ebrahimi   { "fullbincode",                 MOD_PAT,  MOD_CTL, CTL_FULLBINCODE,            PO(control) },
703*22dc650dSSadaf Ebrahimi   { "get",                         MOD_DAT,  MOD_NN,  DO(get_numbers),            DO(get_names) },
704*22dc650dSSadaf Ebrahimi   { "getall",                      MOD_DAT,  MOD_CTL, CTL_GETALL,                 DO(control) },
705*22dc650dSSadaf Ebrahimi   { "global",                      MOD_PNDP, MOD_CTL, CTL_GLOBAL,                 PO(control) },
706*22dc650dSSadaf Ebrahimi   { "heap_limit",                  MOD_CTM,  MOD_INT, 0,                          MO(heap_limit) },
707*22dc650dSSadaf Ebrahimi   { "heapframes_size",             MOD_PND,  MOD_CTL, CTL2_HEAPFRAMES_SIZE,       PO(control2) },
708*22dc650dSSadaf Ebrahimi   { "hex",                         MOD_PAT,  MOD_CTL, CTL_HEXPAT,                 PO(control) },
709*22dc650dSSadaf Ebrahimi   { "info",                        MOD_PAT,  MOD_CTL, CTL_INFO,                   PO(control) },
710*22dc650dSSadaf Ebrahimi   { "jit",                         MOD_PAT,  MOD_IND, 7,                          PO(jit) },
711*22dc650dSSadaf Ebrahimi   { "jitfast",                     MOD_PAT,  MOD_CTL, CTL_JITFAST,                PO(control) },
712*22dc650dSSadaf Ebrahimi   { "jitstack",                    MOD_PNDP, MOD_INT, 0,                          PO(jitstack) },
713*22dc650dSSadaf Ebrahimi   { "jitverify",                   MOD_PAT,  MOD_CTL, CTL_JITVERIFY,              PO(control) },
714*22dc650dSSadaf Ebrahimi   { "literal",                     MOD_PAT,  MOD_OPT, PCRE2_LITERAL,              PO(options) },
715*22dc650dSSadaf Ebrahimi   { "locale",                      MOD_PAT,  MOD_STR, LOCALESIZE,                 PO(locale) },
716*22dc650dSSadaf Ebrahimi   { "mark",                        MOD_PNDP, MOD_CTL, CTL_MARK,                   PO(control) },
717*22dc650dSSadaf Ebrahimi   { "match_invalid_utf",           MOD_PAT,  MOD_OPT, PCRE2_MATCH_INVALID_UTF,    PO(options) },
718*22dc650dSSadaf Ebrahimi   { "match_limit",                 MOD_CTM,  MOD_INT, 0,                          MO(match_limit) },
719*22dc650dSSadaf Ebrahimi   { "match_line",                  MOD_CTC,  MOD_OPT, PCRE2_EXTRA_MATCH_LINE,     CO(extra_options) },
720*22dc650dSSadaf Ebrahimi   { "match_unset_backref",         MOD_PAT,  MOD_OPT, PCRE2_MATCH_UNSET_BACKREF,  PO(options) },
721*22dc650dSSadaf Ebrahimi   { "match_word",                  MOD_CTC,  MOD_OPT, PCRE2_EXTRA_MATCH_WORD,     CO(extra_options) },
722*22dc650dSSadaf Ebrahimi   { "max_pattern_compiled_length", MOD_CTC,  MOD_SIZ, 0,                          CO(max_pattern_compiled_length) },
723*22dc650dSSadaf Ebrahimi   { "max_pattern_length",          MOD_CTC,  MOD_SIZ, 0,                          CO(max_pattern_length) },
724*22dc650dSSadaf Ebrahimi   { "max_varlookbehind",           MOD_CTC,  MOD_INT, 0,                          CO(max_varlookbehind) },
725*22dc650dSSadaf Ebrahimi   { "memory",                      MOD_PD,   MOD_CTL, CTL_MEMORY,                 PD(control) },
726*22dc650dSSadaf Ebrahimi   { "multiline",                   MOD_PATP, MOD_OPT, PCRE2_MULTILINE,            PO(options) },
727*22dc650dSSadaf Ebrahimi   { "never_backslash_c",           MOD_PAT,  MOD_OPT, PCRE2_NEVER_BACKSLASH_C,    PO(options) },
728*22dc650dSSadaf Ebrahimi   { "never_ucp",                   MOD_PAT,  MOD_OPT, PCRE2_NEVER_UCP,            PO(options) },
729*22dc650dSSadaf Ebrahimi   { "never_utf",                   MOD_PAT,  MOD_OPT, PCRE2_NEVER_UTF,            PO(options) },
730*22dc650dSSadaf Ebrahimi   { "newline",                     MOD_CTC,  MOD_NL,  0,                          CO(newline_convention) },
731*22dc650dSSadaf Ebrahimi   { "no_auto_capture",             MOD_PAT,  MOD_OPT, PCRE2_NO_AUTO_CAPTURE,      PO(options) },
732*22dc650dSSadaf Ebrahimi   { "no_auto_possess",             MOD_PATP, MOD_OPT, PCRE2_NO_AUTO_POSSESS,      PO(options) },
733*22dc650dSSadaf Ebrahimi   { "no_dotstar_anchor",           MOD_PAT,  MOD_OPT, PCRE2_NO_DOTSTAR_ANCHOR,    PO(options) },
734*22dc650dSSadaf Ebrahimi   { "no_jit",                      MOD_DATP, MOD_OPT, PCRE2_NO_JIT,               DO(options) },
735*22dc650dSSadaf Ebrahimi   { "no_start_optimize",           MOD_PATP, MOD_OPT, PCRE2_NO_START_OPTIMIZE,    PO(options) },
736*22dc650dSSadaf Ebrahimi   { "no_utf_check",                MOD_PD,   MOD_OPT, PCRE2_NO_UTF_CHECK,         PD(options) },
737*22dc650dSSadaf Ebrahimi   { "notbol",                      MOD_DAT,  MOD_OPT, PCRE2_NOTBOL,               DO(options) },
738*22dc650dSSadaf Ebrahimi   { "notempty",                    MOD_DAT,  MOD_OPT, PCRE2_NOTEMPTY,             DO(options) },
739*22dc650dSSadaf Ebrahimi   { "notempty_atstart",            MOD_DAT,  MOD_OPT, PCRE2_NOTEMPTY_ATSTART,     DO(options) },
740*22dc650dSSadaf Ebrahimi   { "noteol",                      MOD_DAT,  MOD_OPT, PCRE2_NOTEOL,               DO(options) },
741*22dc650dSSadaf Ebrahimi   { "null_context",                MOD_PD,   MOD_CTL, CTL_NULLCONTEXT,            PO(control) },
742*22dc650dSSadaf Ebrahimi   { "null_pattern",                MOD_PAT,  MOD_CTL, CTL2_NULL_PATTERN,          PO(control2) },
743*22dc650dSSadaf Ebrahimi   { "null_replacement",            MOD_DAT,  MOD_CTL, CTL2_NULL_REPLACEMENT,      DO(control2) },
744*22dc650dSSadaf Ebrahimi   { "null_subject",                MOD_DAT,  MOD_CTL, CTL2_NULL_SUBJECT,          DO(control2) },
745*22dc650dSSadaf Ebrahimi   { "offset",                      MOD_DAT,  MOD_INT, 0,                          DO(offset) },
746*22dc650dSSadaf Ebrahimi   { "offset_limit",                MOD_CTM,  MOD_SIZ, 0,                          MO(offset_limit)},
747*22dc650dSSadaf Ebrahimi   { "ovector",                     MOD_DAT,  MOD_INT, 0,                          DO(oveccount) },
748*22dc650dSSadaf Ebrahimi   { "parens_nest_limit",           MOD_CTC,  MOD_INT, 0,                          CO(parens_nest_limit) },
749*22dc650dSSadaf Ebrahimi   { "partial_hard",                MOD_DAT,  MOD_OPT, PCRE2_PARTIAL_HARD,         DO(options) },
750*22dc650dSSadaf Ebrahimi   { "partial_soft",                MOD_DAT,  MOD_OPT, PCRE2_PARTIAL_SOFT,         DO(options) },
751*22dc650dSSadaf Ebrahimi   { "ph",                          MOD_DAT,  MOD_OPT, PCRE2_PARTIAL_HARD,         DO(options) },
752*22dc650dSSadaf Ebrahimi   { "posix",                       MOD_PAT,  MOD_CTL, CTL_POSIX,                  PO(control) },
753*22dc650dSSadaf Ebrahimi   { "posix_nosub",                 MOD_PAT,  MOD_CTL, CTL_POSIX|CTL_POSIX_NOSUB,  PO(control) },
754*22dc650dSSadaf Ebrahimi   { "posix_startend",              MOD_DAT,  MOD_IN2, 0,                          DO(startend) },
755*22dc650dSSadaf Ebrahimi   { "ps",                          MOD_DAT,  MOD_OPT, PCRE2_PARTIAL_SOFT,         DO(options) },
756*22dc650dSSadaf Ebrahimi   { "push",                        MOD_PAT,  MOD_CTL, CTL_PUSH,                   PO(control) },
757*22dc650dSSadaf Ebrahimi   { "pushcopy",                    MOD_PAT,  MOD_CTL, CTL_PUSHCOPY,               PO(control) },
758*22dc650dSSadaf Ebrahimi   { "pushtablescopy",              MOD_PAT,  MOD_CTL, CTL_PUSHTABLESCOPY,         PO(control) },
759*22dc650dSSadaf Ebrahimi   { "recursion_limit",             MOD_CTM,  MOD_INT, 0,                          MO(depth_limit) },  /* Obsolete synonym */
760*22dc650dSSadaf Ebrahimi   { "regerror_buffsize",           MOD_PAT,  MOD_INT, 0,                          PO(regerror_buffsize) },
761*22dc650dSSadaf Ebrahimi   { "replace",                     MOD_PND,  MOD_STR, REPLACE_MODSIZE,            PO(replacement) },
762*22dc650dSSadaf Ebrahimi   { "stackguard",                  MOD_PAT,  MOD_INT, 0,                          PO(stackguard_test) },
763*22dc650dSSadaf Ebrahimi   { "startchar",                   MOD_PND,  MOD_CTL, CTL_STARTCHAR,              PO(control) },
764*22dc650dSSadaf Ebrahimi   { "startoffset",                 MOD_DAT,  MOD_INT, 0,                          DO(offset) },
765*22dc650dSSadaf Ebrahimi   { "subject_literal",             MOD_PATP, MOD_CTL, CTL2_SUBJECT_LITERAL,       PO(control2) },
766*22dc650dSSadaf Ebrahimi   { "substitute_callout",          MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_CALLOUT,    PO(control2) },
767*22dc650dSSadaf Ebrahimi   { "substitute_extended",         MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_EXTENDED,   PO(control2) },
768*22dc650dSSadaf Ebrahimi   { "substitute_literal",          MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_LITERAL,    PO(control2) },
769*22dc650dSSadaf Ebrahimi   { "substitute_matched",          MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_MATCHED,    PO(control2) },
770*22dc650dSSadaf Ebrahimi   { "substitute_overflow_length",  MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_OVERFLOW_LENGTH, PO(control2) },
771*22dc650dSSadaf Ebrahimi   { "substitute_replacement_only", MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_REPLACEMENT_ONLY, PO(control2) },
772*22dc650dSSadaf Ebrahimi   { "substitute_skip",             MOD_PND,  MOD_INT, 0,                          PO(substitute_skip) },
773*22dc650dSSadaf Ebrahimi   { "substitute_stop",             MOD_PND,  MOD_INT, 0,                          PO(substitute_stop) },
774*22dc650dSSadaf Ebrahimi   { "substitute_unknown_unset",    MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_UNKNOWN_UNSET, PO(control2) },
775*22dc650dSSadaf Ebrahimi   { "substitute_unset_empty",      MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_UNSET_EMPTY, PO(control2) },
776*22dc650dSSadaf Ebrahimi   { "tables",                      MOD_PAT,  MOD_INT, 0,                          PO(tables_id) },
777*22dc650dSSadaf Ebrahimi   { "ucp",                         MOD_PATP, MOD_OPT, PCRE2_UCP,                  PO(options) },
778*22dc650dSSadaf Ebrahimi   { "ungreedy",                    MOD_PAT,  MOD_OPT, PCRE2_UNGREEDY,             PO(options) },
779*22dc650dSSadaf Ebrahimi   { "use_length",                  MOD_PAT,  MOD_CTL, CTL_USE_LENGTH,             PO(control) },
780*22dc650dSSadaf Ebrahimi   { "use_offset_limit",            MOD_PAT,  MOD_OPT, PCRE2_USE_OFFSET_LIMIT,     PO(options) },
781*22dc650dSSadaf Ebrahimi   { "utf",                         MOD_PATP, MOD_OPT, PCRE2_UTF,                  PO(options) },
782*22dc650dSSadaf Ebrahimi   { "utf8_input",                  MOD_PAT,  MOD_CTL, CTL_UTF8_INPUT,             PO(control) },
783*22dc650dSSadaf Ebrahimi   { "zero_terminate",              MOD_DAT,  MOD_CTL, CTL_ZERO_TERMINATE,         DO(control) }
784*22dc650dSSadaf Ebrahimi };
785*22dc650dSSadaf Ebrahimi 
786*22dc650dSSadaf Ebrahimi #define MODLISTCOUNT sizeof(modlist)/sizeof(modstruct)
787*22dc650dSSadaf Ebrahimi 
788*22dc650dSSadaf Ebrahimi /* Controls and options that are supported for use with the POSIX interface. */
789*22dc650dSSadaf Ebrahimi 
790*22dc650dSSadaf Ebrahimi #define POSIX_SUPPORTED_COMPILE_OPTIONS ( \
791*22dc650dSSadaf Ebrahimi   PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_LITERAL|PCRE2_MULTILINE|PCRE2_UCP| \
792*22dc650dSSadaf Ebrahimi   PCRE2_UTF|PCRE2_UNGREEDY)
793*22dc650dSSadaf Ebrahimi 
794*22dc650dSSadaf Ebrahimi #define POSIX_SUPPORTED_COMPILE_EXTRA_OPTIONS (0)
795*22dc650dSSadaf Ebrahimi 
796*22dc650dSSadaf Ebrahimi #define POSIX_SUPPORTED_COMPILE_CONTROLS ( \
797*22dc650dSSadaf Ebrahimi   CTL_AFTERTEXT|CTL_ALLAFTERTEXT|CTL_EXPAND|CTL_HEXPAT|CTL_POSIX| \
798*22dc650dSSadaf Ebrahimi   CTL_POSIX_NOSUB|CTL_USE_LENGTH)
799*22dc650dSSadaf Ebrahimi 
800*22dc650dSSadaf Ebrahimi #define POSIX_SUPPORTED_COMPILE_CONTROLS2 (0)
801*22dc650dSSadaf Ebrahimi 
802*22dc650dSSadaf Ebrahimi #define POSIX_SUPPORTED_MATCH_OPTIONS ( \
803*22dc650dSSadaf Ebrahimi   PCRE2_NOTBOL|PCRE2_NOTEMPTY|PCRE2_NOTEOL)
804*22dc650dSSadaf Ebrahimi 
805*22dc650dSSadaf Ebrahimi #define POSIX_SUPPORTED_MATCH_CONTROLS  (CTL_AFTERTEXT|CTL_ALLAFTERTEXT)
806*22dc650dSSadaf Ebrahimi #define POSIX_SUPPORTED_MATCH_CONTROLS2 (CTL2_NULL_SUBJECT)
807*22dc650dSSadaf Ebrahimi 
808*22dc650dSSadaf Ebrahimi /* Control bits that are not ignored with 'push'. */
809*22dc650dSSadaf Ebrahimi 
810*22dc650dSSadaf Ebrahimi #define PUSH_SUPPORTED_COMPILE_CONTROLS ( \
811*22dc650dSSadaf Ebrahimi   CTL_BINCODE|CTL_CALLOUT_INFO|CTL_FULLBINCODE|CTL_HEXPAT|CTL_INFO| \
812*22dc650dSSadaf Ebrahimi   CTL_JITVERIFY|CTL_MEMORY|CTL_PUSH|CTL_PUSHCOPY| \
813*22dc650dSSadaf Ebrahimi   CTL_PUSHTABLESCOPY|CTL_USE_LENGTH)
814*22dc650dSSadaf Ebrahimi 
815*22dc650dSSadaf Ebrahimi #define PUSH_SUPPORTED_COMPILE_CONTROLS2 (CTL2_BSR_SET| \
816*22dc650dSSadaf Ebrahimi   CTL2_HEAPFRAMES_SIZE|CTL2_FRAMESIZE|CTL2_NL_SET)
817*22dc650dSSadaf Ebrahimi 
818*22dc650dSSadaf Ebrahimi /* Controls that apply only at compile time with 'push'. */
819*22dc650dSSadaf Ebrahimi 
820*22dc650dSSadaf Ebrahimi #define PUSH_COMPILE_ONLY_CONTROLS   CTL_JITVERIFY
821*22dc650dSSadaf Ebrahimi #define PUSH_COMPILE_ONLY_CONTROLS2  (0)
822*22dc650dSSadaf Ebrahimi 
823*22dc650dSSadaf Ebrahimi /* Controls that are forbidden with #pop or #popcopy. */
824*22dc650dSSadaf Ebrahimi 
825*22dc650dSSadaf Ebrahimi #define NOTPOP_CONTROLS (CTL_HEXPAT|CTL_POSIX|CTL_POSIX_NOSUB|CTL_PUSH| \
826*22dc650dSSadaf Ebrahimi   CTL_PUSHCOPY|CTL_PUSHTABLESCOPY|CTL_USE_LENGTH)
827*22dc650dSSadaf Ebrahimi 
828*22dc650dSSadaf Ebrahimi /* Pattern controls that are mutually exclusive. At present these are all in
829*22dc650dSSadaf Ebrahimi the first control word. Note that CTL_POSIX_NOSUB is always accompanied by
830*22dc650dSSadaf Ebrahimi CTL_POSIX, so it doesn't need its own entries. */
831*22dc650dSSadaf Ebrahimi 
832*22dc650dSSadaf Ebrahimi static uint32_t exclusive_pat_controls[] = {
833*22dc650dSSadaf Ebrahimi   CTL_POSIX    | CTL_PUSH,
834*22dc650dSSadaf Ebrahimi   CTL_POSIX    | CTL_PUSHCOPY,
835*22dc650dSSadaf Ebrahimi   CTL_POSIX    | CTL_PUSHTABLESCOPY,
836*22dc650dSSadaf Ebrahimi   CTL_PUSH     | CTL_PUSHCOPY,
837*22dc650dSSadaf Ebrahimi   CTL_PUSH     | CTL_PUSHTABLESCOPY,
838*22dc650dSSadaf Ebrahimi   CTL_PUSHCOPY | CTL_PUSHTABLESCOPY,
839*22dc650dSSadaf Ebrahimi   CTL_EXPAND   | CTL_HEXPAT };
840*22dc650dSSadaf Ebrahimi 
841*22dc650dSSadaf Ebrahimi /* Data controls that are mutually exclusive. At present these are all in the
842*22dc650dSSadaf Ebrahimi first control word. */
843*22dc650dSSadaf Ebrahimi 
844*22dc650dSSadaf Ebrahimi static uint32_t exclusive_dat_controls[] = {
845*22dc650dSSadaf Ebrahimi   CTL_ALLUSEDTEXT        | CTL_STARTCHAR,
846*22dc650dSSadaf Ebrahimi   CTL_FINDLIMITS         | CTL_NULLCONTEXT,
847*22dc650dSSadaf Ebrahimi   CTL_FINDLIMITS_NOHEAP  | CTL_NULLCONTEXT };
848*22dc650dSSadaf Ebrahimi 
849*22dc650dSSadaf Ebrahimi /* Table of single-character abbreviated modifiers. The index field is
850*22dc650dSSadaf Ebrahimi initialized to -1, but the first time the modifier is encountered, it is filled
851*22dc650dSSadaf Ebrahimi in with the index of the full entry in modlist, to save repeated searching when
852*22dc650dSSadaf Ebrahimi processing multiple test items. This short list is searched serially, so its
853*22dc650dSSadaf Ebrahimi order does not matter. */
854*22dc650dSSadaf Ebrahimi 
855*22dc650dSSadaf Ebrahimi typedef struct c1modstruct {
856*22dc650dSSadaf Ebrahimi   const char *fullname;
857*22dc650dSSadaf Ebrahimi   uint32_t    onechar;
858*22dc650dSSadaf Ebrahimi   int         index;
859*22dc650dSSadaf Ebrahimi } c1modstruct;
860*22dc650dSSadaf Ebrahimi 
861*22dc650dSSadaf Ebrahimi static c1modstruct c1modlist[] = {
862*22dc650dSSadaf Ebrahimi   { "bincode",           'B',           -1 },
863*22dc650dSSadaf Ebrahimi   { "info",              'I',           -1 },
864*22dc650dSSadaf Ebrahimi   { "ascii_all",         'a',           -1 },
865*22dc650dSSadaf Ebrahimi   { "global",            'g',           -1 },
866*22dc650dSSadaf Ebrahimi   { "caseless",          'i',           -1 },
867*22dc650dSSadaf Ebrahimi   { "multiline",         'm',           -1 },
868*22dc650dSSadaf Ebrahimi   { "no_auto_capture",   'n',           -1 },
869*22dc650dSSadaf Ebrahimi   { "caseless_restrict", 'r',           -1 },
870*22dc650dSSadaf Ebrahimi   { "dotall",            's',           -1 },
871*22dc650dSSadaf Ebrahimi   { "extended",          'x',           -1 }
872*22dc650dSSadaf Ebrahimi };
873*22dc650dSSadaf Ebrahimi 
874*22dc650dSSadaf Ebrahimi #define C1MODLISTCOUNT sizeof(c1modlist)/sizeof(c1modstruct)
875*22dc650dSSadaf Ebrahimi 
876*22dc650dSSadaf Ebrahimi /* Table of arguments for the -C command line option. Use macros to make the
877*22dc650dSSadaf Ebrahimi table itself easier to read. */
878*22dc650dSSadaf Ebrahimi 
879*22dc650dSSadaf Ebrahimi #if defined SUPPORT_PCRE2_8
880*22dc650dSSadaf Ebrahimi #define SUPPORT_8 1
881*22dc650dSSadaf Ebrahimi #endif
882*22dc650dSSadaf Ebrahimi #if defined SUPPORT_PCRE2_16
883*22dc650dSSadaf Ebrahimi #define SUPPORT_16 1
884*22dc650dSSadaf Ebrahimi #endif
885*22dc650dSSadaf Ebrahimi #if defined SUPPORT_PCRE2_32
886*22dc650dSSadaf Ebrahimi #define SUPPORT_32 1
887*22dc650dSSadaf Ebrahimi #endif
888*22dc650dSSadaf Ebrahimi 
889*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_8
890*22dc650dSSadaf Ebrahimi #define SUPPORT_8 0
891*22dc650dSSadaf Ebrahimi #endif
892*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_16
893*22dc650dSSadaf Ebrahimi #define SUPPORT_16 0
894*22dc650dSSadaf Ebrahimi #endif
895*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_32
896*22dc650dSSadaf Ebrahimi #define SUPPORT_32 0
897*22dc650dSSadaf Ebrahimi #endif
898*22dc650dSSadaf Ebrahimi 
899*22dc650dSSadaf Ebrahimi #ifdef EBCDIC
900*22dc650dSSadaf Ebrahimi #define SUPPORT_EBCDIC 1
901*22dc650dSSadaf Ebrahimi #define EBCDIC_NL CHAR_LF
902*22dc650dSSadaf Ebrahimi #else
903*22dc650dSSadaf Ebrahimi #define SUPPORT_EBCDIC 0
904*22dc650dSSadaf Ebrahimi #define EBCDIC_NL 0
905*22dc650dSSadaf Ebrahimi #endif
906*22dc650dSSadaf Ebrahimi 
907*22dc650dSSadaf Ebrahimi #ifdef NEVER_BACKSLASH_C
908*22dc650dSSadaf Ebrahimi #define BACKSLASH_C 0
909*22dc650dSSadaf Ebrahimi #else
910*22dc650dSSadaf Ebrahimi #define BACKSLASH_C 1
911*22dc650dSSadaf Ebrahimi #endif
912*22dc650dSSadaf Ebrahimi 
913*22dc650dSSadaf Ebrahimi typedef struct coptstruct {
914*22dc650dSSadaf Ebrahimi   const char *name;
915*22dc650dSSadaf Ebrahimi   uint32_t    type;
916*22dc650dSSadaf Ebrahimi   uint32_t    value;
917*22dc650dSSadaf Ebrahimi } coptstruct;
918*22dc650dSSadaf Ebrahimi 
919*22dc650dSSadaf Ebrahimi enum { CONF_BSR,
920*22dc650dSSadaf Ebrahimi        CONF_FIX,
921*22dc650dSSadaf Ebrahimi        CONF_FIZ,
922*22dc650dSSadaf Ebrahimi        CONF_INT,
923*22dc650dSSadaf Ebrahimi        CONF_NL
924*22dc650dSSadaf Ebrahimi };
925*22dc650dSSadaf Ebrahimi 
926*22dc650dSSadaf Ebrahimi static coptstruct coptlist[] = {
927*22dc650dSSadaf Ebrahimi   { "backslash-C", CONF_FIX, BACKSLASH_C },
928*22dc650dSSadaf Ebrahimi   { "bsr",         CONF_BSR, PCRE2_CONFIG_BSR },
929*22dc650dSSadaf Ebrahimi   { "ebcdic",      CONF_FIX, SUPPORT_EBCDIC },
930*22dc650dSSadaf Ebrahimi   { "ebcdic-nl",   CONF_FIZ, EBCDIC_NL },
931*22dc650dSSadaf Ebrahimi   { "jit",         CONF_INT, PCRE2_CONFIG_JIT },
932*22dc650dSSadaf Ebrahimi   { "linksize",    CONF_INT, PCRE2_CONFIG_LINKSIZE },
933*22dc650dSSadaf Ebrahimi   { "newline",     CONF_NL,  PCRE2_CONFIG_NEWLINE },
934*22dc650dSSadaf Ebrahimi   { "pcre2-16",    CONF_FIX, SUPPORT_16 },
935*22dc650dSSadaf Ebrahimi   { "pcre2-32",    CONF_FIX, SUPPORT_32 },
936*22dc650dSSadaf Ebrahimi   { "pcre2-8",     CONF_FIX, SUPPORT_8 },
937*22dc650dSSadaf Ebrahimi   { "unicode",     CONF_INT, PCRE2_CONFIG_UNICODE }
938*22dc650dSSadaf Ebrahimi };
939*22dc650dSSadaf Ebrahimi 
940*22dc650dSSadaf Ebrahimi #define COPTLISTCOUNT sizeof(coptlist)/sizeof(coptstruct)
941*22dc650dSSadaf Ebrahimi 
942*22dc650dSSadaf Ebrahimi #undef SUPPORT_8
943*22dc650dSSadaf Ebrahimi #undef SUPPORT_16
944*22dc650dSSadaf Ebrahimi #undef SUPPORT_32
945*22dc650dSSadaf Ebrahimi #undef SUPPORT_EBCDIC
946*22dc650dSSadaf Ebrahimi 
947*22dc650dSSadaf Ebrahimi 
948*22dc650dSSadaf Ebrahimi /* ----------------------- Static variables ------------------------ */
949*22dc650dSSadaf Ebrahimi 
950*22dc650dSSadaf Ebrahimi static FILE *infile;
951*22dc650dSSadaf Ebrahimi static FILE *outfile;
952*22dc650dSSadaf Ebrahimi 
953*22dc650dSSadaf Ebrahimi static const void *last_callout_mark;
954*22dc650dSSadaf Ebrahimi static PCRE2_JIT_STACK *jit_stack = NULL;
955*22dc650dSSadaf Ebrahimi static size_t jit_stack_size = 0;
956*22dc650dSSadaf Ebrahimi 
957*22dc650dSSadaf Ebrahimi static BOOL first_callout;
958*22dc650dSSadaf Ebrahimi static BOOL jit_was_used;
959*22dc650dSSadaf Ebrahimi static BOOL restrict_for_perl_test = FALSE;
960*22dc650dSSadaf Ebrahimi static BOOL show_memory = FALSE;
961*22dc650dSSadaf Ebrahimi 
962*22dc650dSSadaf Ebrahimi static int jitrc;                             /* Return from JIT compile */
963*22dc650dSSadaf Ebrahimi static int test_mode = DEFAULT_TEST_MODE;
964*22dc650dSSadaf Ebrahimi static int timeit = 0;
965*22dc650dSSadaf Ebrahimi static int timeitm = 0;
966*22dc650dSSadaf Ebrahimi 
967*22dc650dSSadaf Ebrahimi clock_t total_compile_time = 0;
968*22dc650dSSadaf Ebrahimi clock_t total_jit_compile_time = 0;
969*22dc650dSSadaf Ebrahimi clock_t total_match_time = 0;
970*22dc650dSSadaf Ebrahimi 
971*22dc650dSSadaf Ebrahimi static uint32_t code_unit_size;               /* Bytes */
972*22dc650dSSadaf Ebrahimi static uint32_t dfa_matched;
973*22dc650dSSadaf Ebrahimi static uint32_t forbid_utf = 0;
974*22dc650dSSadaf Ebrahimi static uint32_t maxlookbehind;
975*22dc650dSSadaf Ebrahimi static uint32_t max_oveccount;
976*22dc650dSSadaf Ebrahimi static uint32_t callout_count;
977*22dc650dSSadaf Ebrahimi static uint32_t maxcapcount;
978*22dc650dSSadaf Ebrahimi 
979*22dc650dSSadaf Ebrahimi static uint16_t local_newline_default = 0;
980*22dc650dSSadaf Ebrahimi 
981*22dc650dSSadaf Ebrahimi static VERSION_TYPE jittarget[VERSION_SIZE];
982*22dc650dSSadaf Ebrahimi static VERSION_TYPE version[VERSION_SIZE];
983*22dc650dSSadaf Ebrahimi static VERSION_TYPE uversion[VERSION_SIZE];
984*22dc650dSSadaf Ebrahimi 
985*22dc650dSSadaf Ebrahimi static patctl def_patctl;
986*22dc650dSSadaf Ebrahimi static patctl pat_patctl;
987*22dc650dSSadaf Ebrahimi static datctl def_datctl;
988*22dc650dSSadaf Ebrahimi static datctl dat_datctl;
989*22dc650dSSadaf Ebrahimi 
990*22dc650dSSadaf Ebrahimi static void *patstack[PATSTACKSIZE];
991*22dc650dSSadaf Ebrahimi static int patstacknext = 0;
992*22dc650dSSadaf Ebrahimi 
993*22dc650dSSadaf Ebrahimi static void *malloclist[MALLOCLISTSIZE];
994*22dc650dSSadaf Ebrahimi static PCRE2_SIZE malloclistlength[MALLOCLISTSIZE];
995*22dc650dSSadaf Ebrahimi static uint32_t malloclistptr = 0;
996*22dc650dSSadaf Ebrahimi 
997*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
998*22dc650dSSadaf Ebrahimi static regex_t preg = { NULL, NULL, 0, 0, 0, 0 };
999*22dc650dSSadaf Ebrahimi #endif
1000*22dc650dSSadaf Ebrahimi 
1001*22dc650dSSadaf Ebrahimi static int *dfa_workspace = NULL;
1002*22dc650dSSadaf Ebrahimi static const uint8_t *locale_tables = NULL;
1003*22dc650dSSadaf Ebrahimi static const uint8_t *use_tables = NULL;
1004*22dc650dSSadaf Ebrahimi static uint8_t locale_name[32];
1005*22dc650dSSadaf Ebrahimi static uint8_t *tables3 = NULL;         /* For binary-loaded tables */
1006*22dc650dSSadaf Ebrahimi static uint32_t loadtables_length = 0;
1007*22dc650dSSadaf Ebrahimi 
1008*22dc650dSSadaf Ebrahimi /* We need buffers for building 16/32-bit strings; 8-bit strings don't need
1009*22dc650dSSadaf Ebrahimi rebuilding, but set up the same naming scheme for use in macros. The "buffer"
1010*22dc650dSSadaf Ebrahimi buffer is where all input lines are read. Its size is the same as pbuffer8.
1011*22dc650dSSadaf Ebrahimi Pattern lines are always copied to pbuffer8 for use in callouts, even if they
1012*22dc650dSSadaf Ebrahimi are actually compiled from pbuffer16 or pbuffer32. */
1013*22dc650dSSadaf Ebrahimi 
1014*22dc650dSSadaf Ebrahimi static size_t    pbuffer8_size  = 50000;        /* Initial size, bytes */
1015*22dc650dSSadaf Ebrahimi static uint8_t  *pbuffer8 = NULL;
1016*22dc650dSSadaf Ebrahimi static uint8_t  *buffer = NULL;
1017*22dc650dSSadaf Ebrahimi 
1018*22dc650dSSadaf Ebrahimi /* The dbuffer is where all processed data lines are put. In non-8-bit modes it
1019*22dc650dSSadaf Ebrahimi is cast as needed. For long data lines it grows as necessary. */
1020*22dc650dSSadaf Ebrahimi 
1021*22dc650dSSadaf Ebrahimi static size_t dbuffer_size = 1u << 14;    /* Initial size, bytes */
1022*22dc650dSSadaf Ebrahimi static uint8_t *dbuffer = NULL;
1023*22dc650dSSadaf Ebrahimi 
1024*22dc650dSSadaf Ebrahimi 
1025*22dc650dSSadaf Ebrahimi /* ---------------- Mode-dependent variables -------------------*/
1026*22dc650dSSadaf Ebrahimi 
1027*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
1028*22dc650dSSadaf Ebrahimi static pcre2_code_8             *compiled_code8;
1029*22dc650dSSadaf Ebrahimi static pcre2_general_context_8  *general_context8, *general_context_copy8;
1030*22dc650dSSadaf Ebrahimi static pcre2_compile_context_8  *pat_context8, *default_pat_context8;
1031*22dc650dSSadaf Ebrahimi static pcre2_convert_context_8  *con_context8, *default_con_context8;
1032*22dc650dSSadaf Ebrahimi static pcre2_match_context_8    *dat_context8, *default_dat_context8;
1033*22dc650dSSadaf Ebrahimi static pcre2_match_data_8       *match_data8;
1034*22dc650dSSadaf Ebrahimi #endif
1035*22dc650dSSadaf Ebrahimi 
1036*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
1037*22dc650dSSadaf Ebrahimi static pcre2_code_16            *compiled_code16;
1038*22dc650dSSadaf Ebrahimi static pcre2_general_context_16 *general_context16, *general_context_copy16;
1039*22dc650dSSadaf Ebrahimi static pcre2_compile_context_16 *pat_context16, *default_pat_context16;
1040*22dc650dSSadaf Ebrahimi static pcre2_convert_context_16 *con_context16, *default_con_context16;
1041*22dc650dSSadaf Ebrahimi static pcre2_match_context_16   *dat_context16, *default_dat_context16;
1042*22dc650dSSadaf Ebrahimi static pcre2_match_data_16      *match_data16;
1043*22dc650dSSadaf Ebrahimi static PCRE2_SIZE pbuffer16_size = 0;   /* Set only when needed */
1044*22dc650dSSadaf Ebrahimi static uint16_t *pbuffer16 = NULL;
1045*22dc650dSSadaf Ebrahimi #endif
1046*22dc650dSSadaf Ebrahimi 
1047*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
1048*22dc650dSSadaf Ebrahimi static pcre2_code_32            *compiled_code32;
1049*22dc650dSSadaf Ebrahimi static pcre2_general_context_32 *general_context32, *general_context_copy32;
1050*22dc650dSSadaf Ebrahimi static pcre2_compile_context_32 *pat_context32, *default_pat_context32;
1051*22dc650dSSadaf Ebrahimi static pcre2_convert_context_32 *con_context32, *default_con_context32;
1052*22dc650dSSadaf Ebrahimi static pcre2_match_context_32   *dat_context32, *default_dat_context32;
1053*22dc650dSSadaf Ebrahimi static pcre2_match_data_32      *match_data32;
1054*22dc650dSSadaf Ebrahimi static PCRE2_SIZE pbuffer32_size = 0;   /* Set only when needed */
1055*22dc650dSSadaf Ebrahimi static uint32_t *pbuffer32 = NULL;
1056*22dc650dSSadaf Ebrahimi #endif
1057*22dc650dSSadaf Ebrahimi 
1058*22dc650dSSadaf Ebrahimi 
1059*22dc650dSSadaf Ebrahimi /* ---------------- Macros that work in all modes ----------------- */
1060*22dc650dSSadaf Ebrahimi 
1061*22dc650dSSadaf Ebrahimi #define CAST8VAR(x) CASTVAR(uint8_t *, x)
1062*22dc650dSSadaf Ebrahimi #define SET(x,y) SETOP(x,y,=)
1063*22dc650dSSadaf Ebrahimi #define SETPLUS(x,y) SETOP(x,y,+=)
1064*22dc650dSSadaf Ebrahimi #define strlen8(x) strlen((char *)x)
1065*22dc650dSSadaf Ebrahimi 
1066*22dc650dSSadaf Ebrahimi 
1067*22dc650dSSadaf Ebrahimi /* ---------------- Mode-dependent, runtime-testing macros ------------------*/
1068*22dc650dSSadaf Ebrahimi 
1069*22dc650dSSadaf Ebrahimi /* Define macros for variables and functions that must be selected dynamically
1070*22dc650dSSadaf Ebrahimi depending on the mode setting (8, 16, 32). These are dependent on which modes
1071*22dc650dSSadaf Ebrahimi are supported. */
1072*22dc650dSSadaf Ebrahimi 
1073*22dc650dSSadaf Ebrahimi #if (defined (SUPPORT_PCRE2_8) + defined (SUPPORT_PCRE2_16) + \
1074*22dc650dSSadaf Ebrahimi      defined (SUPPORT_PCRE2_32)) >= 2
1075*22dc650dSSadaf Ebrahimi 
1076*22dc650dSSadaf Ebrahimi /* ----- All three modes supported ----- */
1077*22dc650dSSadaf Ebrahimi 
1078*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_PCRE2_8) && defined(SUPPORT_PCRE2_16) && defined(SUPPORT_PCRE2_32)
1079*22dc650dSSadaf Ebrahimi 
1080*22dc650dSSadaf Ebrahimi #define CASTFLD(t,a,b) ((test_mode == PCRE8_MODE)? (t)(G(a,8)->b) : \
1081*22dc650dSSadaf Ebrahimi   (test_mode == PCRE16_MODE)? (t)(G(a,16)->b) : (t)(G(a,32)->b))
1082*22dc650dSSadaf Ebrahimi 
1083*22dc650dSSadaf Ebrahimi #define CASTVAR(t,x) ( \
1084*22dc650dSSadaf Ebrahimi   (test_mode == PCRE8_MODE)? (t)G(x,8) : \
1085*22dc650dSSadaf Ebrahimi   (test_mode == PCRE16_MODE)? (t)G(x,16) : (t)G(x,32))
1086*22dc650dSSadaf Ebrahimi 
1087*22dc650dSSadaf Ebrahimi #define CODE_UNIT(a,b) ( \
1088*22dc650dSSadaf Ebrahimi   (test_mode == PCRE8_MODE)? (uint32_t)(((PCRE2_SPTR8)(a))[b]) : \
1089*22dc650dSSadaf Ebrahimi   (test_mode == PCRE16_MODE)? (uint32_t)(((PCRE2_SPTR16)(a))[b]) : \
1090*22dc650dSSadaf Ebrahimi   (uint32_t)(((PCRE2_SPTR32)(a))[b]))
1091*22dc650dSSadaf Ebrahimi 
1092*22dc650dSSadaf Ebrahimi #define CONCTXCPY(a,b) \
1093*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1094*22dc650dSSadaf Ebrahimi     memcpy(G(a,8),G(b,8),sizeof(pcre2_convert_context_8)); \
1095*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1096*22dc650dSSadaf Ebrahimi     memcpy(G(a,16),G(b,16),sizeof(pcre2_convert_context_16)); \
1097*22dc650dSSadaf Ebrahimi   else memcpy(G(a,32),G(b,32),sizeof(pcre2_convert_context_32))
1098*22dc650dSSadaf Ebrahimi 
1099*22dc650dSSadaf Ebrahimi #define CONVERT_COPY(a,b,c) \
1100*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1101*22dc650dSSadaf Ebrahimi     memcpy(G(a,8),(char *)b,c); \
1102*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1103*22dc650dSSadaf Ebrahimi     memcpy(G(a,16),(char *)b,(c)*2); \
1104*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE32_MODE) \
1105*22dc650dSSadaf Ebrahimi     memcpy(G(a,32),(char *)b,(c)*4)
1106*22dc650dSSadaf Ebrahimi 
1107*22dc650dSSadaf Ebrahimi #define DATCTXCPY(a,b) \
1108*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1109*22dc650dSSadaf Ebrahimi     memcpy(G(a,8),G(b,8),sizeof(pcre2_match_context_8)); \
1110*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1111*22dc650dSSadaf Ebrahimi     memcpy(G(a,16),G(b,16),sizeof(pcre2_match_context_16)); \
1112*22dc650dSSadaf Ebrahimi   else memcpy(G(a,32),G(b,32),sizeof(pcre2_match_context_32))
1113*22dc650dSSadaf Ebrahimi 
1114*22dc650dSSadaf Ebrahimi #define FLD(a,b) ((test_mode == PCRE8_MODE)? G(a,8)->b : \
1115*22dc650dSSadaf Ebrahimi   (test_mode == PCRE16_MODE)? G(a,16)->b : G(a,32)->b)
1116*22dc650dSSadaf Ebrahimi 
1117*22dc650dSSadaf Ebrahimi #define PATCTXCPY(a,b) \
1118*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1119*22dc650dSSadaf Ebrahimi     memcpy(G(a,8),G(b,8),sizeof(pcre2_compile_context_8)); \
1120*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1121*22dc650dSSadaf Ebrahimi     memcpy(G(a,16),G(b,16),sizeof(pcre2_compile_context_16)); \
1122*22dc650dSSadaf Ebrahimi   else memcpy(G(a,32),G(b,32),sizeof(pcre2_compile_context_32))
1123*22dc650dSSadaf Ebrahimi 
1124*22dc650dSSadaf Ebrahimi #define PCHARS(lv, p, offset, len, utf, f) \
1125*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE32_MODE) \
1126*22dc650dSSadaf Ebrahimi     lv = pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f); \
1127*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1128*22dc650dSSadaf Ebrahimi     lv = pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f); \
1129*22dc650dSSadaf Ebrahimi   else \
1130*22dc650dSSadaf Ebrahimi     lv = pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f)
1131*22dc650dSSadaf Ebrahimi 
1132*22dc650dSSadaf Ebrahimi #define PCHARSV(p, offset, len, utf, f) \
1133*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE32_MODE) \
1134*22dc650dSSadaf Ebrahimi     (void)pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f); \
1135*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1136*22dc650dSSadaf Ebrahimi     (void)pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f); \
1137*22dc650dSSadaf Ebrahimi   else \
1138*22dc650dSSadaf Ebrahimi     (void)pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f)
1139*22dc650dSSadaf Ebrahimi 
1140*22dc650dSSadaf Ebrahimi #define PCRE2_CALLOUT_ENUMERATE(a,b,c) \
1141*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1142*22dc650dSSadaf Ebrahimi      a = pcre2_callout_enumerate_8(compiled_code8, \
1143*22dc650dSSadaf Ebrahimi        (int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c); \
1144*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1145*22dc650dSSadaf Ebrahimi      a = pcre2_callout_enumerate_16(compiled_code16, \
1146*22dc650dSSadaf Ebrahimi        (int(*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c); \
1147*22dc650dSSadaf Ebrahimi   else \
1148*22dc650dSSadaf Ebrahimi      a = pcre2_callout_enumerate_32(compiled_code32, \
1149*22dc650dSSadaf Ebrahimi        (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c)
1150*22dc650dSSadaf Ebrahimi 
1151*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_FROM_VOID(a,b) \
1152*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1153*22dc650dSSadaf Ebrahimi     G(a,8) = pcre2_code_copy_8(b); \
1154*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1155*22dc650dSSadaf Ebrahimi     G(a,16) = pcre2_code_copy_16(b); \
1156*22dc650dSSadaf Ebrahimi   else \
1157*22dc650dSSadaf Ebrahimi     G(a,32) = pcre2_code_copy_32(b)
1158*22dc650dSSadaf Ebrahimi 
1159*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_TO_VOID(a,b) \
1160*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1161*22dc650dSSadaf Ebrahimi     a = (void *)pcre2_code_copy_8(G(b,8)); \
1162*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1163*22dc650dSSadaf Ebrahimi     a = (void *)pcre2_code_copy_16(G(b,16)); \
1164*22dc650dSSadaf Ebrahimi   else \
1165*22dc650dSSadaf Ebrahimi     a = (void *)pcre2_code_copy_32(G(b,32))
1166*22dc650dSSadaf Ebrahimi 
1167*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) \
1168*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1169*22dc650dSSadaf Ebrahimi     a = (void *)pcre2_code_copy_with_tables_8(G(b,8)); \
1170*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1171*22dc650dSSadaf Ebrahimi     a = (void *)pcre2_code_copy_with_tables_16(G(b,16)); \
1172*22dc650dSSadaf Ebrahimi   else \
1173*22dc650dSSadaf Ebrahimi     a = (void *)pcre2_code_copy_with_tables_32(G(b,32))
1174*22dc650dSSadaf Ebrahimi 
1175*22dc650dSSadaf Ebrahimi #define PCRE2_COMPILE(a,b,c,d,e,f,g) \
1176*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1177*22dc650dSSadaf Ebrahimi     G(a,8) = pcre2_compile_8(b,c,d,e,f,g); \
1178*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1179*22dc650dSSadaf Ebrahimi     G(a,16) = pcre2_compile_16(b,c,d,e,f,g); \
1180*22dc650dSSadaf Ebrahimi   else \
1181*22dc650dSSadaf Ebrahimi     G(a,32) = pcre2_compile_32(b,c,d,e,f,g)
1182*22dc650dSSadaf Ebrahimi 
1183*22dc650dSSadaf Ebrahimi #define PCRE2_CONVERTED_PATTERN_FREE(a) \
1184*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) pcre2_converted_pattern_free_8((PCRE2_UCHAR8 *)a); \
1185*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) pcre2_converted_pattern_free_16((PCRE2_UCHAR16 *)a); \
1186*22dc650dSSadaf Ebrahimi   else pcre2_converted_pattern_free_32((PCRE2_UCHAR32 *)a)
1187*22dc650dSSadaf Ebrahimi 
1188*22dc650dSSadaf Ebrahimi #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
1189*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1190*22dc650dSSadaf Ebrahimi     a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h,i,j); \
1191*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1192*22dc650dSSadaf Ebrahimi     a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h,i,j); \
1193*22dc650dSSadaf Ebrahimi   else \
1194*22dc650dSSadaf Ebrahimi     a = pcre2_dfa_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h,i,j)
1195*22dc650dSSadaf Ebrahimi 
1196*22dc650dSSadaf Ebrahimi #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
1197*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1198*22dc650dSSadaf Ebrahimi     r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size)); \
1199*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1200*22dc650dSSadaf Ebrahimi     r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size/2)); \
1201*22dc650dSSadaf Ebrahimi   else \
1202*22dc650dSSadaf Ebrahimi     r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size/4))
1203*22dc650dSSadaf Ebrahimi 
1204*22dc650dSSadaf Ebrahimi #define PCRE2_GET_MATCH_DATA_HEAPFRAMES_SIZE(r,a) \
1205*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1206*22dc650dSSadaf Ebrahimi     r = pcre2_get_match_data_heapframes_size_8(G(a,8)); \
1207*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1208*22dc650dSSadaf Ebrahimi     r = pcre2_get_match_data_heapframes_size_16(G(a,16)); \
1209*22dc650dSSadaf Ebrahimi   else \
1210*22dc650dSSadaf Ebrahimi     r = pcre2_get_match_data_heapframes_size_32(G(a,32))
1211*22dc650dSSadaf Ebrahimi 
1212*22dc650dSSadaf Ebrahimi #define PCRE2_GET_OVECTOR_COUNT(a,b) \
1213*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1214*22dc650dSSadaf Ebrahimi     a = pcre2_get_ovector_count_8(G(b,8)); \
1215*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1216*22dc650dSSadaf Ebrahimi     a = pcre2_get_ovector_count_16(G(b,16)); \
1217*22dc650dSSadaf Ebrahimi   else \
1218*22dc650dSSadaf Ebrahimi     a = pcre2_get_ovector_count_32(G(b,32))
1219*22dc650dSSadaf Ebrahimi 
1220*22dc650dSSadaf Ebrahimi #define PCRE2_GET_STARTCHAR(a,b) \
1221*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1222*22dc650dSSadaf Ebrahimi     a = pcre2_get_startchar_8(G(b,8)); \
1223*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1224*22dc650dSSadaf Ebrahimi     a = pcre2_get_startchar_16(G(b,16)); \
1225*22dc650dSSadaf Ebrahimi   else \
1226*22dc650dSSadaf Ebrahimi     a = pcre2_get_startchar_32(G(b,32))
1227*22dc650dSSadaf Ebrahimi 
1228*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_COMPILE(r,a,b) \
1229*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) r = pcre2_jit_compile_8(G(a,8),b); \
1230*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) r = pcre2_jit_compile_16(G(a,16),b); \
1231*22dc650dSSadaf Ebrahimi   else r = pcre2_jit_compile_32(G(a,32),b)
1232*22dc650dSSadaf Ebrahimi 
1233*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \
1234*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) pcre2_jit_free_unused_memory_8(G(a,8)); \
1235*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) pcre2_jit_free_unused_memory_16(G(a,16)); \
1236*22dc650dSSadaf Ebrahimi   else pcre2_jit_free_unused_memory_32(G(a,32))
1237*22dc650dSSadaf Ebrahimi 
1238*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \
1239*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1240*22dc650dSSadaf Ebrahimi     a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h); \
1241*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1242*22dc650dSSadaf Ebrahimi     a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h); \
1243*22dc650dSSadaf Ebrahimi   else \
1244*22dc650dSSadaf Ebrahimi     a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h)
1245*22dc650dSSadaf Ebrahimi 
1246*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_CREATE(a,b,c,d) \
1247*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1248*22dc650dSSadaf Ebrahimi     a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_8(b,c,d); \
1249*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1250*22dc650dSSadaf Ebrahimi     a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_16(b,c,d); \
1251*22dc650dSSadaf Ebrahimi   else \
1252*22dc650dSSadaf Ebrahimi     a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_32(b,c,d);
1253*22dc650dSSadaf Ebrahimi 
1254*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_ASSIGN(a,b,c) \
1255*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1256*22dc650dSSadaf Ebrahimi     pcre2_jit_stack_assign_8(G(a,8),(pcre2_jit_callback_8)b,c); \
1257*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1258*22dc650dSSadaf Ebrahimi     pcre2_jit_stack_assign_16(G(a,16),(pcre2_jit_callback_16)b,c); \
1259*22dc650dSSadaf Ebrahimi   else \
1260*22dc650dSSadaf Ebrahimi     pcre2_jit_stack_assign_32(G(a,32),(pcre2_jit_callback_32)b,c);
1261*22dc650dSSadaf Ebrahimi 
1262*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_FREE(a) \
1263*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1264*22dc650dSSadaf Ebrahimi     pcre2_jit_stack_free_8((pcre2_jit_stack_8 *)a); \
1265*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1266*22dc650dSSadaf Ebrahimi     pcre2_jit_stack_free_16((pcre2_jit_stack_16 *)a); \
1267*22dc650dSSadaf Ebrahimi   else \
1268*22dc650dSSadaf Ebrahimi     pcre2_jit_stack_free_32((pcre2_jit_stack_32 *)a);
1269*22dc650dSSadaf Ebrahimi 
1270*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES(a,c) \
1271*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) a = pcre2_maketables_8(G(c,8)); \
1272*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) a = pcre2_maketables_16(G(c,16)); \
1273*22dc650dSSadaf Ebrahimi   else a = pcre2_maketables_32(G(c,32))
1274*22dc650dSSadaf Ebrahimi 
1275*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES_FREE(c,a) \
1276*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) pcre2_maketables_free_8(G(c,8),a); \
1277*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) pcre2_maketables_free_16(G(c,16),a); \
1278*22dc650dSSadaf Ebrahimi   else pcre2_maketables_free_32(G(c,32),a)
1279*22dc650dSSadaf Ebrahimi 
1280*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH(a,b,c,d,e,f,g,h) \
1281*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1282*22dc650dSSadaf Ebrahimi     a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h); \
1283*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1284*22dc650dSSadaf Ebrahimi     a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h); \
1285*22dc650dSSadaf Ebrahimi   else \
1286*22dc650dSSadaf Ebrahimi     a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h)
1287*22dc650dSSadaf Ebrahimi 
1288*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE(a,b,c) \
1289*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1290*22dc650dSSadaf Ebrahimi     G(a,8) = pcre2_match_data_create_8(b,G(c,8)); \
1291*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1292*22dc650dSSadaf Ebrahimi     G(a,16) = pcre2_match_data_create_16(b,G(c,16)); \
1293*22dc650dSSadaf Ebrahimi   else \
1294*22dc650dSSadaf Ebrahimi     G(a,32) = pcre2_match_data_create_32(b,G(c,32))
1295*22dc650dSSadaf Ebrahimi 
1296*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \
1297*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1298*22dc650dSSadaf Ebrahimi     G(a,8) = pcre2_match_data_create_from_pattern_8(G(b,8),G(c,8)); \
1299*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1300*22dc650dSSadaf Ebrahimi     G(a,16) = pcre2_match_data_create_from_pattern_16(G(b,16),G(c,16)); \
1301*22dc650dSSadaf Ebrahimi   else \
1302*22dc650dSSadaf Ebrahimi     G(a,32) = pcre2_match_data_create_from_pattern_32(G(b,32),G(c,32))
1303*22dc650dSSadaf Ebrahimi 
1304*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_FREE(a) \
1305*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1306*22dc650dSSadaf Ebrahimi     pcre2_match_data_free_8(G(a,8)); \
1307*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1308*22dc650dSSadaf Ebrahimi     pcre2_match_data_free_16(G(a,16)); \
1309*22dc650dSSadaf Ebrahimi   else \
1310*22dc650dSSadaf Ebrahimi     pcre2_match_data_free_32(G(a,32))
1311*22dc650dSSadaf Ebrahimi 
1312*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) \
1313*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1314*22dc650dSSadaf Ebrahimi     a = pcre2_pattern_convert_8(G(b,8),c,d,(PCRE2_UCHAR8 **)e,f,G(g,8)); \
1315*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1316*22dc650dSSadaf Ebrahimi     a = pcre2_pattern_convert_16(G(b,16),c,d,(PCRE2_UCHAR16 **)e,f,G(g,16)); \
1317*22dc650dSSadaf Ebrahimi   else \
1318*22dc650dSSadaf Ebrahimi     a = pcre2_pattern_convert_32(G(b,32),c,d,(PCRE2_UCHAR32 **)e,f,G(g,32))
1319*22dc650dSSadaf Ebrahimi 
1320*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_INFO(a,b,c,d) \
1321*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1322*22dc650dSSadaf Ebrahimi     a = pcre2_pattern_info_8(G(b,8),c,d); \
1323*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1324*22dc650dSSadaf Ebrahimi     a = pcre2_pattern_info_16(G(b,16),c,d); \
1325*22dc650dSSadaf Ebrahimi   else \
1326*22dc650dSSadaf Ebrahimi     a = pcre2_pattern_info_32(G(b,32),c,d)
1327*22dc650dSSadaf Ebrahimi 
1328*22dc650dSSadaf Ebrahimi #define PCRE2_PRINTINT(a) \
1329*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1330*22dc650dSSadaf Ebrahimi     pcre2_printint_8(compiled_code8,outfile,a); \
1331*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1332*22dc650dSSadaf Ebrahimi     pcre2_printint_16(compiled_code16,outfile,a); \
1333*22dc650dSSadaf Ebrahimi   else \
1334*22dc650dSSadaf Ebrahimi     pcre2_printint_32(compiled_code32,outfile,a)
1335*22dc650dSSadaf Ebrahimi 
1336*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \
1337*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1338*22dc650dSSadaf Ebrahimi     r = pcre2_serialize_decode_8((pcre2_code_8 **)a,b,c,G(d,8)); \
1339*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1340*22dc650dSSadaf Ebrahimi     r = pcre2_serialize_decode_16((pcre2_code_16 **)a,b,c,G(d,16)); \
1341*22dc650dSSadaf Ebrahimi   else \
1342*22dc650dSSadaf Ebrahimi     r = pcre2_serialize_decode_32((pcre2_code_32 **)a,b,c,G(d,32))
1343*22dc650dSSadaf Ebrahimi 
1344*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \
1345*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1346*22dc650dSSadaf Ebrahimi     r = pcre2_serialize_encode_8((const pcre2_code_8 **)a,b,c,d,G(e,8)); \
1347*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1348*22dc650dSSadaf Ebrahimi     r = pcre2_serialize_encode_16((const pcre2_code_16 **)a,b,c,d,G(e,16)); \
1349*22dc650dSSadaf Ebrahimi   else \
1350*22dc650dSSadaf Ebrahimi     r = pcre2_serialize_encode_32((const pcre2_code_32 **)a,b,c,d,G(e,32))
1351*22dc650dSSadaf Ebrahimi 
1352*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_FREE(a) \
1353*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1354*22dc650dSSadaf Ebrahimi     pcre2_serialize_free_8(a); \
1355*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1356*22dc650dSSadaf Ebrahimi     pcre2_serialize_free_16(a); \
1357*22dc650dSSadaf Ebrahimi   else \
1358*22dc650dSSadaf Ebrahimi     pcre2_serialize_free_32(a)
1359*22dc650dSSadaf Ebrahimi 
1360*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \
1361*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1362*22dc650dSSadaf Ebrahimi     r = pcre2_serialize_get_number_of_codes_8(a); \
1363*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1364*22dc650dSSadaf Ebrahimi     r = pcre2_serialize_get_number_of_codes_16(a); \
1365*22dc650dSSadaf Ebrahimi   else \
1366*22dc650dSSadaf Ebrahimi     r = pcre2_serialize_get_number_of_codes_32(a); \
1367*22dc650dSSadaf Ebrahimi 
1368*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CALLOUT(a,b,c) \
1369*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1370*22dc650dSSadaf Ebrahimi     pcre2_set_callout_8(G(a,8),(int (*)(pcre2_callout_block_8 *, void *))b,c); \
1371*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1372*22dc650dSSadaf Ebrahimi     pcre2_set_callout_16(G(a,16),(int (*)(pcre2_callout_block_16 *, void *))b,c); \
1373*22dc650dSSadaf Ebrahimi   else \
1374*22dc650dSSadaf Ebrahimi     pcre2_set_callout_32(G(a,32),(int (*)(pcre2_callout_block_32 *, void *))b,c);
1375*22dc650dSSadaf Ebrahimi 
1376*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CHARACTER_TABLES(a,b) \
1377*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1378*22dc650dSSadaf Ebrahimi     pcre2_set_character_tables_8(G(a,8),b); \
1379*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1380*22dc650dSSadaf Ebrahimi     pcre2_set_character_tables_16(G(a,16),b); \
1381*22dc650dSSadaf Ebrahimi   else \
1382*22dc650dSSadaf Ebrahimi     pcre2_set_character_tables_32(G(a,32),b)
1383*22dc650dSSadaf Ebrahimi 
1384*22dc650dSSadaf Ebrahimi #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
1385*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1386*22dc650dSSadaf Ebrahimi     pcre2_set_compile_recursion_guard_8(G(a,8),b,c); \
1387*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1388*22dc650dSSadaf Ebrahimi     pcre2_set_compile_recursion_guard_16(G(a,16),b,c); \
1389*22dc650dSSadaf Ebrahimi   else \
1390*22dc650dSSadaf Ebrahimi     pcre2_set_compile_recursion_guard_32(G(a,32),b,c)
1391*22dc650dSSadaf Ebrahimi 
1392*22dc650dSSadaf Ebrahimi #define PCRE2_SET_DEPTH_LIMIT(a,b) \
1393*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1394*22dc650dSSadaf Ebrahimi     pcre2_set_depth_limit_8(G(a,8),b); \
1395*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1396*22dc650dSSadaf Ebrahimi     pcre2_set_depth_limit_16(G(a,16),b); \
1397*22dc650dSSadaf Ebrahimi   else \
1398*22dc650dSSadaf Ebrahimi     pcre2_set_depth_limit_32(G(a,32),b)
1399*22dc650dSSadaf Ebrahimi 
1400*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_SEPARATOR(r,a,b) \
1401*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1402*22dc650dSSadaf Ebrahimi     r = pcre2_set_glob_separator_8(G(a,8),b); \
1403*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1404*22dc650dSSadaf Ebrahimi     r = pcre2_set_glob_separator_16(G(a,16),b); \
1405*22dc650dSSadaf Ebrahimi   else \
1406*22dc650dSSadaf Ebrahimi     r = pcre2_set_glob_separator_32(G(a,32),b)
1407*22dc650dSSadaf Ebrahimi 
1408*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_ESCAPE(r,a,b) \
1409*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1410*22dc650dSSadaf Ebrahimi     r = pcre2_set_glob_escape_8(G(a,8),b); \
1411*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1412*22dc650dSSadaf Ebrahimi     r = pcre2_set_glob_escape_16(G(a,16),b); \
1413*22dc650dSSadaf Ebrahimi   else \
1414*22dc650dSSadaf Ebrahimi     r = pcre2_set_glob_escape_32(G(a,32),b)
1415*22dc650dSSadaf Ebrahimi 
1416*22dc650dSSadaf Ebrahimi #define PCRE2_SET_HEAP_LIMIT(a,b) \
1417*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1418*22dc650dSSadaf Ebrahimi     pcre2_set_heap_limit_8(G(a,8),b); \
1419*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1420*22dc650dSSadaf Ebrahimi     pcre2_set_heap_limit_16(G(a,16),b); \
1421*22dc650dSSadaf Ebrahimi   else \
1422*22dc650dSSadaf Ebrahimi     pcre2_set_heap_limit_32(G(a,32),b)
1423*22dc650dSSadaf Ebrahimi 
1424*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MATCH_LIMIT(a,b) \
1425*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1426*22dc650dSSadaf Ebrahimi     pcre2_set_match_limit_8(G(a,8),b); \
1427*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1428*22dc650dSSadaf Ebrahimi     pcre2_set_match_limit_16(G(a,16),b); \
1429*22dc650dSSadaf Ebrahimi   else \
1430*22dc650dSSadaf Ebrahimi     pcre2_set_match_limit_32(G(a,32),b)
1431*22dc650dSSadaf Ebrahimi 
1432*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH(a,b) \
1433*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1434*22dc650dSSadaf Ebrahimi     pcre2_set_max_pattern_compiled_length_8(G(a,8),b); \
1435*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1436*22dc650dSSadaf Ebrahimi     pcre2_set_max_pattern_compiled_length_16(G(a,16),b); \
1437*22dc650dSSadaf Ebrahimi   else \
1438*22dc650dSSadaf Ebrahimi     pcre2_set_max_pattern_compiled_length_32(G(a,32),b)
1439*22dc650dSSadaf Ebrahimi 
1440*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \
1441*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1442*22dc650dSSadaf Ebrahimi     pcre2_set_max_pattern_length_8(G(a,8),b); \
1443*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1444*22dc650dSSadaf Ebrahimi     pcre2_set_max_pattern_length_16(G(a,16),b); \
1445*22dc650dSSadaf Ebrahimi   else \
1446*22dc650dSSadaf Ebrahimi     pcre2_set_max_pattern_length_32(G(a,32),b)
1447*22dc650dSSadaf Ebrahimi 
1448*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_VARLOOKBEHIND(a,b) \
1449*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1450*22dc650dSSadaf Ebrahimi     pcre2_set_max_varlookbehind_8(G(a,8),b); \
1451*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1452*22dc650dSSadaf Ebrahimi     pcre2_set_max_varlookbehind_16(G(a,16),b); \
1453*22dc650dSSadaf Ebrahimi   else \
1454*22dc650dSSadaf Ebrahimi     pcre2_set_max_varlookbehind_32(G(a,32),b)
1455*22dc650dSSadaf Ebrahimi 
1456*22dc650dSSadaf Ebrahimi #define PCRE2_SET_OFFSET_LIMIT(a,b) \
1457*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1458*22dc650dSSadaf Ebrahimi     pcre2_set_offset_limit_8(G(a,8),b); \
1459*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1460*22dc650dSSadaf Ebrahimi     pcre2_set_offset_limit_16(G(a,16),b); \
1461*22dc650dSSadaf Ebrahimi   else \
1462*22dc650dSSadaf Ebrahimi     pcre2_set_offset_limit_32(G(a,32),b)
1463*22dc650dSSadaf Ebrahimi 
1464*22dc650dSSadaf Ebrahimi #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) \
1465*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1466*22dc650dSSadaf Ebrahimi     pcre2_set_parens_nest_limit_8(G(a,8),b); \
1467*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1468*22dc650dSSadaf Ebrahimi     pcre2_set_parens_nest_limit_16(G(a,16),b); \
1469*22dc650dSSadaf Ebrahimi   else \
1470*22dc650dSSadaf Ebrahimi     pcre2_set_parens_nest_limit_32(G(a,32),b)
1471*22dc650dSSadaf Ebrahimi 
1472*22dc650dSSadaf Ebrahimi #define PCRE2_SET_SUBSTITUTE_CALLOUT(a,b,c) \
1473*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1474*22dc650dSSadaf Ebrahimi     pcre2_set_substitute_callout_8(G(a,8), \
1475*22dc650dSSadaf Ebrahimi       (int (*)(pcre2_substitute_callout_block_8 *, void *))b,c); \
1476*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1477*22dc650dSSadaf Ebrahimi     pcre2_set_substitute_callout_16(G(a,16), \
1478*22dc650dSSadaf Ebrahimi       (int (*)(pcre2_substitute_callout_block_16 *, void *))b,c); \
1479*22dc650dSSadaf Ebrahimi   else \
1480*22dc650dSSadaf Ebrahimi     pcre2_set_substitute_callout_32(G(a,32), \
1481*22dc650dSSadaf Ebrahimi       (int (*)(pcre2_substitute_callout_block_32 *, void *))b,c)
1482*22dc650dSSadaf Ebrahimi 
1483*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
1484*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1485*22dc650dSSadaf Ebrahimi     a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h, \
1486*22dc650dSSadaf Ebrahimi       (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l); \
1487*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1488*22dc650dSSadaf Ebrahimi     a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h, \
1489*22dc650dSSadaf Ebrahimi       (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l); \
1490*22dc650dSSadaf Ebrahimi   else \
1491*22dc650dSSadaf Ebrahimi     a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h, \
1492*22dc650dSSadaf Ebrahimi       (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
1493*22dc650dSSadaf Ebrahimi 
1494*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
1495*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1496*22dc650dSSadaf Ebrahimi     a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e); \
1497*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1498*22dc650dSSadaf Ebrahimi     a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e); \
1499*22dc650dSSadaf Ebrahimi   else \
1500*22dc650dSSadaf Ebrahimi     a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e)
1501*22dc650dSSadaf Ebrahimi 
1502*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
1503*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1504*22dc650dSSadaf Ebrahimi     a = pcre2_substring_copy_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 *)d,e); \
1505*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1506*22dc650dSSadaf Ebrahimi     a = pcre2_substring_copy_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 *)d,e); \
1507*22dc650dSSadaf Ebrahimi   else \
1508*22dc650dSSadaf Ebrahimi     a = pcre2_substring_copy_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 *)d,e)
1509*22dc650dSSadaf Ebrahimi 
1510*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_FREE(a) \
1511*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) pcre2_substring_free_8((PCRE2_UCHAR8 *)a); \
1512*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1513*22dc650dSSadaf Ebrahimi     pcre2_substring_free_16((PCRE2_UCHAR16 *)a); \
1514*22dc650dSSadaf Ebrahimi   else pcre2_substring_free_32((PCRE2_UCHAR32 *)a)
1515*22dc650dSSadaf Ebrahimi 
1516*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \
1517*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1518*22dc650dSSadaf Ebrahimi     a = pcre2_substring_get_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 **)d,e); \
1519*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1520*22dc650dSSadaf Ebrahimi     a = pcre2_substring_get_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 **)d,e); \
1521*22dc650dSSadaf Ebrahimi   else \
1522*22dc650dSSadaf Ebrahimi     a = pcre2_substring_get_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 **)d,e)
1523*22dc650dSSadaf Ebrahimi 
1524*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \
1525*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1526*22dc650dSSadaf Ebrahimi     a = pcre2_substring_get_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 **)d,e); \
1527*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1528*22dc650dSSadaf Ebrahimi     a = pcre2_substring_get_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 **)d,e); \
1529*22dc650dSSadaf Ebrahimi   else \
1530*22dc650dSSadaf Ebrahimi     a = pcre2_substring_get_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 **)d,e)
1531*22dc650dSSadaf Ebrahimi 
1532*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \
1533*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1534*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_byname_8(G(b,8),G(c,8),d); \
1535*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1536*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_byname_16(G(b,16),G(c,16),d); \
1537*22dc650dSSadaf Ebrahimi   else \
1538*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_byname_32(G(b,32),G(c,32),d)
1539*22dc650dSSadaf Ebrahimi 
1540*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \
1541*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1542*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_bynumber_8(G(b,8),c,d); \
1543*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1544*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_bynumber_16(G(b,16),c,d); \
1545*22dc650dSSadaf Ebrahimi   else \
1546*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_bynumber_32(G(b,32),c,d)
1547*22dc650dSSadaf Ebrahimi 
1548*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \
1549*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1550*22dc650dSSadaf Ebrahimi     a = pcre2_substring_list_get_8(G(b,8),(PCRE2_UCHAR8 ***)c,d); \
1551*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1552*22dc650dSSadaf Ebrahimi     a = pcre2_substring_list_get_16(G(b,16),(PCRE2_UCHAR16 ***)c,d); \
1553*22dc650dSSadaf Ebrahimi   else \
1554*22dc650dSSadaf Ebrahimi     a = pcre2_substring_list_get_32(G(b,32),(PCRE2_UCHAR32 ***)c,d)
1555*22dc650dSSadaf Ebrahimi 
1556*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_FREE(a) \
1557*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1558*22dc650dSSadaf Ebrahimi     pcre2_substring_list_free_8((PCRE2_UCHAR8 **)a); \
1559*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1560*22dc650dSSadaf Ebrahimi     pcre2_substring_list_free_16((PCRE2_UCHAR16 **)a); \
1561*22dc650dSSadaf Ebrahimi   else \
1562*22dc650dSSadaf Ebrahimi     pcre2_substring_list_free_32((PCRE2_UCHAR32 **)a)
1563*22dc650dSSadaf Ebrahimi 
1564*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \
1565*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1566*22dc650dSSadaf Ebrahimi     a = pcre2_substring_number_from_name_8(G(b,8),G(c,8)); \
1567*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1568*22dc650dSSadaf Ebrahimi     a = pcre2_substring_number_from_name_16(G(b,16),G(c,16)); \
1569*22dc650dSSadaf Ebrahimi   else \
1570*22dc650dSSadaf Ebrahimi     a = pcre2_substring_number_from_name_32(G(b,32),G(c,32))
1571*22dc650dSSadaf Ebrahimi 
1572*22dc650dSSadaf Ebrahimi #define PTR(x) ( \
1573*22dc650dSSadaf Ebrahimi   (test_mode == PCRE8_MODE)? (void *)G(x,8) : \
1574*22dc650dSSadaf Ebrahimi   (test_mode == PCRE16_MODE)? (void *)G(x,16) : \
1575*22dc650dSSadaf Ebrahimi   (void *)G(x,32))
1576*22dc650dSSadaf Ebrahimi 
1577*22dc650dSSadaf Ebrahimi #define SETFLD(x,y,z) \
1578*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) G(x,8)->y = z; \
1579*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) G(x,16)->y = z; \
1580*22dc650dSSadaf Ebrahimi   else G(x,32)->y = z
1581*22dc650dSSadaf Ebrahimi 
1582*22dc650dSSadaf Ebrahimi #define SETFLDVEC(x,y,v,z) \
1583*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) G(x,8)->y[v] = z; \
1584*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) G(x,16)->y[v] = z; \
1585*22dc650dSSadaf Ebrahimi   else G(x,32)->y[v] = z
1586*22dc650dSSadaf Ebrahimi 
1587*22dc650dSSadaf Ebrahimi #define SETOP(x,y,z) \
1588*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) G(x,8) z y; \
1589*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) G(x,16) z y; \
1590*22dc650dSSadaf Ebrahimi   else G(x,32) z y
1591*22dc650dSSadaf Ebrahimi 
1592*22dc650dSSadaf Ebrahimi #define SETCASTPTR(x,y) \
1593*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) \
1594*22dc650dSSadaf Ebrahimi     G(x,8) = (uint8_t *)(y); \
1595*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) \
1596*22dc650dSSadaf Ebrahimi     G(x,16) = (uint16_t *)(y); \
1597*22dc650dSSadaf Ebrahimi   else \
1598*22dc650dSSadaf Ebrahimi     G(x,32) = (uint32_t *)(y)
1599*22dc650dSSadaf Ebrahimi 
1600*22dc650dSSadaf Ebrahimi #define STRLEN(p) ((test_mode == PCRE8_MODE)? ((int)strlen((char *)p)) : \
1601*22dc650dSSadaf Ebrahimi   (test_mode == PCRE16_MODE)? ((int)strlen16((PCRE2_SPTR16)p)) : \
1602*22dc650dSSadaf Ebrahimi   ((int)strlen32((PCRE2_SPTR32)p)))
1603*22dc650dSSadaf Ebrahimi 
1604*22dc650dSSadaf Ebrahimi #define SUB1(a,b) \
1605*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) G(a,8)(G(b,8)); \
1606*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) G(a,16)(G(b,16)); \
1607*22dc650dSSadaf Ebrahimi   else G(a,32)(G(b,32))
1608*22dc650dSSadaf Ebrahimi 
1609*22dc650dSSadaf Ebrahimi #define SUB2(a,b,c) \
1610*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) G(a,8)(G(b,8),G(c,8)); \
1611*22dc650dSSadaf Ebrahimi   else if (test_mode == PCRE16_MODE) G(a,16)(G(b,16),G(c,16)); \
1612*22dc650dSSadaf Ebrahimi   else G(a,32)(G(b,32),G(c,32))
1613*22dc650dSSadaf Ebrahimi 
1614*22dc650dSSadaf Ebrahimi #define TEST(x,r,y) ( \
1615*22dc650dSSadaf Ebrahimi   (test_mode == PCRE8_MODE && G(x,8) r (y)) || \
1616*22dc650dSSadaf Ebrahimi   (test_mode == PCRE16_MODE && G(x,16) r (y)) || \
1617*22dc650dSSadaf Ebrahimi   (test_mode == PCRE32_MODE && G(x,32) r (y)))
1618*22dc650dSSadaf Ebrahimi 
1619*22dc650dSSadaf Ebrahimi #define TESTFLD(x,f,r,y) ( \
1620*22dc650dSSadaf Ebrahimi   (test_mode == PCRE8_MODE && G(x,8)->f r (y)) || \
1621*22dc650dSSadaf Ebrahimi   (test_mode == PCRE16_MODE && G(x,16)->f r (y)) || \
1622*22dc650dSSadaf Ebrahimi   (test_mode == PCRE32_MODE && G(x,32)->f r (y)))
1623*22dc650dSSadaf Ebrahimi 
1624*22dc650dSSadaf Ebrahimi 
1625*22dc650dSSadaf Ebrahimi /* ----- Two out of three modes are supported ----- */
1626*22dc650dSSadaf Ebrahimi 
1627*22dc650dSSadaf Ebrahimi #else
1628*22dc650dSSadaf Ebrahimi 
1629*22dc650dSSadaf Ebrahimi /* We can use some macro trickery to make a single set of definitions work in
1630*22dc650dSSadaf Ebrahimi the three different cases. */
1631*22dc650dSSadaf Ebrahimi 
1632*22dc650dSSadaf Ebrahimi /* ----- 32-bit and 16-bit but not 8-bit supported ----- */
1633*22dc650dSSadaf Ebrahimi 
1634*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_PCRE2_32) && defined(SUPPORT_PCRE2_16)
1635*22dc650dSSadaf Ebrahimi #define BITONE 32
1636*22dc650dSSadaf Ebrahimi #define BITTWO 16
1637*22dc650dSSadaf Ebrahimi 
1638*22dc650dSSadaf Ebrahimi /* ----- 32-bit and 8-bit but not 16-bit supported ----- */
1639*22dc650dSSadaf Ebrahimi 
1640*22dc650dSSadaf Ebrahimi #elif defined(SUPPORT_PCRE2_32) && defined(SUPPORT_PCRE2_8)
1641*22dc650dSSadaf Ebrahimi #define BITONE 32
1642*22dc650dSSadaf Ebrahimi #define BITTWO 8
1643*22dc650dSSadaf Ebrahimi 
1644*22dc650dSSadaf Ebrahimi /* ----- 16-bit and 8-bit but not 32-bit supported ----- */
1645*22dc650dSSadaf Ebrahimi 
1646*22dc650dSSadaf Ebrahimi #else
1647*22dc650dSSadaf Ebrahimi #define BITONE 16
1648*22dc650dSSadaf Ebrahimi #define BITTWO 8
1649*22dc650dSSadaf Ebrahimi #endif
1650*22dc650dSSadaf Ebrahimi 
1651*22dc650dSSadaf Ebrahimi 
1652*22dc650dSSadaf Ebrahimi /* ----- Common macros for two-mode cases ----- */
1653*22dc650dSSadaf Ebrahimi 
1654*22dc650dSSadaf Ebrahimi #define BYTEONE (BITONE/8)
1655*22dc650dSSadaf Ebrahimi #define BYTETWO (BITTWO/8)
1656*22dc650dSSadaf Ebrahimi 
1657*22dc650dSSadaf Ebrahimi #define CASTFLD(t,a,b) \
1658*22dc650dSSadaf Ebrahimi   ((test_mode == G(G(PCRE,BITONE),_MODE))? (t)(G(a,BITONE)->b) : \
1659*22dc650dSSadaf Ebrahimi     (t)(G(a,BITTWO)->b))
1660*22dc650dSSadaf Ebrahimi 
1661*22dc650dSSadaf Ebrahimi #define CASTVAR(t,x) ( \
1662*22dc650dSSadaf Ebrahimi   (test_mode == G(G(PCRE,BITONE),_MODE))? \
1663*22dc650dSSadaf Ebrahimi     (t)G(x,BITONE) : (t)G(x,BITTWO))
1664*22dc650dSSadaf Ebrahimi 
1665*22dc650dSSadaf Ebrahimi #define CODE_UNIT(a,b) ( \
1666*22dc650dSSadaf Ebrahimi   (test_mode == G(G(PCRE,BITONE),_MODE))? \
1667*22dc650dSSadaf Ebrahimi   (uint32_t)(((G(PCRE2_SPTR,BITONE))(a))[b]) : \
1668*22dc650dSSadaf Ebrahimi   (uint32_t)(((G(PCRE2_SPTR,BITTWO))(a))[b]))
1669*22dc650dSSadaf Ebrahimi 
1670*22dc650dSSadaf Ebrahimi #define CONCTXCPY(a,b) \
1671*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1672*22dc650dSSadaf Ebrahimi     memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_convert_context_,BITONE))); \
1673*22dc650dSSadaf Ebrahimi   else \
1674*22dc650dSSadaf Ebrahimi     memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_convert_context_,BITTWO)))
1675*22dc650dSSadaf Ebrahimi 
1676*22dc650dSSadaf Ebrahimi #define CONVERT_COPY(a,b,c) \
1677*22dc650dSSadaf Ebrahimi   (test_mode == G(G(PCRE,BITONE),_MODE))? \
1678*22dc650dSSadaf Ebrahimi   memcpy(G(a,BITONE),(char *)b,(c)*BYTEONE) : \
1679*22dc650dSSadaf Ebrahimi   memcpy(G(a,BITTWO),(char *)b,(c)*BYTETWO)
1680*22dc650dSSadaf Ebrahimi 
1681*22dc650dSSadaf Ebrahimi #define DATCTXCPY(a,b) \
1682*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1683*22dc650dSSadaf Ebrahimi     memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_match_context_,BITONE))); \
1684*22dc650dSSadaf Ebrahimi   else \
1685*22dc650dSSadaf Ebrahimi     memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_match_context_,BITTWO)))
1686*22dc650dSSadaf Ebrahimi 
1687*22dc650dSSadaf Ebrahimi #define FLD(a,b) \
1688*22dc650dSSadaf Ebrahimi   ((test_mode == G(G(PCRE,BITONE),_MODE))? G(a,BITONE)->b : G(a,BITTWO)->b)
1689*22dc650dSSadaf Ebrahimi 
1690*22dc650dSSadaf Ebrahimi #define PATCTXCPY(a,b) \
1691*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1692*22dc650dSSadaf Ebrahimi     memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_compile_context_,BITONE))); \
1693*22dc650dSSadaf Ebrahimi   else \
1694*22dc650dSSadaf Ebrahimi     memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_compile_context_,BITTWO)))
1695*22dc650dSSadaf Ebrahimi 
1696*22dc650dSSadaf Ebrahimi #define PCHARS(lv, p, offset, len, utf, f) \
1697*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1698*22dc650dSSadaf Ebrahimi     lv = G(pchars,BITONE)((G(PCRE2_SPTR,BITONE))(p)+offset, len, utf, f); \
1699*22dc650dSSadaf Ebrahimi   else \
1700*22dc650dSSadaf Ebrahimi     lv = G(pchars,BITTWO)((G(PCRE2_SPTR,BITTWO))(p)+offset, len, utf, f)
1701*22dc650dSSadaf Ebrahimi 
1702*22dc650dSSadaf Ebrahimi #define PCHARSV(p, offset, len, utf, f) \
1703*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1704*22dc650dSSadaf Ebrahimi     (void)G(pchars,BITONE)((G(PCRE2_SPTR,BITONE))(p)+offset, len, utf, f); \
1705*22dc650dSSadaf Ebrahimi   else \
1706*22dc650dSSadaf Ebrahimi     (void)G(pchars,BITTWO)((G(PCRE2_SPTR,BITTWO))(p)+offset, len, utf, f)
1707*22dc650dSSadaf Ebrahimi 
1708*22dc650dSSadaf Ebrahimi #define PCRE2_CALLOUT_ENUMERATE(a,b,c) \
1709*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1710*22dc650dSSadaf Ebrahimi      a = G(pcre2_callout_enumerate,BITONE)(G(compiled_code,BITONE), \
1711*22dc650dSSadaf Ebrahimi        (int (*)(struct G(pcre2_callout_enumerate_block_,BITONE) *, void *))b,c); \
1712*22dc650dSSadaf Ebrahimi   else \
1713*22dc650dSSadaf Ebrahimi      a = G(pcre2_callout_enumerate,BITTWO)(G(compiled_code,BITTWO), \
1714*22dc650dSSadaf Ebrahimi        (int (*)(struct G(pcre2_callout_enumerate_block_,BITTWO) *, void *))b,c)
1715*22dc650dSSadaf Ebrahimi 
1716*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_FROM_VOID(a,b) \
1717*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1718*22dc650dSSadaf Ebrahimi     G(a,BITONE) = G(pcre2_code_copy_,BITONE)(b); \
1719*22dc650dSSadaf Ebrahimi   else \
1720*22dc650dSSadaf Ebrahimi     G(a,BITTWO) = G(pcre2_code_copy_,BITTWO)(b)
1721*22dc650dSSadaf Ebrahimi 
1722*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_TO_VOID(a,b) \
1723*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1724*22dc650dSSadaf Ebrahimi     a = (void *)G(pcre2_code_copy_,BITONE)(G(b,BITONE)); \
1725*22dc650dSSadaf Ebrahimi   else \
1726*22dc650dSSadaf Ebrahimi     a = (void *)G(pcre2_code_copy_,BITTWO)(G(b,BITTWO))
1727*22dc650dSSadaf Ebrahimi 
1728*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) \
1729*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1730*22dc650dSSadaf Ebrahimi     a = (void *)G(pcre2_code_copy_with_tables_,BITONE)(G(b,BITONE)); \
1731*22dc650dSSadaf Ebrahimi   else \
1732*22dc650dSSadaf Ebrahimi     a = (void *)G(pcre2_code_copy_with_tables_,BITTWO)(G(b,BITTWO))
1733*22dc650dSSadaf Ebrahimi 
1734*22dc650dSSadaf Ebrahimi #define PCRE2_COMPILE(a,b,c,d,e,f,g) \
1735*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1736*22dc650dSSadaf Ebrahimi     G(a,BITONE) = G(pcre2_compile_,BITONE)(b,c,d,e,f,g); \
1737*22dc650dSSadaf Ebrahimi   else \
1738*22dc650dSSadaf Ebrahimi     G(a,BITTWO) = G(pcre2_compile_,BITTWO)(b,c,d,e,f,g)
1739*22dc650dSSadaf Ebrahimi 
1740*22dc650dSSadaf Ebrahimi #define PCRE2_CONVERTED_PATTERN_FREE(a) \
1741*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1742*22dc650dSSadaf Ebrahimi     G(pcre2_converted_pattern_free_,BITONE)((G(PCRE2_UCHAR,BITONE) *)a); \
1743*22dc650dSSadaf Ebrahimi   else \
1744*22dc650dSSadaf Ebrahimi     G(pcre2_converted_pattern_free_,BITTWO)((G(PCRE2_UCHAR,BITTWO) *)a)
1745*22dc650dSSadaf Ebrahimi 
1746*22dc650dSSadaf Ebrahimi #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
1747*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1748*22dc650dSSadaf Ebrahimi     a = G(pcre2_dfa_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
1749*22dc650dSSadaf Ebrahimi       G(g,BITONE),h,i,j); \
1750*22dc650dSSadaf Ebrahimi   else \
1751*22dc650dSSadaf Ebrahimi     a = G(pcre2_dfa_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \
1752*22dc650dSSadaf Ebrahimi       G(g,BITTWO),h,i,j)
1753*22dc650dSSadaf Ebrahimi 
1754*22dc650dSSadaf Ebrahimi #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
1755*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1756*22dc650dSSadaf Ebrahimi     r = G(pcre2_get_error_message_,BITONE)(a,G(b,BITONE),G(G(b,BITONE),_size/BYTEONE)); \
1757*22dc650dSSadaf Ebrahimi   else \
1758*22dc650dSSadaf Ebrahimi     r = G(pcre2_get_error_message_,BITTWO)(a,G(b,BITTWO),G(G(b,BITTWO),_size/BYTETWO))
1759*22dc650dSSadaf Ebrahimi 
1760*22dc650dSSadaf Ebrahimi #define PCRE2_GET_MATCH_DATA_HEAPFRAMES_SIZE(r,a) \
1761*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1762*22dc650dSSadaf Ebrahimi     r = G(pcre2_get_match_data_heapframes_size_,BITONE)(G(a,BITONE)); \
1763*22dc650dSSadaf Ebrahimi   else \
1764*22dc650dSSadaf Ebrahimi     r = G(pcre2_get_match_data_heapframes_size_,BITTWO)(G(a,BITTWO))
1765*22dc650dSSadaf Ebrahimi 
1766*22dc650dSSadaf Ebrahimi #define PCRE2_GET_OVECTOR_COUNT(a,b) \
1767*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1768*22dc650dSSadaf Ebrahimi     a = G(pcre2_get_ovector_count_,BITONE)(G(b,BITONE)); \
1769*22dc650dSSadaf Ebrahimi   else \
1770*22dc650dSSadaf Ebrahimi     a = G(pcre2_get_ovector_count_,BITTWO)(G(b,BITTWO))
1771*22dc650dSSadaf Ebrahimi 
1772*22dc650dSSadaf Ebrahimi #define PCRE2_GET_STARTCHAR(a,b) \
1773*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1774*22dc650dSSadaf Ebrahimi     a = G(pcre2_get_startchar_,BITONE)(G(b,BITONE)); \
1775*22dc650dSSadaf Ebrahimi   else \
1776*22dc650dSSadaf Ebrahimi     a = G(pcre2_get_startchar_,BITTWO)(G(b,BITTWO))
1777*22dc650dSSadaf Ebrahimi 
1778*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_COMPILE(r,a,b) \
1779*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1780*22dc650dSSadaf Ebrahimi     r = G(pcre2_jit_compile_,BITONE)(G(a,BITONE),b); \
1781*22dc650dSSadaf Ebrahimi   else \
1782*22dc650dSSadaf Ebrahimi     r = G(pcre2_jit_compile_,BITTWO)(G(a,BITTWO),b)
1783*22dc650dSSadaf Ebrahimi 
1784*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \
1785*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1786*22dc650dSSadaf Ebrahimi     G(pcre2_jit_free_unused_memory_,BITONE)(G(a,BITONE)); \
1787*22dc650dSSadaf Ebrahimi   else \
1788*22dc650dSSadaf Ebrahimi     G(pcre2_jit_free_unused_memory_,BITTWO)(G(a,BITTWO))
1789*22dc650dSSadaf Ebrahimi 
1790*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \
1791*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1792*22dc650dSSadaf Ebrahimi     a = G(pcre2_jit_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
1793*22dc650dSSadaf Ebrahimi       G(g,BITONE),h); \
1794*22dc650dSSadaf Ebrahimi   else \
1795*22dc650dSSadaf Ebrahimi     a = G(pcre2_jit_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \
1796*22dc650dSSadaf Ebrahimi       G(g,BITTWO),h)
1797*22dc650dSSadaf Ebrahimi 
1798*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_CREATE(a,b,c,d) \
1799*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1800*22dc650dSSadaf Ebrahimi     a = (PCRE2_JIT_STACK *)G(pcre2_jit_stack_create_,BITONE)(b,c,d); \
1801*22dc650dSSadaf Ebrahimi   else \
1802*22dc650dSSadaf Ebrahimi     a = (PCRE2_JIT_STACK *)G(pcre2_jit_stack_create_,BITTWO)(b,c,d); \
1803*22dc650dSSadaf Ebrahimi 
1804*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_ASSIGN(a,b,c) \
1805*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1806*22dc650dSSadaf Ebrahimi     G(pcre2_jit_stack_assign_,BITONE)(G(a,BITONE),(G(pcre2_jit_callback_,BITONE))b,c); \
1807*22dc650dSSadaf Ebrahimi   else \
1808*22dc650dSSadaf Ebrahimi     G(pcre2_jit_stack_assign_,BITTWO)(G(a,BITTWO),(G(pcre2_jit_callback_,BITTWO))b,c);
1809*22dc650dSSadaf Ebrahimi 
1810*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_FREE(a) \
1811*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1812*22dc650dSSadaf Ebrahimi     G(pcre2_jit_stack_free_,BITONE)((G(pcre2_jit_stack_,BITONE) *)a); \
1813*22dc650dSSadaf Ebrahimi   else \
1814*22dc650dSSadaf Ebrahimi     G(pcre2_jit_stack_free_,BITTWO)((G(pcre2_jit_stack_,BITTWO) *)a);
1815*22dc650dSSadaf Ebrahimi 
1816*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES(a,c) \
1817*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1818*22dc650dSSadaf Ebrahimi     a = G(pcre2_maketables_,BITONE)(G(c,BITONE)); \
1819*22dc650dSSadaf Ebrahimi   else \
1820*22dc650dSSadaf Ebrahimi     a = G(pcre2_maketables_,BITTWO)(G(c,BITTWO))
1821*22dc650dSSadaf Ebrahimi 
1822*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES_FREE(c,a) \
1823*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1824*22dc650dSSadaf Ebrahimi     G(pcre2_maketables_free_,BITONE)(G(c,BITONE),a); \
1825*22dc650dSSadaf Ebrahimi   else \
1826*22dc650dSSadaf Ebrahimi     G(pcre2_maketables_free_,BITTWO)(G(c,BITTWO),a)
1827*22dc650dSSadaf Ebrahimi 
1828*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH(a,b,c,d,e,f,g,h) \
1829*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1830*22dc650dSSadaf Ebrahimi     a = G(pcre2_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
1831*22dc650dSSadaf Ebrahimi       G(g,BITONE),h); \
1832*22dc650dSSadaf Ebrahimi   else \
1833*22dc650dSSadaf Ebrahimi     a = G(pcre2_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \
1834*22dc650dSSadaf Ebrahimi       G(g,BITTWO),h)
1835*22dc650dSSadaf Ebrahimi 
1836*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE(a,b,c) \
1837*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1838*22dc650dSSadaf Ebrahimi     G(a,BITONE) = G(pcre2_match_data_create_,BITONE)(b,G(c,BITONE)); \
1839*22dc650dSSadaf Ebrahimi   else \
1840*22dc650dSSadaf Ebrahimi     G(a,BITTWO) = G(pcre2_match_data_create_,BITTWO)(b,G(c,BITTWO))
1841*22dc650dSSadaf Ebrahimi 
1842*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \
1843*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1844*22dc650dSSadaf Ebrahimi     G(a,BITONE) = G(pcre2_match_data_create_from_pattern_,BITONE)(G(b,BITONE),G(c,BITONE)); \
1845*22dc650dSSadaf Ebrahimi   else \
1846*22dc650dSSadaf Ebrahimi     G(a,BITTWO) = G(pcre2_match_data_create_from_pattern_,BITTWO)(G(b,BITTWO),G(c,BITTWO))
1847*22dc650dSSadaf Ebrahimi 
1848*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_FREE(a) \
1849*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1850*22dc650dSSadaf Ebrahimi     G(pcre2_match_data_free_,BITONE)(G(a,BITONE)); \
1851*22dc650dSSadaf Ebrahimi   else \
1852*22dc650dSSadaf Ebrahimi     G(pcre2_match_data_free_,BITTWO)(G(a,BITTWO))
1853*22dc650dSSadaf Ebrahimi 
1854*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) \
1855*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1856*22dc650dSSadaf Ebrahimi     a = G(pcre2_pattern_convert_,BITONE)(G(b,BITONE),c,d,(G(PCRE2_UCHAR,BITONE) **)e,f,G(g,BITONE)); \
1857*22dc650dSSadaf Ebrahimi   else \
1858*22dc650dSSadaf Ebrahimi     a = G(pcre2_pattern_convert_,BITTWO)(G(b,BITTWO),c,d,(G(PCRE2_UCHAR,BITTWO) **)e,f,G(g,BITTWO))
1859*22dc650dSSadaf Ebrahimi 
1860*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_INFO(a,b,c,d) \
1861*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1862*22dc650dSSadaf Ebrahimi     a = G(pcre2_pattern_info_,BITONE)(G(b,BITONE),c,d); \
1863*22dc650dSSadaf Ebrahimi   else \
1864*22dc650dSSadaf Ebrahimi     a = G(pcre2_pattern_info_,BITTWO)(G(b,BITTWO),c,d)
1865*22dc650dSSadaf Ebrahimi 
1866*22dc650dSSadaf Ebrahimi #define PCRE2_PRINTINT(a) \
1867*22dc650dSSadaf Ebrahimi  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1868*22dc650dSSadaf Ebrahimi     G(pcre2_printint_,BITONE)(G(compiled_code,BITONE),outfile,a); \
1869*22dc650dSSadaf Ebrahimi   else \
1870*22dc650dSSadaf Ebrahimi     G(pcre2_printint_,BITTWO)(G(compiled_code,BITTWO),outfile,a)
1871*22dc650dSSadaf Ebrahimi 
1872*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \
1873*22dc650dSSadaf Ebrahimi  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1874*22dc650dSSadaf Ebrahimi     r = G(pcre2_serialize_decode_,BITONE)((G(pcre2_code_,BITONE) **)a,b,c,G(d,BITONE)); \
1875*22dc650dSSadaf Ebrahimi   else \
1876*22dc650dSSadaf Ebrahimi     r = G(pcre2_serialize_decode_,BITTWO)((G(pcre2_code_,BITTWO) **)a,b,c,G(d,BITTWO))
1877*22dc650dSSadaf Ebrahimi 
1878*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \
1879*22dc650dSSadaf Ebrahimi  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1880*22dc650dSSadaf Ebrahimi     r = G(pcre2_serialize_encode_,BITONE)((G(const pcre2_code_,BITONE) **)a,b,c,d,G(e,BITONE)); \
1881*22dc650dSSadaf Ebrahimi   else \
1882*22dc650dSSadaf Ebrahimi     r = G(pcre2_serialize_encode_,BITTWO)((G(const pcre2_code_,BITTWO) **)a,b,c,d,G(e,BITTWO))
1883*22dc650dSSadaf Ebrahimi 
1884*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_FREE(a) \
1885*22dc650dSSadaf Ebrahimi  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1886*22dc650dSSadaf Ebrahimi     G(pcre2_serialize_free_,BITONE)(a); \
1887*22dc650dSSadaf Ebrahimi   else \
1888*22dc650dSSadaf Ebrahimi     G(pcre2_serialize_free_,BITTWO)(a)
1889*22dc650dSSadaf Ebrahimi 
1890*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \
1891*22dc650dSSadaf Ebrahimi  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1892*22dc650dSSadaf Ebrahimi     r = G(pcre2_serialize_get_number_of_codes_,BITONE)(a); \
1893*22dc650dSSadaf Ebrahimi   else \
1894*22dc650dSSadaf Ebrahimi     r = G(pcre2_serialize_get_number_of_codes_,BITTWO)(a)
1895*22dc650dSSadaf Ebrahimi 
1896*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CALLOUT(a,b,c) \
1897*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1898*22dc650dSSadaf Ebrahimi     G(pcre2_set_callout_,BITONE)(G(a,BITONE), \
1899*22dc650dSSadaf Ebrahimi       (int (*)(G(pcre2_callout_block_,BITONE) *, void *))b,c); \
1900*22dc650dSSadaf Ebrahimi   else \
1901*22dc650dSSadaf Ebrahimi     G(pcre2_set_callout_,BITTWO)(G(a,BITTWO), \
1902*22dc650dSSadaf Ebrahimi       (int (*)(G(pcre2_callout_block_,BITTWO) *, void *))b,c);
1903*22dc650dSSadaf Ebrahimi 
1904*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CHARACTER_TABLES(a,b) \
1905*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1906*22dc650dSSadaf Ebrahimi     G(pcre2_set_character_tables_,BITONE)(G(a,BITONE),b); \
1907*22dc650dSSadaf Ebrahimi   else \
1908*22dc650dSSadaf Ebrahimi     G(pcre2_set_character_tables_,BITTWO)(G(a,BITTWO),b)
1909*22dc650dSSadaf Ebrahimi 
1910*22dc650dSSadaf Ebrahimi #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
1911*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1912*22dc650dSSadaf Ebrahimi     G(pcre2_set_compile_recursion_guard_,BITONE)(G(a,BITONE),b,c); \
1913*22dc650dSSadaf Ebrahimi   else \
1914*22dc650dSSadaf Ebrahimi     G(pcre2_set_compile_recursion_guard_,BITTWO)(G(a,BITTWO),b,c)
1915*22dc650dSSadaf Ebrahimi 
1916*22dc650dSSadaf Ebrahimi #define PCRE2_SET_DEPTH_LIMIT(a,b) \
1917*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1918*22dc650dSSadaf Ebrahimi     G(pcre2_set_depth_limit_,BITONE)(G(a,BITONE),b); \
1919*22dc650dSSadaf Ebrahimi   else \
1920*22dc650dSSadaf Ebrahimi     G(pcre2_set_depth_limit_,BITTWO)(G(a,BITTWO),b)
1921*22dc650dSSadaf Ebrahimi 
1922*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_ESCAPE(r,a,b) \
1923*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1924*22dc650dSSadaf Ebrahimi     r = G(pcre2_set_glob_escape_,BITONE)(G(a,BITONE),b); \
1925*22dc650dSSadaf Ebrahimi   else \
1926*22dc650dSSadaf Ebrahimi     r = G(pcre2_set_glob_escape_,BITTWO)(G(a,BITTWO),b)
1927*22dc650dSSadaf Ebrahimi 
1928*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_SEPARATOR(r,a,b) \
1929*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1930*22dc650dSSadaf Ebrahimi     r = G(pcre2_set_glob_separator_,BITONE)(G(a,BITONE),b); \
1931*22dc650dSSadaf Ebrahimi   else \
1932*22dc650dSSadaf Ebrahimi     r = G(pcre2_set_glob_separator_,BITTWO)(G(a,BITTWO),b)
1933*22dc650dSSadaf Ebrahimi 
1934*22dc650dSSadaf Ebrahimi #define PCRE2_SET_HEAP_LIMIT(a,b) \
1935*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1936*22dc650dSSadaf Ebrahimi     G(pcre2_set_heap_limit_,BITONE)(G(a,BITONE),b); \
1937*22dc650dSSadaf Ebrahimi   else \
1938*22dc650dSSadaf Ebrahimi     G(pcre2_set_heap_limit_,BITTWO)(G(a,BITTWO),b)
1939*22dc650dSSadaf Ebrahimi 
1940*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MATCH_LIMIT(a,b) \
1941*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1942*22dc650dSSadaf Ebrahimi     G(pcre2_set_match_limit_,BITONE)(G(a,BITONE),b); \
1943*22dc650dSSadaf Ebrahimi   else \
1944*22dc650dSSadaf Ebrahimi     G(pcre2_set_match_limit_,BITTWO)(G(a,BITTWO),b)
1945*22dc650dSSadaf Ebrahimi 
1946*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH(a,b) \
1947*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1948*22dc650dSSadaf Ebrahimi     G(pcre2_set_max_pattern_compiled_length_,BITONE)(G(a,BITONE),b); \
1949*22dc650dSSadaf Ebrahimi   else \
1950*22dc650dSSadaf Ebrahimi     G(pcre2_set_max_pattern_compiled_length_,BITTWO)(G(a,BITTWO),b)
1951*22dc650dSSadaf Ebrahimi 
1952*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \
1953*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1954*22dc650dSSadaf Ebrahimi     G(pcre2_set_max_pattern_length_,BITONE)(G(a,BITONE),b); \
1955*22dc650dSSadaf Ebrahimi   else \
1956*22dc650dSSadaf Ebrahimi     G(pcre2_set_max_pattern_length_,BITTWO)(G(a,BITTWO),b)
1957*22dc650dSSadaf Ebrahimi 
1958*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_VARLOOKBEHIND(a,b) \
1959*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1960*22dc650dSSadaf Ebrahimi     G(pcre2_set_max_varlookbehind_,BITONE)(G(a,BITONE),b); \
1961*22dc650dSSadaf Ebrahimi   else \
1962*22dc650dSSadaf Ebrahimi     G(pcre2_set_max_varlookbehind_,BITTWO)(G(a,BITTWO),b)
1963*22dc650dSSadaf Ebrahimi 
1964*22dc650dSSadaf Ebrahimi #define PCRE2_SET_OFFSET_LIMIT(a,b) \
1965*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1966*22dc650dSSadaf Ebrahimi     G(pcre2_set_offset_limit_,BITONE)(G(a,BITONE),b); \
1967*22dc650dSSadaf Ebrahimi   else \
1968*22dc650dSSadaf Ebrahimi     G(pcre2_set_offset_limit_,BITTWO)(G(a,BITTWO),b)
1969*22dc650dSSadaf Ebrahimi 
1970*22dc650dSSadaf Ebrahimi #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) \
1971*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1972*22dc650dSSadaf Ebrahimi     G(pcre2_set_parens_nest_limit_,BITONE)(G(a,BITONE),b); \
1973*22dc650dSSadaf Ebrahimi   else \
1974*22dc650dSSadaf Ebrahimi     G(pcre2_set_parens_nest_limit_,BITTWO)(G(a,BITTWO),b)
1975*22dc650dSSadaf Ebrahimi 
1976*22dc650dSSadaf Ebrahimi #define PCRE2_SET_SUBSTITUTE_CALLOUT(a,b,c) \
1977*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1978*22dc650dSSadaf Ebrahimi     G(pcre2_set_substitute_callout_,BITONE)(G(a,BITONE), \
1979*22dc650dSSadaf Ebrahimi       (int (*)(G(pcre2_substitute_callout_block_,BITONE) *, void *))b,c); \
1980*22dc650dSSadaf Ebrahimi   else \
1981*22dc650dSSadaf Ebrahimi     G(pcre2_set_substitute_callout_,BITTWO)(G(a,BITTWO), \
1982*22dc650dSSadaf Ebrahimi       (int (*)(G(pcre2_substitute_callout_block_,BITTWO) *, void *))b,c)
1983*22dc650dSSadaf Ebrahimi 
1984*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
1985*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1986*22dc650dSSadaf Ebrahimi     a = G(pcre2_substitute_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
1987*22dc650dSSadaf Ebrahimi       G(g,BITONE),h,(G(PCRE2_SPTR,BITONE))i,j, \
1988*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITONE) *)k,l); \
1989*22dc650dSSadaf Ebrahimi   else \
1990*22dc650dSSadaf Ebrahimi     a = G(pcre2_substitute_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \
1991*22dc650dSSadaf Ebrahimi       G(g,BITTWO),h,(G(PCRE2_SPTR,BITTWO))i,j, \
1992*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITTWO) *)k,l)
1993*22dc650dSSadaf Ebrahimi 
1994*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
1995*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
1996*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_copy_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\
1997*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITONE) *)d,e); \
1998*22dc650dSSadaf Ebrahimi   else \
1999*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_copy_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),\
2000*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITTWO) *)d,e)
2001*22dc650dSSadaf Ebrahimi 
2002*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
2003*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2004*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_copy_bynumber_,BITONE)(G(b,BITONE),c,\
2005*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITONE) *)d,e); \
2006*22dc650dSSadaf Ebrahimi   else \
2007*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_copy_bynumber_,BITTWO)(G(b,BITTWO),c,\
2008*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITTWO) *)d,e)
2009*22dc650dSSadaf Ebrahimi 
2010*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_FREE(a) \
2011*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2012*22dc650dSSadaf Ebrahimi     G(pcre2_substring_free_,BITONE)((G(PCRE2_UCHAR,BITONE) *)a); \
2013*22dc650dSSadaf Ebrahimi   else G(pcre2_substring_free_,BITTWO)((G(PCRE2_UCHAR,BITTWO) *)a)
2014*22dc650dSSadaf Ebrahimi 
2015*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \
2016*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2017*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_get_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\
2018*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITONE) **)d,e); \
2019*22dc650dSSadaf Ebrahimi   else \
2020*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_get_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),\
2021*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITTWO) **)d,e)
2022*22dc650dSSadaf Ebrahimi 
2023*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \
2024*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2025*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_get_bynumber_,BITONE)(G(b,BITONE),c,\
2026*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITONE) **)d,e); \
2027*22dc650dSSadaf Ebrahimi   else \
2028*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_get_bynumber_,BITTWO)(G(b,BITTWO),c,\
2029*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITTWO) **)d,e)
2030*22dc650dSSadaf Ebrahimi 
2031*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \
2032*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2033*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_length_byname_,BITONE)(G(b,BITONE),G(c,BITONE),d); \
2034*22dc650dSSadaf Ebrahimi   else \
2035*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_length_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),d)
2036*22dc650dSSadaf Ebrahimi 
2037*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \
2038*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2039*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_length_bynumber_,BITONE)(G(b,BITONE),c,d); \
2040*22dc650dSSadaf Ebrahimi   else \
2041*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_length_bynumber_,BITTWO)(G(b,BITTWO),c,d)
2042*22dc650dSSadaf Ebrahimi 
2043*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \
2044*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2045*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_list_get_,BITONE)(G(b,BITONE), \
2046*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITONE) ***)c,d); \
2047*22dc650dSSadaf Ebrahimi   else \
2048*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_list_get_,BITTWO)(G(b,BITTWO), \
2049*22dc650dSSadaf Ebrahimi       (G(PCRE2_UCHAR,BITTWO) ***)c,d)
2050*22dc650dSSadaf Ebrahimi 
2051*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_FREE(a) \
2052*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2053*22dc650dSSadaf Ebrahimi     G(pcre2_substring_list_free_,BITONE)((G(PCRE2_UCHAR,BITONE) **)a); \
2054*22dc650dSSadaf Ebrahimi   else \
2055*22dc650dSSadaf Ebrahimi     G(pcre2_substring_list_free_,BITTWO)((G(PCRE2_UCHAR,BITTWO) **)a)
2056*22dc650dSSadaf Ebrahimi 
2057*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \
2058*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2059*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_number_from_name_,BITONE)(G(b,BITONE),G(c,BITONE)); \
2060*22dc650dSSadaf Ebrahimi   else \
2061*22dc650dSSadaf Ebrahimi     a = G(pcre2_substring_number_from_name_,BITTWO)(G(b,BITTWO),G(c,BITTWO))
2062*22dc650dSSadaf Ebrahimi 
2063*22dc650dSSadaf Ebrahimi #define PTR(x) ( \
2064*22dc650dSSadaf Ebrahimi   (test_mode == G(G(PCRE,BITONE),_MODE))? (void *)G(x,BITONE) : \
2065*22dc650dSSadaf Ebrahimi   (void *)G(x,BITTWO))
2066*22dc650dSSadaf Ebrahimi 
2067*22dc650dSSadaf Ebrahimi #define SETFLD(x,y,z) \
2068*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE)->y = z; \
2069*22dc650dSSadaf Ebrahimi   else G(x,BITTWO)->y = z
2070*22dc650dSSadaf Ebrahimi 
2071*22dc650dSSadaf Ebrahimi #define SETFLDVEC(x,y,v,z) \
2072*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE)->y[v] = z; \
2073*22dc650dSSadaf Ebrahimi   else G(x,BITTWO)->y[v] = z
2074*22dc650dSSadaf Ebrahimi 
2075*22dc650dSSadaf Ebrahimi #define SETOP(x,y,z) \
2076*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE) z y; \
2077*22dc650dSSadaf Ebrahimi   else G(x,BITTWO) z y
2078*22dc650dSSadaf Ebrahimi 
2079*22dc650dSSadaf Ebrahimi #define SETCASTPTR(x,y) \
2080*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2081*22dc650dSSadaf Ebrahimi     G(x,BITONE) = (G(G(uint,BITONE),_t) *)(y); \
2082*22dc650dSSadaf Ebrahimi   else \
2083*22dc650dSSadaf Ebrahimi     G(x,BITTWO) = (G(G(uint,BITTWO),_t) *)(y)
2084*22dc650dSSadaf Ebrahimi 
2085*22dc650dSSadaf Ebrahimi #define STRLEN(p) ((test_mode == G(G(PCRE,BITONE),_MODE))? \
2086*22dc650dSSadaf Ebrahimi   G(strlen,BITONE)((G(PCRE2_SPTR,BITONE))p) : \
2087*22dc650dSSadaf Ebrahimi   G(strlen,BITTWO)((G(PCRE2_SPTR,BITTWO))p))
2088*22dc650dSSadaf Ebrahimi 
2089*22dc650dSSadaf Ebrahimi #define SUB1(a,b) \
2090*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2091*22dc650dSSadaf Ebrahimi     G(a,BITONE)(G(b,BITONE)); \
2092*22dc650dSSadaf Ebrahimi   else \
2093*22dc650dSSadaf Ebrahimi     G(a,BITTWO)(G(b,BITTWO))
2094*22dc650dSSadaf Ebrahimi 
2095*22dc650dSSadaf Ebrahimi #define SUB2(a,b,c) \
2096*22dc650dSSadaf Ebrahimi   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
2097*22dc650dSSadaf Ebrahimi     G(a,BITONE))(G(b,BITONE),G(c,BITONE)); \
2098*22dc650dSSadaf Ebrahimi   else \
2099*22dc650dSSadaf Ebrahimi     G(a,BITTWO))(G(b,BITTWO),G(c,BITTWO))
2100*22dc650dSSadaf Ebrahimi 
2101*22dc650dSSadaf Ebrahimi #define TEST(x,r,y) ( \
2102*22dc650dSSadaf Ebrahimi   (test_mode == G(G(PCRE,BITONE),_MODE) && G(x,BITONE) r (y)) || \
2103*22dc650dSSadaf Ebrahimi   (test_mode == G(G(PCRE,BITTWO),_MODE) && G(x,BITTWO) r (y)))
2104*22dc650dSSadaf Ebrahimi 
2105*22dc650dSSadaf Ebrahimi #define TESTFLD(x,f,r,y) ( \
2106*22dc650dSSadaf Ebrahimi   (test_mode == G(G(PCRE,BITONE),_MODE) && G(x,BITONE)->f r (y)) || \
2107*22dc650dSSadaf Ebrahimi   (test_mode == G(G(PCRE,BITTWO),_MODE) && G(x,BITTWO)->f r (y)))
2108*22dc650dSSadaf Ebrahimi 
2109*22dc650dSSadaf Ebrahimi 
2110*22dc650dSSadaf Ebrahimi #endif  /* Two out of three modes */
2111*22dc650dSSadaf Ebrahimi 
2112*22dc650dSSadaf Ebrahimi /* ----- End of cases where more than one mode is supported ----- */
2113*22dc650dSSadaf Ebrahimi 
2114*22dc650dSSadaf Ebrahimi 
2115*22dc650dSSadaf Ebrahimi /* ----- Only 8-bit mode is supported ----- */
2116*22dc650dSSadaf Ebrahimi 
2117*22dc650dSSadaf Ebrahimi #elif defined SUPPORT_PCRE2_8
2118*22dc650dSSadaf Ebrahimi #define CASTFLD(t,a,b) (t)(G(a,8)->b)
2119*22dc650dSSadaf Ebrahimi #define CASTVAR(t,x) (t)G(x,8)
2120*22dc650dSSadaf Ebrahimi #define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR8)(a))[b])
2121*22dc650dSSadaf Ebrahimi #define CONCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_convert_context_8))
2122*22dc650dSSadaf Ebrahimi #define CONVERT_COPY(a,b,c) memcpy(G(a,8),(char *)b, c)
2123*22dc650dSSadaf Ebrahimi #define DATCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_match_context_8))
2124*22dc650dSSadaf Ebrahimi #define FLD(a,b) G(a,8)->b
2125*22dc650dSSadaf Ebrahimi #define PATCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_compile_context_8))
2126*22dc650dSSadaf Ebrahimi #define PCHARS(lv, p, offset, len, utf, f) \
2127*22dc650dSSadaf Ebrahimi   lv = pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f)
2128*22dc650dSSadaf Ebrahimi #define PCHARSV(p, offset, len, utf, f) \
2129*22dc650dSSadaf Ebrahimi   (void)pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f)
2130*22dc650dSSadaf Ebrahimi #define PCRE2_CALLOUT_ENUMERATE(a,b,c) \
2131*22dc650dSSadaf Ebrahimi    a = pcre2_callout_enumerate_8(compiled_code8, \
2132*22dc650dSSadaf Ebrahimi      (int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c)
2133*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,8) = pcre2_code_copy_8(b)
2134*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_8(G(b,8))
2135*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) a = (void *)pcre2_code_copy_with_tables_8(G(b,8))
2136*22dc650dSSadaf Ebrahimi #define PCRE2_COMPILE(a,b,c,d,e,f,g) G(a,8) = pcre2_compile_8(b,c,d,e,f,g)
2137*22dc650dSSadaf Ebrahimi #define PCRE2_CONVERTED_PATTERN_FREE(a) \
2138*22dc650dSSadaf Ebrahimi   pcre2_converted_pattern_free_8((PCRE2_UCHAR8 *)a)
2139*22dc650dSSadaf Ebrahimi #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
2140*22dc650dSSadaf Ebrahimi   a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h,i,j)
2141*22dc650dSSadaf Ebrahimi #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
2142*22dc650dSSadaf Ebrahimi   r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size))
2143*22dc650dSSadaf Ebrahimi #define PCRE2_GET_MATCH_DATA_HEAPFRAMES_SIZE(r,a) \
2144*22dc650dSSadaf Ebrahimi   r = pcre2_get_match_data_heapframes_size_8(G(a,8))
2145*22dc650dSSadaf Ebrahimi #define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_8(G(b,8))
2146*22dc650dSSadaf Ebrahimi #define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_8(G(b,8))
2147*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_8(G(a,8),b)
2148*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_8(G(a,8))
2149*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \
2150*22dc650dSSadaf Ebrahimi   a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h)
2151*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_CREATE(a,b,c,d) \
2152*22dc650dSSadaf Ebrahimi   a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_8(b,c,d);
2153*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_ASSIGN(a,b,c) \
2154*22dc650dSSadaf Ebrahimi   pcre2_jit_stack_assign_8(G(a,8),(pcre2_jit_callback_8)b,c);
2155*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_8((pcre2_jit_stack_8 *)a);
2156*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES(a,c) a = pcre2_maketables_8(G(c,8))
2157*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES_FREE(c,a) pcre2_maketables_free_8(G(c,8),a)
2158*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH(a,b,c,d,e,f,g,h) \
2159*22dc650dSSadaf Ebrahimi   a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h)
2160*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,8) = pcre2_match_data_create_8(b,G(c,8))
2161*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \
2162*22dc650dSSadaf Ebrahimi   G(a,8) = pcre2_match_data_create_from_pattern_8(G(b,8),G(c,8))
2163*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_8(G(a,8))
2164*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) a = pcre2_pattern_convert_8(G(b,8),c,d,(PCRE2_UCHAR8 **)e,f,G(g,8))
2165*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_8(G(b,8),c,d)
2166*22dc650dSSadaf Ebrahimi #define PCRE2_PRINTINT(a) pcre2_printint_8(compiled_code8,outfile,a)
2167*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \
2168*22dc650dSSadaf Ebrahimi   r = pcre2_serialize_decode_8((pcre2_code_8 **)a,b,c,G(d,8))
2169*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \
2170*22dc650dSSadaf Ebrahimi   r = pcre2_serialize_encode_8((const pcre2_code_8 **)a,b,c,d,G(e,8))
2171*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_8(a)
2172*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \
2173*22dc650dSSadaf Ebrahimi   r = pcre2_serialize_get_number_of_codes_8(a)
2174*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CALLOUT(a,b,c) \
2175*22dc650dSSadaf Ebrahimi   pcre2_set_callout_8(G(a,8),(int (*)(pcre2_callout_block_8 *, void *))b,c)
2176*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_8(G(a,8),b)
2177*22dc650dSSadaf Ebrahimi #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
2178*22dc650dSSadaf Ebrahimi   pcre2_set_compile_recursion_guard_8(G(a,8),b,c)
2179*22dc650dSSadaf Ebrahimi #define PCRE2_SET_DEPTH_LIMIT(a,b) pcre2_set_depth_limit_8(G(a,8),b)
2180*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_ESCAPE(r,a,b) r = pcre2_set_glob_escape_8(G(a,8),b)
2181*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_SEPARATOR(r,a,b) r = pcre2_set_glob_separator_8(G(a,8),b)
2182*22dc650dSSadaf Ebrahimi #define PCRE2_SET_HEAP_LIMIT(a,b) pcre2_set_heap_limit_8(G(a,8),b)
2183*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_8(G(a,8),b)
2184*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH(a,b) pcre2_set_max_pattern_compiled_length_8(G(a,8),b)
2185*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_8(G(a,8),b)
2186*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_VARLOOKBEHIND(a,b) pcre2_set_max_varlookbehind_8(G(a,8),b)
2187*22dc650dSSadaf Ebrahimi #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_8(G(a,8),b)
2188*22dc650dSSadaf Ebrahimi #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_8(G(a,8),b)
2189*22dc650dSSadaf Ebrahimi #define PCRE2_SET_SUBSTITUTE_CALLOUT(a,b,c) \
2190*22dc650dSSadaf Ebrahimi   pcre2_set_substitute_callout_8(G(a,8), \
2191*22dc650dSSadaf Ebrahimi     (int (*)(pcre2_substitute_callout_block_8 *, void *))b,c)
2192*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
2193*22dc650dSSadaf Ebrahimi   a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h, \
2194*22dc650dSSadaf Ebrahimi     (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l)
2195*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
2196*22dc650dSSadaf Ebrahimi   a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e)
2197*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
2198*22dc650dSSadaf Ebrahimi   a = pcre2_substring_copy_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 *)d,e)
2199*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_8((PCRE2_UCHAR8 *)a)
2200*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \
2201*22dc650dSSadaf Ebrahimi   a = pcre2_substring_get_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 **)d,e)
2202*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \
2203*22dc650dSSadaf Ebrahimi   a = pcre2_substring_get_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 **)d,e)
2204*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \
2205*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_byname_8(G(b,8),G(c,8),d)
2206*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \
2207*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_bynumber_8(G(b,8),c,d)
2208*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \
2209*22dc650dSSadaf Ebrahimi   a = pcre2_substring_list_get_8(G(b,8),(PCRE2_UCHAR8 ***)c,d)
2210*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_FREE(a) \
2211*22dc650dSSadaf Ebrahimi   pcre2_substring_list_free_8((PCRE2_UCHAR8 **)a)
2212*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \
2213*22dc650dSSadaf Ebrahimi   a = pcre2_substring_number_from_name_8(G(b,8),G(c,8));
2214*22dc650dSSadaf Ebrahimi #define PTR(x) (void *)G(x,8)
2215*22dc650dSSadaf Ebrahimi #define SETFLD(x,y,z) G(x,8)->y = z
2216*22dc650dSSadaf Ebrahimi #define SETFLDVEC(x,y,v,z) G(x,8)->y[v] = z
2217*22dc650dSSadaf Ebrahimi #define SETOP(x,y,z) G(x,8) z y
2218*22dc650dSSadaf Ebrahimi #define SETCASTPTR(x,y) G(x,8) = (uint8_t *)(y)
2219*22dc650dSSadaf Ebrahimi #define STRLEN(p) (int)strlen((char *)p)
2220*22dc650dSSadaf Ebrahimi #define SUB1(a,b) G(a,8)(G(b,8))
2221*22dc650dSSadaf Ebrahimi #define SUB2(a,b,c) G(a,8)(G(b,8),G(c,8))
2222*22dc650dSSadaf Ebrahimi #define TEST(x,r,y) (G(x,8) r (y))
2223*22dc650dSSadaf Ebrahimi #define TESTFLD(x,f,r,y) (G(x,8)->f r (y))
2224*22dc650dSSadaf Ebrahimi 
2225*22dc650dSSadaf Ebrahimi 
2226*22dc650dSSadaf Ebrahimi /* ----- Only 16-bit mode is supported ----- */
2227*22dc650dSSadaf Ebrahimi 
2228*22dc650dSSadaf Ebrahimi #elif defined SUPPORT_PCRE2_16
2229*22dc650dSSadaf Ebrahimi #define CASTFLD(t,a,b) (t)(G(a,16)->b)
2230*22dc650dSSadaf Ebrahimi #define CASTVAR(t,x) (t)G(x,16)
2231*22dc650dSSadaf Ebrahimi #define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR16)(a))[b])
2232*22dc650dSSadaf Ebrahimi #define CONCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_convert_context_16))
2233*22dc650dSSadaf Ebrahimi #define CONVERT_COPY(a,b,c) memcpy(G(a,16),(char *)b, (c)*2)
2234*22dc650dSSadaf Ebrahimi #define DATCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_match_context_16))
2235*22dc650dSSadaf Ebrahimi #define FLD(a,b) G(a,16)->b
2236*22dc650dSSadaf Ebrahimi #define PATCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_compile_context_16))
2237*22dc650dSSadaf Ebrahimi #define PCHARS(lv, p, offset, len, utf, f) \
2238*22dc650dSSadaf Ebrahimi   lv = pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f)
2239*22dc650dSSadaf Ebrahimi #define PCHARSV(p, offset, len, utf, f) \
2240*22dc650dSSadaf Ebrahimi   (void)pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f)
2241*22dc650dSSadaf Ebrahimi #define PCRE2_CALLOUT_ENUMERATE(a,b,c) \
2242*22dc650dSSadaf Ebrahimi    a = pcre2_callout_enumerate_16(compiled_code16, \
2243*22dc650dSSadaf Ebrahimi      (int (*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c)
2244*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,16) = pcre2_code_copy_16(b)
2245*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_16(G(b,16))
2246*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) a = (void *)pcre2_code_copy_with_tables_16(G(b,16))
2247*22dc650dSSadaf Ebrahimi #define PCRE2_COMPILE(a,b,c,d,e,f,g) G(a,16) = pcre2_compile_16(b,c,d,e,f,g)
2248*22dc650dSSadaf Ebrahimi #define PCRE2_CONVERTED_PATTERN_FREE(a) \
2249*22dc650dSSadaf Ebrahimi   pcre2_converted_pattern_free_16((PCRE2_UCHAR16 *)a)
2250*22dc650dSSadaf Ebrahimi #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
2251*22dc650dSSadaf Ebrahimi   a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h,i,j)
2252*22dc650dSSadaf Ebrahimi #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
2253*22dc650dSSadaf Ebrahimi   r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size/2))
2254*22dc650dSSadaf Ebrahimi #define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_16(G(b,16))
2255*22dc650dSSadaf Ebrahimi #define PCRE2_GET_MATCH_DATA_HEAPFRAMES_SIZE(r,a) \
2256*22dc650dSSadaf Ebrahimi   r = pcre2_get_match_data_heapframes_size_16(G(a,16))
2257*22dc650dSSadaf Ebrahimi #define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_16(G(b,16))
2258*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_16(G(a,16),b)
2259*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_16(G(a,16))
2260*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \
2261*22dc650dSSadaf Ebrahimi   a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h)
2262*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_CREATE(a,b,c,d) \
2263*22dc650dSSadaf Ebrahimi   a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_16(b,c,d);
2264*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_ASSIGN(a,b,c) \
2265*22dc650dSSadaf Ebrahimi   pcre2_jit_stack_assign_16(G(a,16),(pcre2_jit_callback_16)b,c);
2266*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_16((pcre2_jit_stack_16 *)a);
2267*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES(a,c) a = pcre2_maketables_16(G(c,16))
2268*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES_FREE(c,a) pcre2_maketables_free_16(G(c,16),a)
2269*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH(a,b,c,d,e,f,g,h) \
2270*22dc650dSSadaf Ebrahimi   a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h)
2271*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,16) = pcre2_match_data_create_16(b,G(c,16))
2272*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \
2273*22dc650dSSadaf Ebrahimi   G(a,16) = pcre2_match_data_create_from_pattern_16(G(b,16),G(c,16))
2274*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_16(G(a,16))
2275*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) a = pcre2_pattern_convert_16(G(b,16),c,d,(PCRE2_UCHAR16 **)e,f,G(g,16))
2276*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_16(G(b,16),c,d)
2277*22dc650dSSadaf Ebrahimi #define PCRE2_PRINTINT(a) pcre2_printint_16(compiled_code16,outfile,a)
2278*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \
2279*22dc650dSSadaf Ebrahimi   r = pcre2_serialize_decode_16((pcre2_code_16 **)a,b,c,G(d,16))
2280*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \
2281*22dc650dSSadaf Ebrahimi   r = pcre2_serialize_encode_16((const pcre2_code_16 **)a,b,c,d,G(e,16))
2282*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_16(a)
2283*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \
2284*22dc650dSSadaf Ebrahimi   r = pcre2_serialize_get_number_of_codes_16(a)
2285*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CALLOUT(a,b,c) \
2286*22dc650dSSadaf Ebrahimi   pcre2_set_callout_16(G(a,16),(int (*)(pcre2_callout_block_16 *, void *))b,c);
2287*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_16(G(a,16),b)
2288*22dc650dSSadaf Ebrahimi #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
2289*22dc650dSSadaf Ebrahimi   pcre2_set_compile_recursion_guard_16(G(a,16),b,c)
2290*22dc650dSSadaf Ebrahimi #define PCRE2_SET_DEPTH_LIMIT(a,b) pcre2_set_depth_limit_16(G(a,16),b)
2291*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_ESCAPE(r,a,b) r = pcre2_set_glob_escape_16(G(a,16),b)
2292*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_SEPARATOR(r,a,b) r = pcre2_set_glob_separator_16(G(a,16),b)
2293*22dc650dSSadaf Ebrahimi #define PCRE2_SET_HEAP_LIMIT(a,b) pcre2_set_heap_limit_16(G(a,16),b)
2294*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_16(G(a,16),b)
2295*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_VARLOOKBEHIND(a,b) pcre2_set_max_varlookbehind_16(G(a,16),b)
2296*22dc650dSSadaf Ebrahimi #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_16(G(a,16),b)
2297*22dc650dSSadaf Ebrahimi #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_16(G(a,16),b)
2298*22dc650dSSadaf Ebrahimi #define PCRE2_SET_SUBSTITUTE_CALLOUT(a,b,c) \
2299*22dc650dSSadaf Ebrahimi   pcre2_set_substitute_callout_16(G(a,16), \
2300*22dc650dSSadaf Ebrahimi     (int (*)(pcre2_substitute_callout_block_16 *, void *))b,c)
2301*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
2302*22dc650dSSadaf Ebrahimi   a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h, \
2303*22dc650dSSadaf Ebrahimi     (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l)
2304*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
2305*22dc650dSSadaf Ebrahimi   a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e)
2306*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
2307*22dc650dSSadaf Ebrahimi   a = pcre2_substring_copy_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 *)d,e)
2308*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_16((PCRE2_UCHAR16 *)a)
2309*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \
2310*22dc650dSSadaf Ebrahimi   a = pcre2_substring_get_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 **)d,e)
2311*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \
2312*22dc650dSSadaf Ebrahimi   a = pcre2_substring_get_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 **)d,e)
2313*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \
2314*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_byname_16(G(b,16),G(c,16),d)
2315*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \
2316*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_bynumber_16(G(b,16),c,d)
2317*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \
2318*22dc650dSSadaf Ebrahimi   a = pcre2_substring_list_get_16(G(b,16),(PCRE2_UCHAR16 ***)c,d)
2319*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_FREE(a) \
2320*22dc650dSSadaf Ebrahimi   pcre2_substring_list_free_16((PCRE2_UCHAR16 **)a)
2321*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \
2322*22dc650dSSadaf Ebrahimi   a = pcre2_substring_number_from_name_16(G(b,16),G(c,16));
2323*22dc650dSSadaf Ebrahimi #define PTR(x) (void *)G(x,16)
2324*22dc650dSSadaf Ebrahimi #define SETFLD(x,y,z) G(x,16)->y = z
2325*22dc650dSSadaf Ebrahimi #define SETFLDVEC(x,y,v,z) G(x,16)->y[v] = z
2326*22dc650dSSadaf Ebrahimi #define SETOP(x,y,z) G(x,16) z y
2327*22dc650dSSadaf Ebrahimi #define SETCASTPTR(x,y) G(x,16) = (uint16_t *)(y)
2328*22dc650dSSadaf Ebrahimi #define STRLEN(p) (int)strlen16((PCRE2_SPTR16)p)
2329*22dc650dSSadaf Ebrahimi #define SUB1(a,b) G(a,16)(G(b,16))
2330*22dc650dSSadaf Ebrahimi #define SUB2(a,b,c) G(a,16)(G(b,16),G(c,16))
2331*22dc650dSSadaf Ebrahimi #define TEST(x,r,y) (G(x,16) r (y))
2332*22dc650dSSadaf Ebrahimi #define TESTFLD(x,f,r,y) (G(x,16)->f r (y))
2333*22dc650dSSadaf Ebrahimi 
2334*22dc650dSSadaf Ebrahimi 
2335*22dc650dSSadaf Ebrahimi /* ----- Only 32-bit mode is supported ----- */
2336*22dc650dSSadaf Ebrahimi 
2337*22dc650dSSadaf Ebrahimi #elif defined SUPPORT_PCRE2_32
2338*22dc650dSSadaf Ebrahimi #define CASTFLD(t,a,b) (t)(G(a,32)->b)
2339*22dc650dSSadaf Ebrahimi #define CASTVAR(t,x) (t)G(x,32)
2340*22dc650dSSadaf Ebrahimi #define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR32)(a))[b])
2341*22dc650dSSadaf Ebrahimi #define CONCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_convert_context_32))
2342*22dc650dSSadaf Ebrahimi #define CONVERT_COPY(a,b,c) memcpy(G(a,32),(char *)b, (c)*4)
2343*22dc650dSSadaf Ebrahimi #define DATCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_match_context_32))
2344*22dc650dSSadaf Ebrahimi #define FLD(a,b) G(a,32)->b
2345*22dc650dSSadaf Ebrahimi #define PATCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_compile_context_32))
2346*22dc650dSSadaf Ebrahimi #define PCHARS(lv, p, offset, len, utf, f) \
2347*22dc650dSSadaf Ebrahimi   lv = pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f)
2348*22dc650dSSadaf Ebrahimi #define PCHARSV(p, offset, len, utf, f) \
2349*22dc650dSSadaf Ebrahimi   (void)pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f)
2350*22dc650dSSadaf Ebrahimi #define PCRE2_CALLOUT_ENUMERATE(a,b,c) \
2351*22dc650dSSadaf Ebrahimi    a = pcre2_callout_enumerate_32(compiled_code32, \
2352*22dc650dSSadaf Ebrahimi      (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c)
2353*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,32) = pcre2_code_copy_32(b)
2354*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_32(G(b,32))
2355*22dc650dSSadaf Ebrahimi #define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) a = (void *)pcre2_code_copy_with_tables_32(G(b,32))
2356*22dc650dSSadaf Ebrahimi #define PCRE2_COMPILE(a,b,c,d,e,f,g) G(a,32) = pcre2_compile_32(b,c,d,e,f,g)
2357*22dc650dSSadaf Ebrahimi #define PCRE2_CONVERTED_PATTERN_FREE(a) \
2358*22dc650dSSadaf Ebrahimi   pcre2_converted_pattern_free_32((PCRE2_UCHAR32 *)a)
2359*22dc650dSSadaf Ebrahimi #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
2360*22dc650dSSadaf Ebrahimi   a = pcre2_dfa_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h,i,j)
2361*22dc650dSSadaf Ebrahimi #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
2362*22dc650dSSadaf Ebrahimi   r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size/4))
2363*22dc650dSSadaf Ebrahimi #define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_32(G(b,32))
2364*22dc650dSSadaf Ebrahimi #define PCRE2_GET_MATCH_DATA_HEAPFRAMES_SIZE(r,a) \
2365*22dc650dSSadaf Ebrahimi   r = pcre2_get_match_data_heapframes_size_32(G(a,32))
2366*22dc650dSSadaf Ebrahimi #define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_32(G(b,32))
2367*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_32(G(a,32),b)
2368*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_32(G(a,32))
2369*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \
2370*22dc650dSSadaf Ebrahimi   a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h)
2371*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_CREATE(a,b,c,d) \
2372*22dc650dSSadaf Ebrahimi   a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_32(b,c,d);
2373*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_ASSIGN(a,b,c) \
2374*22dc650dSSadaf Ebrahimi   pcre2_jit_stack_assign_32(G(a,32),(pcre2_jit_callback_32)b,c);
2375*22dc650dSSadaf Ebrahimi #define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_32((pcre2_jit_stack_32 *)a);
2376*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES(a,c) a = pcre2_maketables_32(G(c,32))
2377*22dc650dSSadaf Ebrahimi #define PCRE2_MAKETABLES_FREE(c,a) pcre2_maketables_free_32(G(c,32),a)
2378*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH(a,b,c,d,e,f,g,h) \
2379*22dc650dSSadaf Ebrahimi   a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h)
2380*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,32) = pcre2_match_data_create_32(b,G(c,32))
2381*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \
2382*22dc650dSSadaf Ebrahimi   G(a,32) = pcre2_match_data_create_from_pattern_32(G(b,32),G(c,32))
2383*22dc650dSSadaf Ebrahimi #define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_32(G(a,32))
2384*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) a = pcre2_pattern_convert_32(G(b,32),c,d,(PCRE2_UCHAR32 **)e,f,G(g,32))
2385*22dc650dSSadaf Ebrahimi #define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_32(G(b,32),c,d)
2386*22dc650dSSadaf Ebrahimi #define PCRE2_PRINTINT(a) pcre2_printint_32(compiled_code32,outfile,a)
2387*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \
2388*22dc650dSSadaf Ebrahimi   r = pcre2_serialize_decode_32((pcre2_code_32 **)a,b,c,G(d,32))
2389*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \
2390*22dc650dSSadaf Ebrahimi   r = pcre2_serialize_encode_32((const pcre2_code_32 **)a,b,c,d,G(e,32))
2391*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_32(a)
2392*22dc650dSSadaf Ebrahimi #define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \
2393*22dc650dSSadaf Ebrahimi   r = pcre2_serialize_get_number_of_codes_32(a)
2394*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CALLOUT(a,b,c) \
2395*22dc650dSSadaf Ebrahimi   pcre2_set_callout_32(G(a,32),(int (*)(pcre2_callout_block_32 *, void *))b,c)
2396*22dc650dSSadaf Ebrahimi #define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_32(G(a,32),b)
2397*22dc650dSSadaf Ebrahimi #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
2398*22dc650dSSadaf Ebrahimi   pcre2_set_compile_recursion_guard_32(G(a,32),b,c)
2399*22dc650dSSadaf Ebrahimi #define PCRE2_SET_DEPTH_LIMIT(a,b) pcre2_set_depth_limit_32(G(a,32),b)
2400*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_ESCAPE(r,a,b) r = pcre2_set_glob_escape_32(G(a,32),b)
2401*22dc650dSSadaf Ebrahimi #define PCRE2_SET_GLOB_SEPARATOR(r,a,b) r = pcre2_set_glob_separator_32(G(a,32),b)
2402*22dc650dSSadaf Ebrahimi #define PCRE2_SET_HEAP_LIMIT(a,b) pcre2_set_heap_limit_32(G(a,32),b)
2403*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_32(G(a,32),b)
2404*22dc650dSSadaf Ebrahimi #define PCRE2_SET_MAX_VARLOOKBEHIND(a,b) pcre2_set_max_varlookbehind_32(G(a,32),b)
2405*22dc650dSSadaf Ebrahimi #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_32(G(a,32),b)
2406*22dc650dSSadaf Ebrahimi #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_32(G(a,32),b)
2407*22dc650dSSadaf Ebrahimi #define PCRE2_SET_SUBSTITUTE_CALLOUT(a,b,c) \
2408*22dc650dSSadaf Ebrahimi   pcre2_set_substitute_callout_32(G(a,32), \
2409*22dc650dSSadaf Ebrahimi     (int (*)(pcre2_substitute_callout_block_32 *, void *))b,c)
2410*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
2411*22dc650dSSadaf Ebrahimi   a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h, \
2412*22dc650dSSadaf Ebrahimi     (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
2413*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
2414*22dc650dSSadaf Ebrahimi   a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e)
2415*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
2416*22dc650dSSadaf Ebrahimi   a = pcre2_substring_copy_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 *)d,e);
2417*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_32((PCRE2_UCHAR32 *)a)
2418*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \
2419*22dc650dSSadaf Ebrahimi   a = pcre2_substring_get_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 **)d,e)
2420*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \
2421*22dc650dSSadaf Ebrahimi   a = pcre2_substring_get_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 **)d,e)
2422*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \
2423*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_byname_32(G(b,32),G(c,32),d)
2424*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \
2425*22dc650dSSadaf Ebrahimi     a = pcre2_substring_length_bynumber_32(G(b,32),c,d)
2426*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \
2427*22dc650dSSadaf Ebrahimi   a = pcre2_substring_list_get_32(G(b,32),(PCRE2_UCHAR32 ***)c,d)
2428*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_LIST_FREE(a) \
2429*22dc650dSSadaf Ebrahimi   pcre2_substring_list_free_32((PCRE2_UCHAR32 **)a)
2430*22dc650dSSadaf Ebrahimi #define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \
2431*22dc650dSSadaf Ebrahimi   a = pcre2_substring_number_from_name_32(G(b,32),G(c,32));
2432*22dc650dSSadaf Ebrahimi #define PTR(x) (void *)G(x,32)
2433*22dc650dSSadaf Ebrahimi #define SETFLD(x,y,z) G(x,32)->y = z
2434*22dc650dSSadaf Ebrahimi #define SETFLDVEC(x,y,v,z) G(x,32)->y[v] = z
2435*22dc650dSSadaf Ebrahimi #define SETOP(x,y,z) G(x,32) z y
2436*22dc650dSSadaf Ebrahimi #define SETCASTPTR(x,y) G(x,32) = (uint32_t *)(y)
2437*22dc650dSSadaf Ebrahimi #define STRLEN(p) (int)strlen32((PCRE2_SPTR32)p)
2438*22dc650dSSadaf Ebrahimi #define SUB1(a,b) G(a,32)(G(b,32))
2439*22dc650dSSadaf Ebrahimi #define SUB2(a,b,c) G(a,32)(G(b,32),G(c,32))
2440*22dc650dSSadaf Ebrahimi #define TEST(x,r,y) (G(x,32) r (y))
2441*22dc650dSSadaf Ebrahimi #define TESTFLD(x,f,r,y) (G(x,32)->f r (y))
2442*22dc650dSSadaf Ebrahimi 
2443*22dc650dSSadaf Ebrahimi #endif
2444*22dc650dSSadaf Ebrahimi 
2445*22dc650dSSadaf Ebrahimi /* ----- End of mode-specific function call macros ----- */
2446*22dc650dSSadaf Ebrahimi 
2447*22dc650dSSadaf Ebrahimi 
2448*22dc650dSSadaf Ebrahimi 
2449*22dc650dSSadaf Ebrahimi 
2450*22dc650dSSadaf Ebrahimi /*************************************************
2451*22dc650dSSadaf Ebrahimi *         Alternate character tables             *
2452*22dc650dSSadaf Ebrahimi *************************************************/
2453*22dc650dSSadaf Ebrahimi 
2454*22dc650dSSadaf Ebrahimi /* By default, the "tables" pointer in the compile context when calling
2455*22dc650dSSadaf Ebrahimi pcre2_compile() is not set (= NULL), thereby using the default tables of the
2456*22dc650dSSadaf Ebrahimi library. However, the tables modifier can be used to select alternate sets of
2457*22dc650dSSadaf Ebrahimi tables, for different kinds of testing. Note that the locale modifier also
2458*22dc650dSSadaf Ebrahimi adjusts the tables. */
2459*22dc650dSSadaf Ebrahimi 
2460*22dc650dSSadaf Ebrahimi /* This is the set of tables distributed as default with PCRE2. It recognizes
2461*22dc650dSSadaf Ebrahimi only ASCII characters. */
2462*22dc650dSSadaf Ebrahimi 
2463*22dc650dSSadaf Ebrahimi static const uint8_t tables1[] = {
2464*22dc650dSSadaf Ebrahimi 
2465*22dc650dSSadaf Ebrahimi /* This table is a lower casing table. */
2466*22dc650dSSadaf Ebrahimi 
2467*22dc650dSSadaf Ebrahimi     0,  1,  2,  3,  4,  5,  6,  7,
2468*22dc650dSSadaf Ebrahimi     8,  9, 10, 11, 12, 13, 14, 15,
2469*22dc650dSSadaf Ebrahimi    16, 17, 18, 19, 20, 21, 22, 23,
2470*22dc650dSSadaf Ebrahimi    24, 25, 26, 27, 28, 29, 30, 31,
2471*22dc650dSSadaf Ebrahimi    32, 33, 34, 35, 36, 37, 38, 39,
2472*22dc650dSSadaf Ebrahimi    40, 41, 42, 43, 44, 45, 46, 47,
2473*22dc650dSSadaf Ebrahimi    48, 49, 50, 51, 52, 53, 54, 55,
2474*22dc650dSSadaf Ebrahimi    56, 57, 58, 59, 60, 61, 62, 63,
2475*22dc650dSSadaf Ebrahimi    64, 97, 98, 99,100,101,102,103,
2476*22dc650dSSadaf Ebrahimi   104,105,106,107,108,109,110,111,
2477*22dc650dSSadaf Ebrahimi   112,113,114,115,116,117,118,119,
2478*22dc650dSSadaf Ebrahimi   120,121,122, 91, 92, 93, 94, 95,
2479*22dc650dSSadaf Ebrahimi    96, 97, 98, 99,100,101,102,103,
2480*22dc650dSSadaf Ebrahimi   104,105,106,107,108,109,110,111,
2481*22dc650dSSadaf Ebrahimi   112,113,114,115,116,117,118,119,
2482*22dc650dSSadaf Ebrahimi   120,121,122,123,124,125,126,127,
2483*22dc650dSSadaf Ebrahimi   128,129,130,131,132,133,134,135,
2484*22dc650dSSadaf Ebrahimi   136,137,138,139,140,141,142,143,
2485*22dc650dSSadaf Ebrahimi   144,145,146,147,148,149,150,151,
2486*22dc650dSSadaf Ebrahimi   152,153,154,155,156,157,158,159,
2487*22dc650dSSadaf Ebrahimi   160,161,162,163,164,165,166,167,
2488*22dc650dSSadaf Ebrahimi   168,169,170,171,172,173,174,175,
2489*22dc650dSSadaf Ebrahimi   176,177,178,179,180,181,182,183,
2490*22dc650dSSadaf Ebrahimi   184,185,186,187,188,189,190,191,
2491*22dc650dSSadaf Ebrahimi   192,193,194,195,196,197,198,199,
2492*22dc650dSSadaf Ebrahimi   200,201,202,203,204,205,206,207,
2493*22dc650dSSadaf Ebrahimi   208,209,210,211,212,213,214,215,
2494*22dc650dSSadaf Ebrahimi   216,217,218,219,220,221,222,223,
2495*22dc650dSSadaf Ebrahimi   224,225,226,227,228,229,230,231,
2496*22dc650dSSadaf Ebrahimi   232,233,234,235,236,237,238,239,
2497*22dc650dSSadaf Ebrahimi   240,241,242,243,244,245,246,247,
2498*22dc650dSSadaf Ebrahimi   248,249,250,251,252,253,254,255,
2499*22dc650dSSadaf Ebrahimi 
2500*22dc650dSSadaf Ebrahimi /* This table is a case flipping table. */
2501*22dc650dSSadaf Ebrahimi 
2502*22dc650dSSadaf Ebrahimi     0,  1,  2,  3,  4,  5,  6,  7,
2503*22dc650dSSadaf Ebrahimi     8,  9, 10, 11, 12, 13, 14, 15,
2504*22dc650dSSadaf Ebrahimi    16, 17, 18, 19, 20, 21, 22, 23,
2505*22dc650dSSadaf Ebrahimi    24, 25, 26, 27, 28, 29, 30, 31,
2506*22dc650dSSadaf Ebrahimi    32, 33, 34, 35, 36, 37, 38, 39,
2507*22dc650dSSadaf Ebrahimi    40, 41, 42, 43, 44, 45, 46, 47,
2508*22dc650dSSadaf Ebrahimi    48, 49, 50, 51, 52, 53, 54, 55,
2509*22dc650dSSadaf Ebrahimi    56, 57, 58, 59, 60, 61, 62, 63,
2510*22dc650dSSadaf Ebrahimi    64, 97, 98, 99,100,101,102,103,
2511*22dc650dSSadaf Ebrahimi   104,105,106,107,108,109,110,111,
2512*22dc650dSSadaf Ebrahimi   112,113,114,115,116,117,118,119,
2513*22dc650dSSadaf Ebrahimi   120,121,122, 91, 92, 93, 94, 95,
2514*22dc650dSSadaf Ebrahimi    96, 65, 66, 67, 68, 69, 70, 71,
2515*22dc650dSSadaf Ebrahimi    72, 73, 74, 75, 76, 77, 78, 79,
2516*22dc650dSSadaf Ebrahimi    80, 81, 82, 83, 84, 85, 86, 87,
2517*22dc650dSSadaf Ebrahimi    88, 89, 90,123,124,125,126,127,
2518*22dc650dSSadaf Ebrahimi   128,129,130,131,132,133,134,135,
2519*22dc650dSSadaf Ebrahimi   136,137,138,139,140,141,142,143,
2520*22dc650dSSadaf Ebrahimi   144,145,146,147,148,149,150,151,
2521*22dc650dSSadaf Ebrahimi   152,153,154,155,156,157,158,159,
2522*22dc650dSSadaf Ebrahimi   160,161,162,163,164,165,166,167,
2523*22dc650dSSadaf Ebrahimi   168,169,170,171,172,173,174,175,
2524*22dc650dSSadaf Ebrahimi   176,177,178,179,180,181,182,183,
2525*22dc650dSSadaf Ebrahimi   184,185,186,187,188,189,190,191,
2526*22dc650dSSadaf Ebrahimi   192,193,194,195,196,197,198,199,
2527*22dc650dSSadaf Ebrahimi   200,201,202,203,204,205,206,207,
2528*22dc650dSSadaf Ebrahimi   208,209,210,211,212,213,214,215,
2529*22dc650dSSadaf Ebrahimi   216,217,218,219,220,221,222,223,
2530*22dc650dSSadaf Ebrahimi   224,225,226,227,228,229,230,231,
2531*22dc650dSSadaf Ebrahimi   232,233,234,235,236,237,238,239,
2532*22dc650dSSadaf Ebrahimi   240,241,242,243,244,245,246,247,
2533*22dc650dSSadaf Ebrahimi   248,249,250,251,252,253,254,255,
2534*22dc650dSSadaf Ebrahimi 
2535*22dc650dSSadaf Ebrahimi /* This table contains bit maps for various character classes. Each map is 32
2536*22dc650dSSadaf Ebrahimi bytes long and the bits run from the least significant end of each byte. The
2537*22dc650dSSadaf Ebrahimi classes that have their own maps are: space, xdigit, digit, upper, lower, word,
2538*22dc650dSSadaf Ebrahimi graph, print, punct, and cntrl. Other classes are built from combinations. */
2539*22dc650dSSadaf Ebrahimi 
2540*22dc650dSSadaf Ebrahimi   0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
2541*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2542*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2543*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2544*22dc650dSSadaf Ebrahimi 
2545*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
2546*22dc650dSSadaf Ebrahimi   0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
2547*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2548*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2549*22dc650dSSadaf Ebrahimi 
2550*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
2551*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2552*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2553*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2554*22dc650dSSadaf Ebrahimi 
2555*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2556*22dc650dSSadaf Ebrahimi   0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
2557*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2558*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2559*22dc650dSSadaf Ebrahimi 
2560*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2561*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
2562*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2563*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2564*22dc650dSSadaf Ebrahimi 
2565*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
2566*22dc650dSSadaf Ebrahimi   0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
2567*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2568*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2569*22dc650dSSadaf Ebrahimi 
2570*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
2571*22dc650dSSadaf Ebrahimi   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
2572*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2573*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2574*22dc650dSSadaf Ebrahimi 
2575*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
2576*22dc650dSSadaf Ebrahimi   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
2577*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2578*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2579*22dc650dSSadaf Ebrahimi 
2580*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
2581*22dc650dSSadaf Ebrahimi   0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
2582*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2583*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2584*22dc650dSSadaf Ebrahimi 
2585*22dc650dSSadaf Ebrahimi   0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
2586*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
2587*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2588*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2589*22dc650dSSadaf Ebrahimi 
2590*22dc650dSSadaf Ebrahimi /* This table identifies various classes of character by individual bits:
2591*22dc650dSSadaf Ebrahimi   0x01   white space character
2592*22dc650dSSadaf Ebrahimi   0x02   letter
2593*22dc650dSSadaf Ebrahimi   0x04   decimal digit
2594*22dc650dSSadaf Ebrahimi   0x08   hexadecimal digit
2595*22dc650dSSadaf Ebrahimi   0x10   alphanumeric or '_'
2596*22dc650dSSadaf Ebrahimi   0x80   regular expression metacharacter or binary zero
2597*22dc650dSSadaf Ebrahimi */
2598*22dc650dSSadaf Ebrahimi 
2599*22dc650dSSadaf Ebrahimi   0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*   0-  7 */
2600*22dc650dSSadaf Ebrahimi   0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /*   8- 15 */
2601*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  16- 23 */
2602*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */
2603*22dc650dSSadaf Ebrahimi   0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /*    - '  */
2604*22dc650dSSadaf Ebrahimi   0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /*  ( - /  */
2605*22dc650dSSadaf Ebrahimi   0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /*  0 - 7  */
2606*22dc650dSSadaf Ebrahimi   0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /*  8 - ?  */
2607*22dc650dSSadaf Ebrahimi   0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  @ - G  */
2608*22dc650dSSadaf Ebrahimi   0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  H - O  */
2609*22dc650dSSadaf Ebrahimi   0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  P - W  */
2610*22dc650dSSadaf Ebrahimi   0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /*  X - _  */
2611*22dc650dSSadaf Ebrahimi   0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  ` - g  */
2612*22dc650dSSadaf Ebrahimi   0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  h - o  */
2613*22dc650dSSadaf Ebrahimi   0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  p - w  */
2614*22dc650dSSadaf Ebrahimi   0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /*  x -127 */
2615*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
2616*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
2617*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
2618*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
2619*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
2620*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
2621*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
2622*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
2623*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
2624*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
2625*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
2626*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
2627*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
2628*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
2629*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
2630*22dc650dSSadaf Ebrahimi   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
2631*22dc650dSSadaf Ebrahimi 
2632*22dc650dSSadaf Ebrahimi /* This is a set of tables that came originally from a Windows user. It seems
2633*22dc650dSSadaf Ebrahimi to be at least an approximation of ISO 8859. In particular, there are
2634*22dc650dSSadaf Ebrahimi characters greater than 128 that are marked as spaces, letters, etc. */
2635*22dc650dSSadaf Ebrahimi 
2636*22dc650dSSadaf Ebrahimi static const uint8_t tables2[] = {
2637*22dc650dSSadaf Ebrahimi 0,1,2,3,4,5,6,7,
2638*22dc650dSSadaf Ebrahimi 8,9,10,11,12,13,14,15,
2639*22dc650dSSadaf Ebrahimi 16,17,18,19,20,21,22,23,
2640*22dc650dSSadaf Ebrahimi 24,25,26,27,28,29,30,31,
2641*22dc650dSSadaf Ebrahimi 32,33,34,35,36,37,38,39,
2642*22dc650dSSadaf Ebrahimi 40,41,42,43,44,45,46,47,
2643*22dc650dSSadaf Ebrahimi 48,49,50,51,52,53,54,55,
2644*22dc650dSSadaf Ebrahimi 56,57,58,59,60,61,62,63,
2645*22dc650dSSadaf Ebrahimi 64,97,98,99,100,101,102,103,
2646*22dc650dSSadaf Ebrahimi 104,105,106,107,108,109,110,111,
2647*22dc650dSSadaf Ebrahimi 112,113,114,115,116,117,118,119,
2648*22dc650dSSadaf Ebrahimi 120,121,122,91,92,93,94,95,
2649*22dc650dSSadaf Ebrahimi 96,97,98,99,100,101,102,103,
2650*22dc650dSSadaf Ebrahimi 104,105,106,107,108,109,110,111,
2651*22dc650dSSadaf Ebrahimi 112,113,114,115,116,117,118,119,
2652*22dc650dSSadaf Ebrahimi 120,121,122,123,124,125,126,127,
2653*22dc650dSSadaf Ebrahimi 128,129,130,131,132,133,134,135,
2654*22dc650dSSadaf Ebrahimi 136,137,138,139,140,141,142,143,
2655*22dc650dSSadaf Ebrahimi 144,145,146,147,148,149,150,151,
2656*22dc650dSSadaf Ebrahimi 152,153,154,155,156,157,158,159,
2657*22dc650dSSadaf Ebrahimi 160,161,162,163,164,165,166,167,
2658*22dc650dSSadaf Ebrahimi 168,169,170,171,172,173,174,175,
2659*22dc650dSSadaf Ebrahimi 176,177,178,179,180,181,182,183,
2660*22dc650dSSadaf Ebrahimi 184,185,186,187,188,189,190,191,
2661*22dc650dSSadaf Ebrahimi 224,225,226,227,228,229,230,231,
2662*22dc650dSSadaf Ebrahimi 232,233,234,235,236,237,238,239,
2663*22dc650dSSadaf Ebrahimi 240,241,242,243,244,245,246,215,
2664*22dc650dSSadaf Ebrahimi 248,249,250,251,252,253,254,223,
2665*22dc650dSSadaf Ebrahimi 224,225,226,227,228,229,230,231,
2666*22dc650dSSadaf Ebrahimi 232,233,234,235,236,237,238,239,
2667*22dc650dSSadaf Ebrahimi 240,241,242,243,244,245,246,247,
2668*22dc650dSSadaf Ebrahimi 248,249,250,251,252,253,254,255,
2669*22dc650dSSadaf Ebrahimi 0,1,2,3,4,5,6,7,
2670*22dc650dSSadaf Ebrahimi 8,9,10,11,12,13,14,15,
2671*22dc650dSSadaf Ebrahimi 16,17,18,19,20,21,22,23,
2672*22dc650dSSadaf Ebrahimi 24,25,26,27,28,29,30,31,
2673*22dc650dSSadaf Ebrahimi 32,33,34,35,36,37,38,39,
2674*22dc650dSSadaf Ebrahimi 40,41,42,43,44,45,46,47,
2675*22dc650dSSadaf Ebrahimi 48,49,50,51,52,53,54,55,
2676*22dc650dSSadaf Ebrahimi 56,57,58,59,60,61,62,63,
2677*22dc650dSSadaf Ebrahimi 64,97,98,99,100,101,102,103,
2678*22dc650dSSadaf Ebrahimi 104,105,106,107,108,109,110,111,
2679*22dc650dSSadaf Ebrahimi 112,113,114,115,116,117,118,119,
2680*22dc650dSSadaf Ebrahimi 120,121,122,91,92,93,94,95,
2681*22dc650dSSadaf Ebrahimi 96,65,66,67,68,69,70,71,
2682*22dc650dSSadaf Ebrahimi 72,73,74,75,76,77,78,79,
2683*22dc650dSSadaf Ebrahimi 80,81,82,83,84,85,86,87,
2684*22dc650dSSadaf Ebrahimi 88,89,90,123,124,125,126,127,
2685*22dc650dSSadaf Ebrahimi 128,129,130,131,132,133,134,135,
2686*22dc650dSSadaf Ebrahimi 136,137,138,139,140,141,142,143,
2687*22dc650dSSadaf Ebrahimi 144,145,146,147,148,149,150,151,
2688*22dc650dSSadaf Ebrahimi 152,153,154,155,156,157,158,159,
2689*22dc650dSSadaf Ebrahimi 160,161,162,163,164,165,166,167,
2690*22dc650dSSadaf Ebrahimi 168,169,170,171,172,173,174,175,
2691*22dc650dSSadaf Ebrahimi 176,177,178,179,180,181,182,183,
2692*22dc650dSSadaf Ebrahimi 184,185,186,187,188,189,190,191,
2693*22dc650dSSadaf Ebrahimi 224,225,226,227,228,229,230,231,
2694*22dc650dSSadaf Ebrahimi 232,233,234,235,236,237,238,239,
2695*22dc650dSSadaf Ebrahimi 240,241,242,243,244,245,246,215,
2696*22dc650dSSadaf Ebrahimi 248,249,250,251,252,253,254,223,
2697*22dc650dSSadaf Ebrahimi 192,193,194,195,196,197,198,199,
2698*22dc650dSSadaf Ebrahimi 200,201,202,203,204,205,206,207,
2699*22dc650dSSadaf Ebrahimi 208,209,210,211,212,213,214,247,
2700*22dc650dSSadaf Ebrahimi 216,217,218,219,220,221,222,255,
2701*22dc650dSSadaf Ebrahimi 0,62,0,0,1,0,0,0,
2702*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2703*22dc650dSSadaf Ebrahimi 32,0,0,0,1,0,0,0,
2704*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2705*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,255,3,
2706*22dc650dSSadaf Ebrahimi 126,0,0,0,126,0,0,0,
2707*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2708*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2709*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,255,3,
2710*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2711*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,12,2,
2712*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2713*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2714*22dc650dSSadaf Ebrahimi 254,255,255,7,0,0,0,0,
2715*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2716*22dc650dSSadaf Ebrahimi 255,255,127,127,0,0,0,0,
2717*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2718*22dc650dSSadaf Ebrahimi 0,0,0,0,254,255,255,7,
2719*22dc650dSSadaf Ebrahimi 0,0,0,0,0,4,32,4,
2720*22dc650dSSadaf Ebrahimi 0,0,0,128,255,255,127,255,
2721*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,255,3,
2722*22dc650dSSadaf Ebrahimi 254,255,255,135,254,255,255,7,
2723*22dc650dSSadaf Ebrahimi 0,0,0,0,0,4,44,6,
2724*22dc650dSSadaf Ebrahimi 255,255,127,255,255,255,127,255,
2725*22dc650dSSadaf Ebrahimi 0,0,0,0,254,255,255,255,
2726*22dc650dSSadaf Ebrahimi 255,255,255,255,255,255,255,127,
2727*22dc650dSSadaf Ebrahimi 0,0,0,0,254,255,255,255,
2728*22dc650dSSadaf Ebrahimi 255,255,255,255,255,255,255,255,
2729*22dc650dSSadaf Ebrahimi 0,2,0,0,255,255,255,255,
2730*22dc650dSSadaf Ebrahimi 255,255,255,255,255,255,255,127,
2731*22dc650dSSadaf Ebrahimi 0,0,0,0,255,255,255,255,
2732*22dc650dSSadaf Ebrahimi 255,255,255,255,255,255,255,255,
2733*22dc650dSSadaf Ebrahimi 0,0,0,0,254,255,0,252,
2734*22dc650dSSadaf Ebrahimi 1,0,0,248,1,0,0,120,
2735*22dc650dSSadaf Ebrahimi 0,0,0,0,254,255,255,255,
2736*22dc650dSSadaf Ebrahimi 0,0,128,0,0,0,128,0,
2737*22dc650dSSadaf Ebrahimi 255,255,255,255,0,0,0,0,
2738*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,128,
2739*22dc650dSSadaf Ebrahimi 255,255,255,255,0,0,0,0,
2740*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2741*22dc650dSSadaf Ebrahimi 128,0,0,0,0,0,0,0,
2742*22dc650dSSadaf Ebrahimi 0,1,1,0,1,1,0,0,
2743*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2744*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2745*22dc650dSSadaf Ebrahimi 1,0,0,0,128,0,0,0,
2746*22dc650dSSadaf Ebrahimi 128,128,128,128,0,0,128,0,
2747*22dc650dSSadaf Ebrahimi 28,28,28,28,28,28,28,28,
2748*22dc650dSSadaf Ebrahimi 28,28,0,0,0,0,0,128,
2749*22dc650dSSadaf Ebrahimi 0,26,26,26,26,26,26,18,
2750*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18,
2751*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18,
2752*22dc650dSSadaf Ebrahimi 18,18,18,128,128,0,128,16,
2753*22dc650dSSadaf Ebrahimi 0,26,26,26,26,26,26,18,
2754*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18,
2755*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18,
2756*22dc650dSSadaf Ebrahimi 18,18,18,128,128,0,0,0,
2757*22dc650dSSadaf Ebrahimi 0,0,0,0,0,1,0,0,
2758*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2759*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2760*22dc650dSSadaf Ebrahimi 0,0,0,0,0,0,0,0,
2761*22dc650dSSadaf Ebrahimi 1,0,0,0,0,0,0,0,
2762*22dc650dSSadaf Ebrahimi 0,0,18,0,0,0,0,0,
2763*22dc650dSSadaf Ebrahimi 0,0,20,20,0,18,0,0,
2764*22dc650dSSadaf Ebrahimi 0,20,18,0,0,0,0,0,
2765*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18,
2766*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18,
2767*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,0,
2768*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18,
2769*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18,
2770*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18,
2771*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,0,
2772*22dc650dSSadaf Ebrahimi 18,18,18,18,18,18,18,18
2773*22dc650dSSadaf Ebrahimi };
2774*22dc650dSSadaf Ebrahimi 
2775*22dc650dSSadaf Ebrahimi 
2776*22dc650dSSadaf Ebrahimi 
2777*22dc650dSSadaf Ebrahimi #if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)
2778*22dc650dSSadaf Ebrahimi /*************************************************
2779*22dc650dSSadaf Ebrahimi *    Emulated memmove() for systems without it   *
2780*22dc650dSSadaf Ebrahimi *************************************************/
2781*22dc650dSSadaf Ebrahimi 
2782*22dc650dSSadaf Ebrahimi /* This function can make use of bcopy() if it is available. Otherwise do it by
2783*22dc650dSSadaf Ebrahimi steam, as there are some non-Unix environments that lack both memmove() and
2784*22dc650dSSadaf Ebrahimi bcopy(). */
2785*22dc650dSSadaf Ebrahimi 
2786*22dc650dSSadaf Ebrahimi static void *
emulated_memmove(void * d,const void * s,size_t n)2787*22dc650dSSadaf Ebrahimi emulated_memmove(void *d, const void *s, size_t n)
2788*22dc650dSSadaf Ebrahimi {
2789*22dc650dSSadaf Ebrahimi #ifdef HAVE_BCOPY
2790*22dc650dSSadaf Ebrahimi bcopy(s, d, n);
2791*22dc650dSSadaf Ebrahimi return d;
2792*22dc650dSSadaf Ebrahimi #else
2793*22dc650dSSadaf Ebrahimi size_t i;
2794*22dc650dSSadaf Ebrahimi unsigned char *dest = (unsigned char *)d;
2795*22dc650dSSadaf Ebrahimi const unsigned char *src = (const unsigned char *)s;
2796*22dc650dSSadaf Ebrahimi if (dest > src)
2797*22dc650dSSadaf Ebrahimi   {
2798*22dc650dSSadaf Ebrahimi   dest += n;
2799*22dc650dSSadaf Ebrahimi   src += n;
2800*22dc650dSSadaf Ebrahimi   for (i = 0; i < n; ++i) *(--dest) = *(--src);
2801*22dc650dSSadaf Ebrahimi   return (void *)dest;
2802*22dc650dSSadaf Ebrahimi   }
2803*22dc650dSSadaf Ebrahimi else
2804*22dc650dSSadaf Ebrahimi   {
2805*22dc650dSSadaf Ebrahimi   for (i = 0; i < n; ++i) *dest++ = *src++;
2806*22dc650dSSadaf Ebrahimi   return (void *)(dest - n);
2807*22dc650dSSadaf Ebrahimi   }
2808*22dc650dSSadaf Ebrahimi #endif   /* not HAVE_BCOPY */
2809*22dc650dSSadaf Ebrahimi }
2810*22dc650dSSadaf Ebrahimi #undef memmove
2811*22dc650dSSadaf Ebrahimi #define memmove(d,s,n) emulated_memmove(d,s,n)
2812*22dc650dSSadaf Ebrahimi #endif   /* not VPCOMPAT && not HAVE_MEMMOVE */
2813*22dc650dSSadaf Ebrahimi 
2814*22dc650dSSadaf Ebrahimi 
2815*22dc650dSSadaf Ebrahimi 
2816*22dc650dSSadaf Ebrahimi #ifndef HAVE_STRERROR
2817*22dc650dSSadaf Ebrahimi /*************************************************
2818*22dc650dSSadaf Ebrahimi *     Provide strerror() for non-ANSI libraries  *
2819*22dc650dSSadaf Ebrahimi *************************************************/
2820*22dc650dSSadaf Ebrahimi 
2821*22dc650dSSadaf Ebrahimi /* Some old-fashioned systems (e.g. SunOS4) didn't have strerror() in their
2822*22dc650dSSadaf Ebrahimi libraries. They may no longer be around, but just in case, we can try to
2823*22dc650dSSadaf Ebrahimi provide the same facility by this simple alternative function. */
2824*22dc650dSSadaf Ebrahimi 
2825*22dc650dSSadaf Ebrahimi extern int   sys_nerr;
2826*22dc650dSSadaf Ebrahimi extern char *sys_errlist[];
2827*22dc650dSSadaf Ebrahimi 
2828*22dc650dSSadaf Ebrahimi char *
strerror(int n)2829*22dc650dSSadaf Ebrahimi strerror(int n)
2830*22dc650dSSadaf Ebrahimi {
2831*22dc650dSSadaf Ebrahimi if (n < 0 || n >= sys_nerr) return "unknown error number";
2832*22dc650dSSadaf Ebrahimi return sys_errlist[n];
2833*22dc650dSSadaf Ebrahimi }
2834*22dc650dSSadaf Ebrahimi #endif /* HAVE_STRERROR */
2835*22dc650dSSadaf Ebrahimi 
2836*22dc650dSSadaf Ebrahimi 
2837*22dc650dSSadaf Ebrahimi 
2838*22dc650dSSadaf Ebrahimi /*************************************************
2839*22dc650dSSadaf Ebrahimi *            Local memory functions              *
2840*22dc650dSSadaf Ebrahimi *************************************************/
2841*22dc650dSSadaf Ebrahimi 
2842*22dc650dSSadaf Ebrahimi /* Alternative memory functions, to test functionality. */
2843*22dc650dSSadaf Ebrahimi 
my_malloc(size_t size,void * data)2844*22dc650dSSadaf Ebrahimi static void *my_malloc(size_t size, void *data)
2845*22dc650dSSadaf Ebrahimi {
2846*22dc650dSSadaf Ebrahimi void *block = malloc(size);
2847*22dc650dSSadaf Ebrahimi (void)data;
2848*22dc650dSSadaf Ebrahimi if (show_memory)
2849*22dc650dSSadaf Ebrahimi   {
2850*22dc650dSSadaf Ebrahimi   if (block == NULL)
2851*22dc650dSSadaf Ebrahimi     {
2852*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** malloc() failed for %" SIZ_FORM "\n", size);
2853*22dc650dSSadaf Ebrahimi     }
2854*22dc650dSSadaf Ebrahimi   else
2855*22dc650dSSadaf Ebrahimi     {
2856*22dc650dSSadaf Ebrahimi     fprintf(outfile, "malloc  %5" SIZ_FORM, size);
2857*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_MALLOC_ADDRESSES
2858*22dc650dSSadaf Ebrahimi     fprintf(outfile, " %p", block);   /* Not portable */
2859*22dc650dSSadaf Ebrahimi #endif
2860*22dc650dSSadaf Ebrahimi     if (malloclistptr < MALLOCLISTSIZE)
2861*22dc650dSSadaf Ebrahimi       {
2862*22dc650dSSadaf Ebrahimi       malloclist[malloclistptr] = block;
2863*22dc650dSSadaf Ebrahimi       malloclistlength[malloclistptr++] = size;
2864*22dc650dSSadaf Ebrahimi       }
2865*22dc650dSSadaf Ebrahimi     else
2866*22dc650dSSadaf Ebrahimi       fprintf(outfile, " (not remembered)");
2867*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\n");
2868*22dc650dSSadaf Ebrahimi     }
2869*22dc650dSSadaf Ebrahimi   }
2870*22dc650dSSadaf Ebrahimi return block;
2871*22dc650dSSadaf Ebrahimi }
2872*22dc650dSSadaf Ebrahimi 
my_free(void * block,void * data)2873*22dc650dSSadaf Ebrahimi static void my_free(void *block, void *data)
2874*22dc650dSSadaf Ebrahimi {
2875*22dc650dSSadaf Ebrahimi (void)data;
2876*22dc650dSSadaf Ebrahimi if (show_memory && block != NULL)
2877*22dc650dSSadaf Ebrahimi   {
2878*22dc650dSSadaf Ebrahimi   uint32_t i, j;
2879*22dc650dSSadaf Ebrahimi   BOOL found = FALSE;
2880*22dc650dSSadaf Ebrahimi 
2881*22dc650dSSadaf Ebrahimi   fprintf(outfile, "free");
2882*22dc650dSSadaf Ebrahimi   for (i = 0; i < malloclistptr; i++)
2883*22dc650dSSadaf Ebrahimi     {
2884*22dc650dSSadaf Ebrahimi     if (block == malloclist[i])
2885*22dc650dSSadaf Ebrahimi       {
2886*22dc650dSSadaf Ebrahimi       fprintf(outfile, "    %5" SIZ_FORM, malloclistlength[i]);
2887*22dc650dSSadaf Ebrahimi       malloclistptr--;
2888*22dc650dSSadaf Ebrahimi       for (j = i; j < malloclistptr; j++)
2889*22dc650dSSadaf Ebrahimi         {
2890*22dc650dSSadaf Ebrahimi         malloclist[j] = malloclist[j+1];
2891*22dc650dSSadaf Ebrahimi         malloclistlength[j] = malloclistlength[j+1];
2892*22dc650dSSadaf Ebrahimi         }
2893*22dc650dSSadaf Ebrahimi       found = TRUE;
2894*22dc650dSSadaf Ebrahimi       break;
2895*22dc650dSSadaf Ebrahimi       }
2896*22dc650dSSadaf Ebrahimi     }
2897*22dc650dSSadaf Ebrahimi   if (!found) fprintf(outfile, " unremembered block");
2898*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_MALLOC_ADDRESSES
2899*22dc650dSSadaf Ebrahimi   fprintf(outfile, " %p", block);  /* Not portable */
2900*22dc650dSSadaf Ebrahimi #endif
2901*22dc650dSSadaf Ebrahimi   fprintf(outfile, "\n");
2902*22dc650dSSadaf Ebrahimi   }
2903*22dc650dSSadaf Ebrahimi free(block);
2904*22dc650dSSadaf Ebrahimi }
2905*22dc650dSSadaf Ebrahimi 
2906*22dc650dSSadaf Ebrahimi 
2907*22dc650dSSadaf Ebrahimi 
2908*22dc650dSSadaf Ebrahimi /*************************************************
2909*22dc650dSSadaf Ebrahimi *       Callback function for stack guard        *
2910*22dc650dSSadaf Ebrahimi *************************************************/
2911*22dc650dSSadaf Ebrahimi 
2912*22dc650dSSadaf Ebrahimi /* This is set up to be called from pcre2_compile() when the stackguard=n
2913*22dc650dSSadaf Ebrahimi modifier sets a value greater than zero. The test we do is whether the
2914*22dc650dSSadaf Ebrahimi parenthesis nesting depth is greater than the value set by the modifier.
2915*22dc650dSSadaf Ebrahimi 
2916*22dc650dSSadaf Ebrahimi Argument:  the current parenthesis nesting depth
2917*22dc650dSSadaf Ebrahimi Returns:   non-zero to kill the compilation
2918*22dc650dSSadaf Ebrahimi */
2919*22dc650dSSadaf Ebrahimi 
2920*22dc650dSSadaf Ebrahimi static int
stack_guard(uint32_t depth,void * user_data)2921*22dc650dSSadaf Ebrahimi stack_guard(uint32_t depth, void *user_data)
2922*22dc650dSSadaf Ebrahimi {
2923*22dc650dSSadaf Ebrahimi (void)user_data;
2924*22dc650dSSadaf Ebrahimi return depth > pat_patctl.stackguard_test;
2925*22dc650dSSadaf Ebrahimi }
2926*22dc650dSSadaf Ebrahimi 
2927*22dc650dSSadaf Ebrahimi 
2928*22dc650dSSadaf Ebrahimi /*************************************************
2929*22dc650dSSadaf Ebrahimi *         JIT memory callback                    *
2930*22dc650dSSadaf Ebrahimi *************************************************/
2931*22dc650dSSadaf Ebrahimi 
2932*22dc650dSSadaf Ebrahimi static PCRE2_JIT_STACK*
jit_callback(void * arg)2933*22dc650dSSadaf Ebrahimi jit_callback(void *arg)
2934*22dc650dSSadaf Ebrahimi {
2935*22dc650dSSadaf Ebrahimi jit_was_used = TRUE;
2936*22dc650dSSadaf Ebrahimi return (PCRE2_JIT_STACK *)arg;
2937*22dc650dSSadaf Ebrahimi }
2938*22dc650dSSadaf Ebrahimi 
2939*22dc650dSSadaf Ebrahimi 
2940*22dc650dSSadaf Ebrahimi /*************************************************
2941*22dc650dSSadaf Ebrahimi *      Convert UTF-8 character to code point     *
2942*22dc650dSSadaf Ebrahimi *************************************************/
2943*22dc650dSSadaf Ebrahimi 
2944*22dc650dSSadaf Ebrahimi /* This function reads one or more bytes that represent a UTF-8 character,
2945*22dc650dSSadaf Ebrahimi and returns the codepoint of that character. Note that the function supports
2946*22dc650dSSadaf Ebrahimi the original UTF-8 definition of RFC 2279, allowing for values in the range 0
2947*22dc650dSSadaf Ebrahimi to 0x7fffffff, up to 6 bytes long. This makes it possible to generate
2948*22dc650dSSadaf Ebrahimi codepoints greater than 0x10ffff which are useful for testing PCRE2's error
2949*22dc650dSSadaf Ebrahimi checking, and also for generating 32-bit non-UTF data values above the UTF
2950*22dc650dSSadaf Ebrahimi limit.
2951*22dc650dSSadaf Ebrahimi 
2952*22dc650dSSadaf Ebrahimi Argument:
2953*22dc650dSSadaf Ebrahimi   utf8bytes   a pointer to the byte vector
2954*22dc650dSSadaf Ebrahimi   end         a pointer to the end of the byte vector
2955*22dc650dSSadaf Ebrahimi   vptr        a pointer to an int to receive the value
2956*22dc650dSSadaf Ebrahimi 
2957*22dc650dSSadaf Ebrahimi Returns:      >  0 => the number of bytes consumed
2958*22dc650dSSadaf Ebrahimi               -6 to 0 => malformed UTF-8 character at offset = (-return)
2959*22dc650dSSadaf Ebrahimi */
2960*22dc650dSSadaf Ebrahimi 
2961*22dc650dSSadaf Ebrahimi static int
utf82ord(PCRE2_SPTR8 utf8bytes,PCRE2_SPTR8 end,uint32_t * vptr)2962*22dc650dSSadaf Ebrahimi utf82ord(PCRE2_SPTR8 utf8bytes, PCRE2_SPTR8 end, uint32_t *vptr)
2963*22dc650dSSadaf Ebrahimi {
2964*22dc650dSSadaf Ebrahimi uint32_t c = *utf8bytes++;
2965*22dc650dSSadaf Ebrahimi uint32_t d = c;
2966*22dc650dSSadaf Ebrahimi int i, j, s;
2967*22dc650dSSadaf Ebrahimi 
2968*22dc650dSSadaf Ebrahimi for (i = -1; i < 6; i++)               /* i is number of additional bytes */
2969*22dc650dSSadaf Ebrahimi   {
2970*22dc650dSSadaf Ebrahimi   if ((d & 0x80) == 0) break;
2971*22dc650dSSadaf Ebrahimi   d <<= 1;
2972*22dc650dSSadaf Ebrahimi   }
2973*22dc650dSSadaf Ebrahimi 
2974*22dc650dSSadaf Ebrahimi if (i == -1) { *vptr = c; return 1; }  /* ascii character */
2975*22dc650dSSadaf Ebrahimi if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */
2976*22dc650dSSadaf Ebrahimi 
2977*22dc650dSSadaf Ebrahimi /* i now has a value in the range 1-5 */
2978*22dc650dSSadaf Ebrahimi 
2979*22dc650dSSadaf Ebrahimi s = 6*i;
2980*22dc650dSSadaf Ebrahimi d = (c & utf8_table3[i]) << s;
2981*22dc650dSSadaf Ebrahimi 
2982*22dc650dSSadaf Ebrahimi for (j = 0; j < i; j++)
2983*22dc650dSSadaf Ebrahimi   {
2984*22dc650dSSadaf Ebrahimi   if (utf8bytes >= end) return 0;
2985*22dc650dSSadaf Ebrahimi 
2986*22dc650dSSadaf Ebrahimi   c = *utf8bytes++;
2987*22dc650dSSadaf Ebrahimi   if ((c & 0xc0) != 0x80) return -(j+1);
2988*22dc650dSSadaf Ebrahimi   s -= 6;
2989*22dc650dSSadaf Ebrahimi   d |= (c & 0x3f) << s;
2990*22dc650dSSadaf Ebrahimi   }
2991*22dc650dSSadaf Ebrahimi 
2992*22dc650dSSadaf Ebrahimi /* Check that encoding was the correct unique one */
2993*22dc650dSSadaf Ebrahimi 
2994*22dc650dSSadaf Ebrahimi for (j = 0; j < utf8_table1_size; j++)
2995*22dc650dSSadaf Ebrahimi   if (d <= (uint32_t)utf8_table1[j]) break;
2996*22dc650dSSadaf Ebrahimi if (j != i) return -(i+1);
2997*22dc650dSSadaf Ebrahimi 
2998*22dc650dSSadaf Ebrahimi /* Valid value */
2999*22dc650dSSadaf Ebrahimi 
3000*22dc650dSSadaf Ebrahimi *vptr = d;
3001*22dc650dSSadaf Ebrahimi return i+1;
3002*22dc650dSSadaf Ebrahimi }
3003*22dc650dSSadaf Ebrahimi 
3004*22dc650dSSadaf Ebrahimi 
3005*22dc650dSSadaf Ebrahimi 
3006*22dc650dSSadaf Ebrahimi /*************************************************
3007*22dc650dSSadaf Ebrahimi *             Print one character                *
3008*22dc650dSSadaf Ebrahimi *************************************************/
3009*22dc650dSSadaf Ebrahimi 
3010*22dc650dSSadaf Ebrahimi /* Print a single character either literally, or as a hex escape, and count how
3011*22dc650dSSadaf Ebrahimi many printed characters are used.
3012*22dc650dSSadaf Ebrahimi 
3013*22dc650dSSadaf Ebrahimi Arguments:
3014*22dc650dSSadaf Ebrahimi   c            the character
3015*22dc650dSSadaf Ebrahimi   utf          TRUE in UTF mode
3016*22dc650dSSadaf Ebrahimi   f            the FILE to print to, or NULL just to count characters
3017*22dc650dSSadaf Ebrahimi 
3018*22dc650dSSadaf Ebrahimi Returns:       number of characters written
3019*22dc650dSSadaf Ebrahimi */
3020*22dc650dSSadaf Ebrahimi 
3021*22dc650dSSadaf Ebrahimi static int
pchar(uint32_t c,BOOL utf,FILE * f)3022*22dc650dSSadaf Ebrahimi pchar(uint32_t c, BOOL utf, FILE *f)
3023*22dc650dSSadaf Ebrahimi {
3024*22dc650dSSadaf Ebrahimi int n = 0;
3025*22dc650dSSadaf Ebrahimi char tempbuffer[16];
3026*22dc650dSSadaf Ebrahimi 
3027*22dc650dSSadaf Ebrahimi if (PRINTOK(c))
3028*22dc650dSSadaf Ebrahimi   {
3029*22dc650dSSadaf Ebrahimi   if (f != NULL) fprintf(f, "%c", c);
3030*22dc650dSSadaf Ebrahimi   return 1;
3031*22dc650dSSadaf Ebrahimi   }
3032*22dc650dSSadaf Ebrahimi 
3033*22dc650dSSadaf Ebrahimi if (c < 0x100)
3034*22dc650dSSadaf Ebrahimi   {
3035*22dc650dSSadaf Ebrahimi   if (utf)
3036*22dc650dSSadaf Ebrahimi     {
3037*22dc650dSSadaf Ebrahimi     if (f != NULL) fprintf(f, "\\x{%02x}", c);
3038*22dc650dSSadaf Ebrahimi     return 6;
3039*22dc650dSSadaf Ebrahimi     }
3040*22dc650dSSadaf Ebrahimi   else
3041*22dc650dSSadaf Ebrahimi     {
3042*22dc650dSSadaf Ebrahimi     if (f != NULL) fprintf(f, "\\x%02x", c);
3043*22dc650dSSadaf Ebrahimi     return 4;
3044*22dc650dSSadaf Ebrahimi     }
3045*22dc650dSSadaf Ebrahimi   }
3046*22dc650dSSadaf Ebrahimi 
3047*22dc650dSSadaf Ebrahimi if (f != NULL) n = fprintf(f, "\\x{%02x}", c);
3048*22dc650dSSadaf Ebrahimi   else n = sprintf(tempbuffer, "\\x{%02x}", c);
3049*22dc650dSSadaf Ebrahimi 
3050*22dc650dSSadaf Ebrahimi return n >= 0 ? n : 0;
3051*22dc650dSSadaf Ebrahimi }
3052*22dc650dSSadaf Ebrahimi 
3053*22dc650dSSadaf Ebrahimi 
3054*22dc650dSSadaf Ebrahimi 
3055*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
3056*22dc650dSSadaf Ebrahimi /*************************************************
3057*22dc650dSSadaf Ebrahimi *    Find length of 0-terminated 16-bit string   *
3058*22dc650dSSadaf Ebrahimi *************************************************/
3059*22dc650dSSadaf Ebrahimi 
strlen16(PCRE2_SPTR16 p)3060*22dc650dSSadaf Ebrahimi static size_t strlen16(PCRE2_SPTR16 p)
3061*22dc650dSSadaf Ebrahimi {
3062*22dc650dSSadaf Ebrahimi PCRE2_SPTR16 pp = p;
3063*22dc650dSSadaf Ebrahimi while (*pp != 0) pp++;
3064*22dc650dSSadaf Ebrahimi return (int)(pp - p);
3065*22dc650dSSadaf Ebrahimi }
3066*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_PCRE2_16 */
3067*22dc650dSSadaf Ebrahimi 
3068*22dc650dSSadaf Ebrahimi 
3069*22dc650dSSadaf Ebrahimi 
3070*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
3071*22dc650dSSadaf Ebrahimi /*************************************************
3072*22dc650dSSadaf Ebrahimi *    Find length of 0-terminated 32-bit string   *
3073*22dc650dSSadaf Ebrahimi *************************************************/
3074*22dc650dSSadaf Ebrahimi 
strlen32(PCRE2_SPTR32 p)3075*22dc650dSSadaf Ebrahimi static size_t strlen32(PCRE2_SPTR32 p)
3076*22dc650dSSadaf Ebrahimi {
3077*22dc650dSSadaf Ebrahimi PCRE2_SPTR32 pp = p;
3078*22dc650dSSadaf Ebrahimi while (*pp != 0) pp++;
3079*22dc650dSSadaf Ebrahimi return (int)(pp - p);
3080*22dc650dSSadaf Ebrahimi }
3081*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_PCRE2_32 */
3082*22dc650dSSadaf Ebrahimi 
3083*22dc650dSSadaf Ebrahimi 
3084*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
3085*22dc650dSSadaf Ebrahimi /*************************************************
3086*22dc650dSSadaf Ebrahimi *         Print 8-bit character string           *
3087*22dc650dSSadaf Ebrahimi *************************************************/
3088*22dc650dSSadaf Ebrahimi 
3089*22dc650dSSadaf Ebrahimi /* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed.
3090*22dc650dSSadaf Ebrahimi For printing *MARK strings, a negative length is given, indicating that the
3091*22dc650dSSadaf Ebrahimi length is in the first code unit. If handed a NULL file, this function just
3092*22dc650dSSadaf Ebrahimi counts chars without printing (because pchar() does that). */
3093*22dc650dSSadaf Ebrahimi 
pchars8(PCRE2_SPTR8 p,int length,BOOL utf,FILE * f)3094*22dc650dSSadaf Ebrahimi static int pchars8(PCRE2_SPTR8 p, int length, BOOL utf, FILE *f)
3095*22dc650dSSadaf Ebrahimi {
3096*22dc650dSSadaf Ebrahimi PCRE2_SPTR8 end;
3097*22dc650dSSadaf Ebrahimi uint32_t c = 0;
3098*22dc650dSSadaf Ebrahimi int yield = 0;
3099*22dc650dSSadaf Ebrahimi if (length < 0) length = *p++;
3100*22dc650dSSadaf Ebrahimi end = p + length;
3101*22dc650dSSadaf Ebrahimi while (length-- > 0)
3102*22dc650dSSadaf Ebrahimi   {
3103*22dc650dSSadaf Ebrahimi   if (utf)
3104*22dc650dSSadaf Ebrahimi     {
3105*22dc650dSSadaf Ebrahimi     int rc = utf82ord(p, end, &c);
3106*22dc650dSSadaf Ebrahimi     if (rc > 0 && rc <= length + 1)   /* Mustn't run over the end */
3107*22dc650dSSadaf Ebrahimi       {
3108*22dc650dSSadaf Ebrahimi       length -= rc - 1;
3109*22dc650dSSadaf Ebrahimi       p += rc;
3110*22dc650dSSadaf Ebrahimi       yield += pchar(c, utf, f);
3111*22dc650dSSadaf Ebrahimi       continue;
3112*22dc650dSSadaf Ebrahimi       }
3113*22dc650dSSadaf Ebrahimi     }
3114*22dc650dSSadaf Ebrahimi   c = *p++;
3115*22dc650dSSadaf Ebrahimi   yield += pchar(c, utf, f);
3116*22dc650dSSadaf Ebrahimi   }
3117*22dc650dSSadaf Ebrahimi 
3118*22dc650dSSadaf Ebrahimi return yield;
3119*22dc650dSSadaf Ebrahimi }
3120*22dc650dSSadaf Ebrahimi #endif
3121*22dc650dSSadaf Ebrahimi 
3122*22dc650dSSadaf Ebrahimi 
3123*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
3124*22dc650dSSadaf Ebrahimi /*************************************************
3125*22dc650dSSadaf Ebrahimi *           Print 16-bit character string        *
3126*22dc650dSSadaf Ebrahimi *************************************************/
3127*22dc650dSSadaf Ebrahimi 
3128*22dc650dSSadaf Ebrahimi /* Must handle UTF-16 strings in utf mode. Yields number of characters printed.
3129*22dc650dSSadaf Ebrahimi For printing *MARK strings, a negative length is given, indicating that the
3130*22dc650dSSadaf Ebrahimi length is in the first code unit. If handed a NULL file, just counts chars
3131*22dc650dSSadaf Ebrahimi without printing. */
3132*22dc650dSSadaf Ebrahimi 
pchars16(PCRE2_SPTR16 p,int length,BOOL utf,FILE * f)3133*22dc650dSSadaf Ebrahimi static int pchars16(PCRE2_SPTR16 p, int length, BOOL utf, FILE *f)
3134*22dc650dSSadaf Ebrahimi {
3135*22dc650dSSadaf Ebrahimi int yield = 0;
3136*22dc650dSSadaf Ebrahimi if (length < 0) length = *p++;
3137*22dc650dSSadaf Ebrahimi while (length-- > 0)
3138*22dc650dSSadaf Ebrahimi   {
3139*22dc650dSSadaf Ebrahimi   uint32_t c = *p++ & 0xffff;
3140*22dc650dSSadaf Ebrahimi   if (utf && c >= 0xD800 && c < 0xDC00 && length > 0)
3141*22dc650dSSadaf Ebrahimi     {
3142*22dc650dSSadaf Ebrahimi     int d = *p & 0xffff;
3143*22dc650dSSadaf Ebrahimi     if (d >= 0xDC00 && d <= 0xDFFF)
3144*22dc650dSSadaf Ebrahimi       {
3145*22dc650dSSadaf Ebrahimi       c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000;
3146*22dc650dSSadaf Ebrahimi       length--;
3147*22dc650dSSadaf Ebrahimi       p++;
3148*22dc650dSSadaf Ebrahimi       }
3149*22dc650dSSadaf Ebrahimi     }
3150*22dc650dSSadaf Ebrahimi   yield += pchar(c, utf, f);
3151*22dc650dSSadaf Ebrahimi   }
3152*22dc650dSSadaf Ebrahimi return yield;
3153*22dc650dSSadaf Ebrahimi }
3154*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_PCRE2_16 */
3155*22dc650dSSadaf Ebrahimi 
3156*22dc650dSSadaf Ebrahimi 
3157*22dc650dSSadaf Ebrahimi 
3158*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
3159*22dc650dSSadaf Ebrahimi /*************************************************
3160*22dc650dSSadaf Ebrahimi *           Print 32-bit character string        *
3161*22dc650dSSadaf Ebrahimi *************************************************/
3162*22dc650dSSadaf Ebrahimi 
3163*22dc650dSSadaf Ebrahimi /* Must handle UTF-32 strings in utf mode. Yields number of characters printed.
3164*22dc650dSSadaf Ebrahimi For printing *MARK strings, a negative length is given, indicating that the
3165*22dc650dSSadaf Ebrahimi length is in the first code unit. If handed a NULL file, just counts chars
3166*22dc650dSSadaf Ebrahimi without printing. */
3167*22dc650dSSadaf Ebrahimi 
pchars32(PCRE2_SPTR32 p,int length,BOOL utf,FILE * f)3168*22dc650dSSadaf Ebrahimi static int pchars32(PCRE2_SPTR32 p, int length, BOOL utf, FILE *f)
3169*22dc650dSSadaf Ebrahimi {
3170*22dc650dSSadaf Ebrahimi int yield = 0;
3171*22dc650dSSadaf Ebrahimi (void)(utf);  /* Avoid compiler warning */
3172*22dc650dSSadaf Ebrahimi if (length < 0) length = *p++;
3173*22dc650dSSadaf Ebrahimi while (length-- > 0)
3174*22dc650dSSadaf Ebrahimi   {
3175*22dc650dSSadaf Ebrahimi   uint32_t c = *p++;
3176*22dc650dSSadaf Ebrahimi   yield += pchar(c, utf, f);
3177*22dc650dSSadaf Ebrahimi   }
3178*22dc650dSSadaf Ebrahimi return yield;
3179*22dc650dSSadaf Ebrahimi }
3180*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_PCRE2_32 */
3181*22dc650dSSadaf Ebrahimi 
3182*22dc650dSSadaf Ebrahimi 
3183*22dc650dSSadaf Ebrahimi 
3184*22dc650dSSadaf Ebrahimi 
3185*22dc650dSSadaf Ebrahimi /*************************************************
3186*22dc650dSSadaf Ebrahimi *       Convert character value to UTF-8         *
3187*22dc650dSSadaf Ebrahimi *************************************************/
3188*22dc650dSSadaf Ebrahimi 
3189*22dc650dSSadaf Ebrahimi /* This function takes an integer value in the range 0 - 0x7fffffff
3190*22dc650dSSadaf Ebrahimi and encodes it as a UTF-8 character in 0 to 6 bytes. It is needed even when the
3191*22dc650dSSadaf Ebrahimi 8-bit library is not supported, to generate UTF-8 output for non-ASCII
3192*22dc650dSSadaf Ebrahimi characters.
3193*22dc650dSSadaf Ebrahimi 
3194*22dc650dSSadaf Ebrahimi Arguments:
3195*22dc650dSSadaf Ebrahimi   cvalue     the character value
3196*22dc650dSSadaf Ebrahimi   utf8bytes  pointer to buffer for result - at least 6 bytes long
3197*22dc650dSSadaf Ebrahimi 
3198*22dc650dSSadaf Ebrahimi Returns:     number of characters placed in the buffer
3199*22dc650dSSadaf Ebrahimi */
3200*22dc650dSSadaf Ebrahimi 
3201*22dc650dSSadaf Ebrahimi static int
ord2utf8(uint32_t cvalue,uint8_t * utf8bytes)3202*22dc650dSSadaf Ebrahimi ord2utf8(uint32_t cvalue, uint8_t *utf8bytes)
3203*22dc650dSSadaf Ebrahimi {
3204*22dc650dSSadaf Ebrahimi int i, j;
3205*22dc650dSSadaf Ebrahimi if (cvalue > 0x7fffffffu)
3206*22dc650dSSadaf Ebrahimi   return -1;
3207*22dc650dSSadaf Ebrahimi for (i = 0; i < utf8_table1_size; i++)
3208*22dc650dSSadaf Ebrahimi   if (cvalue <= (uint32_t)utf8_table1[i]) break;
3209*22dc650dSSadaf Ebrahimi utf8bytes += i;
3210*22dc650dSSadaf Ebrahimi for (j = i; j > 0; j--)
3211*22dc650dSSadaf Ebrahimi  {
3212*22dc650dSSadaf Ebrahimi  *utf8bytes-- = 0x80 | (cvalue & 0x3f);
3213*22dc650dSSadaf Ebrahimi  cvalue >>= 6;
3214*22dc650dSSadaf Ebrahimi  }
3215*22dc650dSSadaf Ebrahimi *utf8bytes = utf8_table2[i] | cvalue;
3216*22dc650dSSadaf Ebrahimi return i + 1;
3217*22dc650dSSadaf Ebrahimi }
3218*22dc650dSSadaf Ebrahimi 
3219*22dc650dSSadaf Ebrahimi 
3220*22dc650dSSadaf Ebrahimi 
3221*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
3222*22dc650dSSadaf Ebrahimi /*************************************************
3223*22dc650dSSadaf Ebrahimi *           Convert string to 16-bit             *
3224*22dc650dSSadaf Ebrahimi *************************************************/
3225*22dc650dSSadaf Ebrahimi 
3226*22dc650dSSadaf Ebrahimi /* In UTF mode the input is always interpreted as a string of UTF-8 bytes using
3227*22dc650dSSadaf Ebrahimi the original UTF-8 definition of RFC 2279, which allows for up to 6 bytes, and
3228*22dc650dSSadaf Ebrahimi code values from 0 to 0x7fffffff. However, values greater than the later UTF
3229*22dc650dSSadaf Ebrahimi limit of 0x10ffff cause an error. In non-UTF mode the input is interpreted as
3230*22dc650dSSadaf Ebrahimi UTF-8 if the utf8_input modifier is set, but an error is generated for values
3231*22dc650dSSadaf Ebrahimi greater than 0xffff.
3232*22dc650dSSadaf Ebrahimi 
3233*22dc650dSSadaf Ebrahimi If all the input bytes are ASCII, the space needed for a 16-bit string is
3234*22dc650dSSadaf Ebrahimi exactly double the 8-bit size. Otherwise, the size needed for a 16-bit string
3235*22dc650dSSadaf Ebrahimi is no more than double, because up to 0xffff uses no more than 3 bytes in UTF-8
3236*22dc650dSSadaf Ebrahimi but possibly 4 in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes
3237*22dc650dSSadaf Ebrahimi in UTF-16. The result is always left in pbuffer16. Impose a minimum size to
3238*22dc650dSSadaf Ebrahimi save repeated re-sizing.
3239*22dc650dSSadaf Ebrahimi 
3240*22dc650dSSadaf Ebrahimi Note that this function does not object to surrogate values. This is
3241*22dc650dSSadaf Ebrahimi deliberate; it makes it possible to construct UTF-16 strings that are invalid,
3242*22dc650dSSadaf Ebrahimi for the purpose of testing that they are correctly faulted.
3243*22dc650dSSadaf Ebrahimi 
3244*22dc650dSSadaf Ebrahimi Arguments:
3245*22dc650dSSadaf Ebrahimi   p          points to a byte string
3246*22dc650dSSadaf Ebrahimi   utf        true in UTF mode
3247*22dc650dSSadaf Ebrahimi   lenptr     points to number of bytes in the string (excluding trailing zero)
3248*22dc650dSSadaf Ebrahimi 
3249*22dc650dSSadaf Ebrahimi Returns:     0 on success, with the length updated to the number of 16-bit
3250*22dc650dSSadaf Ebrahimi                data items used (excluding the trailing zero)
3251*22dc650dSSadaf Ebrahimi              OR -1 if a UTF-8 string is malformed
3252*22dc650dSSadaf Ebrahimi              OR -2 if a value > 0x10ffff is encountered in UTF mode
3253*22dc650dSSadaf Ebrahimi              OR -3 if a value > 0xffff is encountered when not in UTF mode
3254*22dc650dSSadaf Ebrahimi */
3255*22dc650dSSadaf Ebrahimi 
3256*22dc650dSSadaf Ebrahimi static int
to16(uint8_t * p,int utf,PCRE2_SIZE * lenptr)3257*22dc650dSSadaf Ebrahimi to16(uint8_t *p, int utf, PCRE2_SIZE *lenptr)
3258*22dc650dSSadaf Ebrahimi {
3259*22dc650dSSadaf Ebrahimi uint16_t *pp;
3260*22dc650dSSadaf Ebrahimi PCRE2_SIZE len = *lenptr;
3261*22dc650dSSadaf Ebrahimi 
3262*22dc650dSSadaf Ebrahimi if (pbuffer16_size < 2*len + 2)
3263*22dc650dSSadaf Ebrahimi   {
3264*22dc650dSSadaf Ebrahimi   if (pbuffer16 != NULL) free(pbuffer16);
3265*22dc650dSSadaf Ebrahimi   pbuffer16_size = 2*len + 2;
3266*22dc650dSSadaf Ebrahimi   if (pbuffer16_size < 4096) pbuffer16_size = 4096;
3267*22dc650dSSadaf Ebrahimi   pbuffer16 = (uint16_t *)malloc(pbuffer16_size);
3268*22dc650dSSadaf Ebrahimi   if (pbuffer16 == NULL)
3269*22dc650dSSadaf Ebrahimi     {
3270*22dc650dSSadaf Ebrahimi     fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer16\n",
3271*22dc650dSSadaf Ebrahimi       pbuffer16_size);
3272*22dc650dSSadaf Ebrahimi     exit(1);
3273*22dc650dSSadaf Ebrahimi     }
3274*22dc650dSSadaf Ebrahimi   }
3275*22dc650dSSadaf Ebrahimi 
3276*22dc650dSSadaf Ebrahimi pp = pbuffer16;
3277*22dc650dSSadaf Ebrahimi if (!utf && (pat_patctl.control & CTL_UTF8_INPUT) == 0)
3278*22dc650dSSadaf Ebrahimi   {
3279*22dc650dSSadaf Ebrahimi   for (; len > 0; len--) *pp++ = *p++;
3280*22dc650dSSadaf Ebrahimi   }
3281*22dc650dSSadaf Ebrahimi else while (len > 0)
3282*22dc650dSSadaf Ebrahimi   {
3283*22dc650dSSadaf Ebrahimi   uint32_t c;
3284*22dc650dSSadaf Ebrahimi   const uint8_t *end = p + len;
3285*22dc650dSSadaf Ebrahimi   int chlen = utf82ord(p, end, &c);
3286*22dc650dSSadaf Ebrahimi   if (chlen <= 0) return -1;
3287*22dc650dSSadaf Ebrahimi   if (!utf && c > 0xffff) return -3;
3288*22dc650dSSadaf Ebrahimi   if (c > 0x10ffff) return -2;
3289*22dc650dSSadaf Ebrahimi   p += chlen;
3290*22dc650dSSadaf Ebrahimi   len -= chlen;
3291*22dc650dSSadaf Ebrahimi   if (c < 0x10000) *pp++ = c; else
3292*22dc650dSSadaf Ebrahimi     {
3293*22dc650dSSadaf Ebrahimi     c -= 0x10000;
3294*22dc650dSSadaf Ebrahimi     *pp++ = 0xD800 | (c >> 10);
3295*22dc650dSSadaf Ebrahimi     *pp++ = 0xDC00 | (c & 0x3ff);
3296*22dc650dSSadaf Ebrahimi     }
3297*22dc650dSSadaf Ebrahimi   }
3298*22dc650dSSadaf Ebrahimi 
3299*22dc650dSSadaf Ebrahimi *pp = 0;
3300*22dc650dSSadaf Ebrahimi *lenptr = pp - pbuffer16;
3301*22dc650dSSadaf Ebrahimi return 0;
3302*22dc650dSSadaf Ebrahimi }
3303*22dc650dSSadaf Ebrahimi #endif
3304*22dc650dSSadaf Ebrahimi 
3305*22dc650dSSadaf Ebrahimi 
3306*22dc650dSSadaf Ebrahimi 
3307*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
3308*22dc650dSSadaf Ebrahimi /*************************************************
3309*22dc650dSSadaf Ebrahimi *           Convert string to 32-bit             *
3310*22dc650dSSadaf Ebrahimi *************************************************/
3311*22dc650dSSadaf Ebrahimi 
3312*22dc650dSSadaf Ebrahimi /* In UTF mode the input is always interpreted as a string of UTF-8 bytes using
3313*22dc650dSSadaf Ebrahimi the original UTF-8 definition of RFC 2279, which allows for up to 6 bytes, and
3314*22dc650dSSadaf Ebrahimi code values from 0 to 0x7fffffff. However, values greater than the later UTF
3315*22dc650dSSadaf Ebrahimi limit of 0x10ffff cause an error.
3316*22dc650dSSadaf Ebrahimi 
3317*22dc650dSSadaf Ebrahimi In non-UTF mode the input is interpreted as UTF-8 if the utf8_input modifier
3318*22dc650dSSadaf Ebrahimi is set, and no limit is imposed. There is special interpretation of the 0xff
3319*22dc650dSSadaf Ebrahimi byte (which is illegal in UTF-8) in this case: it causes the top bit of the
3320*22dc650dSSadaf Ebrahimi next character to be set. This provides a way of generating 32-bit characters
3321*22dc650dSSadaf Ebrahimi greater than 0x7fffffff.
3322*22dc650dSSadaf Ebrahimi 
3323*22dc650dSSadaf Ebrahimi If all the input bytes are ASCII, the space needed for a 32-bit string is
3324*22dc650dSSadaf Ebrahimi exactly four times the 8-bit size. Otherwise, the size needed for a 32-bit
3325*22dc650dSSadaf Ebrahimi string is no more than four times, because the number of characters must be
3326*22dc650dSSadaf Ebrahimi less than the number of bytes. The result is always left in pbuffer32. Impose a
3327*22dc650dSSadaf Ebrahimi minimum size to save repeated re-sizing.
3328*22dc650dSSadaf Ebrahimi 
3329*22dc650dSSadaf Ebrahimi Note that this function does not object to surrogate values. This is
3330*22dc650dSSadaf Ebrahimi deliberate; it makes it possible to construct UTF-32 strings that are invalid,
3331*22dc650dSSadaf Ebrahimi for the purpose of testing that they are correctly faulted.
3332*22dc650dSSadaf Ebrahimi 
3333*22dc650dSSadaf Ebrahimi Arguments:
3334*22dc650dSSadaf Ebrahimi   p          points to a byte string
3335*22dc650dSSadaf Ebrahimi   utf        true in UTF mode
3336*22dc650dSSadaf Ebrahimi   lenptr     points to number of bytes in the string (excluding trailing zero)
3337*22dc650dSSadaf Ebrahimi 
3338*22dc650dSSadaf Ebrahimi Returns:     0 on success, with the length updated to the number of 32-bit
3339*22dc650dSSadaf Ebrahimi                data items used (excluding the trailing zero)
3340*22dc650dSSadaf Ebrahimi              OR -1 if a UTF-8 string is malformed
3341*22dc650dSSadaf Ebrahimi              OR -2 if a value > 0x10ffff is encountered in UTF mode
3342*22dc650dSSadaf Ebrahimi */
3343*22dc650dSSadaf Ebrahimi 
3344*22dc650dSSadaf Ebrahimi static int
to32(uint8_t * p,int utf,PCRE2_SIZE * lenptr)3345*22dc650dSSadaf Ebrahimi to32(uint8_t *p, int utf, PCRE2_SIZE *lenptr)
3346*22dc650dSSadaf Ebrahimi {
3347*22dc650dSSadaf Ebrahimi uint32_t *pp;
3348*22dc650dSSadaf Ebrahimi PCRE2_SIZE len = *lenptr;
3349*22dc650dSSadaf Ebrahimi 
3350*22dc650dSSadaf Ebrahimi if (pbuffer32_size < 4*len + 4)
3351*22dc650dSSadaf Ebrahimi   {
3352*22dc650dSSadaf Ebrahimi   if (pbuffer32 != NULL) free(pbuffer32);
3353*22dc650dSSadaf Ebrahimi   pbuffer32_size = 4*len + 4;
3354*22dc650dSSadaf Ebrahimi   if (pbuffer32_size < 8192) pbuffer32_size = 8192;
3355*22dc650dSSadaf Ebrahimi   pbuffer32 = (uint32_t *)malloc(pbuffer32_size);
3356*22dc650dSSadaf Ebrahimi   if (pbuffer32 == NULL)
3357*22dc650dSSadaf Ebrahimi     {
3358*22dc650dSSadaf Ebrahimi     fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer32\n",
3359*22dc650dSSadaf Ebrahimi       pbuffer32_size);
3360*22dc650dSSadaf Ebrahimi     exit(1);
3361*22dc650dSSadaf Ebrahimi     }
3362*22dc650dSSadaf Ebrahimi   }
3363*22dc650dSSadaf Ebrahimi 
3364*22dc650dSSadaf Ebrahimi pp = pbuffer32;
3365*22dc650dSSadaf Ebrahimi 
3366*22dc650dSSadaf Ebrahimi if (!utf && (pat_patctl.control & CTL_UTF8_INPUT) == 0)
3367*22dc650dSSadaf Ebrahimi   {
3368*22dc650dSSadaf Ebrahimi   for (; len > 0; len--) *pp++ = *p++;
3369*22dc650dSSadaf Ebrahimi   }
3370*22dc650dSSadaf Ebrahimi 
3371*22dc650dSSadaf Ebrahimi else while (len > 0)
3372*22dc650dSSadaf Ebrahimi   {
3373*22dc650dSSadaf Ebrahimi   int chlen;
3374*22dc650dSSadaf Ebrahimi   uint32_t c;
3375*22dc650dSSadaf Ebrahimi   uint32_t topbit = 0;
3376*22dc650dSSadaf Ebrahimi   const uint8_t *end = p + len;
3377*22dc650dSSadaf Ebrahimi   if (!utf && *p == 0xff && len > 1)
3378*22dc650dSSadaf Ebrahimi     {
3379*22dc650dSSadaf Ebrahimi     topbit = 0x80000000u;
3380*22dc650dSSadaf Ebrahimi     p++;
3381*22dc650dSSadaf Ebrahimi     len--;
3382*22dc650dSSadaf Ebrahimi     }
3383*22dc650dSSadaf Ebrahimi   chlen = utf82ord(p, end, &c);
3384*22dc650dSSadaf Ebrahimi   if (chlen <= 0) return -1;
3385*22dc650dSSadaf Ebrahimi   if (utf && c > 0x10ffff) return -2;
3386*22dc650dSSadaf Ebrahimi   p += chlen;
3387*22dc650dSSadaf Ebrahimi   len -= chlen;
3388*22dc650dSSadaf Ebrahimi   *pp++ = c | topbit;
3389*22dc650dSSadaf Ebrahimi   }
3390*22dc650dSSadaf Ebrahimi 
3391*22dc650dSSadaf Ebrahimi *pp = 0;
3392*22dc650dSSadaf Ebrahimi *lenptr = pp - pbuffer32;
3393*22dc650dSSadaf Ebrahimi return 0;
3394*22dc650dSSadaf Ebrahimi }
3395*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_PCRE2_32 */
3396*22dc650dSSadaf Ebrahimi 
3397*22dc650dSSadaf Ebrahimi 
3398*22dc650dSSadaf Ebrahimi 
3399*22dc650dSSadaf Ebrahimi /* This function is no longer used. Keep it around for a while, just in case it
3400*22dc650dSSadaf Ebrahimi needs to be re-instated. */
3401*22dc650dSSadaf Ebrahimi 
3402*22dc650dSSadaf Ebrahimi #ifdef NEVERNEVERNEVER
3403*22dc650dSSadaf Ebrahimi 
3404*22dc650dSSadaf Ebrahimi /*************************************************
3405*22dc650dSSadaf Ebrahimi *         Move back by so many characters        *
3406*22dc650dSSadaf Ebrahimi *************************************************/
3407*22dc650dSSadaf Ebrahimi 
3408*22dc650dSSadaf Ebrahimi /* Given a code unit offset in a subject string, move backwards by a number of
3409*22dc650dSSadaf Ebrahimi characters, and return the resulting offset.
3410*22dc650dSSadaf Ebrahimi 
3411*22dc650dSSadaf Ebrahimi Arguments:
3412*22dc650dSSadaf Ebrahimi   subject   pointer to the string
3413*22dc650dSSadaf Ebrahimi   offset    start offset
3414*22dc650dSSadaf Ebrahimi   count     count to move back by
3415*22dc650dSSadaf Ebrahimi   utf       TRUE if in UTF mode
3416*22dc650dSSadaf Ebrahimi 
3417*22dc650dSSadaf Ebrahimi Returns:   a possibly changed offset
3418*22dc650dSSadaf Ebrahimi */
3419*22dc650dSSadaf Ebrahimi 
3420*22dc650dSSadaf Ebrahimi static PCRE2_SIZE
backchars(uint8_t * subject,PCRE2_SIZE offset,uint32_t count,BOOL utf)3421*22dc650dSSadaf Ebrahimi backchars(uint8_t *subject, PCRE2_SIZE offset, uint32_t count, BOOL utf)
3422*22dc650dSSadaf Ebrahimi {
3423*22dc650dSSadaf Ebrahimi if (!utf || test_mode == PCRE32_MODE)
3424*22dc650dSSadaf Ebrahimi   return (count >= offset)? 0 : (offset - count);
3425*22dc650dSSadaf Ebrahimi 
3426*22dc650dSSadaf Ebrahimi else if (test_mode == PCRE8_MODE)
3427*22dc650dSSadaf Ebrahimi   {
3428*22dc650dSSadaf Ebrahimi   PCRE2_SPTR8 pp = (PCRE2_SPTR8)subject + offset;
3429*22dc650dSSadaf Ebrahimi   for (; count > 0 && pp > (PCRE2_SPTR8)subject; count--)
3430*22dc650dSSadaf Ebrahimi     {
3431*22dc650dSSadaf Ebrahimi     pp--;
3432*22dc650dSSadaf Ebrahimi     while ((*pp & 0xc0) == 0x80) pp--;
3433*22dc650dSSadaf Ebrahimi     }
3434*22dc650dSSadaf Ebrahimi   return pp - (PCRE2_SPTR8)subject;
3435*22dc650dSSadaf Ebrahimi   }
3436*22dc650dSSadaf Ebrahimi 
3437*22dc650dSSadaf Ebrahimi else  /* 16-bit mode */
3438*22dc650dSSadaf Ebrahimi   {
3439*22dc650dSSadaf Ebrahimi   PCRE2_SPTR16 pp = (PCRE2_SPTR16)subject + offset;
3440*22dc650dSSadaf Ebrahimi   for (; count > 0 && pp > (PCRE2_SPTR16)subject; count--)
3441*22dc650dSSadaf Ebrahimi     {
3442*22dc650dSSadaf Ebrahimi     pp--;
3443*22dc650dSSadaf Ebrahimi     if ((*pp & 0xfc00) == 0xdc00) pp--;
3444*22dc650dSSadaf Ebrahimi     }
3445*22dc650dSSadaf Ebrahimi   return pp - (PCRE2_SPTR16)subject;
3446*22dc650dSSadaf Ebrahimi   }
3447*22dc650dSSadaf Ebrahimi }
3448*22dc650dSSadaf Ebrahimi #endif  /* NEVERNEVERNEVER */
3449*22dc650dSSadaf Ebrahimi 
3450*22dc650dSSadaf Ebrahimi 
3451*22dc650dSSadaf Ebrahimi 
3452*22dc650dSSadaf Ebrahimi /*************************************************
3453*22dc650dSSadaf Ebrahimi *           Expand input buffers                 *
3454*22dc650dSSadaf Ebrahimi *************************************************/
3455*22dc650dSSadaf Ebrahimi 
3456*22dc650dSSadaf Ebrahimi /* This function doubles the size of the input buffer and the buffer for
3457*22dc650dSSadaf Ebrahimi keeping an 8-bit copy of patterns (pbuffer8), and copies the current buffers to
3458*22dc650dSSadaf Ebrahimi the new ones.
3459*22dc650dSSadaf Ebrahimi 
3460*22dc650dSSadaf Ebrahimi Arguments: none
3461*22dc650dSSadaf Ebrahimi Returns:   nothing (aborts if malloc() fails)
3462*22dc650dSSadaf Ebrahimi */
3463*22dc650dSSadaf Ebrahimi 
3464*22dc650dSSadaf Ebrahimi static void
expand_input_buffers(void)3465*22dc650dSSadaf Ebrahimi expand_input_buffers(void)
3466*22dc650dSSadaf Ebrahimi {
3467*22dc650dSSadaf Ebrahimi int new_pbuffer8_size = 2*pbuffer8_size;
3468*22dc650dSSadaf Ebrahimi uint8_t *new_buffer = (uint8_t *)malloc(new_pbuffer8_size);
3469*22dc650dSSadaf Ebrahimi uint8_t *new_pbuffer8 = (uint8_t *)malloc(new_pbuffer8_size);
3470*22dc650dSSadaf Ebrahimi 
3471*22dc650dSSadaf Ebrahimi if (new_buffer == NULL || new_pbuffer8 == NULL)
3472*22dc650dSSadaf Ebrahimi   {
3473*22dc650dSSadaf Ebrahimi   fprintf(stderr, "pcre2test: malloc(%d) failed\n", new_pbuffer8_size);
3474*22dc650dSSadaf Ebrahimi   exit(1);
3475*22dc650dSSadaf Ebrahimi   }
3476*22dc650dSSadaf Ebrahimi 
3477*22dc650dSSadaf Ebrahimi memcpy(new_buffer, buffer, pbuffer8_size);
3478*22dc650dSSadaf Ebrahimi memcpy(new_pbuffer8, pbuffer8, pbuffer8_size);
3479*22dc650dSSadaf Ebrahimi 
3480*22dc650dSSadaf Ebrahimi pbuffer8_size = new_pbuffer8_size;
3481*22dc650dSSadaf Ebrahimi 
3482*22dc650dSSadaf Ebrahimi free(buffer);
3483*22dc650dSSadaf Ebrahimi free(pbuffer8);
3484*22dc650dSSadaf Ebrahimi 
3485*22dc650dSSadaf Ebrahimi buffer = new_buffer;
3486*22dc650dSSadaf Ebrahimi pbuffer8 = new_pbuffer8;
3487*22dc650dSSadaf Ebrahimi }
3488*22dc650dSSadaf Ebrahimi 
3489*22dc650dSSadaf Ebrahimi 
3490*22dc650dSSadaf Ebrahimi 
3491*22dc650dSSadaf Ebrahimi /*************************************************
3492*22dc650dSSadaf Ebrahimi *        Read or extend an input line            *
3493*22dc650dSSadaf Ebrahimi *************************************************/
3494*22dc650dSSadaf Ebrahimi 
3495*22dc650dSSadaf Ebrahimi /* Input lines are read into buffer, but both patterns and data lines can be
3496*22dc650dSSadaf Ebrahimi continued over multiple input lines. In addition, if the buffer fills up, we
3497*22dc650dSSadaf Ebrahimi want to automatically expand it so as to be able to handle extremely large
3498*22dc650dSSadaf Ebrahimi lines that are needed for certain stress tests, although this is less likely
3499*22dc650dSSadaf Ebrahimi now that there are repetition features for both patterns and data. When the
3500*22dc650dSSadaf Ebrahimi input buffer is expanded, the other two buffers must also be expanded likewise,
3501*22dc650dSSadaf Ebrahimi and the contents of pbuffer, which are a copy of the input for callouts, must
3502*22dc650dSSadaf Ebrahimi be preserved (for when expansion happens for a data line). This is not the most
3503*22dc650dSSadaf Ebrahimi optimal way of handling this, but hey, this is just a test program!
3504*22dc650dSSadaf Ebrahimi 
3505*22dc650dSSadaf Ebrahimi Arguments:
3506*22dc650dSSadaf Ebrahimi   f            the file to read
3507*22dc650dSSadaf Ebrahimi   start        where in buffer to start (this *must* be within buffer)
3508*22dc650dSSadaf Ebrahimi   prompt       for stdin or readline()
3509*22dc650dSSadaf Ebrahimi 
3510*22dc650dSSadaf Ebrahimi Returns:       pointer to the start of new data
3511*22dc650dSSadaf Ebrahimi                could be a copy of start, or could be moved
3512*22dc650dSSadaf Ebrahimi                NULL if no data read and EOF reached
3513*22dc650dSSadaf Ebrahimi */
3514*22dc650dSSadaf Ebrahimi 
3515*22dc650dSSadaf Ebrahimi static uint8_t *
extend_inputline(FILE * f,uint8_t * start,const char * prompt)3516*22dc650dSSadaf Ebrahimi extend_inputline(FILE *f, uint8_t *start, const char *prompt)
3517*22dc650dSSadaf Ebrahimi {
3518*22dc650dSSadaf Ebrahimi uint8_t *here = start;
3519*22dc650dSSadaf Ebrahimi 
3520*22dc650dSSadaf Ebrahimi for (;;)
3521*22dc650dSSadaf Ebrahimi   {
3522*22dc650dSSadaf Ebrahimi   size_t rlen = (size_t)(pbuffer8_size - (here - buffer));
3523*22dc650dSSadaf Ebrahimi 
3524*22dc650dSSadaf Ebrahimi   if (rlen > 1000)
3525*22dc650dSSadaf Ebrahimi     {
3526*22dc650dSSadaf Ebrahimi     size_t dlen;
3527*22dc650dSSadaf Ebrahimi 
3528*22dc650dSSadaf Ebrahimi     /* If libreadline or libedit support is required, use readline() to read a
3529*22dc650dSSadaf Ebrahimi     line if the input is a terminal. Note that readline() removes the trailing
3530*22dc650dSSadaf Ebrahimi     newline, so we must put it back again, to be compatible with fgets(). */
3531*22dc650dSSadaf Ebrahimi 
3532*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
3533*22dc650dSSadaf Ebrahimi     if (INTERACTIVE(f))
3534*22dc650dSSadaf Ebrahimi       {
3535*22dc650dSSadaf Ebrahimi       size_t len;
3536*22dc650dSSadaf Ebrahimi       char *s = readline(prompt);
3537*22dc650dSSadaf Ebrahimi       if (s == NULL) return (here == start)? NULL : start;
3538*22dc650dSSadaf Ebrahimi       len = strlen(s);
3539*22dc650dSSadaf Ebrahimi       if (len > 0) add_history(s);
3540*22dc650dSSadaf Ebrahimi       if (len > rlen - 1) len = rlen - 1;
3541*22dc650dSSadaf Ebrahimi       memcpy(here, s, len);
3542*22dc650dSSadaf Ebrahimi       here[len] = '\n';
3543*22dc650dSSadaf Ebrahimi       here[len+1] = 0;
3544*22dc650dSSadaf Ebrahimi       free(s);
3545*22dc650dSSadaf Ebrahimi       }
3546*22dc650dSSadaf Ebrahimi     else
3547*22dc650dSSadaf Ebrahimi #endif
3548*22dc650dSSadaf Ebrahimi 
3549*22dc650dSSadaf Ebrahimi     /* Read the next line by normal means, prompting if the file is a tty. */
3550*22dc650dSSadaf Ebrahimi 
3551*22dc650dSSadaf Ebrahimi       {
3552*22dc650dSSadaf Ebrahimi       if (INTERACTIVE(f)) printf("%s", prompt);
3553*22dc650dSSadaf Ebrahimi       if (fgets((char *)here, rlen,  f) == NULL)
3554*22dc650dSSadaf Ebrahimi         return (here == start)? NULL : start;
3555*22dc650dSSadaf Ebrahimi       }
3556*22dc650dSSadaf Ebrahimi 
3557*22dc650dSSadaf Ebrahimi     dlen = strlen((char *)here);
3558*22dc650dSSadaf Ebrahimi     here += dlen;
3559*22dc650dSSadaf Ebrahimi 
3560*22dc650dSSadaf Ebrahimi     /* Check for end of line reached. Take care not to read data from before
3561*22dc650dSSadaf Ebrahimi     start (dlen will be zero for a file starting with a binary zero). */
3562*22dc650dSSadaf Ebrahimi 
3563*22dc650dSSadaf Ebrahimi     if (here > start && here[-1] == '\n') return start;
3564*22dc650dSSadaf Ebrahimi 
3565*22dc650dSSadaf Ebrahimi     /* If we have not read a newline when reading a file, we have either filled
3566*22dc650dSSadaf Ebrahimi     the buffer or reached the end of the file. We can detect the former by
3567*22dc650dSSadaf Ebrahimi     checking that the string fills the buffer, and the latter by feof(). If
3568*22dc650dSSadaf Ebrahimi     neither of these is true, it means we read a binary zero which has caused
3569*22dc650dSSadaf Ebrahimi     strlen() to give a short length. This is a hard error because pcre2test
3570*22dc650dSSadaf Ebrahimi     expects to work with C strings. */
3571*22dc650dSSadaf Ebrahimi 
3572*22dc650dSSadaf Ebrahimi     if (!INTERACTIVE(f) && dlen < rlen - 1 && !feof(f))
3573*22dc650dSSadaf Ebrahimi       {
3574*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Binary zero encountered in input\n");
3575*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** pcre2test run abandoned\n");
3576*22dc650dSSadaf Ebrahimi       exit(1);
3577*22dc650dSSadaf Ebrahimi       }
3578*22dc650dSSadaf Ebrahimi     }
3579*22dc650dSSadaf Ebrahimi 
3580*22dc650dSSadaf Ebrahimi   else
3581*22dc650dSSadaf Ebrahimi     {
3582*22dc650dSSadaf Ebrahimi     size_t start_offset = start - buffer;
3583*22dc650dSSadaf Ebrahimi     size_t here_offset = here - buffer;
3584*22dc650dSSadaf Ebrahimi     expand_input_buffers();
3585*22dc650dSSadaf Ebrahimi     start = buffer + start_offset;
3586*22dc650dSSadaf Ebrahimi     here = buffer + here_offset;
3587*22dc650dSSadaf Ebrahimi     }
3588*22dc650dSSadaf Ebrahimi   }
3589*22dc650dSSadaf Ebrahimi 
3590*22dc650dSSadaf Ebrahimi /* Control never gets here */
3591*22dc650dSSadaf Ebrahimi }
3592*22dc650dSSadaf Ebrahimi 
3593*22dc650dSSadaf Ebrahimi 
3594*22dc650dSSadaf Ebrahimi 
3595*22dc650dSSadaf Ebrahimi /*************************************************
3596*22dc650dSSadaf Ebrahimi *         Case-independent strncmp() function    *
3597*22dc650dSSadaf Ebrahimi *************************************************/
3598*22dc650dSSadaf Ebrahimi 
3599*22dc650dSSadaf Ebrahimi /*
3600*22dc650dSSadaf Ebrahimi Arguments:
3601*22dc650dSSadaf Ebrahimi   s         first string
3602*22dc650dSSadaf Ebrahimi   t         second string
3603*22dc650dSSadaf Ebrahimi   n         number of characters to compare
3604*22dc650dSSadaf Ebrahimi 
3605*22dc650dSSadaf Ebrahimi Returns:    < 0, = 0, or > 0, according to the comparison
3606*22dc650dSSadaf Ebrahimi */
3607*22dc650dSSadaf Ebrahimi 
3608*22dc650dSSadaf Ebrahimi static int
strncmpic(const uint8_t * s,const uint8_t * t,int n)3609*22dc650dSSadaf Ebrahimi strncmpic(const uint8_t *s, const uint8_t *t, int n)
3610*22dc650dSSadaf Ebrahimi {
3611*22dc650dSSadaf Ebrahimi while (n--)
3612*22dc650dSSadaf Ebrahimi   {
3613*22dc650dSSadaf Ebrahimi   int c = tolower(*s++) - tolower(*t++);
3614*22dc650dSSadaf Ebrahimi   if (c != 0) return c;
3615*22dc650dSSadaf Ebrahimi   }
3616*22dc650dSSadaf Ebrahimi return 0;
3617*22dc650dSSadaf Ebrahimi }
3618*22dc650dSSadaf Ebrahimi 
3619*22dc650dSSadaf Ebrahimi 
3620*22dc650dSSadaf Ebrahimi 
3621*22dc650dSSadaf Ebrahimi /*************************************************
3622*22dc650dSSadaf Ebrahimi *          Scan the main modifier list           *
3623*22dc650dSSadaf Ebrahimi *************************************************/
3624*22dc650dSSadaf Ebrahimi 
3625*22dc650dSSadaf Ebrahimi /* This function searches the modifier list for a long modifier name.
3626*22dc650dSSadaf Ebrahimi 
3627*22dc650dSSadaf Ebrahimi Argument:
3628*22dc650dSSadaf Ebrahimi   p         start of the name
3629*22dc650dSSadaf Ebrahimi   lenp      length of the name
3630*22dc650dSSadaf Ebrahimi 
3631*22dc650dSSadaf Ebrahimi Returns:    an index in the modifier list, or -1 on failure
3632*22dc650dSSadaf Ebrahimi */
3633*22dc650dSSadaf Ebrahimi 
3634*22dc650dSSadaf Ebrahimi static int
scan_modifiers(const uint8_t * p,unsigned int len)3635*22dc650dSSadaf Ebrahimi scan_modifiers(const uint8_t *p, unsigned int len)
3636*22dc650dSSadaf Ebrahimi {
3637*22dc650dSSadaf Ebrahimi int bot = 0;
3638*22dc650dSSadaf Ebrahimi int top = MODLISTCOUNT;
3639*22dc650dSSadaf Ebrahimi 
3640*22dc650dSSadaf Ebrahimi while (top > bot)
3641*22dc650dSSadaf Ebrahimi   {
3642*22dc650dSSadaf Ebrahimi   int mid = (bot + top)/2;
3643*22dc650dSSadaf Ebrahimi   unsigned int mlen = strlen(modlist[mid].name);
3644*22dc650dSSadaf Ebrahimi   int c = strncmp((char *)p, modlist[mid].name, (len < mlen)? len : mlen);
3645*22dc650dSSadaf Ebrahimi   if (c == 0)
3646*22dc650dSSadaf Ebrahimi     {
3647*22dc650dSSadaf Ebrahimi     if (len == mlen) return mid;
3648*22dc650dSSadaf Ebrahimi     c = (int)len - (int)mlen;
3649*22dc650dSSadaf Ebrahimi     }
3650*22dc650dSSadaf Ebrahimi   if (c > 0) bot = mid + 1; else top = mid;
3651*22dc650dSSadaf Ebrahimi   }
3652*22dc650dSSadaf Ebrahimi 
3653*22dc650dSSadaf Ebrahimi return -1;
3654*22dc650dSSadaf Ebrahimi 
3655*22dc650dSSadaf Ebrahimi }
3656*22dc650dSSadaf Ebrahimi 
3657*22dc650dSSadaf Ebrahimi 
3658*22dc650dSSadaf Ebrahimi 
3659*22dc650dSSadaf Ebrahimi /*************************************************
3660*22dc650dSSadaf Ebrahimi *        Check a modifer and find its field      *
3661*22dc650dSSadaf Ebrahimi *************************************************/
3662*22dc650dSSadaf Ebrahimi 
3663*22dc650dSSadaf Ebrahimi /* This function is called when a modifier has been identified. We check that
3664*22dc650dSSadaf Ebrahimi it is allowed here and find the field that is to be changed.
3665*22dc650dSSadaf Ebrahimi 
3666*22dc650dSSadaf Ebrahimi Arguments:
3667*22dc650dSSadaf Ebrahimi   m          the modifier list entry
3668*22dc650dSSadaf Ebrahimi   ctx        CTX_PAT     => pattern context
3669*22dc650dSSadaf Ebrahimi              CTX_POPPAT  => pattern context for popped pattern
3670*22dc650dSSadaf Ebrahimi              CTX_DEFPAT  => default pattern context
3671*22dc650dSSadaf Ebrahimi              CTX_DAT     => data context
3672*22dc650dSSadaf Ebrahimi              CTX_DEFDAT  => default data context
3673*22dc650dSSadaf Ebrahimi   pctl       point to pattern control block
3674*22dc650dSSadaf Ebrahimi   dctl       point to data control block
3675*22dc650dSSadaf Ebrahimi   c          a single character or 0
3676*22dc650dSSadaf Ebrahimi 
3677*22dc650dSSadaf Ebrahimi Returns:     a field pointer or NULL
3678*22dc650dSSadaf Ebrahimi */
3679*22dc650dSSadaf Ebrahimi 
3680*22dc650dSSadaf Ebrahimi static void *
check_modifier(modstruct * m,int ctx,patctl * pctl,datctl * dctl,uint32_t c)3681*22dc650dSSadaf Ebrahimi check_modifier(modstruct *m, int ctx, patctl *pctl, datctl *dctl, uint32_t c)
3682*22dc650dSSadaf Ebrahimi {
3683*22dc650dSSadaf Ebrahimi void *field = NULL;
3684*22dc650dSSadaf Ebrahimi PCRE2_SIZE offset = m->offset;
3685*22dc650dSSadaf Ebrahimi 
3686*22dc650dSSadaf Ebrahimi if (restrict_for_perl_test) switch(m->which)
3687*22dc650dSSadaf Ebrahimi   {
3688*22dc650dSSadaf Ebrahimi   case MOD_PNDP:
3689*22dc650dSSadaf Ebrahimi   case MOD_PATP:
3690*22dc650dSSadaf Ebrahimi   case MOD_DATP:
3691*22dc650dSSadaf Ebrahimi   case MOD_PDP:
3692*22dc650dSSadaf Ebrahimi   break;
3693*22dc650dSSadaf Ebrahimi 
3694*22dc650dSSadaf Ebrahimi   default:
3695*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** '%s' is not allowed in a Perl-compatible test\n",
3696*22dc650dSSadaf Ebrahimi     m->name);
3697*22dc650dSSadaf Ebrahimi   return NULL;
3698*22dc650dSSadaf Ebrahimi   }
3699*22dc650dSSadaf Ebrahimi 
3700*22dc650dSSadaf Ebrahimi switch (m->which)
3701*22dc650dSSadaf Ebrahimi   {
3702*22dc650dSSadaf Ebrahimi   case MOD_CTC:  /* Compile context modifier */
3703*22dc650dSSadaf Ebrahimi   if (ctx == CTX_DEFPAT) field = PTR(default_pat_context);
3704*22dc650dSSadaf Ebrahimi     else if (ctx == CTX_PAT) field = PTR(pat_context);
3705*22dc650dSSadaf Ebrahimi   break;
3706*22dc650dSSadaf Ebrahimi 
3707*22dc650dSSadaf Ebrahimi   case MOD_CTM:  /* Match context modifier */
3708*22dc650dSSadaf Ebrahimi   if (ctx == CTX_DEFDAT) field = PTR(default_dat_context);
3709*22dc650dSSadaf Ebrahimi     else if (ctx == CTX_DAT) field = PTR(dat_context);
3710*22dc650dSSadaf Ebrahimi   break;
3711*22dc650dSSadaf Ebrahimi 
3712*22dc650dSSadaf Ebrahimi   case MOD_DAT:    /* Data line modifier */
3713*22dc650dSSadaf Ebrahimi   case MOD_DATP:   /* Allowed for Perl test */
3714*22dc650dSSadaf Ebrahimi   if (dctl != NULL) field = dctl;
3715*22dc650dSSadaf Ebrahimi   break;
3716*22dc650dSSadaf Ebrahimi 
3717*22dc650dSSadaf Ebrahimi   case MOD_PAT:    /* Pattern modifier */
3718*22dc650dSSadaf Ebrahimi   case MOD_PATP:   /* Allowed for Perl test */
3719*22dc650dSSadaf Ebrahimi   if (pctl != NULL) field = pctl;
3720*22dc650dSSadaf Ebrahimi   break;
3721*22dc650dSSadaf Ebrahimi 
3722*22dc650dSSadaf Ebrahimi   case MOD_PD:   /* Pattern or data line modifier */
3723*22dc650dSSadaf Ebrahimi   case MOD_PDP:  /* Ditto, allowed for Perl test */
3724*22dc650dSSadaf Ebrahimi   case MOD_PND:  /* Ditto, but not default pattern */
3725*22dc650dSSadaf Ebrahimi   case MOD_PNDP: /* Ditto, allowed for Perl test */
3726*22dc650dSSadaf Ebrahimi   if (dctl != NULL) field = dctl;
3727*22dc650dSSadaf Ebrahimi     else if (pctl != NULL && (m->which == MOD_PD || m->which == MOD_PDP ||
3728*22dc650dSSadaf Ebrahimi              ctx != CTX_DEFPAT))
3729*22dc650dSSadaf Ebrahimi       field = pctl;
3730*22dc650dSSadaf Ebrahimi   break;
3731*22dc650dSSadaf Ebrahimi   }
3732*22dc650dSSadaf Ebrahimi 
3733*22dc650dSSadaf Ebrahimi if (field == NULL)
3734*22dc650dSSadaf Ebrahimi   {
3735*22dc650dSSadaf Ebrahimi   if (c == 0)
3736*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** '%s' is not valid here\n", m->name);
3737*22dc650dSSadaf Ebrahimi   else
3738*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** /%c is not valid here\n", c);
3739*22dc650dSSadaf Ebrahimi   return NULL;
3740*22dc650dSSadaf Ebrahimi   }
3741*22dc650dSSadaf Ebrahimi 
3742*22dc650dSSadaf Ebrahimi return (char *)field + offset;
3743*22dc650dSSadaf Ebrahimi }
3744*22dc650dSSadaf Ebrahimi 
3745*22dc650dSSadaf Ebrahimi 
3746*22dc650dSSadaf Ebrahimi 
3747*22dc650dSSadaf Ebrahimi /*************************************************
3748*22dc650dSSadaf Ebrahimi *            Decode a modifier list              *
3749*22dc650dSSadaf Ebrahimi *************************************************/
3750*22dc650dSSadaf Ebrahimi 
3751*22dc650dSSadaf Ebrahimi /* A pointer to a control block is NULL when called in cases when that block is
3752*22dc650dSSadaf Ebrahimi not relevant. They are never all relevant in one call. At least one of patctl
3753*22dc650dSSadaf Ebrahimi and datctl is NULL. The second argument specifies which context to use for
3754*22dc650dSSadaf Ebrahimi modifiers that apply to contexts.
3755*22dc650dSSadaf Ebrahimi 
3756*22dc650dSSadaf Ebrahimi Arguments:
3757*22dc650dSSadaf Ebrahimi   p          point to modifier string
3758*22dc650dSSadaf Ebrahimi   ctx        CTX_PAT     => pattern context
3759*22dc650dSSadaf Ebrahimi              CTX_POPPAT  => pattern context for popped pattern
3760*22dc650dSSadaf Ebrahimi              CTX_DEFPAT  => default pattern context
3761*22dc650dSSadaf Ebrahimi              CTX_DAT     => data context
3762*22dc650dSSadaf Ebrahimi              CTX_DEFDAT  => default data context
3763*22dc650dSSadaf Ebrahimi   pctl       point to pattern control block
3764*22dc650dSSadaf Ebrahimi   dctl       point to data control block
3765*22dc650dSSadaf Ebrahimi 
3766*22dc650dSSadaf Ebrahimi Returns: TRUE if successful decode, FALSE otherwise
3767*22dc650dSSadaf Ebrahimi */
3768*22dc650dSSadaf Ebrahimi 
3769*22dc650dSSadaf Ebrahimi static BOOL
decode_modifiers(uint8_t * p,int ctx,patctl * pctl,datctl * dctl)3770*22dc650dSSadaf Ebrahimi decode_modifiers(uint8_t *p, int ctx, patctl *pctl, datctl *dctl)
3771*22dc650dSSadaf Ebrahimi {
3772*22dc650dSSadaf Ebrahimi uint8_t *ep, *pp;
3773*22dc650dSSadaf Ebrahimi long li;
3774*22dc650dSSadaf Ebrahimi unsigned long uli;
3775*22dc650dSSadaf Ebrahimi BOOL first = TRUE;
3776*22dc650dSSadaf Ebrahimi 
3777*22dc650dSSadaf Ebrahimi for (;;)
3778*22dc650dSSadaf Ebrahimi   {
3779*22dc650dSSadaf Ebrahimi   void *field;
3780*22dc650dSSadaf Ebrahimi   modstruct *m;
3781*22dc650dSSadaf Ebrahimi   BOOL off = FALSE;
3782*22dc650dSSadaf Ebrahimi   unsigned int i, len;
3783*22dc650dSSadaf Ebrahimi   int index;
3784*22dc650dSSadaf Ebrahimi   char *endptr;
3785*22dc650dSSadaf Ebrahimi 
3786*22dc650dSSadaf Ebrahimi   /* Skip white space and commas. */
3787*22dc650dSSadaf Ebrahimi 
3788*22dc650dSSadaf Ebrahimi   while (isspace(*p) || *p == ',') p++;
3789*22dc650dSSadaf Ebrahimi   if (*p == 0) break;
3790*22dc650dSSadaf Ebrahimi 
3791*22dc650dSSadaf Ebrahimi   /* Find the end of the item; lose trailing whitespace at end of line. */
3792*22dc650dSSadaf Ebrahimi 
3793*22dc650dSSadaf Ebrahimi   for (ep = p; *ep != 0 && *ep != ','; ep++);
3794*22dc650dSSadaf Ebrahimi   if (*ep == 0)
3795*22dc650dSSadaf Ebrahimi     {
3796*22dc650dSSadaf Ebrahimi     while (ep > p && isspace(ep[-1])) ep--;
3797*22dc650dSSadaf Ebrahimi     *ep = 0;
3798*22dc650dSSadaf Ebrahimi     }
3799*22dc650dSSadaf Ebrahimi 
3800*22dc650dSSadaf Ebrahimi   /* Remember if the first character is '-'. */
3801*22dc650dSSadaf Ebrahimi 
3802*22dc650dSSadaf Ebrahimi   if (*p == '-')
3803*22dc650dSSadaf Ebrahimi     {
3804*22dc650dSSadaf Ebrahimi     off = TRUE;
3805*22dc650dSSadaf Ebrahimi     p++;
3806*22dc650dSSadaf Ebrahimi     }
3807*22dc650dSSadaf Ebrahimi 
3808*22dc650dSSadaf Ebrahimi   /* Find the length of a full-length modifier name, and scan for it. */
3809*22dc650dSSadaf Ebrahimi 
3810*22dc650dSSadaf Ebrahimi   pp = p;
3811*22dc650dSSadaf Ebrahimi   while (pp < ep && *pp != '=') pp++;
3812*22dc650dSSadaf Ebrahimi   index = scan_modifiers(p, pp - p);
3813*22dc650dSSadaf Ebrahimi 
3814*22dc650dSSadaf Ebrahimi   /* If the first modifier is unrecognized, try to interpret it as a sequence
3815*22dc650dSSadaf Ebrahimi   of single-character abbreviated modifiers. None of these modifiers have any
3816*22dc650dSSadaf Ebrahimi   associated data. They just set options or control bits. */
3817*22dc650dSSadaf Ebrahimi 
3818*22dc650dSSadaf Ebrahimi   if (index < 0)
3819*22dc650dSSadaf Ebrahimi     {
3820*22dc650dSSadaf Ebrahimi     uint32_t cc;
3821*22dc650dSSadaf Ebrahimi     uint8_t *mp = p;
3822*22dc650dSSadaf Ebrahimi 
3823*22dc650dSSadaf Ebrahimi     if (!first)
3824*22dc650dSSadaf Ebrahimi       {
3825*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p);
3826*22dc650dSSadaf Ebrahimi       if (ep - p == 1)
3827*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Single-character modifiers must come first\n");
3828*22dc650dSSadaf Ebrahimi       return FALSE;
3829*22dc650dSSadaf Ebrahimi       }
3830*22dc650dSSadaf Ebrahimi 
3831*22dc650dSSadaf Ebrahimi     for (cc = *p; cc != ',' && cc != '\n' && cc != 0; cc = *(++p))
3832*22dc650dSSadaf Ebrahimi       {
3833*22dc650dSSadaf Ebrahimi       for (i = 0; i < C1MODLISTCOUNT; i++)
3834*22dc650dSSadaf Ebrahimi         if (cc == c1modlist[i].onechar) break;
3835*22dc650dSSadaf Ebrahimi 
3836*22dc650dSSadaf Ebrahimi       if (i >= C1MODLISTCOUNT)
3837*22dc650dSSadaf Ebrahimi         {
3838*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Unrecognized modifier '%c' in '%.*s'\n",
3839*22dc650dSSadaf Ebrahimi           *p, (int)(ep-mp), mp);
3840*22dc650dSSadaf Ebrahimi         return FALSE;
3841*22dc650dSSadaf Ebrahimi         }
3842*22dc650dSSadaf Ebrahimi 
3843*22dc650dSSadaf Ebrahimi       if (c1modlist[i].index >= 0)
3844*22dc650dSSadaf Ebrahimi         {
3845*22dc650dSSadaf Ebrahimi         index = c1modlist[i].index;
3846*22dc650dSSadaf Ebrahimi         }
3847*22dc650dSSadaf Ebrahimi 
3848*22dc650dSSadaf Ebrahimi       else
3849*22dc650dSSadaf Ebrahimi         {
3850*22dc650dSSadaf Ebrahimi         index = scan_modifiers((uint8_t *)(c1modlist[i].fullname),
3851*22dc650dSSadaf Ebrahimi           strlen(c1modlist[i].fullname));
3852*22dc650dSSadaf Ebrahimi         if (index < 0)
3853*22dc650dSSadaf Ebrahimi           {
3854*22dc650dSSadaf Ebrahimi           fprintf(outfile, "** Internal error: single-character equivalent "
3855*22dc650dSSadaf Ebrahimi             "modifier '%s' not found\n", c1modlist[i].fullname);
3856*22dc650dSSadaf Ebrahimi           return FALSE;
3857*22dc650dSSadaf Ebrahimi           }
3858*22dc650dSSadaf Ebrahimi         c1modlist[i].index = index;     /* Cache for next time */
3859*22dc650dSSadaf Ebrahimi         }
3860*22dc650dSSadaf Ebrahimi 
3861*22dc650dSSadaf Ebrahimi       field = check_modifier(modlist + index, ctx, pctl, dctl, *p);
3862*22dc650dSSadaf Ebrahimi       if (field == NULL) return FALSE;
3863*22dc650dSSadaf Ebrahimi 
3864*22dc650dSSadaf Ebrahimi       /* /x is a special case; a second appearance changes PCRE2_EXTENDED to
3865*22dc650dSSadaf Ebrahimi       PCRE2_EXTENDED_MORE. */
3866*22dc650dSSadaf Ebrahimi 
3867*22dc650dSSadaf Ebrahimi       if (cc == 'x' && (*((uint32_t *)field) & PCRE2_EXTENDED) != 0)
3868*22dc650dSSadaf Ebrahimi         {
3869*22dc650dSSadaf Ebrahimi         *((uint32_t *)field) &= ~PCRE2_EXTENDED;
3870*22dc650dSSadaf Ebrahimi         *((uint32_t *)field) |= PCRE2_EXTENDED_MORE;
3871*22dc650dSSadaf Ebrahimi         }
3872*22dc650dSSadaf Ebrahimi       else
3873*22dc650dSSadaf Ebrahimi         *((uint32_t *)field) |= modlist[index].value;
3874*22dc650dSSadaf Ebrahimi       }
3875*22dc650dSSadaf Ebrahimi 
3876*22dc650dSSadaf Ebrahimi     continue;    /* With tne next (fullname) modifier */
3877*22dc650dSSadaf Ebrahimi     }
3878*22dc650dSSadaf Ebrahimi 
3879*22dc650dSSadaf Ebrahimi   /* We have a match on a full-name modifier. Check for the existence of data
3880*22dc650dSSadaf Ebrahimi   when needed. */
3881*22dc650dSSadaf Ebrahimi 
3882*22dc650dSSadaf Ebrahimi   m = modlist + index;      /* Save typing */
3883*22dc650dSSadaf Ebrahimi   if (m->type != MOD_CTL && m->type != MOD_OPT &&
3884*22dc650dSSadaf Ebrahimi       (m->type != MOD_IND || *pp == '='))
3885*22dc650dSSadaf Ebrahimi     {
3886*22dc650dSSadaf Ebrahimi     if (*pp++ != '=')
3887*22dc650dSSadaf Ebrahimi       {
3888*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** '=' expected after '%s'\n", m->name);
3889*22dc650dSSadaf Ebrahimi       return FALSE;
3890*22dc650dSSadaf Ebrahimi       }
3891*22dc650dSSadaf Ebrahimi     if (off)
3892*22dc650dSSadaf Ebrahimi       {
3893*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** '-' is not valid for '%s'\n", m->name);
3894*22dc650dSSadaf Ebrahimi       return FALSE;
3895*22dc650dSSadaf Ebrahimi       }
3896*22dc650dSSadaf Ebrahimi     }
3897*22dc650dSSadaf Ebrahimi 
3898*22dc650dSSadaf Ebrahimi   /* These on/off types have no data. */
3899*22dc650dSSadaf Ebrahimi 
3900*22dc650dSSadaf Ebrahimi   else if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0)
3901*22dc650dSSadaf Ebrahimi     {
3902*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p);
3903*22dc650dSSadaf Ebrahimi     return FALSE;
3904*22dc650dSSadaf Ebrahimi     }
3905*22dc650dSSadaf Ebrahimi 
3906*22dc650dSSadaf Ebrahimi   /* Set the data length for those types that have data. Then find the field
3907*22dc650dSSadaf Ebrahimi   that is to be set. If check_modifier() returns NULL, it has already output an
3908*22dc650dSSadaf Ebrahimi   error message. */
3909*22dc650dSSadaf Ebrahimi 
3910*22dc650dSSadaf Ebrahimi   len = ep - pp;
3911*22dc650dSSadaf Ebrahimi   field = check_modifier(m, ctx, pctl, dctl, 0);
3912*22dc650dSSadaf Ebrahimi   if (field == NULL) return FALSE;
3913*22dc650dSSadaf Ebrahimi 
3914*22dc650dSSadaf Ebrahimi   /* Process according to data type. */
3915*22dc650dSSadaf Ebrahimi 
3916*22dc650dSSadaf Ebrahimi   switch (m->type)
3917*22dc650dSSadaf Ebrahimi     {
3918*22dc650dSSadaf Ebrahimi     case MOD_CTL:
3919*22dc650dSSadaf Ebrahimi     case MOD_OPT:
3920*22dc650dSSadaf Ebrahimi     if (off) *((uint32_t *)field) &= ~m->value;
3921*22dc650dSSadaf Ebrahimi       else *((uint32_t *)field) |= m->value;
3922*22dc650dSSadaf Ebrahimi     break;
3923*22dc650dSSadaf Ebrahimi 
3924*22dc650dSSadaf Ebrahimi     case MOD_BSR:
3925*22dc650dSSadaf Ebrahimi     if (len == 7 && strncmpic(pp, (const uint8_t *)"default", 7) == 0)
3926*22dc650dSSadaf Ebrahimi       {
3927*22dc650dSSadaf Ebrahimi #ifdef BSR_ANYCRLF
3928*22dc650dSSadaf Ebrahimi       *((uint16_t *)field) = PCRE2_BSR_ANYCRLF;
3929*22dc650dSSadaf Ebrahimi #else
3930*22dc650dSSadaf Ebrahimi       *((uint16_t *)field) = PCRE2_BSR_UNICODE;
3931*22dc650dSSadaf Ebrahimi #endif
3932*22dc650dSSadaf Ebrahimi       if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 &= ~CTL2_BSR_SET;
3933*22dc650dSSadaf Ebrahimi         else dctl->control2 &= ~CTL2_BSR_SET;
3934*22dc650dSSadaf Ebrahimi       }
3935*22dc650dSSadaf Ebrahimi     else
3936*22dc650dSSadaf Ebrahimi       {
3937*22dc650dSSadaf Ebrahimi       if (len == 7 && strncmpic(pp, (const uint8_t *)"anycrlf", 7) == 0)
3938*22dc650dSSadaf Ebrahimi         *((uint16_t *)field) = PCRE2_BSR_ANYCRLF;
3939*22dc650dSSadaf Ebrahimi       else if (len == 7 && strncmpic(pp, (const uint8_t *)"unicode", 7) == 0)
3940*22dc650dSSadaf Ebrahimi         *((uint16_t *)field) = PCRE2_BSR_UNICODE;
3941*22dc650dSSadaf Ebrahimi       else goto INVALID_VALUE;
3942*22dc650dSSadaf Ebrahimi       if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 |= CTL2_BSR_SET;
3943*22dc650dSSadaf Ebrahimi         else dctl->control2 |= CTL2_BSR_SET;
3944*22dc650dSSadaf Ebrahimi       }
3945*22dc650dSSadaf Ebrahimi     pp = ep;
3946*22dc650dSSadaf Ebrahimi     break;
3947*22dc650dSSadaf Ebrahimi 
3948*22dc650dSSadaf Ebrahimi     case MOD_CHR:  /* A single character */
3949*22dc650dSSadaf Ebrahimi     *((uint32_t *)field) = *pp++;
3950*22dc650dSSadaf Ebrahimi     break;
3951*22dc650dSSadaf Ebrahimi 
3952*22dc650dSSadaf Ebrahimi     case MOD_CON:  /* A convert type/options list */
3953*22dc650dSSadaf Ebrahimi     for (;; pp++)
3954*22dc650dSSadaf Ebrahimi       {
3955*22dc650dSSadaf Ebrahimi       uint8_t *colon = (uint8_t *)strchr((const char *)pp, ':');
3956*22dc650dSSadaf Ebrahimi       len = ((colon != NULL && colon < ep)? colon:ep) - pp;
3957*22dc650dSSadaf Ebrahimi       for (i = 0; i < convertlistcount; i++)
3958*22dc650dSSadaf Ebrahimi         {
3959*22dc650dSSadaf Ebrahimi         if (strncmpic(pp, (const uint8_t *)convertlist[i].name, len) == 0)
3960*22dc650dSSadaf Ebrahimi           {
3961*22dc650dSSadaf Ebrahimi           if (*((uint32_t *)field) == CONVERT_UNSET)
3962*22dc650dSSadaf Ebrahimi             *((uint32_t *)field) = convertlist[i].option;
3963*22dc650dSSadaf Ebrahimi           else
3964*22dc650dSSadaf Ebrahimi             *((uint32_t *)field) |= convertlist[i].option;
3965*22dc650dSSadaf Ebrahimi           break;
3966*22dc650dSSadaf Ebrahimi           }
3967*22dc650dSSadaf Ebrahimi         }
3968*22dc650dSSadaf Ebrahimi       if (i >= convertlistcount) goto INVALID_VALUE;
3969*22dc650dSSadaf Ebrahimi       pp += len;
3970*22dc650dSSadaf Ebrahimi       if (*pp != ':') break;
3971*22dc650dSSadaf Ebrahimi       }
3972*22dc650dSSadaf Ebrahimi     break;
3973*22dc650dSSadaf Ebrahimi 
3974*22dc650dSSadaf Ebrahimi     case MOD_IN2:    /* One or two unsigned integers */
3975*22dc650dSSadaf Ebrahimi     if (!isdigit(*pp)) goto INVALID_VALUE;
3976*22dc650dSSadaf Ebrahimi     uli = strtoul((const char *)pp, &endptr, 10);
3977*22dc650dSSadaf Ebrahimi     if (U32OVERFLOW(uli)) goto INVALID_VALUE;
3978*22dc650dSSadaf Ebrahimi     ((uint32_t *)field)[0] = (uint32_t)uli;
3979*22dc650dSSadaf Ebrahimi     if (*endptr == ':')
3980*22dc650dSSadaf Ebrahimi       {
3981*22dc650dSSadaf Ebrahimi       uli = strtoul((const char *)endptr+1, &endptr, 10);
3982*22dc650dSSadaf Ebrahimi       if (U32OVERFLOW(uli)) goto INVALID_VALUE;
3983*22dc650dSSadaf Ebrahimi       ((uint32_t *)field)[1] = (uint32_t)uli;
3984*22dc650dSSadaf Ebrahimi       }
3985*22dc650dSSadaf Ebrahimi     else ((uint32_t *)field)[1] = 0;
3986*22dc650dSSadaf Ebrahimi     pp = (uint8_t *)endptr;
3987*22dc650dSSadaf Ebrahimi     break;
3988*22dc650dSSadaf Ebrahimi 
3989*22dc650dSSadaf Ebrahimi     /* PCRE2_SIZE_MAX is usually SIZE_MAX, which may be greater, equal to, or
3990*22dc650dSSadaf Ebrahimi     less than ULONG_MAX. So first test for overflowing the long int, and then
3991*22dc650dSSadaf Ebrahimi     test for overflowing PCRE2_SIZE_MAX if it is smaller than ULONG_MAX. */
3992*22dc650dSSadaf Ebrahimi 
3993*22dc650dSSadaf Ebrahimi     case MOD_SIZ:    /* PCRE2_SIZE value */
3994*22dc650dSSadaf Ebrahimi     if (!isdigit(*pp)) goto INVALID_VALUE;
3995*22dc650dSSadaf Ebrahimi     uli = strtoul((const char *)pp, &endptr, 10);
3996*22dc650dSSadaf Ebrahimi     if (uli == ULONG_MAX) goto INVALID_VALUE;
3997*22dc650dSSadaf Ebrahimi #if ULONG_MAX > PCRE2_SIZE_MAX
3998*22dc650dSSadaf Ebrahimi     if (uli > PCRE2_SIZE_MAX) goto INVALID_VALUE;
3999*22dc650dSSadaf Ebrahimi #endif
4000*22dc650dSSadaf Ebrahimi     *((PCRE2_SIZE *)field) = (PCRE2_SIZE)uli;
4001*22dc650dSSadaf Ebrahimi     pp = (uint8_t *)endptr;
4002*22dc650dSSadaf Ebrahimi     break;
4003*22dc650dSSadaf Ebrahimi 
4004*22dc650dSSadaf Ebrahimi     case MOD_IND:    /* Unsigned integer with default */
4005*22dc650dSSadaf Ebrahimi     if (len == 0)
4006*22dc650dSSadaf Ebrahimi       {
4007*22dc650dSSadaf Ebrahimi       *((uint32_t *)field) = (uint32_t)(m->value);
4008*22dc650dSSadaf Ebrahimi       break;
4009*22dc650dSSadaf Ebrahimi       }
4010*22dc650dSSadaf Ebrahimi     /* Fall through */
4011*22dc650dSSadaf Ebrahimi 
4012*22dc650dSSadaf Ebrahimi     case MOD_INT:    /* Unsigned integer */
4013*22dc650dSSadaf Ebrahimi     if (!isdigit(*pp)) goto INVALID_VALUE;
4014*22dc650dSSadaf Ebrahimi     uli = strtoul((const char *)pp, &endptr, 10);
4015*22dc650dSSadaf Ebrahimi     if (U32OVERFLOW(uli)) goto INVALID_VALUE;
4016*22dc650dSSadaf Ebrahimi     *((uint32_t *)field) = (uint32_t)uli;
4017*22dc650dSSadaf Ebrahimi     pp = (uint8_t *)endptr;
4018*22dc650dSSadaf Ebrahimi     break;
4019*22dc650dSSadaf Ebrahimi 
4020*22dc650dSSadaf Ebrahimi     case MOD_INS:   /* Signed integer */
4021*22dc650dSSadaf Ebrahimi     if (!isdigit(*pp) && *pp != '-') goto INVALID_VALUE;
4022*22dc650dSSadaf Ebrahimi     li = strtol((const char *)pp, &endptr, 10);
4023*22dc650dSSadaf Ebrahimi     if (S32OVERFLOW(li)) goto INVALID_VALUE;
4024*22dc650dSSadaf Ebrahimi     *((int32_t *)field) = (int32_t)li;
4025*22dc650dSSadaf Ebrahimi     pp = (uint8_t *)endptr;
4026*22dc650dSSadaf Ebrahimi     break;
4027*22dc650dSSadaf Ebrahimi 
4028*22dc650dSSadaf Ebrahimi     case MOD_NL:
4029*22dc650dSSadaf Ebrahimi     for (i = 0; i < sizeof(newlines)/sizeof(char *); i++)
4030*22dc650dSSadaf Ebrahimi       if (len == strlen(newlines[i]) &&
4031*22dc650dSSadaf Ebrahimi         strncmpic(pp, (const uint8_t *)newlines[i], len) == 0) break;
4032*22dc650dSSadaf Ebrahimi     if (i >= sizeof(newlines)/sizeof(char *)) goto INVALID_VALUE;
4033*22dc650dSSadaf Ebrahimi     if (i == 0)
4034*22dc650dSSadaf Ebrahimi       {
4035*22dc650dSSadaf Ebrahimi       *((uint16_t *)field) = NEWLINE_DEFAULT;
4036*22dc650dSSadaf Ebrahimi       if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 &= ~CTL2_NL_SET;
4037*22dc650dSSadaf Ebrahimi         else dctl->control2 &= ~CTL2_NL_SET;
4038*22dc650dSSadaf Ebrahimi       }
4039*22dc650dSSadaf Ebrahimi     else
4040*22dc650dSSadaf Ebrahimi       {
4041*22dc650dSSadaf Ebrahimi       *((uint16_t *)field) = i;
4042*22dc650dSSadaf Ebrahimi       if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 |= CTL2_NL_SET;
4043*22dc650dSSadaf Ebrahimi         else dctl->control2 |= CTL2_NL_SET;
4044*22dc650dSSadaf Ebrahimi       }
4045*22dc650dSSadaf Ebrahimi     pp = ep;
4046*22dc650dSSadaf Ebrahimi     break;
4047*22dc650dSSadaf Ebrahimi 
4048*22dc650dSSadaf Ebrahimi     case MOD_NN:              /* Name or (signed) number; may be several */
4049*22dc650dSSadaf Ebrahimi     if (isdigit(*pp) || *pp == '-')
4050*22dc650dSSadaf Ebrahimi       {
4051*22dc650dSSadaf Ebrahimi       int ct = MAXCPYGET - 1;
4052*22dc650dSSadaf Ebrahimi       int32_t value;
4053*22dc650dSSadaf Ebrahimi       li = strtol((const char *)pp, &endptr, 10);
4054*22dc650dSSadaf Ebrahimi       if (S32OVERFLOW(li)) goto INVALID_VALUE;
4055*22dc650dSSadaf Ebrahimi       value = (int32_t)li;
4056*22dc650dSSadaf Ebrahimi       field = (char *)field - m->offset + m->value;      /* Adjust field ptr */
4057*22dc650dSSadaf Ebrahimi       if (value >= 0)                                    /* Add new number */
4058*22dc650dSSadaf Ebrahimi         {
4059*22dc650dSSadaf Ebrahimi         while (*((int32_t *)field) >= 0 && ct-- > 0)   /* Skip previous */
4060*22dc650dSSadaf Ebrahimi           field = (char *)field + sizeof(int32_t);
4061*22dc650dSSadaf Ebrahimi         if (ct <= 0)
4062*22dc650dSSadaf Ebrahimi           {
4063*22dc650dSSadaf Ebrahimi           fprintf(outfile, "** Too many numeric '%s' modifiers\n", m->name);
4064*22dc650dSSadaf Ebrahimi           return FALSE;
4065*22dc650dSSadaf Ebrahimi           }
4066*22dc650dSSadaf Ebrahimi         }
4067*22dc650dSSadaf Ebrahimi       *((int32_t *)field) = value;
4068*22dc650dSSadaf Ebrahimi       if (ct > 0) ((int32_t *)field)[1] = -1;
4069*22dc650dSSadaf Ebrahimi       pp = (uint8_t *)endptr;
4070*22dc650dSSadaf Ebrahimi       }
4071*22dc650dSSadaf Ebrahimi 
4072*22dc650dSSadaf Ebrahimi     /* Multiple strings are put end to end. */
4073*22dc650dSSadaf Ebrahimi 
4074*22dc650dSSadaf Ebrahimi     else
4075*22dc650dSSadaf Ebrahimi       {
4076*22dc650dSSadaf Ebrahimi       char *nn = (char *)field;
4077*22dc650dSSadaf Ebrahimi       if (len > 0)                    /* Add new name */
4078*22dc650dSSadaf Ebrahimi         {
4079*22dc650dSSadaf Ebrahimi         if (len > MAX_NAME_SIZE)
4080*22dc650dSSadaf Ebrahimi           {
4081*22dc650dSSadaf Ebrahimi           fprintf(outfile, "** Group name in '%s' is too long\n", m->name);
4082*22dc650dSSadaf Ebrahimi           return FALSE;
4083*22dc650dSSadaf Ebrahimi           }
4084*22dc650dSSadaf Ebrahimi         while (*nn != 0) nn += strlen(nn) + 1;
4085*22dc650dSSadaf Ebrahimi         if (nn + len + 2 - (char *)field > LENCPYGET)
4086*22dc650dSSadaf Ebrahimi           {
4087*22dc650dSSadaf Ebrahimi           fprintf(outfile, "** Too many characters in named '%s' modifiers\n",
4088*22dc650dSSadaf Ebrahimi             m->name);
4089*22dc650dSSadaf Ebrahimi           return FALSE;
4090*22dc650dSSadaf Ebrahimi           }
4091*22dc650dSSadaf Ebrahimi         memcpy(nn, pp, len);
4092*22dc650dSSadaf Ebrahimi         }
4093*22dc650dSSadaf Ebrahimi       nn[len] = 0 ;
4094*22dc650dSSadaf Ebrahimi       nn[len+1] = 0;
4095*22dc650dSSadaf Ebrahimi       pp = ep;
4096*22dc650dSSadaf Ebrahimi       }
4097*22dc650dSSadaf Ebrahimi     break;
4098*22dc650dSSadaf Ebrahimi 
4099*22dc650dSSadaf Ebrahimi     case MOD_STR:
4100*22dc650dSSadaf Ebrahimi     if (len + 1 > m->value)
4101*22dc650dSSadaf Ebrahimi       {
4102*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Overlong value for '%s' (max %d code units)\n",
4103*22dc650dSSadaf Ebrahimi         m->name, m->value - 1);
4104*22dc650dSSadaf Ebrahimi       return FALSE;
4105*22dc650dSSadaf Ebrahimi       }
4106*22dc650dSSadaf Ebrahimi     memcpy(field, pp, len);
4107*22dc650dSSadaf Ebrahimi     ((uint8_t *)field)[len] = 0;
4108*22dc650dSSadaf Ebrahimi     pp = ep;
4109*22dc650dSSadaf Ebrahimi     break;
4110*22dc650dSSadaf Ebrahimi     }
4111*22dc650dSSadaf Ebrahimi 
4112*22dc650dSSadaf Ebrahimi   if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0)
4113*22dc650dSSadaf Ebrahimi     {
4114*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Comma expected after modifier item '%s'\n", m->name);
4115*22dc650dSSadaf Ebrahimi     return FALSE;
4116*22dc650dSSadaf Ebrahimi     }
4117*22dc650dSSadaf Ebrahimi 
4118*22dc650dSSadaf Ebrahimi   p = pp;
4119*22dc650dSSadaf Ebrahimi   first = FALSE;
4120*22dc650dSSadaf Ebrahimi 
4121*22dc650dSSadaf Ebrahimi   if (ctx == CTX_POPPAT &&
4122*22dc650dSSadaf Ebrahimi      (pctl->options != 0 ||
4123*22dc650dSSadaf Ebrahimi       pctl->tables_id != 0 ||
4124*22dc650dSSadaf Ebrahimi       pctl->locale[0] != 0 ||
4125*22dc650dSSadaf Ebrahimi       (pctl->control & NOTPOP_CONTROLS) != 0))
4126*22dc650dSSadaf Ebrahimi     {
4127*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** '%s' is not valid here\n", m->name);
4128*22dc650dSSadaf Ebrahimi     return FALSE;
4129*22dc650dSSadaf Ebrahimi     }
4130*22dc650dSSadaf Ebrahimi   }
4131*22dc650dSSadaf Ebrahimi 
4132*22dc650dSSadaf Ebrahimi return TRUE;
4133*22dc650dSSadaf Ebrahimi 
4134*22dc650dSSadaf Ebrahimi INVALID_VALUE:
4135*22dc650dSSadaf Ebrahimi fprintf(outfile, "** Invalid value in '%.*s'\n", (int)(ep-p), p);
4136*22dc650dSSadaf Ebrahimi return FALSE;
4137*22dc650dSSadaf Ebrahimi }
4138*22dc650dSSadaf Ebrahimi 
4139*22dc650dSSadaf Ebrahimi 
4140*22dc650dSSadaf Ebrahimi /*************************************************
4141*22dc650dSSadaf Ebrahimi *             Get info from a pattern            *
4142*22dc650dSSadaf Ebrahimi *************************************************/
4143*22dc650dSSadaf Ebrahimi 
4144*22dc650dSSadaf Ebrahimi /* A wrapped call to pcre2_pattern_info(), applied to the current compiled
4145*22dc650dSSadaf Ebrahimi pattern.
4146*22dc650dSSadaf Ebrahimi 
4147*22dc650dSSadaf Ebrahimi Arguments:
4148*22dc650dSSadaf Ebrahimi   what        code for the required information
4149*22dc650dSSadaf Ebrahimi   where       where to put the answer
4150*22dc650dSSadaf Ebrahimi   unsetok     PCRE2_ERROR_UNSET is an "expected" result
4151*22dc650dSSadaf Ebrahimi 
4152*22dc650dSSadaf Ebrahimi Returns:      the return from pcre2_pattern_info()
4153*22dc650dSSadaf Ebrahimi */
4154*22dc650dSSadaf Ebrahimi 
4155*22dc650dSSadaf Ebrahimi static int
pattern_info(int what,void * where,BOOL unsetok)4156*22dc650dSSadaf Ebrahimi pattern_info(int what, void *where, BOOL unsetok)
4157*22dc650dSSadaf Ebrahimi {
4158*22dc650dSSadaf Ebrahimi int rc;
4159*22dc650dSSadaf Ebrahimi PCRE2_PATTERN_INFO(rc, compiled_code, what, NULL);  /* Exercise the code */
4160*22dc650dSSadaf Ebrahimi PCRE2_PATTERN_INFO(rc, compiled_code, what, where);
4161*22dc650dSSadaf Ebrahimi if (rc >= 0) return 0;
4162*22dc650dSSadaf Ebrahimi if (rc != PCRE2_ERROR_UNSET || !unsetok)
4163*22dc650dSSadaf Ebrahimi   {
4164*22dc650dSSadaf Ebrahimi   fprintf(outfile, "Error %d from pcre2_pattern_info_%d(%d)\n", rc, test_mode,
4165*22dc650dSSadaf Ebrahimi     what);
4166*22dc650dSSadaf Ebrahimi   if (rc == PCRE2_ERROR_BADMODE)
4167*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Running in %d-bit mode but pattern was compiled in "
4168*22dc650dSSadaf Ebrahimi       "%d-bit mode\n", test_mode,
4169*22dc650dSSadaf Ebrahimi       8 * (FLD(compiled_code, flags) & PCRE2_MODE_MASK));
4170*22dc650dSSadaf Ebrahimi   }
4171*22dc650dSSadaf Ebrahimi return rc;
4172*22dc650dSSadaf Ebrahimi }
4173*22dc650dSSadaf Ebrahimi 
4174*22dc650dSSadaf Ebrahimi 
4175*22dc650dSSadaf Ebrahimi 
4176*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
4177*22dc650dSSadaf Ebrahimi /*************************************************
4178*22dc650dSSadaf Ebrahimi *             Show something in a list           *
4179*22dc650dSSadaf Ebrahimi *************************************************/
4180*22dc650dSSadaf Ebrahimi 
4181*22dc650dSSadaf Ebrahimi /* This function just helps to keep the code that uses it tidier. It's used for
4182*22dc650dSSadaf Ebrahimi various lists of things where there needs to be introductory text before the
4183*22dc650dSSadaf Ebrahimi first item. As these calls are all in the POSIX-support code, they happen only
4184*22dc650dSSadaf Ebrahimi when 8-bit mode is supported. */
4185*22dc650dSSadaf Ebrahimi 
4186*22dc650dSSadaf Ebrahimi static void
prmsg(const char ** msg,const char * s)4187*22dc650dSSadaf Ebrahimi prmsg(const char **msg, const char *s)
4188*22dc650dSSadaf Ebrahimi {
4189*22dc650dSSadaf Ebrahimi fprintf(outfile, "%s %s", *msg, s);
4190*22dc650dSSadaf Ebrahimi *msg = "";
4191*22dc650dSSadaf Ebrahimi }
4192*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_PCRE2_8 */
4193*22dc650dSSadaf Ebrahimi 
4194*22dc650dSSadaf Ebrahimi 
4195*22dc650dSSadaf Ebrahimi 
4196*22dc650dSSadaf Ebrahimi /*************************************************
4197*22dc650dSSadaf Ebrahimi *                Show control bits               *
4198*22dc650dSSadaf Ebrahimi *************************************************/
4199*22dc650dSSadaf Ebrahimi 
4200*22dc650dSSadaf Ebrahimi /* Called for mutually exclusive controls and for unsupported POSIX controls.
4201*22dc650dSSadaf Ebrahimi Because the bits are unique, this can be used for both pattern and data control
4202*22dc650dSSadaf Ebrahimi words.
4203*22dc650dSSadaf Ebrahimi 
4204*22dc650dSSadaf Ebrahimi Arguments:
4205*22dc650dSSadaf Ebrahimi   controls    control bits
4206*22dc650dSSadaf Ebrahimi   controls2   more control bits
4207*22dc650dSSadaf Ebrahimi   before      text to print before
4208*22dc650dSSadaf Ebrahimi 
4209*22dc650dSSadaf Ebrahimi Returns:      nothing
4210*22dc650dSSadaf Ebrahimi */
4211*22dc650dSSadaf Ebrahimi 
4212*22dc650dSSadaf Ebrahimi static void
show_controls(uint32_t controls,uint32_t controls2,const char * before)4213*22dc650dSSadaf Ebrahimi show_controls(uint32_t controls, uint32_t controls2, const char *before)
4214*22dc650dSSadaf Ebrahimi {
4215*22dc650dSSadaf Ebrahimi fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
4216*22dc650dSSadaf Ebrahimi   before,
4217*22dc650dSSadaf Ebrahimi   ((controls & CTL_AFTERTEXT) != 0)? " aftertext" : "",
4218*22dc650dSSadaf Ebrahimi   ((controls & CTL_ALLAFTERTEXT) != 0)? " allaftertext" : "",
4219*22dc650dSSadaf Ebrahimi   ((controls & CTL_ALLCAPTURES) != 0)? " allcaptures" : "",
4220*22dc650dSSadaf Ebrahimi   ((controls & CTL_ALLUSEDTEXT) != 0)? " allusedtext" : "",
4221*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_ALLVECTOR) != 0)? " allvector" : "",
4222*22dc650dSSadaf Ebrahimi   ((controls & CTL_ALTGLOBAL) != 0)? " altglobal" : "",
4223*22dc650dSSadaf Ebrahimi   ((controls & CTL_BINCODE) != 0)? " bincode" : "",
4224*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_BSR_SET) != 0)? " bsr" : "",
4225*22dc650dSSadaf Ebrahimi   ((controls & CTL_CALLOUT_CAPTURE) != 0)? " callout_capture" : "",
4226*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_CALLOUT_EXTRA) != 0)? " callout_extra" : "",
4227*22dc650dSSadaf Ebrahimi   ((controls & CTL_CALLOUT_INFO) != 0)? " callout_info" : "",
4228*22dc650dSSadaf Ebrahimi   ((controls & CTL_CALLOUT_NONE) != 0)? " callout_none" : "",
4229*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_CALLOUT_NO_WHERE) != 0)? " callout_no_where" : "",
4230*22dc650dSSadaf Ebrahimi   ((controls & CTL_DFA) != 0)? " dfa" : "",
4231*22dc650dSSadaf Ebrahimi   ((controls & CTL_EXPAND) != 0)? " expand" : "",
4232*22dc650dSSadaf Ebrahimi   ((controls & CTL_FINDLIMITS) != 0)? " find_limits" : "",
4233*22dc650dSSadaf Ebrahimi   ((controls & CTL_FINDLIMITS_NOHEAP) != 0)? " find_limits_noheap" : "",
4234*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_FRAMESIZE) != 0)? " framesize" : "",
4235*22dc650dSSadaf Ebrahimi   ((controls & CTL_FULLBINCODE) != 0)? " fullbincode" : "",
4236*22dc650dSSadaf Ebrahimi   ((controls & CTL_GETALL) != 0)? " getall" : "",
4237*22dc650dSSadaf Ebrahimi   ((controls & CTL_GLOBAL) != 0)? " global" : "",
4238*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_HEAPFRAMES_SIZE) != 0)? " heapframes_size" : "",
4239*22dc650dSSadaf Ebrahimi   ((controls & CTL_HEXPAT) != 0)? " hex" : "",
4240*22dc650dSSadaf Ebrahimi   ((controls & CTL_INFO) != 0)? " info" : "",
4241*22dc650dSSadaf Ebrahimi   ((controls & CTL_JITFAST) != 0)? " jitfast" : "",
4242*22dc650dSSadaf Ebrahimi   ((controls & CTL_JITVERIFY) != 0)? " jitverify" : "",
4243*22dc650dSSadaf Ebrahimi   ((controls & CTL_MARK) != 0)? " mark" : "",
4244*22dc650dSSadaf Ebrahimi   ((controls & CTL_MEMORY) != 0)? " memory" : "",
4245*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_NL_SET) != 0)? " newline" : "",
4246*22dc650dSSadaf Ebrahimi   ((controls & CTL_NULLCONTEXT) != 0)? " null_context" : "",
4247*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_NULL_REPLACEMENT) != 0)? " null_replacement" : "",
4248*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_NULL_SUBJECT) != 0)? " null_subject" : "",
4249*22dc650dSSadaf Ebrahimi   ((controls & CTL_POSIX) != 0)? " posix" : "",
4250*22dc650dSSadaf Ebrahimi   ((controls & CTL_POSIX_NOSUB) != 0)? " posix_nosub" : "",
4251*22dc650dSSadaf Ebrahimi   ((controls & CTL_PUSH) != 0)? " push" : "",
4252*22dc650dSSadaf Ebrahimi   ((controls & CTL_PUSHCOPY) != 0)? " pushcopy" : "",
4253*22dc650dSSadaf Ebrahimi   ((controls & CTL_PUSHTABLESCOPY) != 0)? " pushtablescopy" : "",
4254*22dc650dSSadaf Ebrahimi   ((controls & CTL_STARTCHAR) != 0)? " startchar" : "",
4255*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_SUBSTITUTE_CALLOUT) != 0)? " substitute_callout" : "",
4256*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_SUBSTITUTE_EXTENDED) != 0)? " substitute_extended" : "",
4257*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_SUBSTITUTE_LITERAL) != 0)? " substitute_literal" : "",
4258*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_SUBSTITUTE_MATCHED) != 0)? " substitute_matched" : "",
4259*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)? " substitute_overflow_length" : "",
4260*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_SUBSTITUTE_REPLACEMENT_ONLY) != 0)? " substitute_replacement_only" : "",
4261*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_SUBSTITUTE_UNKNOWN_UNSET) != 0)? " substitute_unknown_unset" : "",
4262*22dc650dSSadaf Ebrahimi   ((controls2 & CTL2_SUBSTITUTE_UNSET_EMPTY) != 0)? " substitute_unset_empty" : "",
4263*22dc650dSSadaf Ebrahimi   ((controls & CTL_USE_LENGTH) != 0)? " use_length" : "",
4264*22dc650dSSadaf Ebrahimi   ((controls & CTL_UTF8_INPUT) != 0)? " utf8_input" : "",
4265*22dc650dSSadaf Ebrahimi   ((controls & CTL_ZERO_TERMINATE) != 0)? " zero_terminate" : "");
4266*22dc650dSSadaf Ebrahimi }
4267*22dc650dSSadaf Ebrahimi 
4268*22dc650dSSadaf Ebrahimi 
4269*22dc650dSSadaf Ebrahimi 
4270*22dc650dSSadaf Ebrahimi /*************************************************
4271*22dc650dSSadaf Ebrahimi *                Show compile options            *
4272*22dc650dSSadaf Ebrahimi *************************************************/
4273*22dc650dSSadaf Ebrahimi 
4274*22dc650dSSadaf Ebrahimi /* Called from show_pattern_info() and for unsupported POSIX options.
4275*22dc650dSSadaf Ebrahimi 
4276*22dc650dSSadaf Ebrahimi Arguments:
4277*22dc650dSSadaf Ebrahimi   options     an options word
4278*22dc650dSSadaf Ebrahimi   before      text to print before
4279*22dc650dSSadaf Ebrahimi   after       text to print after
4280*22dc650dSSadaf Ebrahimi 
4281*22dc650dSSadaf Ebrahimi Returns:      nothing
4282*22dc650dSSadaf Ebrahimi */
4283*22dc650dSSadaf Ebrahimi 
4284*22dc650dSSadaf Ebrahimi static void
show_compile_options(uint32_t options,const char * before,const char * after)4285*22dc650dSSadaf Ebrahimi show_compile_options(uint32_t options, const char *before, const char *after)
4286*22dc650dSSadaf Ebrahimi {
4287*22dc650dSSadaf Ebrahimi if (options == 0) fprintf(outfile, "%s <none>%s", before, after);
4288*22dc650dSSadaf Ebrahimi else fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
4289*22dc650dSSadaf Ebrahimi   before,
4290*22dc650dSSadaf Ebrahimi   ((options & PCRE2_ALT_BSUX) != 0)? " alt_bsux" : "",
4291*22dc650dSSadaf Ebrahimi   ((options & PCRE2_ALT_CIRCUMFLEX) != 0)? " alt_circumflex" : "",
4292*22dc650dSSadaf Ebrahimi   ((options & PCRE2_ALT_VERBNAMES) != 0)? " alt_verbnames" : "",
4293*22dc650dSSadaf Ebrahimi   ((options & PCRE2_ALLOW_EMPTY_CLASS) != 0)? " allow_empty_class" : "",
4294*22dc650dSSadaf Ebrahimi   ((options & PCRE2_ANCHORED) != 0)? " anchored" : "",
4295*22dc650dSSadaf Ebrahimi   ((options & PCRE2_AUTO_CALLOUT) != 0)? " auto_callout" : "",
4296*22dc650dSSadaf Ebrahimi   ((options & PCRE2_CASELESS) != 0)? " caseless" : "",
4297*22dc650dSSadaf Ebrahimi   ((options & PCRE2_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
4298*22dc650dSSadaf Ebrahimi   ((options & PCRE2_DOTALL) != 0)? " dotall" : "",
4299*22dc650dSSadaf Ebrahimi   ((options & PCRE2_DUPNAMES) != 0)? " dupnames" : "",
4300*22dc650dSSadaf Ebrahimi   ((options & PCRE2_ENDANCHORED) != 0)? " endanchored" : "",
4301*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTENDED) != 0)? " extended" : "",
4302*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTENDED_MORE) != 0)? " extended_more" : "",
4303*22dc650dSSadaf Ebrahimi   ((options & PCRE2_FIRSTLINE) != 0)? " firstline" : "",
4304*22dc650dSSadaf Ebrahimi   ((options & PCRE2_LITERAL) != 0)? " literal" : "",
4305*22dc650dSSadaf Ebrahimi   ((options & PCRE2_MATCH_INVALID_UTF) != 0)? " match_invalid_utf" : "",
4306*22dc650dSSadaf Ebrahimi   ((options & PCRE2_MATCH_UNSET_BACKREF) != 0)? " match_unset_backref" : "",
4307*22dc650dSSadaf Ebrahimi   ((options & PCRE2_MULTILINE) != 0)? " multiline" : "",
4308*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NEVER_BACKSLASH_C) != 0)? " never_backslash_c" : "",
4309*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NEVER_UCP) != 0)? " never_ucp" : "",
4310*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NEVER_UTF) != 0)? " never_utf" : "",
4311*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",
4312*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NO_AUTO_POSSESS) != 0)? " no_auto_possess" : "",
4313*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)? " no_dotstar_anchor" : "",
4314*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "",
4315*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "",
4316*22dc650dSSadaf Ebrahimi   ((options & PCRE2_UCP) != 0)? " ucp" : "",
4317*22dc650dSSadaf Ebrahimi   ((options & PCRE2_UNGREEDY) != 0)? " ungreedy" : "",
4318*22dc650dSSadaf Ebrahimi   ((options & PCRE2_USE_OFFSET_LIMIT) != 0)? " use_offset_limit" : "",
4319*22dc650dSSadaf Ebrahimi   ((options & PCRE2_UTF) != 0)? " utf" : "",
4320*22dc650dSSadaf Ebrahimi   after);
4321*22dc650dSSadaf Ebrahimi }
4322*22dc650dSSadaf Ebrahimi 
4323*22dc650dSSadaf Ebrahimi 
4324*22dc650dSSadaf Ebrahimi /*************************************************
4325*22dc650dSSadaf Ebrahimi *           Show compile extra options           *
4326*22dc650dSSadaf Ebrahimi *************************************************/
4327*22dc650dSSadaf Ebrahimi 
4328*22dc650dSSadaf Ebrahimi /* Called from show_pattern_info() and for unsupported POSIX options.
4329*22dc650dSSadaf Ebrahimi 
4330*22dc650dSSadaf Ebrahimi Arguments:
4331*22dc650dSSadaf Ebrahimi   options     an options word
4332*22dc650dSSadaf Ebrahimi   before      text to print before
4333*22dc650dSSadaf Ebrahimi   after       text to print after
4334*22dc650dSSadaf Ebrahimi 
4335*22dc650dSSadaf Ebrahimi Returns:      nothing
4336*22dc650dSSadaf Ebrahimi */
4337*22dc650dSSadaf Ebrahimi 
4338*22dc650dSSadaf Ebrahimi static void
show_compile_extra_options(uint32_t options,const char * before,const char * after)4339*22dc650dSSadaf Ebrahimi show_compile_extra_options(uint32_t options, const char *before,
4340*22dc650dSSadaf Ebrahimi   const char *after)
4341*22dc650dSSadaf Ebrahimi {
4342*22dc650dSSadaf Ebrahimi if (options == 0) fprintf(outfile, "%s <none>%s", before, after);
4343*22dc650dSSadaf Ebrahimi else fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
4344*22dc650dSSadaf Ebrahimi   before,
4345*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) != 0)? " allow_surrogate_escapes" : "",
4346*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_ALT_BSUX) != 0)? " alt_bsux" : "",
4347*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_ASCII_BSD) != 0)? " ascii_bsd" : "",
4348*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_ASCII_BSS) != 0)? " ascii_bss" : "",
4349*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_ASCII_BSW) != 0)? " ascii_bsw" : "",
4350*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_ASCII_DIGIT) != 0)? " ascii_digit" : "",
4351*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_ASCII_POSIX) != 0)? " ascii_posix" : "",
4352*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) != 0)? " bad_escape_is_literal" : "",
4353*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)? " caseless_restrict" : "",
4354*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0)? " escaped_cr_is_lf" : "",
4355*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_MATCH_WORD) != 0)? " match_word" : "",
4356*22dc650dSSadaf Ebrahimi   ((options & PCRE2_EXTRA_MATCH_LINE) != 0)? " match_line" : "",
4357*22dc650dSSadaf Ebrahimi   after);
4358*22dc650dSSadaf Ebrahimi }
4359*22dc650dSSadaf Ebrahimi 
4360*22dc650dSSadaf Ebrahimi 
4361*22dc650dSSadaf Ebrahimi 
4362*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
4363*22dc650dSSadaf Ebrahimi /*************************************************
4364*22dc650dSSadaf Ebrahimi *                Show match options              *
4365*22dc650dSSadaf Ebrahimi *************************************************/
4366*22dc650dSSadaf Ebrahimi 
4367*22dc650dSSadaf Ebrahimi /* Called for unsupported POSIX options. */
4368*22dc650dSSadaf Ebrahimi 
4369*22dc650dSSadaf Ebrahimi static void
show_match_options(uint32_t options)4370*22dc650dSSadaf Ebrahimi show_match_options(uint32_t options)
4371*22dc650dSSadaf Ebrahimi {
4372*22dc650dSSadaf Ebrahimi fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
4373*22dc650dSSadaf Ebrahimi   ((options & PCRE2_ANCHORED) != 0)? " anchored" : "",
4374*22dc650dSSadaf Ebrahimi   ((options & PCRE2_COPY_MATCHED_SUBJECT) != 0)? " copy_matched_subject" : "",
4375*22dc650dSSadaf Ebrahimi   ((options & PCRE2_DFA_RESTART) != 0)? " dfa_restart" : "",
4376*22dc650dSSadaf Ebrahimi   ((options & PCRE2_DFA_SHORTEST) != 0)? " dfa_shortest" : "",
4377*22dc650dSSadaf Ebrahimi   ((options & PCRE2_DISABLE_RECURSELOOP_CHECK) != 0)? " disable_recurseloop_check" : "",
4378*22dc650dSSadaf Ebrahimi   ((options & PCRE2_ENDANCHORED) != 0)? " endanchored" : "",
4379*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NO_JIT) != 0)? " no_jit" : "",
4380*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "",
4381*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NOTBOL) != 0)? " notbol" : "",
4382*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NOTEMPTY) != 0)? " notempty" : "",
4383*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NOTEMPTY_ATSTART) != 0)? " notempty_atstart" : "",
4384*22dc650dSSadaf Ebrahimi   ((options & PCRE2_NOTEOL) != 0)? " noteol" : "",
4385*22dc650dSSadaf Ebrahimi   ((options & PCRE2_PARTIAL_HARD) != 0)? " partial_hard" : "",
4386*22dc650dSSadaf Ebrahimi   ((options & PCRE2_PARTIAL_SOFT) != 0)? " partial_soft" : "");
4387*22dc650dSSadaf Ebrahimi }
4388*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_PCRE2_8 */
4389*22dc650dSSadaf Ebrahimi 
4390*22dc650dSSadaf Ebrahimi 
4391*22dc650dSSadaf Ebrahimi 
4392*22dc650dSSadaf Ebrahimi /*************************************************
4393*22dc650dSSadaf Ebrahimi *      Show memory usage info for a pattern      *
4394*22dc650dSSadaf Ebrahimi *************************************************/
4395*22dc650dSSadaf Ebrahimi 
4396*22dc650dSSadaf Ebrahimi static void
show_memory_info(void)4397*22dc650dSSadaf Ebrahimi show_memory_info(void)
4398*22dc650dSSadaf Ebrahimi {
4399*22dc650dSSadaf Ebrahimi uint32_t name_count, name_entry_size;
4400*22dc650dSSadaf Ebrahimi PCRE2_SIZE size, cblock_size;
4401*22dc650dSSadaf Ebrahimi 
4402*22dc650dSSadaf Ebrahimi /* One of the test_mode values will always be true, but to stop a compiler
4403*22dc650dSSadaf Ebrahimi warning we must initialize cblock_size. */
4404*22dc650dSSadaf Ebrahimi 
4405*22dc650dSSadaf Ebrahimi cblock_size = 0;
4406*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
4407*22dc650dSSadaf Ebrahimi if (test_mode == PCRE8_MODE) cblock_size = sizeof(pcre2_real_code_8);
4408*22dc650dSSadaf Ebrahimi #endif
4409*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
4410*22dc650dSSadaf Ebrahimi if (test_mode == PCRE16_MODE) cblock_size = sizeof(pcre2_real_code_16);
4411*22dc650dSSadaf Ebrahimi #endif
4412*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
4413*22dc650dSSadaf Ebrahimi if (test_mode == PCRE32_MODE) cblock_size = sizeof(pcre2_real_code_32);
4414*22dc650dSSadaf Ebrahimi #endif
4415*22dc650dSSadaf Ebrahimi 
4416*22dc650dSSadaf Ebrahimi (void)pattern_info(PCRE2_INFO_SIZE, &size, FALSE);
4417*22dc650dSSadaf Ebrahimi (void)pattern_info(PCRE2_INFO_NAMECOUNT, &name_count, FALSE);
4418*22dc650dSSadaf Ebrahimi (void)pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &name_entry_size, FALSE);
4419*22dc650dSSadaf Ebrahimi 
4420*22dc650dSSadaf Ebrahimi /* The uint32_t variables are cast before multiplying to stop code analyzers
4421*22dc650dSSadaf Ebrahimi grumbling about potential overflow. */
4422*22dc650dSSadaf Ebrahimi 
4423*22dc650dSSadaf Ebrahimi fprintf(outfile, "Memory allocation - compiled block : %" SIZ_FORM "\n", size);
4424*22dc650dSSadaf Ebrahimi fprintf(outfile, "Memory allocation - code portion   : %" SIZ_FORM "\n", size -
4425*22dc650dSSadaf Ebrahimi   (PCRE2_SIZE)name_count * (PCRE2_SIZE)name_entry_size * (PCRE2_SIZE)code_unit_size -
4426*22dc650dSSadaf Ebrahimi   cblock_size);
4427*22dc650dSSadaf Ebrahimi 
4428*22dc650dSSadaf Ebrahimi if (pat_patctl.jit != 0)
4429*22dc650dSSadaf Ebrahimi   {
4430*22dc650dSSadaf Ebrahimi   (void)pattern_info(PCRE2_INFO_JITSIZE, &size, FALSE);
4431*22dc650dSSadaf Ebrahimi   fprintf(outfile, "Memory allocation - JIT code       : %" SIZ_FORM "\n", size);
4432*22dc650dSSadaf Ebrahimi   }
4433*22dc650dSSadaf Ebrahimi }
4434*22dc650dSSadaf Ebrahimi 
4435*22dc650dSSadaf Ebrahimi 
4436*22dc650dSSadaf Ebrahimi 
4437*22dc650dSSadaf Ebrahimi /*************************************************
4438*22dc650dSSadaf Ebrahimi *       Show frame size info for a pattern       *
4439*22dc650dSSadaf Ebrahimi *************************************************/
4440*22dc650dSSadaf Ebrahimi 
4441*22dc650dSSadaf Ebrahimi static void
show_framesize(void)4442*22dc650dSSadaf Ebrahimi show_framesize(void)
4443*22dc650dSSadaf Ebrahimi {
4444*22dc650dSSadaf Ebrahimi PCRE2_SIZE frame_size;
4445*22dc650dSSadaf Ebrahimi (void)pattern_info(PCRE2_INFO_FRAMESIZE, &frame_size, FALSE);
4446*22dc650dSSadaf Ebrahimi fprintf(outfile, "Frame size for pcre2_match(): %" SIZ_FORM "\n", frame_size);
4447*22dc650dSSadaf Ebrahimi }
4448*22dc650dSSadaf Ebrahimi 
4449*22dc650dSSadaf Ebrahimi 
4450*22dc650dSSadaf Ebrahimi 
4451*22dc650dSSadaf Ebrahimi /*************************************************
4452*22dc650dSSadaf Ebrahimi *   Show heapframes size info for a match_data   *
4453*22dc650dSSadaf Ebrahimi *************************************************/
4454*22dc650dSSadaf Ebrahimi 
4455*22dc650dSSadaf Ebrahimi static void
show_heapframes_size(void)4456*22dc650dSSadaf Ebrahimi show_heapframes_size(void)
4457*22dc650dSSadaf Ebrahimi {
4458*22dc650dSSadaf Ebrahimi PCRE2_SIZE heapframes_size;
4459*22dc650dSSadaf Ebrahimi PCRE2_GET_MATCH_DATA_HEAPFRAMES_SIZE(heapframes_size, match_data);
4460*22dc650dSSadaf Ebrahimi fprintf(outfile, "Heapframes size in match_data: %" SIZ_FORM "\n",
4461*22dc650dSSadaf Ebrahimi   heapframes_size);
4462*22dc650dSSadaf Ebrahimi }
4463*22dc650dSSadaf Ebrahimi 
4464*22dc650dSSadaf Ebrahimi 
4465*22dc650dSSadaf Ebrahimi 
4466*22dc650dSSadaf Ebrahimi /*************************************************
4467*22dc650dSSadaf Ebrahimi *         Get and output an error message        *
4468*22dc650dSSadaf Ebrahimi *************************************************/
4469*22dc650dSSadaf Ebrahimi 
4470*22dc650dSSadaf Ebrahimi static BOOL
print_error_message(int errorcode,const char * before,const char * after)4471*22dc650dSSadaf Ebrahimi print_error_message(int errorcode, const char *before, const char *after)
4472*22dc650dSSadaf Ebrahimi {
4473*22dc650dSSadaf Ebrahimi int len;
4474*22dc650dSSadaf Ebrahimi PCRE2_GET_ERROR_MESSAGE(len, errorcode, pbuffer);
4475*22dc650dSSadaf Ebrahimi if (len < 0)
4476*22dc650dSSadaf Ebrahimi   {
4477*22dc650dSSadaf Ebrahimi   fprintf(outfile, "\n** pcre2test internal error: cannot interpret error "
4478*22dc650dSSadaf Ebrahimi     "number\n** Unexpected return (%d) from pcre2_get_error_message()\n", len);
4479*22dc650dSSadaf Ebrahimi   }
4480*22dc650dSSadaf Ebrahimi else
4481*22dc650dSSadaf Ebrahimi   {
4482*22dc650dSSadaf Ebrahimi   fprintf(outfile, "%s", before);
4483*22dc650dSSadaf Ebrahimi   PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile);
4484*22dc650dSSadaf Ebrahimi   fprintf(outfile, "%s", after);
4485*22dc650dSSadaf Ebrahimi   }
4486*22dc650dSSadaf Ebrahimi return len >= 0;
4487*22dc650dSSadaf Ebrahimi }
4488*22dc650dSSadaf Ebrahimi 
4489*22dc650dSSadaf Ebrahimi 
4490*22dc650dSSadaf Ebrahimi /*************************************************
4491*22dc650dSSadaf Ebrahimi *     Callback function for callout enumeration  *
4492*22dc650dSSadaf Ebrahimi *************************************************/
4493*22dc650dSSadaf Ebrahimi 
4494*22dc650dSSadaf Ebrahimi /* The only differences in the callout emumeration block for different code
4495*22dc650dSSadaf Ebrahimi unit widths are that the pointers to the subject, the most recent MARK, and a
4496*22dc650dSSadaf Ebrahimi callout argument string point to strings of the appropriate width. Casts can be
4497*22dc650dSSadaf Ebrahimi used to deal with this.
4498*22dc650dSSadaf Ebrahimi 
4499*22dc650dSSadaf Ebrahimi Argument:
4500*22dc650dSSadaf Ebrahimi   cb            pointer to enumerate block
4501*22dc650dSSadaf Ebrahimi   callout_data  user data
4502*22dc650dSSadaf Ebrahimi 
4503*22dc650dSSadaf Ebrahimi Returns:    0
4504*22dc650dSSadaf Ebrahimi */
4505*22dc650dSSadaf Ebrahimi 
callout_callback(pcre2_callout_enumerate_block_8 * cb,void * callout_data)4506*22dc650dSSadaf Ebrahimi static int callout_callback(pcre2_callout_enumerate_block_8 *cb,
4507*22dc650dSSadaf Ebrahimi   void *callout_data)
4508*22dc650dSSadaf Ebrahimi {
4509*22dc650dSSadaf Ebrahimi uint32_t i;
4510*22dc650dSSadaf Ebrahimi BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;
4511*22dc650dSSadaf Ebrahimi 
4512*22dc650dSSadaf Ebrahimi (void)callout_data;  /* Not currently displayed */
4513*22dc650dSSadaf Ebrahimi 
4514*22dc650dSSadaf Ebrahimi fprintf(outfile, "Callout ");
4515*22dc650dSSadaf Ebrahimi if (cb->callout_string != NULL)
4516*22dc650dSSadaf Ebrahimi   {
4517*22dc650dSSadaf Ebrahimi   uint32_t delimiter = CODE_UNIT(cb->callout_string, -1);
4518*22dc650dSSadaf Ebrahimi   fprintf(outfile, "%c", delimiter);
4519*22dc650dSSadaf Ebrahimi   PCHARSV(cb->callout_string, 0,
4520*22dc650dSSadaf Ebrahimi     cb->callout_string_length, utf, outfile);
4521*22dc650dSSadaf Ebrahimi   for (i = 0; callout_start_delims[i] != 0; i++)
4522*22dc650dSSadaf Ebrahimi     if (delimiter == callout_start_delims[i])
4523*22dc650dSSadaf Ebrahimi       {
4524*22dc650dSSadaf Ebrahimi       delimiter = callout_end_delims[i];
4525*22dc650dSSadaf Ebrahimi       break;
4526*22dc650dSSadaf Ebrahimi       }
4527*22dc650dSSadaf Ebrahimi   fprintf(outfile, "%c  ", delimiter);
4528*22dc650dSSadaf Ebrahimi   }
4529*22dc650dSSadaf Ebrahimi else fprintf(outfile, "%d  ", cb->callout_number);
4530*22dc650dSSadaf Ebrahimi 
4531*22dc650dSSadaf Ebrahimi fprintf(outfile, "%.*s\n",
4532*22dc650dSSadaf Ebrahimi   (int)((cb->next_item_length == 0)? 1 : cb->next_item_length),
4533*22dc650dSSadaf Ebrahimi   pbuffer8 + cb->pattern_position);
4534*22dc650dSSadaf Ebrahimi 
4535*22dc650dSSadaf Ebrahimi return 0;
4536*22dc650dSSadaf Ebrahimi }
4537*22dc650dSSadaf Ebrahimi 
4538*22dc650dSSadaf Ebrahimi 
4539*22dc650dSSadaf Ebrahimi 
4540*22dc650dSSadaf Ebrahimi /*************************************************
4541*22dc650dSSadaf Ebrahimi *        Show information about a pattern        *
4542*22dc650dSSadaf Ebrahimi *************************************************/
4543*22dc650dSSadaf Ebrahimi 
4544*22dc650dSSadaf Ebrahimi /* This function is called after a pattern has been compiled if any of the
4545*22dc650dSSadaf Ebrahimi information-requesting controls have been set.
4546*22dc650dSSadaf Ebrahimi 
4547*22dc650dSSadaf Ebrahimi Arguments:  none
4548*22dc650dSSadaf Ebrahimi 
4549*22dc650dSSadaf Ebrahimi Returns:    PR_OK     continue processing next line
4550*22dc650dSSadaf Ebrahimi             PR_SKIP   skip to a blank line
4551*22dc650dSSadaf Ebrahimi             PR_ABEND  abort the pcre2test run
4552*22dc650dSSadaf Ebrahimi */
4553*22dc650dSSadaf Ebrahimi 
4554*22dc650dSSadaf Ebrahimi static int
show_pattern_info(void)4555*22dc650dSSadaf Ebrahimi show_pattern_info(void)
4556*22dc650dSSadaf Ebrahimi {
4557*22dc650dSSadaf Ebrahimi uint32_t compile_options, overall_options, extra_options;
4558*22dc650dSSadaf Ebrahimi BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;
4559*22dc650dSSadaf Ebrahimi 
4560*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & (CTL_BINCODE|CTL_FULLBINCODE)) != 0)
4561*22dc650dSSadaf Ebrahimi   {
4562*22dc650dSSadaf Ebrahimi   fprintf(outfile, "------------------------------------------------------------------\n");
4563*22dc650dSSadaf Ebrahimi   PCRE2_PRINTINT((pat_patctl.control & CTL_FULLBINCODE) != 0);
4564*22dc650dSSadaf Ebrahimi   }
4565*22dc650dSSadaf Ebrahimi 
4566*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_INFO) != 0)
4567*22dc650dSSadaf Ebrahimi   {
4568*22dc650dSSadaf Ebrahimi   int rc;
4569*22dc650dSSadaf Ebrahimi   void *nametable;
4570*22dc650dSSadaf Ebrahimi   uint8_t *start_bits;
4571*22dc650dSSadaf Ebrahimi   BOOL heap_limit_set, match_limit_set, depth_limit_set;
4572*22dc650dSSadaf Ebrahimi   uint32_t backrefmax, bsr_convention, capture_count, first_ctype, first_cunit,
4573*22dc650dSSadaf Ebrahimi     hasbackslashc, hascrorlf, jchanged, last_ctype, last_cunit, match_empty,
4574*22dc650dSSadaf Ebrahimi     depth_limit, heap_limit, match_limit, minlength, nameentrysize, namecount,
4575*22dc650dSSadaf Ebrahimi     newline_convention;
4576*22dc650dSSadaf Ebrahimi 
4577*22dc650dSSadaf Ebrahimi   /* Exercise the error route. */
4578*22dc650dSSadaf Ebrahimi 
4579*22dc650dSSadaf Ebrahimi   PCRE2_PATTERN_INFO(rc, compiled_code, 999, NULL);
4580*22dc650dSSadaf Ebrahimi   (void)rc;
4581*22dc650dSSadaf Ebrahimi 
4582*22dc650dSSadaf Ebrahimi   /* These info requests may return PCRE2_ERROR_UNSET. */
4583*22dc650dSSadaf Ebrahimi 
4584*22dc650dSSadaf Ebrahimi   switch(pattern_info(PCRE2_INFO_HEAPLIMIT, &heap_limit, TRUE))
4585*22dc650dSSadaf Ebrahimi     {
4586*22dc650dSSadaf Ebrahimi     case 0:
4587*22dc650dSSadaf Ebrahimi     heap_limit_set = TRUE;
4588*22dc650dSSadaf Ebrahimi     break;
4589*22dc650dSSadaf Ebrahimi 
4590*22dc650dSSadaf Ebrahimi     case PCRE2_ERROR_UNSET:
4591*22dc650dSSadaf Ebrahimi     heap_limit_set = FALSE;
4592*22dc650dSSadaf Ebrahimi     break;
4593*22dc650dSSadaf Ebrahimi 
4594*22dc650dSSadaf Ebrahimi     default:
4595*22dc650dSSadaf Ebrahimi     return PR_ABEND;
4596*22dc650dSSadaf Ebrahimi     }
4597*22dc650dSSadaf Ebrahimi 
4598*22dc650dSSadaf Ebrahimi   switch(pattern_info(PCRE2_INFO_MATCHLIMIT, &match_limit, TRUE))
4599*22dc650dSSadaf Ebrahimi     {
4600*22dc650dSSadaf Ebrahimi     case 0:
4601*22dc650dSSadaf Ebrahimi     match_limit_set = TRUE;
4602*22dc650dSSadaf Ebrahimi     break;
4603*22dc650dSSadaf Ebrahimi 
4604*22dc650dSSadaf Ebrahimi     case PCRE2_ERROR_UNSET:
4605*22dc650dSSadaf Ebrahimi     match_limit_set = FALSE;
4606*22dc650dSSadaf Ebrahimi     break;
4607*22dc650dSSadaf Ebrahimi 
4608*22dc650dSSadaf Ebrahimi     default:
4609*22dc650dSSadaf Ebrahimi     return PR_ABEND;
4610*22dc650dSSadaf Ebrahimi     }
4611*22dc650dSSadaf Ebrahimi 
4612*22dc650dSSadaf Ebrahimi   switch(pattern_info(PCRE2_INFO_DEPTHLIMIT, &depth_limit, TRUE))
4613*22dc650dSSadaf Ebrahimi     {
4614*22dc650dSSadaf Ebrahimi     case 0:
4615*22dc650dSSadaf Ebrahimi     depth_limit_set = TRUE;
4616*22dc650dSSadaf Ebrahimi     break;
4617*22dc650dSSadaf Ebrahimi 
4618*22dc650dSSadaf Ebrahimi     case PCRE2_ERROR_UNSET:
4619*22dc650dSSadaf Ebrahimi     depth_limit_set = FALSE;
4620*22dc650dSSadaf Ebrahimi     break;
4621*22dc650dSSadaf Ebrahimi 
4622*22dc650dSSadaf Ebrahimi     default:
4623*22dc650dSSadaf Ebrahimi     return PR_ABEND;
4624*22dc650dSSadaf Ebrahimi     }
4625*22dc650dSSadaf Ebrahimi 
4626*22dc650dSSadaf Ebrahimi   /* These info requests should always succeed. */
4627*22dc650dSSadaf Ebrahimi 
4628*22dc650dSSadaf Ebrahimi   if (pattern_info(PCRE2_INFO_BACKREFMAX, &backrefmax, FALSE) +
4629*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_BSR, &bsr_convention, FALSE) +
4630*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_CAPTURECOUNT, &capture_count, FALSE) +
4631*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_FIRSTBITMAP, &start_bits, FALSE) +
4632*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_FIRSTCODEUNIT, &first_cunit, FALSE) +
4633*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_FIRSTCODETYPE, &first_ctype, FALSE) +
4634*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_HASBACKSLASHC, &hasbackslashc, FALSE) +
4635*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_HASCRORLF, &hascrorlf, FALSE) +
4636*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_JCHANGED, &jchanged, FALSE) +
4637*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_LASTCODEUNIT, &last_cunit, FALSE) +
4638*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_LASTCODETYPE, &last_ctype, FALSE) +
4639*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_MATCHEMPTY, &match_empty, FALSE) +
4640*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_MINLENGTH, &minlength, FALSE) +
4641*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_NAMECOUNT, &namecount, FALSE) +
4642*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &nameentrysize, FALSE) +
4643*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_NAMETABLE, &nametable, FALSE) +
4644*22dc650dSSadaf Ebrahimi       pattern_info(PCRE2_INFO_NEWLINE, &newline_convention, FALSE)
4645*22dc650dSSadaf Ebrahimi       != 0)
4646*22dc650dSSadaf Ebrahimi     return PR_ABEND;
4647*22dc650dSSadaf Ebrahimi 
4648*22dc650dSSadaf Ebrahimi   fprintf(outfile, "Capture group count = %d\n", capture_count);
4649*22dc650dSSadaf Ebrahimi 
4650*22dc650dSSadaf Ebrahimi   if (backrefmax > 0)
4651*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Max back reference = %d\n", backrefmax);
4652*22dc650dSSadaf Ebrahimi 
4653*22dc650dSSadaf Ebrahimi   if (maxlookbehind > 0)
4654*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Max lookbehind = %d\n", maxlookbehind);
4655*22dc650dSSadaf Ebrahimi 
4656*22dc650dSSadaf Ebrahimi   if (heap_limit_set)
4657*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Heap limit = %u\n", heap_limit);
4658*22dc650dSSadaf Ebrahimi 
4659*22dc650dSSadaf Ebrahimi   if (match_limit_set)
4660*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Match limit = %u\n", match_limit);
4661*22dc650dSSadaf Ebrahimi 
4662*22dc650dSSadaf Ebrahimi   if (depth_limit_set)
4663*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Depth limit = %u\n", depth_limit);
4664*22dc650dSSadaf Ebrahimi 
4665*22dc650dSSadaf Ebrahimi   if (namecount > 0)
4666*22dc650dSSadaf Ebrahimi     {
4667*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Named capture groups:\n");
4668*22dc650dSSadaf Ebrahimi     for (; namecount > 0; namecount--)
4669*22dc650dSSadaf Ebrahimi       {
4670*22dc650dSSadaf Ebrahimi       int imm2_size = test_mode == PCRE8_MODE ? 2 : 1;
4671*22dc650dSSadaf Ebrahimi       uint32_t length = (uint32_t)STRLEN(nametable + imm2_size);
4672*22dc650dSSadaf Ebrahimi       fprintf(outfile, "  ");
4673*22dc650dSSadaf Ebrahimi 
4674*22dc650dSSadaf Ebrahimi       /* In UTF mode the name may be a UTF string containing non-ASCII
4675*22dc650dSSadaf Ebrahimi       letters and digits. We must output it as a UTF-8 string. In non-UTF mode,
4676*22dc650dSSadaf Ebrahimi       use the normal string printing functions, which use escapes for all
4677*22dc650dSSadaf Ebrahimi       non-ASCII characters. */
4678*22dc650dSSadaf Ebrahimi 
4679*22dc650dSSadaf Ebrahimi       if (utf)
4680*22dc650dSSadaf Ebrahimi         {
4681*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
4682*22dc650dSSadaf Ebrahimi         if (test_mode == PCRE32_MODE)
4683*22dc650dSSadaf Ebrahimi           {
4684*22dc650dSSadaf Ebrahimi           PCRE2_SPTR32 nameptr = (PCRE2_SPTR32)nametable + imm2_size;
4685*22dc650dSSadaf Ebrahimi           while (*nameptr != 0)
4686*22dc650dSSadaf Ebrahimi             {
4687*22dc650dSSadaf Ebrahimi             uint8_t u8buff[6];
4688*22dc650dSSadaf Ebrahimi             int len = ord2utf8(*nameptr++, u8buff);
4689*22dc650dSSadaf Ebrahimi             fprintf(outfile, "%.*s", len, u8buff);
4690*22dc650dSSadaf Ebrahimi             }
4691*22dc650dSSadaf Ebrahimi           }
4692*22dc650dSSadaf Ebrahimi #endif
4693*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
4694*22dc650dSSadaf Ebrahimi         if (test_mode == PCRE16_MODE)
4695*22dc650dSSadaf Ebrahimi           {
4696*22dc650dSSadaf Ebrahimi           PCRE2_SPTR16 nameptr = (PCRE2_SPTR16)nametable + imm2_size;
4697*22dc650dSSadaf Ebrahimi           while (*nameptr != 0)
4698*22dc650dSSadaf Ebrahimi             {
4699*22dc650dSSadaf Ebrahimi             int len;
4700*22dc650dSSadaf Ebrahimi             uint8_t u8buff[6];
4701*22dc650dSSadaf Ebrahimi             uint32_t c = *nameptr++ & 0xffff;
4702*22dc650dSSadaf Ebrahimi             if (c >= 0xD800 && c < 0xDC00)
4703*22dc650dSSadaf Ebrahimi               c = ((c & 0x3ff) << 10) + (*nameptr++ & 0x3ff) + 0x10000;
4704*22dc650dSSadaf Ebrahimi             len = ord2utf8(c, u8buff);
4705*22dc650dSSadaf Ebrahimi             fprintf(outfile, "%.*s", len, u8buff);
4706*22dc650dSSadaf Ebrahimi             }
4707*22dc650dSSadaf Ebrahimi           }
4708*22dc650dSSadaf Ebrahimi #endif
4709*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
4710*22dc650dSSadaf Ebrahimi         if (test_mode == PCRE8_MODE)
4711*22dc650dSSadaf Ebrahimi           fprintf(outfile, "%s", (PCRE2_SPTR8)nametable + imm2_size);
4712*22dc650dSSadaf Ebrahimi #endif
4713*22dc650dSSadaf Ebrahimi         }
4714*22dc650dSSadaf Ebrahimi       else  /* Not UTF mode */
4715*22dc650dSSadaf Ebrahimi         {
4716*22dc650dSSadaf Ebrahimi         PCHARSV(nametable, imm2_size, length, FALSE, outfile);
4717*22dc650dSSadaf Ebrahimi         }
4718*22dc650dSSadaf Ebrahimi 
4719*22dc650dSSadaf Ebrahimi       while (length++ < nameentrysize - imm2_size) putc(' ', outfile);
4720*22dc650dSSadaf Ebrahimi 
4721*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
4722*22dc650dSSadaf Ebrahimi       if (test_mode == PCRE32_MODE)
4723*22dc650dSSadaf Ebrahimi         fprintf(outfile, "%3d\n", (int)(((PCRE2_SPTR32)nametable)[0]));
4724*22dc650dSSadaf Ebrahimi #endif
4725*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
4726*22dc650dSSadaf Ebrahimi       if (test_mode == PCRE16_MODE)
4727*22dc650dSSadaf Ebrahimi         fprintf(outfile, "%3d\n", (int)(((PCRE2_SPTR16)nametable)[0]));
4728*22dc650dSSadaf Ebrahimi #endif
4729*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
4730*22dc650dSSadaf Ebrahimi       if (test_mode == PCRE8_MODE)
4731*22dc650dSSadaf Ebrahimi         fprintf(outfile, "%3d\n", (int)(
4732*22dc650dSSadaf Ebrahimi         ((((PCRE2_SPTR8)nametable)[0]) << 8) | ((PCRE2_SPTR8)nametable)[1]));
4733*22dc650dSSadaf Ebrahimi #endif
4734*22dc650dSSadaf Ebrahimi 
4735*22dc650dSSadaf Ebrahimi       nametable = (void*)((PCRE2_SPTR8)nametable + nameentrysize * code_unit_size);
4736*22dc650dSSadaf Ebrahimi       }
4737*22dc650dSSadaf Ebrahimi     }
4738*22dc650dSSadaf Ebrahimi 
4739*22dc650dSSadaf Ebrahimi   if (hascrorlf)     fprintf(outfile, "Contains explicit CR or LF match\n");
4740*22dc650dSSadaf Ebrahimi   if (hasbackslashc) fprintf(outfile, "Contains \\C\n");
4741*22dc650dSSadaf Ebrahimi   if (match_empty)   fprintf(outfile, "May match empty string\n");
4742*22dc650dSSadaf Ebrahimi 
4743*22dc650dSSadaf Ebrahimi   pattern_info(PCRE2_INFO_ARGOPTIONS, &compile_options, FALSE);
4744*22dc650dSSadaf Ebrahimi   pattern_info(PCRE2_INFO_ALLOPTIONS, &overall_options, FALSE);
4745*22dc650dSSadaf Ebrahimi   pattern_info(PCRE2_INFO_EXTRAOPTIONS, &extra_options, FALSE);
4746*22dc650dSSadaf Ebrahimi 
4747*22dc650dSSadaf Ebrahimi   /* Remove UTF/UCP if they were there only because of forbid_utf. This saves
4748*22dc650dSSadaf Ebrahimi   cluttering up the verification output of non-UTF test files. */
4749*22dc650dSSadaf Ebrahimi 
4750*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & PCRE2_NEVER_UTF) == 0)
4751*22dc650dSSadaf Ebrahimi     {
4752*22dc650dSSadaf Ebrahimi     compile_options &= ~PCRE2_NEVER_UTF;
4753*22dc650dSSadaf Ebrahimi     overall_options &= ~PCRE2_NEVER_UTF;
4754*22dc650dSSadaf Ebrahimi     }
4755*22dc650dSSadaf Ebrahimi 
4756*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & PCRE2_NEVER_UCP) == 0)
4757*22dc650dSSadaf Ebrahimi     {
4758*22dc650dSSadaf Ebrahimi     compile_options &= ~PCRE2_NEVER_UCP;
4759*22dc650dSSadaf Ebrahimi     overall_options &= ~PCRE2_NEVER_UCP;
4760*22dc650dSSadaf Ebrahimi     }
4761*22dc650dSSadaf Ebrahimi 
4762*22dc650dSSadaf Ebrahimi   if ((compile_options|overall_options) != 0)
4763*22dc650dSSadaf Ebrahimi     {
4764*22dc650dSSadaf Ebrahimi     if (compile_options == overall_options)
4765*22dc650dSSadaf Ebrahimi       show_compile_options(compile_options, "Options:", "\n");
4766*22dc650dSSadaf Ebrahimi     else
4767*22dc650dSSadaf Ebrahimi       {
4768*22dc650dSSadaf Ebrahimi       show_compile_options(compile_options, "Compile options:", "\n");
4769*22dc650dSSadaf Ebrahimi       show_compile_options(overall_options, "Overall options:", "\n");
4770*22dc650dSSadaf Ebrahimi       }
4771*22dc650dSSadaf Ebrahimi     }
4772*22dc650dSSadaf Ebrahimi 
4773*22dc650dSSadaf Ebrahimi   if (extra_options != 0)
4774*22dc650dSSadaf Ebrahimi     show_compile_extra_options(extra_options, "Extra options:", "\n");
4775*22dc650dSSadaf Ebrahimi 
4776*22dc650dSSadaf Ebrahimi   if (jchanged) fprintf(outfile, "Duplicate name status changes\n");
4777*22dc650dSSadaf Ebrahimi 
4778*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control2 & CTL2_BSR_SET) != 0 ||
4779*22dc650dSSadaf Ebrahimi       (FLD(compiled_code, flags) & PCRE2_BSR_SET) != 0)
4780*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\\R matches %s\n", (bsr_convention == PCRE2_BSR_UNICODE)?
4781*22dc650dSSadaf Ebrahimi       "any Unicode newline" : "CR, LF, or CRLF");
4782*22dc650dSSadaf Ebrahimi 
4783*22dc650dSSadaf Ebrahimi   if ((FLD(compiled_code, flags) & PCRE2_NL_SET) != 0)
4784*22dc650dSSadaf Ebrahimi     {
4785*22dc650dSSadaf Ebrahimi     switch (newline_convention)
4786*22dc650dSSadaf Ebrahimi       {
4787*22dc650dSSadaf Ebrahimi       case PCRE2_NEWLINE_CR:
4788*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Forced newline is CR\n");
4789*22dc650dSSadaf Ebrahimi       break;
4790*22dc650dSSadaf Ebrahimi 
4791*22dc650dSSadaf Ebrahimi       case PCRE2_NEWLINE_LF:
4792*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Forced newline is LF\n");
4793*22dc650dSSadaf Ebrahimi       break;
4794*22dc650dSSadaf Ebrahimi 
4795*22dc650dSSadaf Ebrahimi       case PCRE2_NEWLINE_CRLF:
4796*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Forced newline is CRLF\n");
4797*22dc650dSSadaf Ebrahimi       break;
4798*22dc650dSSadaf Ebrahimi 
4799*22dc650dSSadaf Ebrahimi       case PCRE2_NEWLINE_ANYCRLF:
4800*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Forced newline is CR, LF, or CRLF\n");
4801*22dc650dSSadaf Ebrahimi       break;
4802*22dc650dSSadaf Ebrahimi 
4803*22dc650dSSadaf Ebrahimi       case PCRE2_NEWLINE_ANY:
4804*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Forced newline is any Unicode newline\n");
4805*22dc650dSSadaf Ebrahimi       break;
4806*22dc650dSSadaf Ebrahimi 
4807*22dc650dSSadaf Ebrahimi       case PCRE2_NEWLINE_NUL:
4808*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Forced newline is NUL\n");
4809*22dc650dSSadaf Ebrahimi       break;
4810*22dc650dSSadaf Ebrahimi 
4811*22dc650dSSadaf Ebrahimi       default:
4812*22dc650dSSadaf Ebrahimi       break;
4813*22dc650dSSadaf Ebrahimi       }
4814*22dc650dSSadaf Ebrahimi     }
4815*22dc650dSSadaf Ebrahimi 
4816*22dc650dSSadaf Ebrahimi   if (first_ctype == 2)
4817*22dc650dSSadaf Ebrahimi     {
4818*22dc650dSSadaf Ebrahimi     fprintf(outfile, "First code unit at start or follows newline\n");
4819*22dc650dSSadaf Ebrahimi     }
4820*22dc650dSSadaf Ebrahimi   else if (first_ctype == 1)
4821*22dc650dSSadaf Ebrahimi     {
4822*22dc650dSSadaf Ebrahimi     const char *caseless =
4823*22dc650dSSadaf Ebrahimi       ((FLD(compiled_code, flags) & PCRE2_FIRSTCASELESS) == 0)?
4824*22dc650dSSadaf Ebrahimi       "" : " (caseless)";
4825*22dc650dSSadaf Ebrahimi     if (PRINTOK(first_cunit))
4826*22dc650dSSadaf Ebrahimi       fprintf(outfile, "First code unit = \'%c\'%s\n", first_cunit, caseless);
4827*22dc650dSSadaf Ebrahimi     else
4828*22dc650dSSadaf Ebrahimi       {
4829*22dc650dSSadaf Ebrahimi       fprintf(outfile, "First code unit = ");
4830*22dc650dSSadaf Ebrahimi       pchar(first_cunit, FALSE, outfile);
4831*22dc650dSSadaf Ebrahimi       fprintf(outfile, "%s\n", caseless);
4832*22dc650dSSadaf Ebrahimi       }
4833*22dc650dSSadaf Ebrahimi     }
4834*22dc650dSSadaf Ebrahimi   else if (start_bits != NULL)
4835*22dc650dSSadaf Ebrahimi     {
4836*22dc650dSSadaf Ebrahimi     int i;
4837*22dc650dSSadaf Ebrahimi     int c = 24;
4838*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Starting code units: ");
4839*22dc650dSSadaf Ebrahimi     for (i = 0; i < 256; i++)
4840*22dc650dSSadaf Ebrahimi       {
4841*22dc650dSSadaf Ebrahimi       if ((start_bits[i/8] & (1u << (i&7))) != 0)
4842*22dc650dSSadaf Ebrahimi         {
4843*22dc650dSSadaf Ebrahimi         if (c > 75)
4844*22dc650dSSadaf Ebrahimi           {
4845*22dc650dSSadaf Ebrahimi           fprintf(outfile, "\n  ");
4846*22dc650dSSadaf Ebrahimi           c = 2;
4847*22dc650dSSadaf Ebrahimi           }
4848*22dc650dSSadaf Ebrahimi         if (PRINTOK(i) && i != ' ')
4849*22dc650dSSadaf Ebrahimi           {
4850*22dc650dSSadaf Ebrahimi           fprintf(outfile, "%c ", i);
4851*22dc650dSSadaf Ebrahimi           c += 2;
4852*22dc650dSSadaf Ebrahimi           }
4853*22dc650dSSadaf Ebrahimi         else
4854*22dc650dSSadaf Ebrahimi           {
4855*22dc650dSSadaf Ebrahimi           fprintf(outfile, "\\x%02x ", i);
4856*22dc650dSSadaf Ebrahimi           c += 5;
4857*22dc650dSSadaf Ebrahimi           }
4858*22dc650dSSadaf Ebrahimi         }
4859*22dc650dSSadaf Ebrahimi       }
4860*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\n");
4861*22dc650dSSadaf Ebrahimi     }
4862*22dc650dSSadaf Ebrahimi 
4863*22dc650dSSadaf Ebrahimi   if (last_ctype != 0)
4864*22dc650dSSadaf Ebrahimi     {
4865*22dc650dSSadaf Ebrahimi     const char *caseless =
4866*22dc650dSSadaf Ebrahimi       ((FLD(compiled_code, flags) & PCRE2_LASTCASELESS) == 0)?
4867*22dc650dSSadaf Ebrahimi       "" : " (caseless)";
4868*22dc650dSSadaf Ebrahimi     if (PRINTOK(last_cunit))
4869*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Last code unit = \'%c\'%s\n", last_cunit, caseless);
4870*22dc650dSSadaf Ebrahimi     else
4871*22dc650dSSadaf Ebrahimi       {
4872*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Last code unit = ");
4873*22dc650dSSadaf Ebrahimi       pchar(last_cunit, FALSE, outfile);
4874*22dc650dSSadaf Ebrahimi       fprintf(outfile, "%s\n", caseless);
4875*22dc650dSSadaf Ebrahimi       }
4876*22dc650dSSadaf Ebrahimi     }
4877*22dc650dSSadaf Ebrahimi 
4878*22dc650dSSadaf Ebrahimi   if ((FLD(compiled_code, overall_options) & PCRE2_NO_START_OPTIMIZE) == 0)
4879*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Subject length lower bound = %d\n", minlength);
4880*22dc650dSSadaf Ebrahimi 
4881*22dc650dSSadaf Ebrahimi   if (pat_patctl.jit != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0)
4882*22dc650dSSadaf Ebrahimi     {
4883*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_JIT
4884*22dc650dSSadaf Ebrahimi     if (FLD(compiled_code, executable_jit) != NULL)
4885*22dc650dSSadaf Ebrahimi       fprintf(outfile, "JIT compilation was successful\n");
4886*22dc650dSSadaf Ebrahimi     else
4887*22dc650dSSadaf Ebrahimi       {
4888*22dc650dSSadaf Ebrahimi       fprintf(outfile, "JIT compilation was not successful");
4889*22dc650dSSadaf Ebrahimi       if (jitrc != 0 && !print_error_message(jitrc, " (", ")"))
4890*22dc650dSSadaf Ebrahimi         return PR_ABEND;
4891*22dc650dSSadaf Ebrahimi       fprintf(outfile, "\n");
4892*22dc650dSSadaf Ebrahimi       }
4893*22dc650dSSadaf Ebrahimi #else
4894*22dc650dSSadaf Ebrahimi       fprintf(outfile, "JIT support is not available in this version of PCRE2\n");
4895*22dc650dSSadaf Ebrahimi #endif
4896*22dc650dSSadaf Ebrahimi     }
4897*22dc650dSSadaf Ebrahimi   }
4898*22dc650dSSadaf Ebrahimi 
4899*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_CALLOUT_INFO) != 0)
4900*22dc650dSSadaf Ebrahimi   {
4901*22dc650dSSadaf Ebrahimi   int errorcode;
4902*22dc650dSSadaf Ebrahimi   PCRE2_CALLOUT_ENUMERATE(errorcode, callout_callback, 0);
4903*22dc650dSSadaf Ebrahimi   if (errorcode != 0)
4904*22dc650dSSadaf Ebrahimi     {
4905*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Callout enumerate failed: error %d: ", errorcode);
4906*22dc650dSSadaf Ebrahimi     if (errorcode < 0 && !print_error_message(errorcode, "", "\n"))
4907*22dc650dSSadaf Ebrahimi       return PR_ABEND;
4908*22dc650dSSadaf Ebrahimi     return PR_SKIP;
4909*22dc650dSSadaf Ebrahimi     }
4910*22dc650dSSadaf Ebrahimi   }
4911*22dc650dSSadaf Ebrahimi 
4912*22dc650dSSadaf Ebrahimi return PR_OK;
4913*22dc650dSSadaf Ebrahimi }
4914*22dc650dSSadaf Ebrahimi 
4915*22dc650dSSadaf Ebrahimi 
4916*22dc650dSSadaf Ebrahimi 
4917*22dc650dSSadaf Ebrahimi /*************************************************
4918*22dc650dSSadaf Ebrahimi *              Handle serialization error        *
4919*22dc650dSSadaf Ebrahimi *************************************************/
4920*22dc650dSSadaf Ebrahimi 
4921*22dc650dSSadaf Ebrahimi /* Print an error message after a serialization failure.
4922*22dc650dSSadaf Ebrahimi 
4923*22dc650dSSadaf Ebrahimi Arguments:
4924*22dc650dSSadaf Ebrahimi   rc         the error code
4925*22dc650dSSadaf Ebrahimi   msg        an initial message for what failed
4926*22dc650dSSadaf Ebrahimi 
4927*22dc650dSSadaf Ebrahimi Returns:     FALSE if print_error_message() fails
4928*22dc650dSSadaf Ebrahimi */
4929*22dc650dSSadaf Ebrahimi 
4930*22dc650dSSadaf Ebrahimi static BOOL
serial_error(int rc,const char * msg)4931*22dc650dSSadaf Ebrahimi serial_error(int rc, const char *msg)
4932*22dc650dSSadaf Ebrahimi {
4933*22dc650dSSadaf Ebrahimi fprintf(outfile, "%s failed: error %d: ", msg, rc);
4934*22dc650dSSadaf Ebrahimi return print_error_message(rc, "", "\n");
4935*22dc650dSSadaf Ebrahimi }
4936*22dc650dSSadaf Ebrahimi 
4937*22dc650dSSadaf Ebrahimi 
4938*22dc650dSSadaf Ebrahimi 
4939*22dc650dSSadaf Ebrahimi /*************************************************
4940*22dc650dSSadaf Ebrahimi *        Open file for save/load commands        *
4941*22dc650dSSadaf Ebrahimi *************************************************/
4942*22dc650dSSadaf Ebrahimi 
4943*22dc650dSSadaf Ebrahimi /* This function decodes the file name and opens the file.
4944*22dc650dSSadaf Ebrahimi 
4945*22dc650dSSadaf Ebrahimi Arguments:
4946*22dc650dSSadaf Ebrahimi   buffptr     point after the #command
4947*22dc650dSSadaf Ebrahimi   mode        open mode
4948*22dc650dSSadaf Ebrahimi   fptr        points to the FILE variable
4949*22dc650dSSadaf Ebrahimi   name        name of # command
4950*22dc650dSSadaf Ebrahimi 
4951*22dc650dSSadaf Ebrahimi Returns:      PR_OK or PR_ABEND
4952*22dc650dSSadaf Ebrahimi */
4953*22dc650dSSadaf Ebrahimi 
4954*22dc650dSSadaf Ebrahimi static int
open_file(uint8_t * buffptr,const char * mode,FILE ** fptr,const char * name)4955*22dc650dSSadaf Ebrahimi open_file(uint8_t *buffptr, const char *mode, FILE **fptr, const char *name)
4956*22dc650dSSadaf Ebrahimi {
4957*22dc650dSSadaf Ebrahimi char *endf;
4958*22dc650dSSadaf Ebrahimi char *filename = (char *)buffptr;
4959*22dc650dSSadaf Ebrahimi while (isspace(*filename)) filename++;
4960*22dc650dSSadaf Ebrahimi endf = filename + strlen8(filename);
4961*22dc650dSSadaf Ebrahimi while (endf > filename && isspace(endf[-1])) endf--;
4962*22dc650dSSadaf Ebrahimi 
4963*22dc650dSSadaf Ebrahimi if (endf == filename)
4964*22dc650dSSadaf Ebrahimi   {
4965*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** File name expected after %s\n", name);
4966*22dc650dSSadaf Ebrahimi   return PR_ABEND;
4967*22dc650dSSadaf Ebrahimi   }
4968*22dc650dSSadaf Ebrahimi 
4969*22dc650dSSadaf Ebrahimi *endf = 0;
4970*22dc650dSSadaf Ebrahimi *fptr = fopen((const char *)filename, mode);
4971*22dc650dSSadaf Ebrahimi if (*fptr == NULL)
4972*22dc650dSSadaf Ebrahimi   {
4973*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** Failed to open '%s': %s\n", filename, strerror(errno));
4974*22dc650dSSadaf Ebrahimi   return PR_ABEND;
4975*22dc650dSSadaf Ebrahimi   }
4976*22dc650dSSadaf Ebrahimi 
4977*22dc650dSSadaf Ebrahimi return PR_OK;
4978*22dc650dSSadaf Ebrahimi }
4979*22dc650dSSadaf Ebrahimi 
4980*22dc650dSSadaf Ebrahimi 
4981*22dc650dSSadaf Ebrahimi 
4982*22dc650dSSadaf Ebrahimi /*************************************************
4983*22dc650dSSadaf Ebrahimi *               Process command line             *
4984*22dc650dSSadaf Ebrahimi *************************************************/
4985*22dc650dSSadaf Ebrahimi 
4986*22dc650dSSadaf Ebrahimi /* This function is called for lines beginning with # and a character that is
4987*22dc650dSSadaf Ebrahimi not ! or whitespace, when encountered between tests, which means that there is
4988*22dc650dSSadaf Ebrahimi no compiled pattern (compiled_code is NULL). The line is in buffer.
4989*22dc650dSSadaf Ebrahimi 
4990*22dc650dSSadaf Ebrahimi Arguments:  none
4991*22dc650dSSadaf Ebrahimi 
4992*22dc650dSSadaf Ebrahimi Returns:    PR_OK     continue processing next line
4993*22dc650dSSadaf Ebrahimi             PR_SKIP   skip to a blank line
4994*22dc650dSSadaf Ebrahimi             PR_ABEND  abort the pcre2test run
4995*22dc650dSSadaf Ebrahimi */
4996*22dc650dSSadaf Ebrahimi 
4997*22dc650dSSadaf Ebrahimi static int
process_command(void)4998*22dc650dSSadaf Ebrahimi process_command(void)
4999*22dc650dSSadaf Ebrahimi {
5000*22dc650dSSadaf Ebrahimi FILE *f;
5001*22dc650dSSadaf Ebrahimi PCRE2_SIZE serial_size;
5002*22dc650dSSadaf Ebrahimi size_t i;
5003*22dc650dSSadaf Ebrahimi int rc, cmd, cmdlen, yield;
5004*22dc650dSSadaf Ebrahimi uint16_t first_listed_newline;
5005*22dc650dSSadaf Ebrahimi const char *cmdname;
5006*22dc650dSSadaf Ebrahimi uint8_t *argptr, *serial;
5007*22dc650dSSadaf Ebrahimi 
5008*22dc650dSSadaf Ebrahimi yield = PR_OK;
5009*22dc650dSSadaf Ebrahimi cmd = CMD_UNKNOWN;
5010*22dc650dSSadaf Ebrahimi cmdlen = 0;
5011*22dc650dSSadaf Ebrahimi 
5012*22dc650dSSadaf Ebrahimi for (i = 0; i < cmdlistcount; i++)
5013*22dc650dSSadaf Ebrahimi   {
5014*22dc650dSSadaf Ebrahimi   cmdname = cmdlist[i].name;
5015*22dc650dSSadaf Ebrahimi   cmdlen = strlen(cmdname);
5016*22dc650dSSadaf Ebrahimi   if (strncmp((char *)(buffer+1), cmdname, cmdlen) == 0 &&
5017*22dc650dSSadaf Ebrahimi       isspace(buffer[cmdlen+1]))
5018*22dc650dSSadaf Ebrahimi     {
5019*22dc650dSSadaf Ebrahimi     cmd = cmdlist[i].value;
5020*22dc650dSSadaf Ebrahimi     break;
5021*22dc650dSSadaf Ebrahimi     }
5022*22dc650dSSadaf Ebrahimi   }
5023*22dc650dSSadaf Ebrahimi 
5024*22dc650dSSadaf Ebrahimi argptr = buffer + cmdlen + 1;
5025*22dc650dSSadaf Ebrahimi 
5026*22dc650dSSadaf Ebrahimi if (restrict_for_perl_test && cmd != CMD_PATTERN && cmd != CMD_SUBJECT)
5027*22dc650dSSadaf Ebrahimi   {
5028*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** #%s is not allowed after #perltest\n", cmdname);
5029*22dc650dSSadaf Ebrahimi   return PR_ABEND;
5030*22dc650dSSadaf Ebrahimi   }
5031*22dc650dSSadaf Ebrahimi 
5032*22dc650dSSadaf Ebrahimi switch(cmd)
5033*22dc650dSSadaf Ebrahimi   {
5034*22dc650dSSadaf Ebrahimi   case CMD_UNKNOWN:
5035*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** Unknown command: %s", buffer);
5036*22dc650dSSadaf Ebrahimi   break;
5037*22dc650dSSadaf Ebrahimi 
5038*22dc650dSSadaf Ebrahimi   case CMD_FORBID_UTF:
5039*22dc650dSSadaf Ebrahimi   forbid_utf = PCRE2_NEVER_UTF|PCRE2_NEVER_UCP;
5040*22dc650dSSadaf Ebrahimi   break;
5041*22dc650dSSadaf Ebrahimi 
5042*22dc650dSSadaf Ebrahimi   case CMD_PERLTEST:
5043*22dc650dSSadaf Ebrahimi   restrict_for_perl_test = TRUE;
5044*22dc650dSSadaf Ebrahimi   break;
5045*22dc650dSSadaf Ebrahimi 
5046*22dc650dSSadaf Ebrahimi   /* Set default pattern modifiers */
5047*22dc650dSSadaf Ebrahimi 
5048*22dc650dSSadaf Ebrahimi   case CMD_PATTERN:
5049*22dc650dSSadaf Ebrahimi   (void)decode_modifiers(argptr, CTX_DEFPAT, &def_patctl, NULL);
5050*22dc650dSSadaf Ebrahimi   if (def_patctl.jit == 0 && (def_patctl.control & CTL_JITVERIFY) != 0)
5051*22dc650dSSadaf Ebrahimi     def_patctl.jit = JIT_DEFAULT;
5052*22dc650dSSadaf Ebrahimi   break;
5053*22dc650dSSadaf Ebrahimi 
5054*22dc650dSSadaf Ebrahimi   /* Set default subject modifiers */
5055*22dc650dSSadaf Ebrahimi 
5056*22dc650dSSadaf Ebrahimi   case CMD_SUBJECT:
5057*22dc650dSSadaf Ebrahimi   (void)decode_modifiers(argptr, CTX_DEFDAT, NULL, &def_datctl);
5058*22dc650dSSadaf Ebrahimi   break;
5059*22dc650dSSadaf Ebrahimi 
5060*22dc650dSSadaf Ebrahimi   /* Check the default newline, and if not one of those listed, set up the
5061*22dc650dSSadaf Ebrahimi   first one to be forced. An empty list unsets. */
5062*22dc650dSSadaf Ebrahimi 
5063*22dc650dSSadaf Ebrahimi   case CMD_NEWLINE_DEFAULT:
5064*22dc650dSSadaf Ebrahimi   local_newline_default = 0;   /* Unset */
5065*22dc650dSSadaf Ebrahimi   first_listed_newline = 0;
5066*22dc650dSSadaf Ebrahimi   for (;;)
5067*22dc650dSSadaf Ebrahimi     {
5068*22dc650dSSadaf Ebrahimi     while (isspace(*argptr)) argptr++;
5069*22dc650dSSadaf Ebrahimi     if (*argptr == 0) break;
5070*22dc650dSSadaf Ebrahimi     for (i = 1; i < sizeof(newlines)/sizeof(char *); i++)
5071*22dc650dSSadaf Ebrahimi       {
5072*22dc650dSSadaf Ebrahimi       size_t nlen = strlen(newlines[i]);
5073*22dc650dSSadaf Ebrahimi       if (strncmpic(argptr, (const uint8_t *)newlines[i], nlen) == 0 &&
5074*22dc650dSSadaf Ebrahimi           isspace(argptr[nlen]))
5075*22dc650dSSadaf Ebrahimi         {
5076*22dc650dSSadaf Ebrahimi         if (i == NEWLINE_DEFAULT) return PR_OK;  /* Default is valid */
5077*22dc650dSSadaf Ebrahimi         if (first_listed_newline == 0) first_listed_newline = i;
5078*22dc650dSSadaf Ebrahimi         }
5079*22dc650dSSadaf Ebrahimi       }
5080*22dc650dSSadaf Ebrahimi     while (*argptr != 0 && !isspace(*argptr)) argptr++;
5081*22dc650dSSadaf Ebrahimi     }
5082*22dc650dSSadaf Ebrahimi   local_newline_default = first_listed_newline;
5083*22dc650dSSadaf Ebrahimi   break;
5084*22dc650dSSadaf Ebrahimi 
5085*22dc650dSSadaf Ebrahimi   /* Pop or copy a compiled pattern off the stack. Modifiers that do not affect
5086*22dc650dSSadaf Ebrahimi   the compiled pattern (e.g. to give information) are permitted. The default
5087*22dc650dSSadaf Ebrahimi   pattern modifiers are ignored. */
5088*22dc650dSSadaf Ebrahimi 
5089*22dc650dSSadaf Ebrahimi   case CMD_POP:
5090*22dc650dSSadaf Ebrahimi   case CMD_POPCOPY:
5091*22dc650dSSadaf Ebrahimi   if (patstacknext <= 0)
5092*22dc650dSSadaf Ebrahimi     {
5093*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Can't pop off an empty stack\n");
5094*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5095*22dc650dSSadaf Ebrahimi     }
5096*22dc650dSSadaf Ebrahimi   memset(&pat_patctl, 0, sizeof(patctl));   /* Completely unset */
5097*22dc650dSSadaf Ebrahimi   if (!decode_modifiers(argptr, CTX_POPPAT, &pat_patctl, NULL))
5098*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5099*22dc650dSSadaf Ebrahimi 
5100*22dc650dSSadaf Ebrahimi   if (cmd == CMD_POP)
5101*22dc650dSSadaf Ebrahimi     {
5102*22dc650dSSadaf Ebrahimi     SET(compiled_code, patstack[--patstacknext]);
5103*22dc650dSSadaf Ebrahimi     }
5104*22dc650dSSadaf Ebrahimi   else
5105*22dc650dSSadaf Ebrahimi     {
5106*22dc650dSSadaf Ebrahimi     PCRE2_CODE_COPY_FROM_VOID(compiled_code, patstack[patstacknext - 1]);
5107*22dc650dSSadaf Ebrahimi     }
5108*22dc650dSSadaf Ebrahimi 
5109*22dc650dSSadaf Ebrahimi   if (pat_patctl.jit != 0)
5110*22dc650dSSadaf Ebrahimi     {
5111*22dc650dSSadaf Ebrahimi     PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
5112*22dc650dSSadaf Ebrahimi     }
5113*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info();
5114*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control2 & CTL2_FRAMESIZE) != 0) show_framesize();
5115*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control & CTL_ANYINFO) != 0)
5116*22dc650dSSadaf Ebrahimi     {
5117*22dc650dSSadaf Ebrahimi     rc = show_pattern_info();
5118*22dc650dSSadaf Ebrahimi     if (rc != PR_OK) return rc;
5119*22dc650dSSadaf Ebrahimi     }
5120*22dc650dSSadaf Ebrahimi   break;
5121*22dc650dSSadaf Ebrahimi 
5122*22dc650dSSadaf Ebrahimi   /* Save the stack of compiled patterns to a file, then empty the stack. */
5123*22dc650dSSadaf Ebrahimi 
5124*22dc650dSSadaf Ebrahimi   case CMD_SAVE:
5125*22dc650dSSadaf Ebrahimi   if (patstacknext <= 0)
5126*22dc650dSSadaf Ebrahimi     {
5127*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** No stacked patterns to save\n");
5128*22dc650dSSadaf Ebrahimi     return PR_OK;
5129*22dc650dSSadaf Ebrahimi     }
5130*22dc650dSSadaf Ebrahimi 
5131*22dc650dSSadaf Ebrahimi   rc = open_file(argptr+1, BINARY_OUTPUT_MODE, &f, "#save");
5132*22dc650dSSadaf Ebrahimi   if (rc != PR_OK) return rc;
5133*22dc650dSSadaf Ebrahimi 
5134*22dc650dSSadaf Ebrahimi   PCRE2_SERIALIZE_ENCODE(rc, patstack, patstacknext, &serial, &serial_size,
5135*22dc650dSSadaf Ebrahimi     general_context);
5136*22dc650dSSadaf Ebrahimi   if (rc < 0)
5137*22dc650dSSadaf Ebrahimi     {
5138*22dc650dSSadaf Ebrahimi     fclose(f);
5139*22dc650dSSadaf Ebrahimi     if (!serial_error(rc, "Serialization")) return PR_ABEND;
5140*22dc650dSSadaf Ebrahimi     break;
5141*22dc650dSSadaf Ebrahimi     }
5142*22dc650dSSadaf Ebrahimi 
5143*22dc650dSSadaf Ebrahimi   /* Write the length at the start of the file to make it straightforward to
5144*22dc650dSSadaf Ebrahimi   get the right memory when re-loading. This saves having to read the file size
5145*22dc650dSSadaf Ebrahimi   in different operating systems. To allow for different endianness (even
5146*22dc650dSSadaf Ebrahimi   though reloading with the opposite endianness does not work), write the
5147*22dc650dSSadaf Ebrahimi   length byte-by-byte. */
5148*22dc650dSSadaf Ebrahimi 
5149*22dc650dSSadaf Ebrahimi   for (i = 0; i < 4; i++) fputc((serial_size >> (i*8)) & 255, f);
5150*22dc650dSSadaf Ebrahimi   if (fwrite(serial, 1, serial_size, f) != serial_size)
5151*22dc650dSSadaf Ebrahimi     {
5152*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Wrong return from fwrite()\n");
5153*22dc650dSSadaf Ebrahimi     fclose(f);
5154*22dc650dSSadaf Ebrahimi     return PR_ABEND;
5155*22dc650dSSadaf Ebrahimi     }
5156*22dc650dSSadaf Ebrahimi 
5157*22dc650dSSadaf Ebrahimi   fclose(f);
5158*22dc650dSSadaf Ebrahimi   PCRE2_SERIALIZE_FREE(serial);
5159*22dc650dSSadaf Ebrahimi   while(patstacknext > 0)
5160*22dc650dSSadaf Ebrahimi     {
5161*22dc650dSSadaf Ebrahimi     SET(compiled_code, patstack[--patstacknext]);
5162*22dc650dSSadaf Ebrahimi     SUB1(pcre2_code_free, compiled_code);
5163*22dc650dSSadaf Ebrahimi     }
5164*22dc650dSSadaf Ebrahimi   SET(compiled_code, NULL);
5165*22dc650dSSadaf Ebrahimi   break;
5166*22dc650dSSadaf Ebrahimi 
5167*22dc650dSSadaf Ebrahimi   /* Load a set of compiled patterns from a file onto the stack */
5168*22dc650dSSadaf Ebrahimi 
5169*22dc650dSSadaf Ebrahimi   case CMD_LOAD:
5170*22dc650dSSadaf Ebrahimi   rc = open_file(argptr+1, BINARY_INPUT_MODE, &f, "#load");
5171*22dc650dSSadaf Ebrahimi   if (rc != PR_OK) return rc;
5172*22dc650dSSadaf Ebrahimi 
5173*22dc650dSSadaf Ebrahimi   serial_size = 0;
5174*22dc650dSSadaf Ebrahimi   for (i = 0; i < 4; i++) serial_size |= fgetc(f) << (i*8);
5175*22dc650dSSadaf Ebrahimi 
5176*22dc650dSSadaf Ebrahimi   serial = malloc(serial_size);
5177*22dc650dSSadaf Ebrahimi   if (serial == NULL)
5178*22dc650dSSadaf Ebrahimi     {
5179*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Failed to get memory (size %" SIZ_FORM ") for #load\n",
5180*22dc650dSSadaf Ebrahimi       serial_size);
5181*22dc650dSSadaf Ebrahimi     fclose(f);
5182*22dc650dSSadaf Ebrahimi     return PR_ABEND;
5183*22dc650dSSadaf Ebrahimi     }
5184*22dc650dSSadaf Ebrahimi 
5185*22dc650dSSadaf Ebrahimi   i = fread(serial, 1, serial_size, f);
5186*22dc650dSSadaf Ebrahimi   fclose(f);
5187*22dc650dSSadaf Ebrahimi 
5188*22dc650dSSadaf Ebrahimi   if (i != serial_size)
5189*22dc650dSSadaf Ebrahimi     {
5190*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Wrong return from fread()\n");
5191*22dc650dSSadaf Ebrahimi     yield = PR_ABEND;
5192*22dc650dSSadaf Ebrahimi     }
5193*22dc650dSSadaf Ebrahimi   else
5194*22dc650dSSadaf Ebrahimi     {
5195*22dc650dSSadaf Ebrahimi     PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(rc, serial);
5196*22dc650dSSadaf Ebrahimi     if (rc < 0)
5197*22dc650dSSadaf Ebrahimi       {
5198*22dc650dSSadaf Ebrahimi       if (!serial_error(rc, "Get number of codes")) yield = PR_ABEND;
5199*22dc650dSSadaf Ebrahimi       }
5200*22dc650dSSadaf Ebrahimi     else
5201*22dc650dSSadaf Ebrahimi       {
5202*22dc650dSSadaf Ebrahimi       if (rc + patstacknext > PATSTACKSIZE)
5203*22dc650dSSadaf Ebrahimi         {
5204*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Not enough space on pattern stack for %d pattern%s\n",
5205*22dc650dSSadaf Ebrahimi           rc, (rc == 1)? "" : "s");
5206*22dc650dSSadaf Ebrahimi         rc = PATSTACKSIZE - patstacknext;
5207*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Decoding %d pattern%s\n", rc,
5208*22dc650dSSadaf Ebrahimi           (rc == 1)? "" : "s");
5209*22dc650dSSadaf Ebrahimi         }
5210*22dc650dSSadaf Ebrahimi       PCRE2_SERIALIZE_DECODE(rc, patstack + patstacknext, rc, serial,
5211*22dc650dSSadaf Ebrahimi         general_context);
5212*22dc650dSSadaf Ebrahimi       if (rc < 0)
5213*22dc650dSSadaf Ebrahimi         {
5214*22dc650dSSadaf Ebrahimi         if (!serial_error(rc, "Deserialization")) yield = PR_ABEND;
5215*22dc650dSSadaf Ebrahimi         }
5216*22dc650dSSadaf Ebrahimi       else patstacknext += rc;
5217*22dc650dSSadaf Ebrahimi       }
5218*22dc650dSSadaf Ebrahimi     }
5219*22dc650dSSadaf Ebrahimi 
5220*22dc650dSSadaf Ebrahimi   free(serial);
5221*22dc650dSSadaf Ebrahimi   break;
5222*22dc650dSSadaf Ebrahimi 
5223*22dc650dSSadaf Ebrahimi   /* Load a set of binary tables into tables3. */
5224*22dc650dSSadaf Ebrahimi 
5225*22dc650dSSadaf Ebrahimi   case CMD_LOADTABLES:
5226*22dc650dSSadaf Ebrahimi   rc = open_file(argptr+1, BINARY_INPUT_MODE, &f, "#loadtables");
5227*22dc650dSSadaf Ebrahimi   if (rc != PR_OK) return rc;
5228*22dc650dSSadaf Ebrahimi 
5229*22dc650dSSadaf Ebrahimi   if (tables3 == NULL)
5230*22dc650dSSadaf Ebrahimi     {
5231*22dc650dSSadaf Ebrahimi     (void)PCRE2_CONFIG(PCRE2_CONFIG_TABLES_LENGTH, &loadtables_length);
5232*22dc650dSSadaf Ebrahimi     tables3 = malloc(loadtables_length);
5233*22dc650dSSadaf Ebrahimi     }
5234*22dc650dSSadaf Ebrahimi 
5235*22dc650dSSadaf Ebrahimi   if (tables3 == NULL)
5236*22dc650dSSadaf Ebrahimi     {
5237*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Failed: malloc failed for #loadtables\n");
5238*22dc650dSSadaf Ebrahimi     yield = PR_ABEND;
5239*22dc650dSSadaf Ebrahimi     }
5240*22dc650dSSadaf Ebrahimi   else if (fread(tables3, 1, loadtables_length, f) != loadtables_length)
5241*22dc650dSSadaf Ebrahimi     {
5242*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Wrong return from fread()\n");
5243*22dc650dSSadaf Ebrahimi     yield = PR_ABEND;
5244*22dc650dSSadaf Ebrahimi     }
5245*22dc650dSSadaf Ebrahimi 
5246*22dc650dSSadaf Ebrahimi   fclose(f);
5247*22dc650dSSadaf Ebrahimi   break;
5248*22dc650dSSadaf Ebrahimi   }
5249*22dc650dSSadaf Ebrahimi 
5250*22dc650dSSadaf Ebrahimi return yield;
5251*22dc650dSSadaf Ebrahimi }
5252*22dc650dSSadaf Ebrahimi 
5253*22dc650dSSadaf Ebrahimi 
5254*22dc650dSSadaf Ebrahimi 
5255*22dc650dSSadaf Ebrahimi /*************************************************
5256*22dc650dSSadaf Ebrahimi *               Process pattern line             *
5257*22dc650dSSadaf Ebrahimi *************************************************/
5258*22dc650dSSadaf Ebrahimi 
5259*22dc650dSSadaf Ebrahimi /* This function is called when the input buffer contains the start of a
5260*22dc650dSSadaf Ebrahimi pattern. The first character is known to be a valid delimiter. The pattern is
5261*22dc650dSSadaf Ebrahimi read, modifiers are interpreted, and a suitable local context is set up for
5262*22dc650dSSadaf Ebrahimi this test. The pattern is then compiled.
5263*22dc650dSSadaf Ebrahimi 
5264*22dc650dSSadaf Ebrahimi Arguments:  none
5265*22dc650dSSadaf Ebrahimi 
5266*22dc650dSSadaf Ebrahimi Returns:    PR_OK     continue processing next line
5267*22dc650dSSadaf Ebrahimi             PR_SKIP   skip to a blank line
5268*22dc650dSSadaf Ebrahimi             PR_ABEND  abort the pcre2test run
5269*22dc650dSSadaf Ebrahimi */
5270*22dc650dSSadaf Ebrahimi 
5271*22dc650dSSadaf Ebrahimi static int
process_pattern(void)5272*22dc650dSSadaf Ebrahimi process_pattern(void)
5273*22dc650dSSadaf Ebrahimi {
5274*22dc650dSSadaf Ebrahimi BOOL utf;
5275*22dc650dSSadaf Ebrahimi uint32_t k;
5276*22dc650dSSadaf Ebrahimi uint8_t *p = buffer;
5277*22dc650dSSadaf Ebrahimi unsigned int delimiter = *p++;
5278*22dc650dSSadaf Ebrahimi int errorcode;
5279*22dc650dSSadaf Ebrahimi void *use_pat_context;
5280*22dc650dSSadaf Ebrahimi void *use_pbuffer = NULL;
5281*22dc650dSSadaf Ebrahimi uint32_t use_forbid_utf = forbid_utf;
5282*22dc650dSSadaf Ebrahimi PCRE2_SIZE patlen;
5283*22dc650dSSadaf Ebrahimi PCRE2_SIZE valgrind_access_length;
5284*22dc650dSSadaf Ebrahimi PCRE2_SIZE erroroffset;
5285*22dc650dSSadaf Ebrahimi 
5286*22dc650dSSadaf Ebrahimi /* The perltest.sh script supports only / as a delimiter. */
5287*22dc650dSSadaf Ebrahimi 
5288*22dc650dSSadaf Ebrahimi if (restrict_for_perl_test && delimiter != '/')
5289*22dc650dSSadaf Ebrahimi   {
5290*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** The only allowed delimiter after #perltest is '/'\n");
5291*22dc650dSSadaf Ebrahimi   return PR_ABEND;
5292*22dc650dSSadaf Ebrahimi   }
5293*22dc650dSSadaf Ebrahimi 
5294*22dc650dSSadaf Ebrahimi /* Initialize the context and pattern/data controls for this test from the
5295*22dc650dSSadaf Ebrahimi defaults. */
5296*22dc650dSSadaf Ebrahimi 
5297*22dc650dSSadaf Ebrahimi PATCTXCPY(pat_context, default_pat_context);
5298*22dc650dSSadaf Ebrahimi memcpy(&pat_patctl, &def_patctl, sizeof(patctl));
5299*22dc650dSSadaf Ebrahimi 
5300*22dc650dSSadaf Ebrahimi /* Find the end of the pattern, reading more lines if necessary. */
5301*22dc650dSSadaf Ebrahimi 
5302*22dc650dSSadaf Ebrahimi for(;;)
5303*22dc650dSSadaf Ebrahimi   {
5304*22dc650dSSadaf Ebrahimi   while (*p != 0)
5305*22dc650dSSadaf Ebrahimi     {
5306*22dc650dSSadaf Ebrahimi     if (*p == '\\' && p[1] != 0) p++;
5307*22dc650dSSadaf Ebrahimi       else if (*p == delimiter) break;
5308*22dc650dSSadaf Ebrahimi     p++;
5309*22dc650dSSadaf Ebrahimi     }
5310*22dc650dSSadaf Ebrahimi   if (*p != 0) break;
5311*22dc650dSSadaf Ebrahimi   if ((p = extend_inputline(infile, p, "    > ")) == NULL)
5312*22dc650dSSadaf Ebrahimi     {
5313*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Unexpected EOF\n");
5314*22dc650dSSadaf Ebrahimi     return PR_ABEND;
5315*22dc650dSSadaf Ebrahimi     }
5316*22dc650dSSadaf Ebrahimi   if (!INTERACTIVE(infile)) fprintf(outfile, "%s", (char *)p);
5317*22dc650dSSadaf Ebrahimi   }
5318*22dc650dSSadaf Ebrahimi 
5319*22dc650dSSadaf Ebrahimi /* If the first character after the delimiter is backslash, make the pattern
5320*22dc650dSSadaf Ebrahimi end with backslash. This is purely to provide a way of testing for the error
5321*22dc650dSSadaf Ebrahimi message when a pattern ends with backslash. */
5322*22dc650dSSadaf Ebrahimi 
5323*22dc650dSSadaf Ebrahimi if (p[1] == '\\') *p++ = '\\';
5324*22dc650dSSadaf Ebrahimi 
5325*22dc650dSSadaf Ebrahimi /* Terminate the pattern at the delimiter, and compute the length. */
5326*22dc650dSSadaf Ebrahimi 
5327*22dc650dSSadaf Ebrahimi *p++ = 0;
5328*22dc650dSSadaf Ebrahimi patlen = p - buffer - 2;
5329*22dc650dSSadaf Ebrahimi 
5330*22dc650dSSadaf Ebrahimi /* Look for modifiers and options after the final delimiter. */
5331*22dc650dSSadaf Ebrahimi 
5332*22dc650dSSadaf Ebrahimi if (!decode_modifiers(p, CTX_PAT, &pat_patctl, NULL)) return PR_SKIP;
5333*22dc650dSSadaf Ebrahimi 
5334*22dc650dSSadaf Ebrahimi /* Note that the match_invalid_utf option also sets utf when passed to
5335*22dc650dSSadaf Ebrahimi pcre2_compile(). */
5336*22dc650dSSadaf Ebrahimi 
5337*22dc650dSSadaf Ebrahimi utf = (pat_patctl.options & (PCRE2_UTF|PCRE2_MATCH_INVALID_UTF)) != 0;
5338*22dc650dSSadaf Ebrahimi 
5339*22dc650dSSadaf Ebrahimi /* The utf8_input modifier is not allowed in 8-bit mode, and is mutually
5340*22dc650dSSadaf Ebrahimi exclusive with the utf modifier. */
5341*22dc650dSSadaf Ebrahimi 
5342*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_UTF8_INPUT) != 0)
5343*22dc650dSSadaf Ebrahimi   {
5344*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE)
5345*22dc650dSSadaf Ebrahimi     {
5346*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** The utf8_input modifier is not allowed in 8-bit mode\n");
5347*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5348*22dc650dSSadaf Ebrahimi     }
5349*22dc650dSSadaf Ebrahimi   if (utf)
5350*22dc650dSSadaf Ebrahimi     {
5351*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** The utf and utf8_input modifiers are mutually exclusive\n");
5352*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5353*22dc650dSSadaf Ebrahimi     }
5354*22dc650dSSadaf Ebrahimi   }
5355*22dc650dSSadaf Ebrahimi 
5356*22dc650dSSadaf Ebrahimi /* The convert and posix modifiers are mutually exclusive. */
5357*22dc650dSSadaf Ebrahimi 
5358*22dc650dSSadaf Ebrahimi if (pat_patctl.convert_type != CONVERT_UNSET &&
5359*22dc650dSSadaf Ebrahimi     (pat_patctl.control & CTL_POSIX) != 0)
5360*22dc650dSSadaf Ebrahimi   {
5361*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** The convert and posix modifiers are mutually exclusive\n");
5362*22dc650dSSadaf Ebrahimi   return PR_SKIP;
5363*22dc650dSSadaf Ebrahimi   }
5364*22dc650dSSadaf Ebrahimi 
5365*22dc650dSSadaf Ebrahimi /* Check for mutually exclusive control modifiers. At present, these are all in
5366*22dc650dSSadaf Ebrahimi the first control word. */
5367*22dc650dSSadaf Ebrahimi 
5368*22dc650dSSadaf Ebrahimi for (k = 0; k < sizeof(exclusive_pat_controls)/sizeof(uint32_t); k++)
5369*22dc650dSSadaf Ebrahimi   {
5370*22dc650dSSadaf Ebrahimi   uint32_t c = pat_patctl.control & exclusive_pat_controls[k];
5371*22dc650dSSadaf Ebrahimi   if (c != 0 && c != (c & (~c+1)))
5372*22dc650dSSadaf Ebrahimi     {
5373*22dc650dSSadaf Ebrahimi     show_controls(c, 0, "** Not allowed together:");
5374*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\n");
5375*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5376*22dc650dSSadaf Ebrahimi     }
5377*22dc650dSSadaf Ebrahimi   }
5378*22dc650dSSadaf Ebrahimi 
5379*22dc650dSSadaf Ebrahimi /* Assume full JIT compile for jitverify and/or jitfast if nothing else was
5380*22dc650dSSadaf Ebrahimi specified. */
5381*22dc650dSSadaf Ebrahimi 
5382*22dc650dSSadaf Ebrahimi if (pat_patctl.jit == 0 &&
5383*22dc650dSSadaf Ebrahimi     (pat_patctl.control & (CTL_JITVERIFY|CTL_JITFAST)) != 0)
5384*22dc650dSSadaf Ebrahimi   pat_patctl.jit = JIT_DEFAULT;
5385*22dc650dSSadaf Ebrahimi 
5386*22dc650dSSadaf Ebrahimi /* Now copy the pattern to pbuffer8 for use in 8-bit testing and for reflecting
5387*22dc650dSSadaf Ebrahimi in callouts. Convert from hex if requested (literal strings in quotes may be
5388*22dc650dSSadaf Ebrahimi present within the hexadecimal pairs). The result must necessarily be fewer
5389*22dc650dSSadaf Ebrahimi characters so will always fit in pbuffer8. */
5390*22dc650dSSadaf Ebrahimi 
5391*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_HEXPAT) != 0)
5392*22dc650dSSadaf Ebrahimi   {
5393*22dc650dSSadaf Ebrahimi   uint8_t *pp, *pt;
5394*22dc650dSSadaf Ebrahimi   uint32_t c, d;
5395*22dc650dSSadaf Ebrahimi 
5396*22dc650dSSadaf Ebrahimi   pt = pbuffer8;
5397*22dc650dSSadaf Ebrahimi   for (pp = buffer + 1; *pp != 0; pp++)
5398*22dc650dSSadaf Ebrahimi     {
5399*22dc650dSSadaf Ebrahimi     if (isspace(*pp)) continue;
5400*22dc650dSSadaf Ebrahimi     c = *pp++;
5401*22dc650dSSadaf Ebrahimi 
5402*22dc650dSSadaf Ebrahimi     /* Handle a literal substring */
5403*22dc650dSSadaf Ebrahimi 
5404*22dc650dSSadaf Ebrahimi     if (c == '\'' || c == '"')
5405*22dc650dSSadaf Ebrahimi       {
5406*22dc650dSSadaf Ebrahimi       uint8_t *pq = pp;
5407*22dc650dSSadaf Ebrahimi       for (;; pp++)
5408*22dc650dSSadaf Ebrahimi         {
5409*22dc650dSSadaf Ebrahimi         d = *pp;
5410*22dc650dSSadaf Ebrahimi         if (d == 0)
5411*22dc650dSSadaf Ebrahimi           {
5412*22dc650dSSadaf Ebrahimi           fprintf(outfile, "** Missing closing quote in hex pattern: "
5413*22dc650dSSadaf Ebrahimi             "opening quote is at offset %" PTR_FORM ".\n", pq - buffer - 2);
5414*22dc650dSSadaf Ebrahimi           return PR_SKIP;
5415*22dc650dSSadaf Ebrahimi           }
5416*22dc650dSSadaf Ebrahimi         if (d == c) break;
5417*22dc650dSSadaf Ebrahimi         *pt++ = d;
5418*22dc650dSSadaf Ebrahimi         }
5419*22dc650dSSadaf Ebrahimi       }
5420*22dc650dSSadaf Ebrahimi 
5421*22dc650dSSadaf Ebrahimi     /* Expect a hex pair */
5422*22dc650dSSadaf Ebrahimi 
5423*22dc650dSSadaf Ebrahimi     else
5424*22dc650dSSadaf Ebrahimi       {
5425*22dc650dSSadaf Ebrahimi       if (!isxdigit(c))
5426*22dc650dSSadaf Ebrahimi         {
5427*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Unexpected non-hex-digit '%c' at offset %"
5428*22dc650dSSadaf Ebrahimi           PTR_FORM " in hex pattern: quote missing?\n", c, pp - buffer - 2);
5429*22dc650dSSadaf Ebrahimi         return PR_SKIP;
5430*22dc650dSSadaf Ebrahimi         }
5431*22dc650dSSadaf Ebrahimi       if (*pp == 0)
5432*22dc650dSSadaf Ebrahimi         {
5433*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Odd number of digits in hex pattern\n");
5434*22dc650dSSadaf Ebrahimi         return PR_SKIP;
5435*22dc650dSSadaf Ebrahimi         }
5436*22dc650dSSadaf Ebrahimi       d = *pp;
5437*22dc650dSSadaf Ebrahimi       if (!isxdigit(d))
5438*22dc650dSSadaf Ebrahimi         {
5439*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Unexpected non-hex-digit '%c' at offset %"
5440*22dc650dSSadaf Ebrahimi           PTR_FORM " in hex pattern: quote missing?\n", d, pp - buffer - 1);
5441*22dc650dSSadaf Ebrahimi         return PR_SKIP;
5442*22dc650dSSadaf Ebrahimi         }
5443*22dc650dSSadaf Ebrahimi       c = toupper(c);
5444*22dc650dSSadaf Ebrahimi       d = toupper(d);
5445*22dc650dSSadaf Ebrahimi       *pt++ = ((isdigit(c)? (c - '0') : (c - 'A' + 10)) << 4) +
5446*22dc650dSSadaf Ebrahimi                (isdigit(d)? (d - '0') : (d - 'A' + 10));
5447*22dc650dSSadaf Ebrahimi       }
5448*22dc650dSSadaf Ebrahimi     }
5449*22dc650dSSadaf Ebrahimi   *pt = 0;
5450*22dc650dSSadaf Ebrahimi   patlen = pt - pbuffer8;
5451*22dc650dSSadaf Ebrahimi   }
5452*22dc650dSSadaf Ebrahimi 
5453*22dc650dSSadaf Ebrahimi /* If not a hex string, process for repetition expansion if requested. */
5454*22dc650dSSadaf Ebrahimi 
5455*22dc650dSSadaf Ebrahimi else if ((pat_patctl.control & CTL_EXPAND) != 0)
5456*22dc650dSSadaf Ebrahimi   {
5457*22dc650dSSadaf Ebrahimi   uint8_t *pp, *pt;
5458*22dc650dSSadaf Ebrahimi 
5459*22dc650dSSadaf Ebrahimi   pt = pbuffer8;
5460*22dc650dSSadaf Ebrahimi   for (pp = buffer + 1; *pp != 0; pp++)
5461*22dc650dSSadaf Ebrahimi     {
5462*22dc650dSSadaf Ebrahimi     uint8_t *pc = pp;
5463*22dc650dSSadaf Ebrahimi     uint32_t count = 1;
5464*22dc650dSSadaf Ebrahimi     size_t length = 1;
5465*22dc650dSSadaf Ebrahimi 
5466*22dc650dSSadaf Ebrahimi     /* Check for replication syntax; if not found, the defaults just set will
5467*22dc650dSSadaf Ebrahimi     prevail and one character will be copied. */
5468*22dc650dSSadaf Ebrahimi 
5469*22dc650dSSadaf Ebrahimi     if (pp[0] == '\\' && pp[1] == '[')
5470*22dc650dSSadaf Ebrahimi       {
5471*22dc650dSSadaf Ebrahimi       uint8_t *pe;
5472*22dc650dSSadaf Ebrahimi       for (pe = pp + 2; *pe != 0; pe++)
5473*22dc650dSSadaf Ebrahimi         {
5474*22dc650dSSadaf Ebrahimi         if (pe[0] == ']' && pe[1] == '{')
5475*22dc650dSSadaf Ebrahimi           {
5476*22dc650dSSadaf Ebrahimi           uint32_t clen = pe - pc - 2;
5477*22dc650dSSadaf Ebrahimi           uint32_t i = 0;
5478*22dc650dSSadaf Ebrahimi           unsigned long uli;
5479*22dc650dSSadaf Ebrahimi           char *endptr;
5480*22dc650dSSadaf Ebrahimi 
5481*22dc650dSSadaf Ebrahimi           pe += 2;
5482*22dc650dSSadaf Ebrahimi           uli = strtoul((const char *)pe, &endptr, 10);
5483*22dc650dSSadaf Ebrahimi           if (U32OVERFLOW(uli))
5484*22dc650dSSadaf Ebrahimi             {
5485*22dc650dSSadaf Ebrahimi             fprintf(outfile, "** Pattern repeat count too large\n");
5486*22dc650dSSadaf Ebrahimi             return PR_SKIP;
5487*22dc650dSSadaf Ebrahimi             }
5488*22dc650dSSadaf Ebrahimi 
5489*22dc650dSSadaf Ebrahimi           i = (uint32_t)uli;
5490*22dc650dSSadaf Ebrahimi           pe = (uint8_t *)endptr;
5491*22dc650dSSadaf Ebrahimi           if (*pe == '}')
5492*22dc650dSSadaf Ebrahimi             {
5493*22dc650dSSadaf Ebrahimi             if (i == 0)
5494*22dc650dSSadaf Ebrahimi               {
5495*22dc650dSSadaf Ebrahimi               fprintf(outfile, "** Zero repeat not allowed\n");
5496*22dc650dSSadaf Ebrahimi               return PR_SKIP;
5497*22dc650dSSadaf Ebrahimi               }
5498*22dc650dSSadaf Ebrahimi             pc += 2;
5499*22dc650dSSadaf Ebrahimi             count = i;
5500*22dc650dSSadaf Ebrahimi             length = clen;
5501*22dc650dSSadaf Ebrahimi             pp = pe;
5502*22dc650dSSadaf Ebrahimi             break;
5503*22dc650dSSadaf Ebrahimi             }
5504*22dc650dSSadaf Ebrahimi           }
5505*22dc650dSSadaf Ebrahimi         }
5506*22dc650dSSadaf Ebrahimi       }
5507*22dc650dSSadaf Ebrahimi 
5508*22dc650dSSadaf Ebrahimi     /* Add to output. If the buffer is too small expand it. The function for
5509*22dc650dSSadaf Ebrahimi     expanding buffers always keeps buffer and pbuffer8 in step as far as their
5510*22dc650dSSadaf Ebrahimi     size goes. */
5511*22dc650dSSadaf Ebrahimi 
5512*22dc650dSSadaf Ebrahimi     while (pt + count * length > pbuffer8 + pbuffer8_size)
5513*22dc650dSSadaf Ebrahimi       {
5514*22dc650dSSadaf Ebrahimi       size_t pc_offset = pc - buffer;
5515*22dc650dSSadaf Ebrahimi       size_t pp_offset = pp - buffer;
5516*22dc650dSSadaf Ebrahimi       size_t pt_offset = pt - pbuffer8;
5517*22dc650dSSadaf Ebrahimi       expand_input_buffers();
5518*22dc650dSSadaf Ebrahimi       pc = buffer + pc_offset;
5519*22dc650dSSadaf Ebrahimi       pp = buffer + pp_offset;
5520*22dc650dSSadaf Ebrahimi       pt = pbuffer8 + pt_offset;
5521*22dc650dSSadaf Ebrahimi       }
5522*22dc650dSSadaf Ebrahimi 
5523*22dc650dSSadaf Ebrahimi     for (; count > 0; count--)
5524*22dc650dSSadaf Ebrahimi       {
5525*22dc650dSSadaf Ebrahimi       memcpy(pt, pc, length);
5526*22dc650dSSadaf Ebrahimi       pt += length;
5527*22dc650dSSadaf Ebrahimi       }
5528*22dc650dSSadaf Ebrahimi     }
5529*22dc650dSSadaf Ebrahimi 
5530*22dc650dSSadaf Ebrahimi   *pt = 0;
5531*22dc650dSSadaf Ebrahimi   patlen = pt - pbuffer8;
5532*22dc650dSSadaf Ebrahimi 
5533*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control & CTL_INFO) != 0)
5534*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Expanded: %s\n", pbuffer8);
5535*22dc650dSSadaf Ebrahimi   }
5536*22dc650dSSadaf Ebrahimi 
5537*22dc650dSSadaf Ebrahimi /* Neither hex nor expanded, just copy the input verbatim. */
5538*22dc650dSSadaf Ebrahimi 
5539*22dc650dSSadaf Ebrahimi else
5540*22dc650dSSadaf Ebrahimi   {
5541*22dc650dSSadaf Ebrahimi   strncpy((char *)pbuffer8, (char *)(buffer+1), patlen + 1);
5542*22dc650dSSadaf Ebrahimi   }
5543*22dc650dSSadaf Ebrahimi 
5544*22dc650dSSadaf Ebrahimi /* Sort out character tables */
5545*22dc650dSSadaf Ebrahimi 
5546*22dc650dSSadaf Ebrahimi if (pat_patctl.locale[0] != 0)
5547*22dc650dSSadaf Ebrahimi   {
5548*22dc650dSSadaf Ebrahimi   if (pat_patctl.tables_id != 0)
5549*22dc650dSSadaf Ebrahimi     {
5550*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** 'Locale' and 'tables' must not both be set\n");
5551*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5552*22dc650dSSadaf Ebrahimi     }
5553*22dc650dSSadaf Ebrahimi   if (setlocale(LC_CTYPE, (const char *)pat_patctl.locale) == NULL)
5554*22dc650dSSadaf Ebrahimi     {
5555*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Failed to set locale '%s'\n", pat_patctl.locale);
5556*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5557*22dc650dSSadaf Ebrahimi     }
5558*22dc650dSSadaf Ebrahimi   if (strcmp((const char *)pat_patctl.locale, (const char *)locale_name) != 0)
5559*22dc650dSSadaf Ebrahimi     {
5560*22dc650dSSadaf Ebrahimi     strcpy((char *)locale_name, (char *)pat_patctl.locale);
5561*22dc650dSSadaf Ebrahimi     if (locale_tables != NULL)
5562*22dc650dSSadaf Ebrahimi       {
5563*22dc650dSSadaf Ebrahimi       PCRE2_MAKETABLES_FREE(general_context, (void *)locale_tables);
5564*22dc650dSSadaf Ebrahimi       }
5565*22dc650dSSadaf Ebrahimi     PCRE2_MAKETABLES(locale_tables, general_context);
5566*22dc650dSSadaf Ebrahimi     }
5567*22dc650dSSadaf Ebrahimi   use_tables = locale_tables;
5568*22dc650dSSadaf Ebrahimi   }
5569*22dc650dSSadaf Ebrahimi 
5570*22dc650dSSadaf Ebrahimi else switch (pat_patctl.tables_id)
5571*22dc650dSSadaf Ebrahimi   {
5572*22dc650dSSadaf Ebrahimi   case 0: use_tables = NULL; break;
5573*22dc650dSSadaf Ebrahimi   case 1: use_tables = tables1; break;
5574*22dc650dSSadaf Ebrahimi   case 2: use_tables = tables2; break;
5575*22dc650dSSadaf Ebrahimi 
5576*22dc650dSSadaf Ebrahimi   case 3:
5577*22dc650dSSadaf Ebrahimi   if (tables3 == NULL)
5578*22dc650dSSadaf Ebrahimi     {
5579*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** 'Tables = 3' is invalid: binary tables have not "
5580*22dc650dSSadaf Ebrahimi       "been loaded\n");
5581*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5582*22dc650dSSadaf Ebrahimi     }
5583*22dc650dSSadaf Ebrahimi   use_tables = tables3;
5584*22dc650dSSadaf Ebrahimi   break;
5585*22dc650dSSadaf Ebrahimi 
5586*22dc650dSSadaf Ebrahimi   default:
5587*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** 'Tables' must specify 0, 1, 2, or 3.\n");
5588*22dc650dSSadaf Ebrahimi   return PR_SKIP;
5589*22dc650dSSadaf Ebrahimi   }
5590*22dc650dSSadaf Ebrahimi 
5591*22dc650dSSadaf Ebrahimi PCRE2_SET_CHARACTER_TABLES(pat_context, use_tables);
5592*22dc650dSSadaf Ebrahimi 
5593*22dc650dSSadaf Ebrahimi /* Set up for the stackguard test. */
5594*22dc650dSSadaf Ebrahimi 
5595*22dc650dSSadaf Ebrahimi if (pat_patctl.stackguard_test != 0)
5596*22dc650dSSadaf Ebrahimi   {
5597*22dc650dSSadaf Ebrahimi   PCRE2_SET_COMPILE_RECURSION_GUARD(pat_context, stack_guard, NULL);
5598*22dc650dSSadaf Ebrahimi   }
5599*22dc650dSSadaf Ebrahimi 
5600*22dc650dSSadaf Ebrahimi /* Handle compiling via the POSIX interface, which doesn't support the
5601*22dc650dSSadaf Ebrahimi timing, showing, or debugging options, nor the ability to pass over
5602*22dc650dSSadaf Ebrahimi local character tables. Neither does it have 16-bit or 32-bit support. */
5603*22dc650dSSadaf Ebrahimi 
5604*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_POSIX) != 0)
5605*22dc650dSSadaf Ebrahimi   {
5606*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
5607*22dc650dSSadaf Ebrahimi   int rc;
5608*22dc650dSSadaf Ebrahimi   int cflags = 0;
5609*22dc650dSSadaf Ebrahimi   const char *msg = "** Ignored with POSIX interface:";
5610*22dc650dSSadaf Ebrahimi #endif
5611*22dc650dSSadaf Ebrahimi 
5612*22dc650dSSadaf Ebrahimi   if (test_mode != PCRE8_MODE)
5613*22dc650dSSadaf Ebrahimi     {
5614*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** The POSIX interface is available only in 8-bit mode\n");
5615*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5616*22dc650dSSadaf Ebrahimi     }
5617*22dc650dSSadaf Ebrahimi 
5618*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
5619*22dc650dSSadaf Ebrahimi   /* Check for features that the POSIX interface does not support. */
5620*22dc650dSSadaf Ebrahimi 
5621*22dc650dSSadaf Ebrahimi   if (pat_patctl.locale[0] != 0) prmsg(&msg, "locale");
5622*22dc650dSSadaf Ebrahimi   if (pat_patctl.replacement[0] != 0) prmsg(&msg, "replace");
5623*22dc650dSSadaf Ebrahimi   if (pat_patctl.tables_id != 0) prmsg(&msg, "tables");
5624*22dc650dSSadaf Ebrahimi   if (pat_patctl.stackguard_test != 0) prmsg(&msg, "stackguard");
5625*22dc650dSSadaf Ebrahimi   if (timeit > 0) prmsg(&msg, "timing");
5626*22dc650dSSadaf Ebrahimi   if (pat_patctl.jit != 0) prmsg(&msg, "JIT");
5627*22dc650dSSadaf Ebrahimi 
5628*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & ~POSIX_SUPPORTED_COMPILE_OPTIONS) != 0)
5629*22dc650dSSadaf Ebrahimi     {
5630*22dc650dSSadaf Ebrahimi     show_compile_options(
5631*22dc650dSSadaf Ebrahimi       pat_patctl.options & (uint32_t)(~POSIX_SUPPORTED_COMPILE_OPTIONS),
5632*22dc650dSSadaf Ebrahimi         msg, "");
5633*22dc650dSSadaf Ebrahimi     msg = "";
5634*22dc650dSSadaf Ebrahimi     }
5635*22dc650dSSadaf Ebrahimi 
5636*22dc650dSSadaf Ebrahimi   if ((FLD(pat_context, extra_options) &
5637*22dc650dSSadaf Ebrahimi        (uint32_t)(~POSIX_SUPPORTED_COMPILE_EXTRA_OPTIONS)) != 0)
5638*22dc650dSSadaf Ebrahimi     {
5639*22dc650dSSadaf Ebrahimi     show_compile_extra_options(
5640*22dc650dSSadaf Ebrahimi       FLD(pat_context, extra_options) &
5641*22dc650dSSadaf Ebrahimi         (uint32_t)(~POSIX_SUPPORTED_COMPILE_EXTRA_OPTIONS), msg, "");
5642*22dc650dSSadaf Ebrahimi     msg = "";
5643*22dc650dSSadaf Ebrahimi     }
5644*22dc650dSSadaf Ebrahimi 
5645*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control & (uint32_t)(~POSIX_SUPPORTED_COMPILE_CONTROLS)) != 0 ||
5646*22dc650dSSadaf Ebrahimi       (pat_patctl.control2 & (uint32_t)(~POSIX_SUPPORTED_COMPILE_CONTROLS2)) != 0)
5647*22dc650dSSadaf Ebrahimi     {
5648*22dc650dSSadaf Ebrahimi     show_controls(
5649*22dc650dSSadaf Ebrahimi       pat_patctl.control & (uint32_t)(~POSIX_SUPPORTED_COMPILE_CONTROLS),
5650*22dc650dSSadaf Ebrahimi       pat_patctl.control2 & (uint32_t)(~POSIX_SUPPORTED_COMPILE_CONTROLS2),
5651*22dc650dSSadaf Ebrahimi       msg);
5652*22dc650dSSadaf Ebrahimi     msg = "";
5653*22dc650dSSadaf Ebrahimi 
5654*22dc650dSSadaf Ebrahimi     /* Remove ignored options so as not to get a repeated message for those
5655*22dc650dSSadaf Ebrahimi     that are actually subject controls. */
5656*22dc650dSSadaf Ebrahimi 
5657*22dc650dSSadaf Ebrahimi     pat_patctl.control &= (uint32_t)(POSIX_SUPPORTED_COMPILE_CONTROLS);
5658*22dc650dSSadaf Ebrahimi     pat_patctl.control2 &= (uint32_t)(POSIX_SUPPORTED_COMPILE_CONTROLS2);
5659*22dc650dSSadaf Ebrahimi     }
5660*22dc650dSSadaf Ebrahimi 
5661*22dc650dSSadaf Ebrahimi   if (local_newline_default != 0) prmsg(&msg, "#newline_default");
5662*22dc650dSSadaf Ebrahimi   if (FLD(pat_context, max_pattern_length) != PCRE2_UNSET)
5663*22dc650dSSadaf Ebrahimi     prmsg(&msg, "max_pattern_length");
5664*22dc650dSSadaf Ebrahimi   if (FLD(pat_context, max_pattern_compiled_length) != PCRE2_UNSET)
5665*22dc650dSSadaf Ebrahimi     prmsg(&msg, "max_pattern_compiled_length");
5666*22dc650dSSadaf Ebrahimi   if (FLD(pat_context, parens_nest_limit) != PARENS_NEST_DEFAULT)
5667*22dc650dSSadaf Ebrahimi     prmsg(&msg, "parens_nest_limit");
5668*22dc650dSSadaf Ebrahimi 
5669*22dc650dSSadaf Ebrahimi   if (msg[0] == 0) fprintf(outfile, "\n");
5670*22dc650dSSadaf Ebrahimi 
5671*22dc650dSSadaf Ebrahimi   /* Translate PCRE2 options to POSIX options and then compile. */
5672*22dc650dSSadaf Ebrahimi 
5673*22dc650dSSadaf Ebrahimi   if (utf) cflags |= REG_UTF;
5674*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control & CTL_POSIX_NOSUB) != 0) cflags |= REG_NOSUB;
5675*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & PCRE2_UCP) != 0) cflags |= REG_UCP;
5676*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & PCRE2_CASELESS) != 0) cflags |= REG_ICASE;
5677*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & PCRE2_LITERAL) != 0) cflags |= REG_NOSPEC;
5678*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & PCRE2_MULTILINE) != 0) cflags |= REG_NEWLINE;
5679*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & PCRE2_DOTALL) != 0) cflags |= REG_DOTALL;
5680*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & PCRE2_UNGREEDY) != 0) cflags |= REG_UNGREEDY;
5681*22dc650dSSadaf Ebrahimi 
5682*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control & (CTL_HEXPAT|CTL_USE_LENGTH)) != 0)
5683*22dc650dSSadaf Ebrahimi     {
5684*22dc650dSSadaf Ebrahimi     preg.re_endp = (char *)pbuffer8 + patlen;
5685*22dc650dSSadaf Ebrahimi     cflags |= REG_PEND;
5686*22dc650dSSadaf Ebrahimi     }
5687*22dc650dSSadaf Ebrahimi 
5688*22dc650dSSadaf Ebrahimi   rc = regcomp(&preg, (char *)pbuffer8, cflags);
5689*22dc650dSSadaf Ebrahimi 
5690*22dc650dSSadaf Ebrahimi   /* Compiling failed */
5691*22dc650dSSadaf Ebrahimi 
5692*22dc650dSSadaf Ebrahimi   if (rc != 0)
5693*22dc650dSSadaf Ebrahimi     {
5694*22dc650dSSadaf Ebrahimi     size_t bsize, usize;
5695*22dc650dSSadaf Ebrahimi     int psize;
5696*22dc650dSSadaf Ebrahimi 
5697*22dc650dSSadaf Ebrahimi     preg.re_pcre2_code = NULL;     /* In case something was left in there */
5698*22dc650dSSadaf Ebrahimi     preg.re_match_data = NULL;
5699*22dc650dSSadaf Ebrahimi 
5700*22dc650dSSadaf Ebrahimi     bsize = (pat_patctl.regerror_buffsize != 0)?
5701*22dc650dSSadaf Ebrahimi       pat_patctl.regerror_buffsize : pbuffer8_size;
5702*22dc650dSSadaf Ebrahimi     if (bsize + 8 < pbuffer8_size)
5703*22dc650dSSadaf Ebrahimi       memcpy(pbuffer8 + bsize, "DEADBEEF", 8);
5704*22dc650dSSadaf Ebrahimi     usize = regerror(rc, &preg, (char *)pbuffer8, bsize);
5705*22dc650dSSadaf Ebrahimi 
5706*22dc650dSSadaf Ebrahimi     /* Inside regerror(), snprintf() is used. If the buffer is too small, some
5707*22dc650dSSadaf Ebrahimi     versions of snprintf() put a zero byte at the end, but others do not.
5708*22dc650dSSadaf Ebrahimi     Therefore, we print a maximum of one less than the size of the buffer. */
5709*22dc650dSSadaf Ebrahimi 
5710*22dc650dSSadaf Ebrahimi     psize = (int)bsize - 1;
5711*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Failed: POSIX code %d: %.*s\n", rc, psize, pbuffer8);
5712*22dc650dSSadaf Ebrahimi     if (usize > bsize)
5713*22dc650dSSadaf Ebrahimi       {
5714*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** regerror() message truncated\n");
5715*22dc650dSSadaf Ebrahimi       if (memcmp(pbuffer8 + bsize, "DEADBEEF", 8) != 0)
5716*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** regerror() buffer overflow\n");
5717*22dc650dSSadaf Ebrahimi       }
5718*22dc650dSSadaf Ebrahimi     return PR_SKIP;
5719*22dc650dSSadaf Ebrahimi     }
5720*22dc650dSSadaf Ebrahimi 
5721*22dc650dSSadaf Ebrahimi   /* Compiling succeeded. Check that the values in the preg block are sensible.
5722*22dc650dSSadaf Ebrahimi   It can happen that pcre2test is accidentally linked with a different POSIX
5723*22dc650dSSadaf Ebrahimi   library which succeeds, but of course puts different things into preg. In
5724*22dc650dSSadaf Ebrahimi   this situation, calling regfree() may cause a segfault (or invalid free() in
5725*22dc650dSSadaf Ebrahimi   valgrind), so ensure that preg.re_pcre2_code is NULL, which suppresses the
5726*22dc650dSSadaf Ebrahimi   calling of regfree() on exit. */
5727*22dc650dSSadaf Ebrahimi 
5728*22dc650dSSadaf Ebrahimi   if (preg.re_pcre2_code == NULL ||
5729*22dc650dSSadaf Ebrahimi       ((pcre2_real_code_8 *)preg.re_pcre2_code)->magic_number != MAGIC_NUMBER ||
5730*22dc650dSSadaf Ebrahimi       ((pcre2_real_code_8 *)preg.re_pcre2_code)->top_bracket != preg.re_nsub ||
5731*22dc650dSSadaf Ebrahimi       preg.re_match_data == NULL ||
5732*22dc650dSSadaf Ebrahimi       preg.re_cflags != cflags)
5733*22dc650dSSadaf Ebrahimi     {
5734*22dc650dSSadaf Ebrahimi     fprintf(outfile,
5735*22dc650dSSadaf Ebrahimi       "** The regcomp() function returned zero (success), but the values set\n"
5736*22dc650dSSadaf Ebrahimi       "** in the preg block are not valid for PCRE2. Check that pcre2test is\n"
5737*22dc650dSSadaf Ebrahimi       "** linked with PCRE2's pcre2posix module (-lpcre2-posix) and not with\n"
5738*22dc650dSSadaf Ebrahimi       "** some other POSIX regex library.\n**\n");
5739*22dc650dSSadaf Ebrahimi     preg.re_pcre2_code = NULL;
5740*22dc650dSSadaf Ebrahimi     return PR_ABEND;
5741*22dc650dSSadaf Ebrahimi     }
5742*22dc650dSSadaf Ebrahimi 
5743*22dc650dSSadaf Ebrahimi   return PR_OK;
5744*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_PCRE2_8 */
5745*22dc650dSSadaf Ebrahimi   }
5746*22dc650dSSadaf Ebrahimi 
5747*22dc650dSSadaf Ebrahimi /* Handle compiling via the native interface. Controls that act later are
5748*22dc650dSSadaf Ebrahimi ignored with "push". Replacements are locked out. */
5749*22dc650dSSadaf Ebrahimi 
5750*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & (CTL_PUSH|CTL_PUSHCOPY|CTL_PUSHTABLESCOPY)) != 0)
5751*22dc650dSSadaf Ebrahimi   {
5752*22dc650dSSadaf Ebrahimi   if (pat_patctl.replacement[0] != 0)
5753*22dc650dSSadaf Ebrahimi     {
5754*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Replacement text is not supported with 'push'.\n");
5755*22dc650dSSadaf Ebrahimi     return PR_OK;
5756*22dc650dSSadaf Ebrahimi     }
5757*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS) != 0 ||
5758*22dc650dSSadaf Ebrahimi       (pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2) != 0)
5759*22dc650dSSadaf Ebrahimi     {
5760*22dc650dSSadaf Ebrahimi     show_controls(pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS,
5761*22dc650dSSadaf Ebrahimi                   pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2,
5762*22dc650dSSadaf Ebrahimi       "** Ignored when compiled pattern is stacked with 'push':");
5763*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\n");
5764*22dc650dSSadaf Ebrahimi     }
5765*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS) != 0 ||
5766*22dc650dSSadaf Ebrahimi       (pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2) != 0)
5767*22dc650dSSadaf Ebrahimi     {
5768*22dc650dSSadaf Ebrahimi     show_controls(pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS,
5769*22dc650dSSadaf Ebrahimi                   pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2,
5770*22dc650dSSadaf Ebrahimi       "** Applies only to compile when pattern is stacked with 'push':");
5771*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\n");
5772*22dc650dSSadaf Ebrahimi     }
5773*22dc650dSSadaf Ebrahimi   }
5774*22dc650dSSadaf Ebrahimi 
5775*22dc650dSSadaf Ebrahimi /* Convert the input in non-8-bit modes. */
5776*22dc650dSSadaf Ebrahimi 
5777*22dc650dSSadaf Ebrahimi errorcode = 0;
5778*22dc650dSSadaf Ebrahimi 
5779*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
5780*22dc650dSSadaf Ebrahimi if (test_mode == PCRE16_MODE) errorcode = to16(pbuffer8, utf, &patlen);
5781*22dc650dSSadaf Ebrahimi #endif
5782*22dc650dSSadaf Ebrahimi 
5783*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
5784*22dc650dSSadaf Ebrahimi if (test_mode == PCRE32_MODE) errorcode = to32(pbuffer8, utf, &patlen);
5785*22dc650dSSadaf Ebrahimi #endif
5786*22dc650dSSadaf Ebrahimi 
5787*22dc650dSSadaf Ebrahimi switch(errorcode)
5788*22dc650dSSadaf Ebrahimi   {
5789*22dc650dSSadaf Ebrahimi   case -1:
5790*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** Failed: invalid UTF-8 string cannot be "
5791*22dc650dSSadaf Ebrahimi     "converted to %d-bit string\n", (test_mode == PCRE16_MODE)? 16:32);
5792*22dc650dSSadaf Ebrahimi   return PR_SKIP;
5793*22dc650dSSadaf Ebrahimi 
5794*22dc650dSSadaf Ebrahimi   case -2:
5795*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** Failed: character value greater than 0x10ffff "
5796*22dc650dSSadaf Ebrahimi     "cannot be converted to UTF\n");
5797*22dc650dSSadaf Ebrahimi   return PR_SKIP;
5798*22dc650dSSadaf Ebrahimi 
5799*22dc650dSSadaf Ebrahimi   case -3:
5800*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** Failed: character value greater than 0xffff "
5801*22dc650dSSadaf Ebrahimi     "cannot be converted to 16-bit in non-UTF mode\n");
5802*22dc650dSSadaf Ebrahimi   return PR_SKIP;
5803*22dc650dSSadaf Ebrahimi 
5804*22dc650dSSadaf Ebrahimi   default:
5805*22dc650dSSadaf Ebrahimi   break;
5806*22dc650dSSadaf Ebrahimi   }
5807*22dc650dSSadaf Ebrahimi 
5808*22dc650dSSadaf Ebrahimi /* The pattern is now in pbuffer[8|16|32], with the length in code units in
5809*22dc650dSSadaf Ebrahimi patlen. If it is to be converted, copy the result back afterwards so that it
5810*22dc650dSSadaf Ebrahimi ends up back in the usual place. */
5811*22dc650dSSadaf Ebrahimi 
5812*22dc650dSSadaf Ebrahimi if (pat_patctl.convert_type != CONVERT_UNSET)
5813*22dc650dSSadaf Ebrahimi   {
5814*22dc650dSSadaf Ebrahimi   int rc;
5815*22dc650dSSadaf Ebrahimi   int convert_return = PR_OK;
5816*22dc650dSSadaf Ebrahimi   uint32_t convert_options = pat_patctl.convert_type;
5817*22dc650dSSadaf Ebrahimi   void *converted_pattern;
5818*22dc650dSSadaf Ebrahimi   PCRE2_SIZE converted_length;
5819*22dc650dSSadaf Ebrahimi 
5820*22dc650dSSadaf Ebrahimi   if (pat_patctl.convert_length != 0)
5821*22dc650dSSadaf Ebrahimi     {
5822*22dc650dSSadaf Ebrahimi     converted_length = pat_patctl.convert_length;
5823*22dc650dSSadaf Ebrahimi     converted_pattern = malloc(converted_length * code_unit_size);
5824*22dc650dSSadaf Ebrahimi     if (converted_pattern == NULL)
5825*22dc650dSSadaf Ebrahimi       {
5826*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Failed: malloc failed for converted pattern\n");
5827*22dc650dSSadaf Ebrahimi       return PR_SKIP;
5828*22dc650dSSadaf Ebrahimi       }
5829*22dc650dSSadaf Ebrahimi     }
5830*22dc650dSSadaf Ebrahimi   else converted_pattern = NULL;  /* Let the library allocate */
5831*22dc650dSSadaf Ebrahimi 
5832*22dc650dSSadaf Ebrahimi   if (utf) convert_options |= PCRE2_CONVERT_UTF;
5833*22dc650dSSadaf Ebrahimi   if ((pat_patctl.options & PCRE2_NO_UTF_CHECK) != 0)
5834*22dc650dSSadaf Ebrahimi     convert_options |= PCRE2_CONVERT_NO_UTF_CHECK;
5835*22dc650dSSadaf Ebrahimi 
5836*22dc650dSSadaf Ebrahimi   CONCTXCPY(con_context, default_con_context);
5837*22dc650dSSadaf Ebrahimi 
5838*22dc650dSSadaf Ebrahimi   if (pat_patctl.convert_glob_escape != 0)
5839*22dc650dSSadaf Ebrahimi     {
5840*22dc650dSSadaf Ebrahimi     uint32_t escape = (pat_patctl.convert_glob_escape == '0')? 0 :
5841*22dc650dSSadaf Ebrahimi       pat_patctl.convert_glob_escape;
5842*22dc650dSSadaf Ebrahimi     PCRE2_SET_GLOB_ESCAPE(rc, con_context, escape);
5843*22dc650dSSadaf Ebrahimi     if (rc != 0)
5844*22dc650dSSadaf Ebrahimi       {
5845*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Invalid glob escape '%c'\n",
5846*22dc650dSSadaf Ebrahimi         pat_patctl.convert_glob_escape);
5847*22dc650dSSadaf Ebrahimi       convert_return = PR_SKIP;
5848*22dc650dSSadaf Ebrahimi       goto CONVERT_FINISH;
5849*22dc650dSSadaf Ebrahimi       }
5850*22dc650dSSadaf Ebrahimi     }
5851*22dc650dSSadaf Ebrahimi 
5852*22dc650dSSadaf Ebrahimi   if (pat_patctl.convert_glob_separator != 0)
5853*22dc650dSSadaf Ebrahimi     {
5854*22dc650dSSadaf Ebrahimi     PCRE2_SET_GLOB_SEPARATOR(rc, con_context, pat_patctl.convert_glob_separator);
5855*22dc650dSSadaf Ebrahimi     if (rc != 0)
5856*22dc650dSSadaf Ebrahimi       {
5857*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Invalid glob separator '%c'\n",
5858*22dc650dSSadaf Ebrahimi         pat_patctl.convert_glob_separator);
5859*22dc650dSSadaf Ebrahimi       convert_return = PR_SKIP;
5860*22dc650dSSadaf Ebrahimi       goto CONVERT_FINISH;
5861*22dc650dSSadaf Ebrahimi       }
5862*22dc650dSSadaf Ebrahimi     }
5863*22dc650dSSadaf Ebrahimi 
5864*22dc650dSSadaf Ebrahimi   PCRE2_PATTERN_CONVERT(rc, pbuffer, patlen, convert_options,
5865*22dc650dSSadaf Ebrahimi     &converted_pattern, &converted_length, con_context);
5866*22dc650dSSadaf Ebrahimi 
5867*22dc650dSSadaf Ebrahimi   if (rc != 0)
5868*22dc650dSSadaf Ebrahimi     {
5869*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Pattern conversion error at offset %" SIZ_FORM ": ",
5870*22dc650dSSadaf Ebrahimi       converted_length);
5871*22dc650dSSadaf Ebrahimi     convert_return = print_error_message(rc, "", "\n")? PR_SKIP:PR_ABEND;
5872*22dc650dSSadaf Ebrahimi     }
5873*22dc650dSSadaf Ebrahimi 
5874*22dc650dSSadaf Ebrahimi   /* Output the converted pattern, then copy it. */
5875*22dc650dSSadaf Ebrahimi 
5876*22dc650dSSadaf Ebrahimi   else
5877*22dc650dSSadaf Ebrahimi     {
5878*22dc650dSSadaf Ebrahimi     BOOL toolong;
5879*22dc650dSSadaf Ebrahimi     PCHARSV(converted_pattern, 0, converted_length, utf, outfile);
5880*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\n");
5881*22dc650dSSadaf Ebrahimi 
5882*22dc650dSSadaf Ebrahimi     if (test_mode == PCRE8_MODE)
5883*22dc650dSSadaf Ebrahimi       toolong = (converted_length + 1 > pbuffer8_size);
5884*22dc650dSSadaf Ebrahimi     else if (test_mode == PCRE16_MODE)
5885*22dc650dSSadaf Ebrahimi       toolong = (2*(converted_length + 1) > pbuffer8_size);
5886*22dc650dSSadaf Ebrahimi     else  /* 32-bit */
5887*22dc650dSSadaf Ebrahimi       toolong = (4*(converted_length + 1) > pbuffer8_size);
5888*22dc650dSSadaf Ebrahimi 
5889*22dc650dSSadaf Ebrahimi     if (toolong)
5890*22dc650dSSadaf Ebrahimi       {
5891*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Pattern conversion is too long for the buffer\n");
5892*22dc650dSSadaf Ebrahimi       convert_return = PR_SKIP;
5893*22dc650dSSadaf Ebrahimi       }
5894*22dc650dSSadaf Ebrahimi     else
5895*22dc650dSSadaf Ebrahimi       {
5896*22dc650dSSadaf Ebrahimi       CONVERT_COPY(pbuffer, converted_pattern, converted_length + 1);
5897*22dc650dSSadaf Ebrahimi       patlen = converted_length;
5898*22dc650dSSadaf Ebrahimi       }
5899*22dc650dSSadaf Ebrahimi     }
5900*22dc650dSSadaf Ebrahimi 
5901*22dc650dSSadaf Ebrahimi   /* Free the converted pattern. */
5902*22dc650dSSadaf Ebrahimi 
5903*22dc650dSSadaf Ebrahimi   CONVERT_FINISH:
5904*22dc650dSSadaf Ebrahimi   if (pat_patctl.convert_length != 0)
5905*22dc650dSSadaf Ebrahimi     free(converted_pattern);
5906*22dc650dSSadaf Ebrahimi   else
5907*22dc650dSSadaf Ebrahimi     PCRE2_CONVERTED_PATTERN_FREE(converted_pattern);
5908*22dc650dSSadaf Ebrahimi 
5909*22dc650dSSadaf Ebrahimi   /* Return if conversion was unsuccessful. */
5910*22dc650dSSadaf Ebrahimi 
5911*22dc650dSSadaf Ebrahimi   if (convert_return != PR_OK) return convert_return;
5912*22dc650dSSadaf Ebrahimi   }
5913*22dc650dSSadaf Ebrahimi 
5914*22dc650dSSadaf Ebrahimi /* By default we pass a zero-terminated pattern, but a length is passed if
5915*22dc650dSSadaf Ebrahimi "use_length" was specified or this is a hex pattern (which might contain binary
5916*22dc650dSSadaf Ebrahimi zeros). When valgrind is supported, arrange for the unused part of the buffer
5917*22dc650dSSadaf Ebrahimi to be marked as no access. */
5918*22dc650dSSadaf Ebrahimi 
5919*22dc650dSSadaf Ebrahimi valgrind_access_length = patlen;
5920*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & (CTL_HEXPAT|CTL_USE_LENGTH)) == 0)
5921*22dc650dSSadaf Ebrahimi   {
5922*22dc650dSSadaf Ebrahimi   patlen = PCRE2_ZERO_TERMINATED;
5923*22dc650dSSadaf Ebrahimi   valgrind_access_length += 1;  /* For the terminating zero */
5924*22dc650dSSadaf Ebrahimi   }
5925*22dc650dSSadaf Ebrahimi 
5926*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_VALGRIND
5927*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
5928*22dc650dSSadaf Ebrahimi if (test_mode == PCRE8_MODE && pbuffer8 != NULL)
5929*22dc650dSSadaf Ebrahimi   {
5930*22dc650dSSadaf Ebrahimi   VALGRIND_MAKE_MEM_NOACCESS(pbuffer8 + valgrind_access_length,
5931*22dc650dSSadaf Ebrahimi     pbuffer8_size - valgrind_access_length);
5932*22dc650dSSadaf Ebrahimi   }
5933*22dc650dSSadaf Ebrahimi #endif
5934*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
5935*22dc650dSSadaf Ebrahimi if (test_mode == PCRE16_MODE && pbuffer16 != NULL)
5936*22dc650dSSadaf Ebrahimi   {
5937*22dc650dSSadaf Ebrahimi   VALGRIND_MAKE_MEM_NOACCESS(pbuffer16 + valgrind_access_length,
5938*22dc650dSSadaf Ebrahimi     pbuffer16_size - valgrind_access_length*sizeof(uint16_t));
5939*22dc650dSSadaf Ebrahimi   }
5940*22dc650dSSadaf Ebrahimi #endif
5941*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
5942*22dc650dSSadaf Ebrahimi if (test_mode == PCRE32_MODE && pbuffer32 != NULL)
5943*22dc650dSSadaf Ebrahimi   {
5944*22dc650dSSadaf Ebrahimi   VALGRIND_MAKE_MEM_NOACCESS(pbuffer32 + valgrind_access_length,
5945*22dc650dSSadaf Ebrahimi     pbuffer32_size - valgrind_access_length*sizeof(uint32_t));
5946*22dc650dSSadaf Ebrahimi   }
5947*22dc650dSSadaf Ebrahimi #endif
5948*22dc650dSSadaf Ebrahimi #else  /* Valgrind not supported */
5949*22dc650dSSadaf Ebrahimi (void)valgrind_access_length;  /* Avoid compiler warning */
5950*22dc650dSSadaf Ebrahimi #endif
5951*22dc650dSSadaf Ebrahimi 
5952*22dc650dSSadaf Ebrahimi /* If #newline_default has been used and the library was not compiled with an
5953*22dc650dSSadaf Ebrahimi appropriate default newline setting, local_newline_default will be non-zero. We
5954*22dc650dSSadaf Ebrahimi use this if there is no explicit newline modifier. */
5955*22dc650dSSadaf Ebrahimi 
5956*22dc650dSSadaf Ebrahimi if ((pat_patctl.control2 & CTL2_NL_SET) == 0 && local_newline_default != 0)
5957*22dc650dSSadaf Ebrahimi   {
5958*22dc650dSSadaf Ebrahimi   SETFLD(pat_context, newline_convention, local_newline_default);
5959*22dc650dSSadaf Ebrahimi   }
5960*22dc650dSSadaf Ebrahimi 
5961*22dc650dSSadaf Ebrahimi /* The null_context modifier is used to test calling pcre2_compile() with a
5962*22dc650dSSadaf Ebrahimi NULL context. */
5963*22dc650dSSadaf Ebrahimi 
5964*22dc650dSSadaf Ebrahimi use_pat_context = ((pat_patctl.control & CTL_NULLCONTEXT) != 0)?
5965*22dc650dSSadaf Ebrahimi   NULL : PTR(pat_context);
5966*22dc650dSSadaf Ebrahimi 
5967*22dc650dSSadaf Ebrahimi /* If PCRE2_LITERAL is set, set use_forbid_utf zero because PCRE2_NEVER_UTF
5968*22dc650dSSadaf Ebrahimi and PCRE2_NEVER_UCP are invalid with it. */
5969*22dc650dSSadaf Ebrahimi 
5970*22dc650dSSadaf Ebrahimi if ((pat_patctl.options & PCRE2_LITERAL) != 0) use_forbid_utf = 0;
5971*22dc650dSSadaf Ebrahimi 
5972*22dc650dSSadaf Ebrahimi /* Set use_pbuffer to the input buffer, or leave it as NULL if requested. */
5973*22dc650dSSadaf Ebrahimi 
5974*22dc650dSSadaf Ebrahimi if ((pat_patctl.control2 & CTL2_NULL_PATTERN) == 0)
5975*22dc650dSSadaf Ebrahimi   {
5976*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
5977*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) use_pbuffer = pbuffer8;
5978*22dc650dSSadaf Ebrahimi #endif
5979*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
5980*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE16_MODE) use_pbuffer = pbuffer16;
5981*22dc650dSSadaf Ebrahimi #endif
5982*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
5983*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE32_MODE) use_pbuffer = pbuffer32;
5984*22dc650dSSadaf Ebrahimi #endif
5985*22dc650dSSadaf Ebrahimi   }
5986*22dc650dSSadaf Ebrahimi 
5987*22dc650dSSadaf Ebrahimi /* Compile many times when timing. */
5988*22dc650dSSadaf Ebrahimi 
5989*22dc650dSSadaf Ebrahimi if (timeit > 0)
5990*22dc650dSSadaf Ebrahimi   {
5991*22dc650dSSadaf Ebrahimi   int i;
5992*22dc650dSSadaf Ebrahimi   clock_t time_taken = 0;
5993*22dc650dSSadaf Ebrahimi   for (i = 0; i < timeit; i++)
5994*22dc650dSSadaf Ebrahimi     {
5995*22dc650dSSadaf Ebrahimi     clock_t start_time = clock();
5996*22dc650dSSadaf Ebrahimi     PCRE2_COMPILE(compiled_code, use_pbuffer, patlen,
5997*22dc650dSSadaf Ebrahimi       pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset,
5998*22dc650dSSadaf Ebrahimi         use_pat_context);
5999*22dc650dSSadaf Ebrahimi     time_taken += clock() - start_time;
6000*22dc650dSSadaf Ebrahimi     if (TEST(compiled_code, !=, NULL))
6001*22dc650dSSadaf Ebrahimi       { SUB1(pcre2_code_free, compiled_code); }
6002*22dc650dSSadaf Ebrahimi     }
6003*22dc650dSSadaf Ebrahimi   total_compile_time += time_taken;
6004*22dc650dSSadaf Ebrahimi   fprintf(outfile, "Compile time %8.4f microseconds\n",
6005*22dc650dSSadaf Ebrahimi     ((1000000 / CLOCKS_PER_SEC) * (double)time_taken) / timeit);
6006*22dc650dSSadaf Ebrahimi   }
6007*22dc650dSSadaf Ebrahimi 
6008*22dc650dSSadaf Ebrahimi /* A final compile that is used "for real". */
6009*22dc650dSSadaf Ebrahimi 
6010*22dc650dSSadaf Ebrahimi PCRE2_COMPILE(compiled_code, use_pbuffer, patlen,
6011*22dc650dSSadaf Ebrahimi   pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset, use_pat_context);
6012*22dc650dSSadaf Ebrahimi 
6013*22dc650dSSadaf Ebrahimi /* If valgrind is supported, mark the pbuffer as accessible again. The 16-bit
6014*22dc650dSSadaf Ebrahimi and 32-bit buffers can be marked completely undefined, but we must leave the
6015*22dc650dSSadaf Ebrahimi pattern in the 8-bit buffer defined because it may be read from a callout
6016*22dc650dSSadaf Ebrahimi during matching. */
6017*22dc650dSSadaf Ebrahimi 
6018*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_VALGRIND
6019*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
6020*22dc650dSSadaf Ebrahimi if (test_mode == PCRE8_MODE)
6021*22dc650dSSadaf Ebrahimi   {
6022*22dc650dSSadaf Ebrahimi   VALGRIND_MAKE_MEM_UNDEFINED(pbuffer8 + valgrind_access_length,
6023*22dc650dSSadaf Ebrahimi     pbuffer8_size - valgrind_access_length);
6024*22dc650dSSadaf Ebrahimi   }
6025*22dc650dSSadaf Ebrahimi #endif
6026*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
6027*22dc650dSSadaf Ebrahimi if (test_mode == PCRE16_MODE)
6028*22dc650dSSadaf Ebrahimi   {
6029*22dc650dSSadaf Ebrahimi   VALGRIND_MAKE_MEM_UNDEFINED(pbuffer16, pbuffer16_size);
6030*22dc650dSSadaf Ebrahimi   }
6031*22dc650dSSadaf Ebrahimi #endif
6032*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
6033*22dc650dSSadaf Ebrahimi if (test_mode == PCRE32_MODE)
6034*22dc650dSSadaf Ebrahimi   {
6035*22dc650dSSadaf Ebrahimi   VALGRIND_MAKE_MEM_UNDEFINED(pbuffer32, pbuffer32_size);
6036*22dc650dSSadaf Ebrahimi   }
6037*22dc650dSSadaf Ebrahimi #endif
6038*22dc650dSSadaf Ebrahimi #endif
6039*22dc650dSSadaf Ebrahimi 
6040*22dc650dSSadaf Ebrahimi /* Call the JIT compiler if requested. When timing, we must free and recompile
6041*22dc650dSSadaf Ebrahimi the pattern each time because that is the only way to free the JIT compiled
6042*22dc650dSSadaf Ebrahimi code. We know that compilation will always succeed. */
6043*22dc650dSSadaf Ebrahimi 
6044*22dc650dSSadaf Ebrahimi if (TEST(compiled_code, !=, NULL) && pat_patctl.jit != 0)
6045*22dc650dSSadaf Ebrahimi   {
6046*22dc650dSSadaf Ebrahimi   if (timeit > 0)
6047*22dc650dSSadaf Ebrahimi     {
6048*22dc650dSSadaf Ebrahimi     int i;
6049*22dc650dSSadaf Ebrahimi     clock_t time_taken = 0;
6050*22dc650dSSadaf Ebrahimi 
6051*22dc650dSSadaf Ebrahimi     for (i = 0; i < timeit; i++)
6052*22dc650dSSadaf Ebrahimi       {
6053*22dc650dSSadaf Ebrahimi       clock_t start_time;
6054*22dc650dSSadaf Ebrahimi       SUB1(pcre2_code_free, compiled_code);
6055*22dc650dSSadaf Ebrahimi       PCRE2_COMPILE(compiled_code, use_pbuffer, patlen,
6056*22dc650dSSadaf Ebrahimi         pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset,
6057*22dc650dSSadaf Ebrahimi         use_pat_context);
6058*22dc650dSSadaf Ebrahimi       start_time = clock();
6059*22dc650dSSadaf Ebrahimi       PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
6060*22dc650dSSadaf Ebrahimi       time_taken += clock() - start_time;
6061*22dc650dSSadaf Ebrahimi       if (jitrc != 0)
6062*22dc650dSSadaf Ebrahimi         {
6063*22dc650dSSadaf Ebrahimi         fprintf(outfile, "JIT compilation was not successful");
6064*22dc650dSSadaf Ebrahimi         if (!print_error_message(jitrc, " (", ")\n")) return PR_ABEND;
6065*22dc650dSSadaf Ebrahimi         break;
6066*22dc650dSSadaf Ebrahimi         }
6067*22dc650dSSadaf Ebrahimi       }
6068*22dc650dSSadaf Ebrahimi     total_jit_compile_time += time_taken;
6069*22dc650dSSadaf Ebrahimi     if (jitrc == 0)
6070*22dc650dSSadaf Ebrahimi       fprintf(outfile, "JIT compile  %8.4f microseconds\n",
6071*22dc650dSSadaf Ebrahimi         ((1000000 / CLOCKS_PER_SEC) * (double)time_taken) / timeit);
6072*22dc650dSSadaf Ebrahimi     }
6073*22dc650dSSadaf Ebrahimi   else
6074*22dc650dSSadaf Ebrahimi     {
6075*22dc650dSSadaf Ebrahimi     PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
6076*22dc650dSSadaf Ebrahimi     if (jitrc != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0)
6077*22dc650dSSadaf Ebrahimi       {
6078*22dc650dSSadaf Ebrahimi       fprintf(outfile, "JIT compilation was not successful");
6079*22dc650dSSadaf Ebrahimi       if (!print_error_message(jitrc, " (", ")\n")) return PR_ABEND;
6080*22dc650dSSadaf Ebrahimi       }
6081*22dc650dSSadaf Ebrahimi     }
6082*22dc650dSSadaf Ebrahimi   }
6083*22dc650dSSadaf Ebrahimi 
6084*22dc650dSSadaf Ebrahimi /* Compilation failed; go back for another re, skipping to blank line
6085*22dc650dSSadaf Ebrahimi if non-interactive. */
6086*22dc650dSSadaf Ebrahimi 
6087*22dc650dSSadaf Ebrahimi if (TEST(compiled_code, ==, NULL))
6088*22dc650dSSadaf Ebrahimi   {
6089*22dc650dSSadaf Ebrahimi   fprintf(outfile, "Failed: error %d at offset %d: ", errorcode,
6090*22dc650dSSadaf Ebrahimi     (int)erroroffset);
6091*22dc650dSSadaf Ebrahimi   if (!print_error_message(errorcode, "", "\n")) return PR_ABEND;
6092*22dc650dSSadaf Ebrahimi   return PR_SKIP;
6093*22dc650dSSadaf Ebrahimi   }
6094*22dc650dSSadaf Ebrahimi 
6095*22dc650dSSadaf Ebrahimi /* If forbid_utf is non-zero, we are running a non-UTF test. UTF and UCP are
6096*22dc650dSSadaf Ebrahimi locked out at compile time, but we must also check for occurrences of \P, \p,
6097*22dc650dSSadaf Ebrahimi and \X, which are only supported when Unicode is supported. */
6098*22dc650dSSadaf Ebrahimi 
6099*22dc650dSSadaf Ebrahimi if (forbid_utf != 0)
6100*22dc650dSSadaf Ebrahimi   {
6101*22dc650dSSadaf Ebrahimi   if ((FLD(compiled_code, flags) & PCRE2_HASBKPORX) != 0)
6102*22dc650dSSadaf Ebrahimi     {
6103*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** \\P, \\p, and \\X are not allowed after the "
6104*22dc650dSSadaf Ebrahimi       "#forbid_utf command\n");
6105*22dc650dSSadaf Ebrahimi     return PR_SKIP;
6106*22dc650dSSadaf Ebrahimi     }
6107*22dc650dSSadaf Ebrahimi   }
6108*22dc650dSSadaf Ebrahimi 
6109*22dc650dSSadaf Ebrahimi /* Remember the maximum lookbehind, for partial matching. */
6110*22dc650dSSadaf Ebrahimi 
6111*22dc650dSSadaf Ebrahimi if (pattern_info(PCRE2_INFO_MAXLOOKBEHIND, &maxlookbehind, FALSE) != 0)
6112*22dc650dSSadaf Ebrahimi   return PR_ABEND;
6113*22dc650dSSadaf Ebrahimi 
6114*22dc650dSSadaf Ebrahimi /* Remember the number of captures. */
6115*22dc650dSSadaf Ebrahimi 
6116*22dc650dSSadaf Ebrahimi if (pattern_info(PCRE2_INFO_CAPTURECOUNT, &maxcapcount, FALSE) < 0)
6117*22dc650dSSadaf Ebrahimi   return PR_ABEND;
6118*22dc650dSSadaf Ebrahimi 
6119*22dc650dSSadaf Ebrahimi /* If an explicit newline modifier was given, set the information flag in the
6120*22dc650dSSadaf Ebrahimi pattern so that it is preserved over push/pop. */
6121*22dc650dSSadaf Ebrahimi 
6122*22dc650dSSadaf Ebrahimi if ((pat_patctl.control2 & CTL2_NL_SET) != 0)
6123*22dc650dSSadaf Ebrahimi   {
6124*22dc650dSSadaf Ebrahimi   SETFLD(compiled_code, flags, FLD(compiled_code, flags) | PCRE2_NL_SET);
6125*22dc650dSSadaf Ebrahimi   }
6126*22dc650dSSadaf Ebrahimi 
6127*22dc650dSSadaf Ebrahimi /* Output code size and other information if requested. */
6128*22dc650dSSadaf Ebrahimi 
6129*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info();
6130*22dc650dSSadaf Ebrahimi if ((pat_patctl.control2 & CTL2_FRAMESIZE) != 0) show_framesize();
6131*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_ANYINFO) != 0)
6132*22dc650dSSadaf Ebrahimi   {
6133*22dc650dSSadaf Ebrahimi   int rc = show_pattern_info();
6134*22dc650dSSadaf Ebrahimi   if (rc != PR_OK) return rc;
6135*22dc650dSSadaf Ebrahimi   }
6136*22dc650dSSadaf Ebrahimi 
6137*22dc650dSSadaf Ebrahimi /* The "push" control requests that the compiled pattern be remembered on a
6138*22dc650dSSadaf Ebrahimi stack. This is mainly for testing the serialization functionality. */
6139*22dc650dSSadaf Ebrahimi 
6140*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_PUSH) != 0)
6141*22dc650dSSadaf Ebrahimi   {
6142*22dc650dSSadaf Ebrahimi   if (patstacknext >= PATSTACKSIZE)
6143*22dc650dSSadaf Ebrahimi     {
6144*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Too many pushed patterns (max %d)\n", PATSTACKSIZE);
6145*22dc650dSSadaf Ebrahimi     return PR_ABEND;
6146*22dc650dSSadaf Ebrahimi     }
6147*22dc650dSSadaf Ebrahimi   patstack[patstacknext++] = PTR(compiled_code);
6148*22dc650dSSadaf Ebrahimi   SET(compiled_code, NULL);
6149*22dc650dSSadaf Ebrahimi   }
6150*22dc650dSSadaf Ebrahimi 
6151*22dc650dSSadaf Ebrahimi /* The "pushcopy" and "pushtablescopy" controls are similar, but push a
6152*22dc650dSSadaf Ebrahimi copy of the pattern, the latter with a copy of its character tables. This tests
6153*22dc650dSSadaf Ebrahimi the pcre2_code_copy() and pcre2_code_copy_with_tables() functions. */
6154*22dc650dSSadaf Ebrahimi 
6155*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & (CTL_PUSHCOPY|CTL_PUSHTABLESCOPY)) != 0)
6156*22dc650dSSadaf Ebrahimi   {
6157*22dc650dSSadaf Ebrahimi   if (patstacknext >= PATSTACKSIZE)
6158*22dc650dSSadaf Ebrahimi     {
6159*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Too many pushed patterns (max %d)\n", PATSTACKSIZE);
6160*22dc650dSSadaf Ebrahimi     return PR_ABEND;
6161*22dc650dSSadaf Ebrahimi     }
6162*22dc650dSSadaf Ebrahimi   if ((pat_patctl.control & CTL_PUSHCOPY) != 0)
6163*22dc650dSSadaf Ebrahimi     {
6164*22dc650dSSadaf Ebrahimi     PCRE2_CODE_COPY_TO_VOID(patstack[patstacknext++], compiled_code);
6165*22dc650dSSadaf Ebrahimi     }
6166*22dc650dSSadaf Ebrahimi   else
6167*22dc650dSSadaf Ebrahimi     {
6168*22dc650dSSadaf Ebrahimi     PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(patstack[patstacknext++],
6169*22dc650dSSadaf Ebrahimi       compiled_code); }
6170*22dc650dSSadaf Ebrahimi   }
6171*22dc650dSSadaf Ebrahimi 
6172*22dc650dSSadaf Ebrahimi return PR_OK;
6173*22dc650dSSadaf Ebrahimi }
6174*22dc650dSSadaf Ebrahimi 
6175*22dc650dSSadaf Ebrahimi 
6176*22dc650dSSadaf Ebrahimi 
6177*22dc650dSSadaf Ebrahimi /*************************************************
6178*22dc650dSSadaf Ebrahimi *          Check heap, match or depth limit      *
6179*22dc650dSSadaf Ebrahimi *************************************************/
6180*22dc650dSSadaf Ebrahimi 
6181*22dc650dSSadaf Ebrahimi /* This is used for DFA, normal, and JIT fast matching. For DFA matching it
6182*22dc650dSSadaf Ebrahimi should only be called with the third argument set to PCRE2_ERROR_DEPTHLIMIT.
6183*22dc650dSSadaf Ebrahimi 
6184*22dc650dSSadaf Ebrahimi Arguments:
6185*22dc650dSSadaf Ebrahimi   pp        the subject string
6186*22dc650dSSadaf Ebrahimi   ulen      length of subject or PCRE2_ZERO_TERMINATED
6187*22dc650dSSadaf Ebrahimi   errnumber defines which limit to test
6188*22dc650dSSadaf Ebrahimi   msg       string to include in final message
6189*22dc650dSSadaf Ebrahimi 
6190*22dc650dSSadaf Ebrahimi Returns:    the return from the final match function call
6191*22dc650dSSadaf Ebrahimi */
6192*22dc650dSSadaf Ebrahimi 
6193*22dc650dSSadaf Ebrahimi static int
check_match_limit(uint8_t * pp,PCRE2_SIZE ulen,int errnumber,const char * msg)6194*22dc650dSSadaf Ebrahimi check_match_limit(uint8_t *pp, PCRE2_SIZE ulen, int errnumber, const char *msg)
6195*22dc650dSSadaf Ebrahimi {
6196*22dc650dSSadaf Ebrahimi int capcount;
6197*22dc650dSSadaf Ebrahimi uint32_t min = 0;
6198*22dc650dSSadaf Ebrahimi uint32_t mid = 64;
6199*22dc650dSSadaf Ebrahimi uint32_t max = UINT32_MAX;
6200*22dc650dSSadaf Ebrahimi 
6201*22dc650dSSadaf Ebrahimi PCRE2_SET_MATCH_LIMIT(dat_context, max);
6202*22dc650dSSadaf Ebrahimi PCRE2_SET_DEPTH_LIMIT(dat_context, max);
6203*22dc650dSSadaf Ebrahimi PCRE2_SET_HEAP_LIMIT(dat_context, max);
6204*22dc650dSSadaf Ebrahimi 
6205*22dc650dSSadaf Ebrahimi for (;;)
6206*22dc650dSSadaf Ebrahimi   {
6207*22dc650dSSadaf Ebrahimi   uint32_t stack_start = 0;
6208*22dc650dSSadaf Ebrahimi 
6209*22dc650dSSadaf Ebrahimi   /* If we are checking the heap limit, free any frames vector that is cached
6210*22dc650dSSadaf Ebrahimi   in the match_data so we always start without one. */
6211*22dc650dSSadaf Ebrahimi 
6212*22dc650dSSadaf Ebrahimi   if (errnumber == PCRE2_ERROR_HEAPLIMIT)
6213*22dc650dSSadaf Ebrahimi     {
6214*22dc650dSSadaf Ebrahimi     PCRE2_SET_HEAP_LIMIT(dat_context, mid);
6215*22dc650dSSadaf Ebrahimi 
6216*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
6217*22dc650dSSadaf Ebrahimi     if (code_unit_size == 1)
6218*22dc650dSSadaf Ebrahimi       {
6219*22dc650dSSadaf Ebrahimi       match_data8->memctl.free(match_data8->heapframes,
6220*22dc650dSSadaf Ebrahimi         match_data8->memctl.memory_data);
6221*22dc650dSSadaf Ebrahimi       match_data8->heapframes = NULL;
6222*22dc650dSSadaf Ebrahimi       match_data8->heapframes_size = 0;
6223*22dc650dSSadaf Ebrahimi       }
6224*22dc650dSSadaf Ebrahimi #endif
6225*22dc650dSSadaf Ebrahimi 
6226*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
6227*22dc650dSSadaf Ebrahimi     if (code_unit_size == 2)
6228*22dc650dSSadaf Ebrahimi       {
6229*22dc650dSSadaf Ebrahimi       match_data16->memctl.free(match_data16->heapframes,
6230*22dc650dSSadaf Ebrahimi         match_data16->memctl.memory_data);
6231*22dc650dSSadaf Ebrahimi       match_data16->heapframes = NULL;
6232*22dc650dSSadaf Ebrahimi       match_data16->heapframes_size = 0;
6233*22dc650dSSadaf Ebrahimi       }
6234*22dc650dSSadaf Ebrahimi #endif
6235*22dc650dSSadaf Ebrahimi 
6236*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
6237*22dc650dSSadaf Ebrahimi     if (code_unit_size == 4)
6238*22dc650dSSadaf Ebrahimi       {
6239*22dc650dSSadaf Ebrahimi       match_data32->memctl.free(match_data32->heapframes,
6240*22dc650dSSadaf Ebrahimi         match_data32->memctl.memory_data);
6241*22dc650dSSadaf Ebrahimi       match_data32->heapframes = NULL;
6242*22dc650dSSadaf Ebrahimi       match_data32->heapframes_size = 0;
6243*22dc650dSSadaf Ebrahimi       }
6244*22dc650dSSadaf Ebrahimi #endif
6245*22dc650dSSadaf Ebrahimi     }
6246*22dc650dSSadaf Ebrahimi 
6247*22dc650dSSadaf Ebrahimi   /* No need to mess with the frames vector for match or depth limits. */
6248*22dc650dSSadaf Ebrahimi 
6249*22dc650dSSadaf Ebrahimi   else if (errnumber == PCRE2_ERROR_MATCHLIMIT)
6250*22dc650dSSadaf Ebrahimi     {
6251*22dc650dSSadaf Ebrahimi     PCRE2_SET_MATCH_LIMIT(dat_context, mid);
6252*22dc650dSSadaf Ebrahimi     }
6253*22dc650dSSadaf Ebrahimi   else
6254*22dc650dSSadaf Ebrahimi     {
6255*22dc650dSSadaf Ebrahimi     PCRE2_SET_DEPTH_LIMIT(dat_context, mid);
6256*22dc650dSSadaf Ebrahimi     }
6257*22dc650dSSadaf Ebrahimi 
6258*22dc650dSSadaf Ebrahimi   /* Do the appropriate match */
6259*22dc650dSSadaf Ebrahimi 
6260*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control & CTL_DFA) != 0)
6261*22dc650dSSadaf Ebrahimi     {
6262*22dc650dSSadaf Ebrahimi     stack_start = DFA_START_RWS_SIZE/1024;
6263*22dc650dSSadaf Ebrahimi     if (dfa_workspace == NULL)
6264*22dc650dSSadaf Ebrahimi       dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));
6265*22dc650dSSadaf Ebrahimi     if (dfa_matched++ == 0)
6266*22dc650dSSadaf Ebrahimi       dfa_workspace[0] = -1;  /* To catch bad restart */
6267*22dc650dSSadaf Ebrahimi     PCRE2_DFA_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset,
6268*22dc650dSSadaf Ebrahimi       dat_datctl.options, match_data,
6269*22dc650dSSadaf Ebrahimi       PTR(dat_context), dfa_workspace, DFA_WS_DIMENSION);
6270*22dc650dSSadaf Ebrahimi     }
6271*22dc650dSSadaf Ebrahimi 
6272*22dc650dSSadaf Ebrahimi   else if ((pat_patctl.control & CTL_JITFAST) != 0)
6273*22dc650dSSadaf Ebrahimi     PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset,
6274*22dc650dSSadaf Ebrahimi       dat_datctl.options, match_data, PTR(dat_context));
6275*22dc650dSSadaf Ebrahimi 
6276*22dc650dSSadaf Ebrahimi   else
6277*22dc650dSSadaf Ebrahimi     {
6278*22dc650dSSadaf Ebrahimi     PCRE2_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset,
6279*22dc650dSSadaf Ebrahimi       dat_datctl.options, match_data, PTR(dat_context));
6280*22dc650dSSadaf Ebrahimi     }
6281*22dc650dSSadaf Ebrahimi 
6282*22dc650dSSadaf Ebrahimi   if (capcount == errnumber)
6283*22dc650dSSadaf Ebrahimi     {
6284*22dc650dSSadaf Ebrahimi     if ((mid & 0x80000000u) != 0)
6285*22dc650dSSadaf Ebrahimi       {
6286*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Can't find minimum %s limit: check pattern for "
6287*22dc650dSSadaf Ebrahimi         "restriction\n", msg);
6288*22dc650dSSadaf Ebrahimi       break;
6289*22dc650dSSadaf Ebrahimi       }
6290*22dc650dSSadaf Ebrahimi 
6291*22dc650dSSadaf Ebrahimi     min = mid;
6292*22dc650dSSadaf Ebrahimi     mid = (mid == max - 1)? max : (max != UINT32_MAX)? (min + max)/2 : mid*2;
6293*22dc650dSSadaf Ebrahimi     }
6294*22dc650dSSadaf Ebrahimi   else if (capcount >= 0 ||
6295*22dc650dSSadaf Ebrahimi            capcount == PCRE2_ERROR_NOMATCH ||
6296*22dc650dSSadaf Ebrahimi            capcount == PCRE2_ERROR_PARTIAL)
6297*22dc650dSSadaf Ebrahimi     {
6298*22dc650dSSadaf Ebrahimi     /* If we've not hit the error with a heap limit less than the size of the
6299*22dc650dSSadaf Ebrahimi     initial stack frame vector (for pcre2_match()) or the initial stack
6300*22dc650dSSadaf Ebrahimi     workspace vector (for pcre2_dfa_match()), the heap is not being used, so
6301*22dc650dSSadaf Ebrahimi     the minimum limit is zero; there's no need to go on. The other limits are
6302*22dc650dSSadaf Ebrahimi     always greater than zero. */
6303*22dc650dSSadaf Ebrahimi 
6304*22dc650dSSadaf Ebrahimi     if (errnumber == PCRE2_ERROR_HEAPLIMIT && mid < stack_start)
6305*22dc650dSSadaf Ebrahimi       {
6306*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Minimum %s limit = 0\n", msg);
6307*22dc650dSSadaf Ebrahimi       break;
6308*22dc650dSSadaf Ebrahimi       }
6309*22dc650dSSadaf Ebrahimi     if (mid == min + 1)
6310*22dc650dSSadaf Ebrahimi       {
6311*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Minimum %s limit = %d\n", msg, mid);
6312*22dc650dSSadaf Ebrahimi       break;
6313*22dc650dSSadaf Ebrahimi       }
6314*22dc650dSSadaf Ebrahimi     max = mid;
6315*22dc650dSSadaf Ebrahimi     mid = (min + max)/2;
6316*22dc650dSSadaf Ebrahimi     }
6317*22dc650dSSadaf Ebrahimi   else break;    /* Some other error */
6318*22dc650dSSadaf Ebrahimi   }
6319*22dc650dSSadaf Ebrahimi 
6320*22dc650dSSadaf Ebrahimi return capcount;
6321*22dc650dSSadaf Ebrahimi }
6322*22dc650dSSadaf Ebrahimi 
6323*22dc650dSSadaf Ebrahimi 
6324*22dc650dSSadaf Ebrahimi 
6325*22dc650dSSadaf Ebrahimi /*************************************************
6326*22dc650dSSadaf Ebrahimi *        Substitute callout function             *
6327*22dc650dSSadaf Ebrahimi *************************************************/
6328*22dc650dSSadaf Ebrahimi 
6329*22dc650dSSadaf Ebrahimi /* Called from pcre2_substitute() when the substitute_callout modifier is set.
6330*22dc650dSSadaf Ebrahimi Print out the data that is passed back. The substitute callout block is
6331*22dc650dSSadaf Ebrahimi identical for all code unit widths, so we just pick one.
6332*22dc650dSSadaf Ebrahimi 
6333*22dc650dSSadaf Ebrahimi Arguments:
6334*22dc650dSSadaf Ebrahimi   scb         pointer to substitute callout block
6335*22dc650dSSadaf Ebrahimi   data_ptr    callout data
6336*22dc650dSSadaf Ebrahimi 
6337*22dc650dSSadaf Ebrahimi Returns:      nothing
6338*22dc650dSSadaf Ebrahimi */
6339*22dc650dSSadaf Ebrahimi 
6340*22dc650dSSadaf Ebrahimi static int
substitute_callout_function(pcre2_substitute_callout_block_8 * scb,void * data_ptr)6341*22dc650dSSadaf Ebrahimi substitute_callout_function(pcre2_substitute_callout_block_8 *scb,
6342*22dc650dSSadaf Ebrahimi   void *data_ptr)
6343*22dc650dSSadaf Ebrahimi {
6344*22dc650dSSadaf Ebrahimi int yield = 0;
6345*22dc650dSSadaf Ebrahimi BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;
6346*22dc650dSSadaf Ebrahimi (void)data_ptr;   /* Not used */
6347*22dc650dSSadaf Ebrahimi 
6348*22dc650dSSadaf Ebrahimi fprintf(outfile, "%2d(%d) Old %" SIZ_FORM " %" SIZ_FORM " \"",
6349*22dc650dSSadaf Ebrahimi   scb->subscount, scb->oveccount,
6350*22dc650dSSadaf Ebrahimi   scb->ovector[0], scb->ovector[1]);
6351*22dc650dSSadaf Ebrahimi 
6352*22dc650dSSadaf Ebrahimi PCHARSV(scb->input, scb->ovector[0], scb->ovector[1] - scb->ovector[0],
6353*22dc650dSSadaf Ebrahimi   utf, outfile);
6354*22dc650dSSadaf Ebrahimi 
6355*22dc650dSSadaf Ebrahimi fprintf(outfile, "\" New %" SIZ_FORM " %" SIZ_FORM " \"",
6356*22dc650dSSadaf Ebrahimi   scb->output_offsets[0], scb->output_offsets[1]);
6357*22dc650dSSadaf Ebrahimi 
6358*22dc650dSSadaf Ebrahimi PCHARSV(scb->output, scb->output_offsets[0],
6359*22dc650dSSadaf Ebrahimi   scb->output_offsets[1] - scb->output_offsets[0], utf, outfile);
6360*22dc650dSSadaf Ebrahimi 
6361*22dc650dSSadaf Ebrahimi if (scb->subscount == dat_datctl.substitute_stop)
6362*22dc650dSSadaf Ebrahimi   {
6363*22dc650dSSadaf Ebrahimi   yield = -1;
6364*22dc650dSSadaf Ebrahimi   fprintf(outfile, " STOPPED");
6365*22dc650dSSadaf Ebrahimi   }
6366*22dc650dSSadaf Ebrahimi else if (scb->subscount == dat_datctl.substitute_skip)
6367*22dc650dSSadaf Ebrahimi   {
6368*22dc650dSSadaf Ebrahimi   yield = +1;
6369*22dc650dSSadaf Ebrahimi   fprintf(outfile, " SKIPPED");
6370*22dc650dSSadaf Ebrahimi   }
6371*22dc650dSSadaf Ebrahimi 
6372*22dc650dSSadaf Ebrahimi fprintf(outfile, "\"\n");
6373*22dc650dSSadaf Ebrahimi return yield;
6374*22dc650dSSadaf Ebrahimi }
6375*22dc650dSSadaf Ebrahimi 
6376*22dc650dSSadaf Ebrahimi 
6377*22dc650dSSadaf Ebrahimi /*************************************************
6378*22dc650dSSadaf Ebrahimi *              Callout function                  *
6379*22dc650dSSadaf Ebrahimi *************************************************/
6380*22dc650dSSadaf Ebrahimi 
6381*22dc650dSSadaf Ebrahimi /* Called from a PCRE2 library as a result of the (?C) item. We print out where
6382*22dc650dSSadaf Ebrahimi we are in the match (unless suppressed). Yield zero unless more callouts than
6383*22dc650dSSadaf Ebrahimi the fail count, or the callout data is not zero. The only differences in the
6384*22dc650dSSadaf Ebrahimi callout block for different code unit widths are that the pointers to the
6385*22dc650dSSadaf Ebrahimi subject, the most recent MARK, and a callout argument string point to strings
6386*22dc650dSSadaf Ebrahimi of the appropriate width. Casts can be used to deal with this.
6387*22dc650dSSadaf Ebrahimi 
6388*22dc650dSSadaf Ebrahimi Arguments:
6389*22dc650dSSadaf Ebrahimi   cb                a pointer to a callout block
6390*22dc650dSSadaf Ebrahimi   callout_data_ptr  the provided callout data
6391*22dc650dSSadaf Ebrahimi 
6392*22dc650dSSadaf Ebrahimi Returns:            0 or 1 or an error, as determined by settings
6393*22dc650dSSadaf Ebrahimi */
6394*22dc650dSSadaf Ebrahimi 
6395*22dc650dSSadaf Ebrahimi static int
callout_function(pcre2_callout_block_8 * cb,void * callout_data_ptr)6396*22dc650dSSadaf Ebrahimi callout_function(pcre2_callout_block_8 *cb, void *callout_data_ptr)
6397*22dc650dSSadaf Ebrahimi {
6398*22dc650dSSadaf Ebrahimi FILE *f, *fdefault;
6399*22dc650dSSadaf Ebrahimi uint32_t i, pre_start, post_start, subject_length;
6400*22dc650dSSadaf Ebrahimi PCRE2_SIZE current_position;
6401*22dc650dSSadaf Ebrahimi BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;
6402*22dc650dSSadaf Ebrahimi BOOL callout_capture = (dat_datctl.control & CTL_CALLOUT_CAPTURE) != 0;
6403*22dc650dSSadaf Ebrahimi BOOL callout_where = (dat_datctl.control2 & CTL2_CALLOUT_NO_WHERE) == 0;
6404*22dc650dSSadaf Ebrahimi 
6405*22dc650dSSadaf Ebrahimi /* The FILE f is used for echoing the subject string if it is non-NULL. This
6406*22dc650dSSadaf Ebrahimi happens only once in simple cases, but we want to repeat after any additional
6407*22dc650dSSadaf Ebrahimi output caused by CALLOUT_EXTRA. */
6408*22dc650dSSadaf Ebrahimi 
6409*22dc650dSSadaf Ebrahimi fdefault = (!first_callout && !callout_capture && cb->callout_string == NULL)?
6410*22dc650dSSadaf Ebrahimi   NULL : outfile;
6411*22dc650dSSadaf Ebrahimi 
6412*22dc650dSSadaf Ebrahimi if ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0)
6413*22dc650dSSadaf Ebrahimi   {
6414*22dc650dSSadaf Ebrahimi   f = outfile;
6415*22dc650dSSadaf Ebrahimi   switch (cb->callout_flags)
6416*22dc650dSSadaf Ebrahimi     {
6417*22dc650dSSadaf Ebrahimi     case PCRE2_CALLOUT_BACKTRACK:
6418*22dc650dSSadaf Ebrahimi     fprintf(f, "Backtrack\n");
6419*22dc650dSSadaf Ebrahimi     break;
6420*22dc650dSSadaf Ebrahimi 
6421*22dc650dSSadaf Ebrahimi     case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK:
6422*22dc650dSSadaf Ebrahimi     fprintf(f, "Backtrack\nNo other matching paths\n");
6423*22dc650dSSadaf Ebrahimi     /* Fall through */
6424*22dc650dSSadaf Ebrahimi 
6425*22dc650dSSadaf Ebrahimi     case PCRE2_CALLOUT_STARTMATCH:
6426*22dc650dSSadaf Ebrahimi     fprintf(f, "New match attempt\n");
6427*22dc650dSSadaf Ebrahimi     break;
6428*22dc650dSSadaf Ebrahimi 
6429*22dc650dSSadaf Ebrahimi     default:
6430*22dc650dSSadaf Ebrahimi     f = fdefault;
6431*22dc650dSSadaf Ebrahimi     break;
6432*22dc650dSSadaf Ebrahimi     }
6433*22dc650dSSadaf Ebrahimi   }
6434*22dc650dSSadaf Ebrahimi else f = fdefault;
6435*22dc650dSSadaf Ebrahimi 
6436*22dc650dSSadaf Ebrahimi /* For a callout with a string argument, show the string first because there
6437*22dc650dSSadaf Ebrahimi isn't a tidy way to fit it in the rest of the data. */
6438*22dc650dSSadaf Ebrahimi 
6439*22dc650dSSadaf Ebrahimi if (cb->callout_string != NULL)
6440*22dc650dSSadaf Ebrahimi   {
6441*22dc650dSSadaf Ebrahimi   uint32_t delimiter = CODE_UNIT(cb->callout_string, -1);
6442*22dc650dSSadaf Ebrahimi   fprintf(outfile, "Callout (%" SIZ_FORM "): %c",
6443*22dc650dSSadaf Ebrahimi     cb->callout_string_offset, delimiter);
6444*22dc650dSSadaf Ebrahimi   PCHARSV(cb->callout_string, 0,
6445*22dc650dSSadaf Ebrahimi     cb->callout_string_length, utf, outfile);
6446*22dc650dSSadaf Ebrahimi   for (i = 0; callout_start_delims[i] != 0; i++)
6447*22dc650dSSadaf Ebrahimi     if (delimiter == callout_start_delims[i])
6448*22dc650dSSadaf Ebrahimi       {
6449*22dc650dSSadaf Ebrahimi       delimiter = callout_end_delims[i];
6450*22dc650dSSadaf Ebrahimi       break;
6451*22dc650dSSadaf Ebrahimi       }
6452*22dc650dSSadaf Ebrahimi   fprintf(outfile, "%c", delimiter);
6453*22dc650dSSadaf Ebrahimi   if (!callout_capture) fprintf(outfile, "\n");
6454*22dc650dSSadaf Ebrahimi   }
6455*22dc650dSSadaf Ebrahimi 
6456*22dc650dSSadaf Ebrahimi /* Show captured strings if required */
6457*22dc650dSSadaf Ebrahimi 
6458*22dc650dSSadaf Ebrahimi if (callout_capture)
6459*22dc650dSSadaf Ebrahimi   {
6460*22dc650dSSadaf Ebrahimi   if (cb->callout_string == NULL)
6461*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Callout %d:", cb->callout_number);
6462*22dc650dSSadaf Ebrahimi   fprintf(outfile, " last capture = %d\n", cb->capture_last);
6463*22dc650dSSadaf Ebrahimi   for (i = 2; i < cb->capture_top * 2; i += 2)
6464*22dc650dSSadaf Ebrahimi     {
6465*22dc650dSSadaf Ebrahimi     fprintf(outfile, "%2d: ", i/2);
6466*22dc650dSSadaf Ebrahimi     if (cb->offset_vector[i] == PCRE2_UNSET)
6467*22dc650dSSadaf Ebrahimi       fprintf(outfile, "<unset>");
6468*22dc650dSSadaf Ebrahimi     else
6469*22dc650dSSadaf Ebrahimi       {
6470*22dc650dSSadaf Ebrahimi       PCHARSV(cb->subject, cb->offset_vector[i],
6471*22dc650dSSadaf Ebrahimi         cb->offset_vector[i+1] - cb->offset_vector[i], utf, f);
6472*22dc650dSSadaf Ebrahimi       }
6473*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\n");
6474*22dc650dSSadaf Ebrahimi     }
6475*22dc650dSSadaf Ebrahimi   }
6476*22dc650dSSadaf Ebrahimi 
6477*22dc650dSSadaf Ebrahimi /* Unless suppressed, re-print the subject in canonical form (with escapes for
6478*22dc650dSSadaf Ebrahimi non-printing characters), the first time, or if giving full details. On
6479*22dc650dSSadaf Ebrahimi subsequent calls in the same match, we use PCHARS() just to find the printed
6480*22dc650dSSadaf Ebrahimi lengths of the substrings. */
6481*22dc650dSSadaf Ebrahimi 
6482*22dc650dSSadaf Ebrahimi if (callout_where)
6483*22dc650dSSadaf Ebrahimi   {
6484*22dc650dSSadaf Ebrahimi   if (f != NULL) fprintf(f, "--->");
6485*22dc650dSSadaf Ebrahimi 
6486*22dc650dSSadaf Ebrahimi   /* The subject before the match start. */
6487*22dc650dSSadaf Ebrahimi 
6488*22dc650dSSadaf Ebrahimi   PCHARS(pre_start, cb->subject, 0, cb->start_match, utf, f);
6489*22dc650dSSadaf Ebrahimi 
6490*22dc650dSSadaf Ebrahimi   /* If a lookbehind is involved, the current position may be earlier than the
6491*22dc650dSSadaf Ebrahimi   match start. If so, use the match start instead. */
6492*22dc650dSSadaf Ebrahimi 
6493*22dc650dSSadaf Ebrahimi   current_position = (cb->current_position >= cb->start_match)?
6494*22dc650dSSadaf Ebrahimi     cb->current_position : cb->start_match;
6495*22dc650dSSadaf Ebrahimi 
6496*22dc650dSSadaf Ebrahimi   /* The subject between the match start and the current position. */
6497*22dc650dSSadaf Ebrahimi 
6498*22dc650dSSadaf Ebrahimi   PCHARS(post_start, cb->subject, cb->start_match,
6499*22dc650dSSadaf Ebrahimi     current_position - cb->start_match, utf, f);
6500*22dc650dSSadaf Ebrahimi 
6501*22dc650dSSadaf Ebrahimi   /* Print from the current position to the end. */
6502*22dc650dSSadaf Ebrahimi 
6503*22dc650dSSadaf Ebrahimi   PCHARSV(cb->subject, current_position, cb->subject_length - current_position,
6504*22dc650dSSadaf Ebrahimi     utf, f);
6505*22dc650dSSadaf Ebrahimi 
6506*22dc650dSSadaf Ebrahimi   /* Calculate the total subject printed length (no print). */
6507*22dc650dSSadaf Ebrahimi 
6508*22dc650dSSadaf Ebrahimi   PCHARS(subject_length, cb->subject, 0, cb->subject_length, utf, NULL);
6509*22dc650dSSadaf Ebrahimi 
6510*22dc650dSSadaf Ebrahimi   if (f != NULL) fprintf(f, "\n");
6511*22dc650dSSadaf Ebrahimi 
6512*22dc650dSSadaf Ebrahimi   /* For automatic callouts, show the pattern offset. Otherwise, for a
6513*22dc650dSSadaf Ebrahimi   numerical callout whose number has not already been shown with captured
6514*22dc650dSSadaf Ebrahimi   strings, show the number here. A callout with a string argument has been
6515*22dc650dSSadaf Ebrahimi   displayed above. */
6516*22dc650dSSadaf Ebrahimi 
6517*22dc650dSSadaf Ebrahimi   if (cb->callout_number == 255)
6518*22dc650dSSadaf Ebrahimi     {
6519*22dc650dSSadaf Ebrahimi     fprintf(outfile, "%+3d ", (int)cb->pattern_position);
6520*22dc650dSSadaf Ebrahimi     if (cb->pattern_position > 99) fprintf(outfile, "\n    ");
6521*22dc650dSSadaf Ebrahimi     }
6522*22dc650dSSadaf Ebrahimi   else
6523*22dc650dSSadaf Ebrahimi     {
6524*22dc650dSSadaf Ebrahimi     if (callout_capture || cb->callout_string != NULL) fprintf(outfile, "    ");
6525*22dc650dSSadaf Ebrahimi       else fprintf(outfile, "%3d ", cb->callout_number);
6526*22dc650dSSadaf Ebrahimi     }
6527*22dc650dSSadaf Ebrahimi 
6528*22dc650dSSadaf Ebrahimi   /* Now show position indicators */
6529*22dc650dSSadaf Ebrahimi 
6530*22dc650dSSadaf Ebrahimi   for (i = 0; i < pre_start; i++) fprintf(outfile, " ");
6531*22dc650dSSadaf Ebrahimi   fprintf(outfile, "^");
6532*22dc650dSSadaf Ebrahimi 
6533*22dc650dSSadaf Ebrahimi   if (post_start > 0)
6534*22dc650dSSadaf Ebrahimi     {
6535*22dc650dSSadaf Ebrahimi     for (i = 0; i < post_start - 1; i++) fprintf(outfile, " ");
6536*22dc650dSSadaf Ebrahimi     fprintf(outfile, "^");
6537*22dc650dSSadaf Ebrahimi     }
6538*22dc650dSSadaf Ebrahimi 
6539*22dc650dSSadaf Ebrahimi   for (i = 0; i < subject_length - pre_start - post_start + 4; i++)
6540*22dc650dSSadaf Ebrahimi     fprintf(outfile, " ");
6541*22dc650dSSadaf Ebrahimi 
6542*22dc650dSSadaf Ebrahimi   if (cb->next_item_length != 0)
6543*22dc650dSSadaf Ebrahimi     fprintf(outfile, "%.*s", (int)(cb->next_item_length),
6544*22dc650dSSadaf Ebrahimi       pbuffer8 + cb->pattern_position);
6545*22dc650dSSadaf Ebrahimi   else
6546*22dc650dSSadaf Ebrahimi     fprintf(outfile, "End of pattern");
6547*22dc650dSSadaf Ebrahimi 
6548*22dc650dSSadaf Ebrahimi   fprintf(outfile, "\n");
6549*22dc650dSSadaf Ebrahimi   }
6550*22dc650dSSadaf Ebrahimi 
6551*22dc650dSSadaf Ebrahimi first_callout = FALSE;
6552*22dc650dSSadaf Ebrahimi 
6553*22dc650dSSadaf Ebrahimi /* Show any mark info */
6554*22dc650dSSadaf Ebrahimi 
6555*22dc650dSSadaf Ebrahimi if (cb->mark != last_callout_mark)
6556*22dc650dSSadaf Ebrahimi   {
6557*22dc650dSSadaf Ebrahimi   if (cb->mark == NULL)
6558*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Latest Mark: <unset>\n");
6559*22dc650dSSadaf Ebrahimi   else
6560*22dc650dSSadaf Ebrahimi     {
6561*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Latest Mark: ");
6562*22dc650dSSadaf Ebrahimi     PCHARSV(cb->mark, -1, -1, utf, outfile);
6563*22dc650dSSadaf Ebrahimi     putc('\n', outfile);
6564*22dc650dSSadaf Ebrahimi     }
6565*22dc650dSSadaf Ebrahimi   last_callout_mark = cb->mark;
6566*22dc650dSSadaf Ebrahimi   }
6567*22dc650dSSadaf Ebrahimi 
6568*22dc650dSSadaf Ebrahimi /* Show callout data */
6569*22dc650dSSadaf Ebrahimi 
6570*22dc650dSSadaf Ebrahimi if (callout_data_ptr != NULL)
6571*22dc650dSSadaf Ebrahimi   {
6572*22dc650dSSadaf Ebrahimi   int callout_data = *((int32_t *)callout_data_ptr);
6573*22dc650dSSadaf Ebrahimi   if (callout_data != 0)
6574*22dc650dSSadaf Ebrahimi     {
6575*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Callout data = %d\n", callout_data);
6576*22dc650dSSadaf Ebrahimi     return callout_data;
6577*22dc650dSSadaf Ebrahimi     }
6578*22dc650dSSadaf Ebrahimi   }
6579*22dc650dSSadaf Ebrahimi 
6580*22dc650dSSadaf Ebrahimi /* Keep count and give the appropriate return code */
6581*22dc650dSSadaf Ebrahimi 
6582*22dc650dSSadaf Ebrahimi callout_count++;
6583*22dc650dSSadaf Ebrahimi 
6584*22dc650dSSadaf Ebrahimi if (cb->callout_number == dat_datctl.cerror[0] &&
6585*22dc650dSSadaf Ebrahimi     callout_count >= dat_datctl.cerror[1])
6586*22dc650dSSadaf Ebrahimi   return PCRE2_ERROR_CALLOUT;
6587*22dc650dSSadaf Ebrahimi 
6588*22dc650dSSadaf Ebrahimi if (cb->callout_number == dat_datctl.cfail[0] &&
6589*22dc650dSSadaf Ebrahimi     callout_count >= dat_datctl.cfail[1])
6590*22dc650dSSadaf Ebrahimi   return 1;
6591*22dc650dSSadaf Ebrahimi 
6592*22dc650dSSadaf Ebrahimi return 0;
6593*22dc650dSSadaf Ebrahimi }
6594*22dc650dSSadaf Ebrahimi 
6595*22dc650dSSadaf Ebrahimi 
6596*22dc650dSSadaf Ebrahimi 
6597*22dc650dSSadaf Ebrahimi /*************************************************
6598*22dc650dSSadaf Ebrahimi *       Handle *MARK and copy/get tests          *
6599*22dc650dSSadaf Ebrahimi *************************************************/
6600*22dc650dSSadaf Ebrahimi 
6601*22dc650dSSadaf Ebrahimi /* This function is called after complete and partial matches. It runs the
6602*22dc650dSSadaf Ebrahimi tests for substring extraction.
6603*22dc650dSSadaf Ebrahimi 
6604*22dc650dSSadaf Ebrahimi Arguments:
6605*22dc650dSSadaf Ebrahimi   utf       TRUE for utf
6606*22dc650dSSadaf Ebrahimi   capcount  return from pcre2_match()
6607*22dc650dSSadaf Ebrahimi 
6608*22dc650dSSadaf Ebrahimi Returns:    FALSE if print_error_message() fails
6609*22dc650dSSadaf Ebrahimi */
6610*22dc650dSSadaf Ebrahimi 
6611*22dc650dSSadaf Ebrahimi static BOOL
copy_and_get(BOOL utf,int capcount)6612*22dc650dSSadaf Ebrahimi copy_and_get(BOOL utf, int capcount)
6613*22dc650dSSadaf Ebrahimi {
6614*22dc650dSSadaf Ebrahimi int i;
6615*22dc650dSSadaf Ebrahimi uint8_t *nptr;
6616*22dc650dSSadaf Ebrahimi 
6617*22dc650dSSadaf Ebrahimi /* Test copy strings by number */
6618*22dc650dSSadaf Ebrahimi 
6619*22dc650dSSadaf Ebrahimi for (i = 0; i < MAXCPYGET && dat_datctl.copy_numbers[i] >= 0; i++)
6620*22dc650dSSadaf Ebrahimi   {
6621*22dc650dSSadaf Ebrahimi   int rc;
6622*22dc650dSSadaf Ebrahimi   PCRE2_SIZE length, length2;
6623*22dc650dSSadaf Ebrahimi   uint32_t copybuffer[256];
6624*22dc650dSSadaf Ebrahimi   uint32_t n = (uint32_t)(dat_datctl.copy_numbers[i]);
6625*22dc650dSSadaf Ebrahimi   length = sizeof(copybuffer)/code_unit_size;
6626*22dc650dSSadaf Ebrahimi   PCRE2_SUBSTRING_COPY_BYNUMBER(rc, match_data, n, copybuffer, &length);
6627*22dc650dSSadaf Ebrahimi   if (rc < 0)
6628*22dc650dSSadaf Ebrahimi     {
6629*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Copy substring %d failed (%d): ", n, rc);
6630*22dc650dSSadaf Ebrahimi     if (!print_error_message(rc, "", "\n")) return FALSE;
6631*22dc650dSSadaf Ebrahimi     }
6632*22dc650dSSadaf Ebrahimi   else
6633*22dc650dSSadaf Ebrahimi     {
6634*22dc650dSSadaf Ebrahimi     PCRE2_SUBSTRING_LENGTH_BYNUMBER(rc, match_data, n, &length2);
6635*22dc650dSSadaf Ebrahimi     if (rc < 0)
6636*22dc650dSSadaf Ebrahimi       {
6637*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Get substring %d length failed (%d): ", n, rc);
6638*22dc650dSSadaf Ebrahimi       if (!print_error_message(rc, "", "\n")) return FALSE;
6639*22dc650dSSadaf Ebrahimi       }
6640*22dc650dSSadaf Ebrahimi     else if (length2 != length)
6641*22dc650dSSadaf Ebrahimi       {
6642*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Mismatched substring lengths: %"
6643*22dc650dSSadaf Ebrahimi         SIZ_FORM " %" SIZ_FORM "\n", length, length2);
6644*22dc650dSSadaf Ebrahimi       }
6645*22dc650dSSadaf Ebrahimi     fprintf(outfile, "%2dC ", n);
6646*22dc650dSSadaf Ebrahimi     PCHARSV(copybuffer, 0, length, utf, outfile);
6647*22dc650dSSadaf Ebrahimi     fprintf(outfile, " (%" SIZ_FORM ")\n", length);
6648*22dc650dSSadaf Ebrahimi     }
6649*22dc650dSSadaf Ebrahimi   }
6650*22dc650dSSadaf Ebrahimi 
6651*22dc650dSSadaf Ebrahimi /* Test copy strings by name */
6652*22dc650dSSadaf Ebrahimi 
6653*22dc650dSSadaf Ebrahimi nptr = dat_datctl.copy_names;
6654*22dc650dSSadaf Ebrahimi for (;;)
6655*22dc650dSSadaf Ebrahimi   {
6656*22dc650dSSadaf Ebrahimi   int rc;
6657*22dc650dSSadaf Ebrahimi   int groupnumber;
6658*22dc650dSSadaf Ebrahimi   PCRE2_SIZE length, length2;
6659*22dc650dSSadaf Ebrahimi   uint32_t copybuffer[256];
6660*22dc650dSSadaf Ebrahimi   int namelen = strlen((const char *)nptr);
6661*22dc650dSSadaf Ebrahimi #if defined SUPPORT_PCRE2_16 || defined SUPPORT_PCRE2_32
6662*22dc650dSSadaf Ebrahimi   PCRE2_SIZE cnl = namelen;
6663*22dc650dSSadaf Ebrahimi #endif
6664*22dc650dSSadaf Ebrahimi   if (namelen == 0) break;
6665*22dc650dSSadaf Ebrahimi 
6666*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
6667*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) strcpy((char *)pbuffer8, (char *)nptr);
6668*22dc650dSSadaf Ebrahimi #endif
6669*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
6670*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE16_MODE)(void)to16(nptr, utf, &cnl);
6671*22dc650dSSadaf Ebrahimi #endif
6672*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
6673*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE32_MODE)(void)to32(nptr, utf, &cnl);
6674*22dc650dSSadaf Ebrahimi #endif
6675*22dc650dSSadaf Ebrahimi 
6676*22dc650dSSadaf Ebrahimi   PCRE2_SUBSTRING_NUMBER_FROM_NAME(groupnumber, compiled_code, pbuffer);
6677*22dc650dSSadaf Ebrahimi   if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING)
6678*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Number not found for group '%s'\n", nptr);
6679*22dc650dSSadaf Ebrahimi 
6680*22dc650dSSadaf Ebrahimi   length = sizeof(copybuffer)/code_unit_size;
6681*22dc650dSSadaf Ebrahimi   PCRE2_SUBSTRING_COPY_BYNAME(rc, match_data, pbuffer, copybuffer, &length);
6682*22dc650dSSadaf Ebrahimi   if (rc < 0)
6683*22dc650dSSadaf Ebrahimi     {
6684*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Copy substring '%s' failed (%d): ", nptr, rc);
6685*22dc650dSSadaf Ebrahimi     if (!print_error_message(rc, "", "\n")) return FALSE;
6686*22dc650dSSadaf Ebrahimi     }
6687*22dc650dSSadaf Ebrahimi   else
6688*22dc650dSSadaf Ebrahimi     {
6689*22dc650dSSadaf Ebrahimi     PCRE2_SUBSTRING_LENGTH_BYNAME(rc, match_data, pbuffer, &length2);
6690*22dc650dSSadaf Ebrahimi     if (rc < 0)
6691*22dc650dSSadaf Ebrahimi       {
6692*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Get substring '%s' length failed (%d): ", nptr, rc);
6693*22dc650dSSadaf Ebrahimi       if (!print_error_message(rc, "", "\n")) return FALSE;
6694*22dc650dSSadaf Ebrahimi       }
6695*22dc650dSSadaf Ebrahimi     else if (length2 != length)
6696*22dc650dSSadaf Ebrahimi       {
6697*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Mismatched substring lengths: %"
6698*22dc650dSSadaf Ebrahimi         SIZ_FORM " %" SIZ_FORM "\n", length, length2);
6699*22dc650dSSadaf Ebrahimi       }
6700*22dc650dSSadaf Ebrahimi     fprintf(outfile, "  C ");
6701*22dc650dSSadaf Ebrahimi     PCHARSV(copybuffer, 0, length, utf, outfile);
6702*22dc650dSSadaf Ebrahimi     fprintf(outfile, " (%" SIZ_FORM ") %s", length, nptr);
6703*22dc650dSSadaf Ebrahimi     if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber);
6704*22dc650dSSadaf Ebrahimi       else fprintf(outfile, " (non-unique)\n");
6705*22dc650dSSadaf Ebrahimi     }
6706*22dc650dSSadaf Ebrahimi   nptr += namelen + 1;
6707*22dc650dSSadaf Ebrahimi   }
6708*22dc650dSSadaf Ebrahimi 
6709*22dc650dSSadaf Ebrahimi /* Test get strings by number */
6710*22dc650dSSadaf Ebrahimi 
6711*22dc650dSSadaf Ebrahimi for (i = 0; i < MAXCPYGET && dat_datctl.get_numbers[i] >= 0; i++)
6712*22dc650dSSadaf Ebrahimi   {
6713*22dc650dSSadaf Ebrahimi   int rc;
6714*22dc650dSSadaf Ebrahimi   PCRE2_SIZE length;
6715*22dc650dSSadaf Ebrahimi   void *gotbuffer;
6716*22dc650dSSadaf Ebrahimi   uint32_t n = (uint32_t)(dat_datctl.get_numbers[i]);
6717*22dc650dSSadaf Ebrahimi   PCRE2_SUBSTRING_GET_BYNUMBER(rc, match_data, n, &gotbuffer, &length);
6718*22dc650dSSadaf Ebrahimi   if (rc < 0)
6719*22dc650dSSadaf Ebrahimi     {
6720*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Get substring %d failed (%d): ", n, rc);
6721*22dc650dSSadaf Ebrahimi     if (!print_error_message(rc, "", "\n")) return FALSE;
6722*22dc650dSSadaf Ebrahimi     }
6723*22dc650dSSadaf Ebrahimi   else
6724*22dc650dSSadaf Ebrahimi     {
6725*22dc650dSSadaf Ebrahimi     fprintf(outfile, "%2dG ", n);
6726*22dc650dSSadaf Ebrahimi     PCHARSV(gotbuffer, 0, length, utf, outfile);
6727*22dc650dSSadaf Ebrahimi     fprintf(outfile, " (%" SIZ_FORM ")\n", length);
6728*22dc650dSSadaf Ebrahimi     PCRE2_SUBSTRING_FREE(gotbuffer);
6729*22dc650dSSadaf Ebrahimi     }
6730*22dc650dSSadaf Ebrahimi   }
6731*22dc650dSSadaf Ebrahimi 
6732*22dc650dSSadaf Ebrahimi /* Test get strings by name */
6733*22dc650dSSadaf Ebrahimi 
6734*22dc650dSSadaf Ebrahimi nptr = dat_datctl.get_names;
6735*22dc650dSSadaf Ebrahimi for (;;)
6736*22dc650dSSadaf Ebrahimi   {
6737*22dc650dSSadaf Ebrahimi   PCRE2_SIZE length;
6738*22dc650dSSadaf Ebrahimi   void *gotbuffer;
6739*22dc650dSSadaf Ebrahimi   int rc;
6740*22dc650dSSadaf Ebrahimi   int groupnumber;
6741*22dc650dSSadaf Ebrahimi   int namelen = strlen((const char *)nptr);
6742*22dc650dSSadaf Ebrahimi #if defined SUPPORT_PCRE2_16 || defined SUPPORT_PCRE2_32
6743*22dc650dSSadaf Ebrahimi   PCRE2_SIZE cnl = namelen;
6744*22dc650dSSadaf Ebrahimi #endif
6745*22dc650dSSadaf Ebrahimi   if (namelen == 0) break;
6746*22dc650dSSadaf Ebrahimi 
6747*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
6748*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE) strcpy((char *)pbuffer8, (char *)nptr);
6749*22dc650dSSadaf Ebrahimi #endif
6750*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
6751*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE16_MODE)(void)to16(nptr, utf, &cnl);
6752*22dc650dSSadaf Ebrahimi #endif
6753*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
6754*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE32_MODE)(void)to32(nptr, utf, &cnl);
6755*22dc650dSSadaf Ebrahimi #endif
6756*22dc650dSSadaf Ebrahimi 
6757*22dc650dSSadaf Ebrahimi   PCRE2_SUBSTRING_NUMBER_FROM_NAME(groupnumber, compiled_code, pbuffer);
6758*22dc650dSSadaf Ebrahimi   if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING)
6759*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Number not found for group '%s'\n", nptr);
6760*22dc650dSSadaf Ebrahimi 
6761*22dc650dSSadaf Ebrahimi   PCRE2_SUBSTRING_GET_BYNAME(rc, match_data, pbuffer, &gotbuffer, &length);
6762*22dc650dSSadaf Ebrahimi   if (rc < 0)
6763*22dc650dSSadaf Ebrahimi     {
6764*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Get substring '%s' failed (%d): ", nptr, rc);
6765*22dc650dSSadaf Ebrahimi     if (!print_error_message(rc, "", "\n")) return FALSE;
6766*22dc650dSSadaf Ebrahimi     }
6767*22dc650dSSadaf Ebrahimi   else
6768*22dc650dSSadaf Ebrahimi     {
6769*22dc650dSSadaf Ebrahimi     fprintf(outfile, "  G ");
6770*22dc650dSSadaf Ebrahimi     PCHARSV(gotbuffer, 0, length, utf, outfile);
6771*22dc650dSSadaf Ebrahimi     fprintf(outfile, " (%" SIZ_FORM ") %s", length, nptr);
6772*22dc650dSSadaf Ebrahimi     if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber);
6773*22dc650dSSadaf Ebrahimi       else fprintf(outfile, " (non-unique)\n");
6774*22dc650dSSadaf Ebrahimi     PCRE2_SUBSTRING_FREE(gotbuffer);
6775*22dc650dSSadaf Ebrahimi     }
6776*22dc650dSSadaf Ebrahimi   nptr += namelen + 1;
6777*22dc650dSSadaf Ebrahimi   }
6778*22dc650dSSadaf Ebrahimi 
6779*22dc650dSSadaf Ebrahimi /* Test getting the complete list of captured strings. */
6780*22dc650dSSadaf Ebrahimi 
6781*22dc650dSSadaf Ebrahimi if ((dat_datctl.control & CTL_GETALL) != 0)
6782*22dc650dSSadaf Ebrahimi   {
6783*22dc650dSSadaf Ebrahimi   int rc;
6784*22dc650dSSadaf Ebrahimi   void **stringlist;
6785*22dc650dSSadaf Ebrahimi   PCRE2_SIZE *lengths;
6786*22dc650dSSadaf Ebrahimi   PCRE2_SUBSTRING_LIST_GET(rc, match_data, &stringlist, &lengths);
6787*22dc650dSSadaf Ebrahimi   if (rc < 0)
6788*22dc650dSSadaf Ebrahimi     {
6789*22dc650dSSadaf Ebrahimi     fprintf(outfile, "get substring list failed (%d): ", rc);
6790*22dc650dSSadaf Ebrahimi     if (!print_error_message(rc, "", "\n")) return FALSE;
6791*22dc650dSSadaf Ebrahimi     }
6792*22dc650dSSadaf Ebrahimi   else
6793*22dc650dSSadaf Ebrahimi     {
6794*22dc650dSSadaf Ebrahimi     for (i = 0; i < capcount; i++)
6795*22dc650dSSadaf Ebrahimi       {
6796*22dc650dSSadaf Ebrahimi       fprintf(outfile, "%2dL ", i);
6797*22dc650dSSadaf Ebrahimi       PCHARSV(stringlist[i], 0, lengths[i], utf, outfile);
6798*22dc650dSSadaf Ebrahimi       putc('\n', outfile);
6799*22dc650dSSadaf Ebrahimi       }
6800*22dc650dSSadaf Ebrahimi     if (stringlist[i] != NULL)
6801*22dc650dSSadaf Ebrahimi       fprintf(outfile, "string list not terminated by NULL\n");
6802*22dc650dSSadaf Ebrahimi     PCRE2_SUBSTRING_LIST_FREE(stringlist);
6803*22dc650dSSadaf Ebrahimi     }
6804*22dc650dSSadaf Ebrahimi   }
6805*22dc650dSSadaf Ebrahimi 
6806*22dc650dSSadaf Ebrahimi return TRUE;
6807*22dc650dSSadaf Ebrahimi }
6808*22dc650dSSadaf Ebrahimi 
6809*22dc650dSSadaf Ebrahimi 
6810*22dc650dSSadaf Ebrahimi 
6811*22dc650dSSadaf Ebrahimi /*************************************************
6812*22dc650dSSadaf Ebrahimi *            Show an entire ovector              *
6813*22dc650dSSadaf Ebrahimi *************************************************/
6814*22dc650dSSadaf Ebrahimi 
6815*22dc650dSSadaf Ebrahimi /* This function is called after partial matching or match failure, when the
6816*22dc650dSSadaf Ebrahimi "allvector" modifier is set. It is a means of checking the contents of the
6817*22dc650dSSadaf Ebrahimi entire ovector, to ensure no modification of fields that should be unchanged.
6818*22dc650dSSadaf Ebrahimi 
6819*22dc650dSSadaf Ebrahimi Arguments:
6820*22dc650dSSadaf Ebrahimi   ovector      points to the ovector
6821*22dc650dSSadaf Ebrahimi   oveccount    number of pairs
6822*22dc650dSSadaf Ebrahimi 
6823*22dc650dSSadaf Ebrahimi Returns:       nothing
6824*22dc650dSSadaf Ebrahimi */
6825*22dc650dSSadaf Ebrahimi 
6826*22dc650dSSadaf Ebrahimi static void
show_ovector(PCRE2_SIZE * ovector,uint32_t oveccount)6827*22dc650dSSadaf Ebrahimi show_ovector(PCRE2_SIZE *ovector, uint32_t oveccount)
6828*22dc650dSSadaf Ebrahimi {
6829*22dc650dSSadaf Ebrahimi uint32_t i;
6830*22dc650dSSadaf Ebrahimi for (i = 0; i < 2*oveccount; i += 2)
6831*22dc650dSSadaf Ebrahimi   {
6832*22dc650dSSadaf Ebrahimi   PCRE2_SIZE start = ovector[i];
6833*22dc650dSSadaf Ebrahimi   PCRE2_SIZE end = ovector[i+1];
6834*22dc650dSSadaf Ebrahimi 
6835*22dc650dSSadaf Ebrahimi   fprintf(outfile, "%2d: ", i/2);
6836*22dc650dSSadaf Ebrahimi   if (start == PCRE2_UNSET && end == PCRE2_UNSET)
6837*22dc650dSSadaf Ebrahimi     fprintf(outfile, "<unset>\n");
6838*22dc650dSSadaf Ebrahimi   else if (start == JUNK_OFFSET && end == JUNK_OFFSET)
6839*22dc650dSSadaf Ebrahimi     fprintf(outfile, "<unchanged>\n");
6840*22dc650dSSadaf Ebrahimi   else
6841*22dc650dSSadaf Ebrahimi     fprintf(outfile, "%ld %ld\n", (unsigned long int)start,
6842*22dc650dSSadaf Ebrahimi       (unsigned long int)end);
6843*22dc650dSSadaf Ebrahimi   }
6844*22dc650dSSadaf Ebrahimi }
6845*22dc650dSSadaf Ebrahimi 
6846*22dc650dSSadaf Ebrahimi 
6847*22dc650dSSadaf Ebrahimi /*************************************************
6848*22dc650dSSadaf Ebrahimi *               Process a data line              *
6849*22dc650dSSadaf Ebrahimi *************************************************/
6850*22dc650dSSadaf Ebrahimi 
6851*22dc650dSSadaf Ebrahimi /* The line is in buffer; it will not be empty.
6852*22dc650dSSadaf Ebrahimi 
6853*22dc650dSSadaf Ebrahimi Arguments:  none
6854*22dc650dSSadaf Ebrahimi 
6855*22dc650dSSadaf Ebrahimi Returns:    PR_OK     continue processing next line
6856*22dc650dSSadaf Ebrahimi             PR_SKIP   skip to a blank line
6857*22dc650dSSadaf Ebrahimi             PR_ABEND  abort the pcre2test run
6858*22dc650dSSadaf Ebrahimi */
6859*22dc650dSSadaf Ebrahimi 
6860*22dc650dSSadaf Ebrahimi static int
process_data(void)6861*22dc650dSSadaf Ebrahimi process_data(void)
6862*22dc650dSSadaf Ebrahimi {
6863*22dc650dSSadaf Ebrahimi PCRE2_SIZE len, ulen, arg_ulen;
6864*22dc650dSSadaf Ebrahimi uint32_t gmatched;
6865*22dc650dSSadaf Ebrahimi uint32_t c, k;
6866*22dc650dSSadaf Ebrahimi uint32_t g_notempty = 0;
6867*22dc650dSSadaf Ebrahimi uint8_t *p, *pp, *start_rep;
6868*22dc650dSSadaf Ebrahimi size_t needlen;
6869*22dc650dSSadaf Ebrahimi void *use_dat_context;
6870*22dc650dSSadaf Ebrahimi BOOL utf;
6871*22dc650dSSadaf Ebrahimi BOOL subject_literal;
6872*22dc650dSSadaf Ebrahimi 
6873*22dc650dSSadaf Ebrahimi PCRE2_SIZE *ovector;
6874*22dc650dSSadaf Ebrahimi PCRE2_SIZE ovecsave[3];
6875*22dc650dSSadaf Ebrahimi uint32_t oveccount;
6876*22dc650dSSadaf Ebrahimi 
6877*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
6878*22dc650dSSadaf Ebrahimi uint8_t *q8 = NULL;
6879*22dc650dSSadaf Ebrahimi #endif
6880*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
6881*22dc650dSSadaf Ebrahimi uint16_t *q16 = NULL;
6882*22dc650dSSadaf Ebrahimi #endif
6883*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
6884*22dc650dSSadaf Ebrahimi uint32_t *q32 = NULL;
6885*22dc650dSSadaf Ebrahimi #endif
6886*22dc650dSSadaf Ebrahimi 
6887*22dc650dSSadaf Ebrahimi subject_literal = (pat_patctl.control2 & CTL2_SUBJECT_LITERAL) != 0;
6888*22dc650dSSadaf Ebrahimi 
6889*22dc650dSSadaf Ebrahimi /* Copy the default context and data control blocks to the active ones. Then
6890*22dc650dSSadaf Ebrahimi copy from the pattern the controls that can be set in either the pattern or the
6891*22dc650dSSadaf Ebrahimi data. This allows them to be overridden in the data line. We do not do this for
6892*22dc650dSSadaf Ebrahimi options because those that are common apply separately to compiling and
6893*22dc650dSSadaf Ebrahimi matching. */
6894*22dc650dSSadaf Ebrahimi 
6895*22dc650dSSadaf Ebrahimi DATCTXCPY(dat_context, default_dat_context);
6896*22dc650dSSadaf Ebrahimi memcpy(&dat_datctl, &def_datctl, sizeof(datctl));
6897*22dc650dSSadaf Ebrahimi dat_datctl.control |= (pat_patctl.control & CTL_ALLPD);
6898*22dc650dSSadaf Ebrahimi dat_datctl.control2 |= (pat_patctl.control2 & CTL2_ALLPD);
6899*22dc650dSSadaf Ebrahimi strcpy((char *)dat_datctl.replacement, (char *)pat_patctl.replacement);
6900*22dc650dSSadaf Ebrahimi if (dat_datctl.jitstack == 0) dat_datctl.jitstack = pat_patctl.jitstack;
6901*22dc650dSSadaf Ebrahimi 
6902*22dc650dSSadaf Ebrahimi if (dat_datctl.substitute_skip == 0)
6903*22dc650dSSadaf Ebrahimi     dat_datctl.substitute_skip = pat_patctl.substitute_skip;
6904*22dc650dSSadaf Ebrahimi if (dat_datctl.substitute_stop == 0)
6905*22dc650dSSadaf Ebrahimi     dat_datctl.substitute_stop = pat_patctl.substitute_stop;
6906*22dc650dSSadaf Ebrahimi 
6907*22dc650dSSadaf Ebrahimi /* Initialize for scanning the data line. */
6908*22dc650dSSadaf Ebrahimi 
6909*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
6910*22dc650dSSadaf Ebrahimi utf = ((((pat_patctl.control & CTL_POSIX) != 0)?
6911*22dc650dSSadaf Ebrahimi   ((pcre2_real_code_8 *)preg.re_pcre2_code)->overall_options :
6912*22dc650dSSadaf Ebrahimi   FLD(compiled_code, overall_options)) & PCRE2_UTF) != 0;
6913*22dc650dSSadaf Ebrahimi #else
6914*22dc650dSSadaf Ebrahimi utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;
6915*22dc650dSSadaf Ebrahimi #endif
6916*22dc650dSSadaf Ebrahimi 
6917*22dc650dSSadaf Ebrahimi start_rep = NULL;
6918*22dc650dSSadaf Ebrahimi len = strlen((const char *)buffer);
6919*22dc650dSSadaf Ebrahimi while (len > 0 && isspace(buffer[len-1])) len--;
6920*22dc650dSSadaf Ebrahimi buffer[len] = 0;
6921*22dc650dSSadaf Ebrahimi p = buffer;
6922*22dc650dSSadaf Ebrahimi while (isspace(*p)) p++;
6923*22dc650dSSadaf Ebrahimi 
6924*22dc650dSSadaf Ebrahimi /* Check that the data is well-formed UTF-8 if we're in UTF mode. To create
6925*22dc650dSSadaf Ebrahimi invalid input to pcre2_match(), you must use \x?? or \x{} sequences. */
6926*22dc650dSSadaf Ebrahimi 
6927*22dc650dSSadaf Ebrahimi if (utf)
6928*22dc650dSSadaf Ebrahimi   {
6929*22dc650dSSadaf Ebrahimi   uint8_t *q;
6930*22dc650dSSadaf Ebrahimi   uint32_t cc;
6931*22dc650dSSadaf Ebrahimi   int n = 1;
6932*22dc650dSSadaf Ebrahimi   uint8_t *q_end = p + len;
6933*22dc650dSSadaf Ebrahimi 
6934*22dc650dSSadaf Ebrahimi   for (q = p; n > 0 && *q; q += n) n = utf82ord(q, q_end, &cc);
6935*22dc650dSSadaf Ebrahimi   if (n <= 0)
6936*22dc650dSSadaf Ebrahimi     {
6937*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Failed: invalid UTF-8 string cannot be used as input "
6938*22dc650dSSadaf Ebrahimi       "in UTF mode\n");
6939*22dc650dSSadaf Ebrahimi     return PR_OK;
6940*22dc650dSSadaf Ebrahimi     }
6941*22dc650dSSadaf Ebrahimi   }
6942*22dc650dSSadaf Ebrahimi 
6943*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_VALGRIND
6944*22dc650dSSadaf Ebrahimi /* Mark the dbuffer as addressable but undefined again. */
6945*22dc650dSSadaf Ebrahimi if (dbuffer != NULL)
6946*22dc650dSSadaf Ebrahimi   {
6947*22dc650dSSadaf Ebrahimi   VALGRIND_MAKE_MEM_UNDEFINED(dbuffer, dbuffer_size);
6948*22dc650dSSadaf Ebrahimi   }
6949*22dc650dSSadaf Ebrahimi #endif
6950*22dc650dSSadaf Ebrahimi 
6951*22dc650dSSadaf Ebrahimi /* Allocate a buffer to hold the data line; len+1 is an upper bound on
6952*22dc650dSSadaf Ebrahimi the number of code units that will be needed (though the buffer may have to be
6953*22dc650dSSadaf Ebrahimi extended if replication is involved). */
6954*22dc650dSSadaf Ebrahimi 
6955*22dc650dSSadaf Ebrahimi needlen = (len+1) * code_unit_size;
6956*22dc650dSSadaf Ebrahimi if (dbuffer == NULL || needlen >= dbuffer_size)
6957*22dc650dSSadaf Ebrahimi   {
6958*22dc650dSSadaf Ebrahimi   while (needlen >= dbuffer_size)
6959*22dc650dSSadaf Ebrahimi     {
6960*22dc650dSSadaf Ebrahimi     if (dbuffer_size < SIZE_MAX/2) dbuffer_size *= 2;
6961*22dc650dSSadaf Ebrahimi       else dbuffer_size = needlen + 1;
6962*22dc650dSSadaf Ebrahimi     }
6963*22dc650dSSadaf Ebrahimi   dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size);
6964*22dc650dSSadaf Ebrahimi   if (dbuffer == NULL)
6965*22dc650dSSadaf Ebrahimi     {
6966*22dc650dSSadaf Ebrahimi     fprintf(stderr, "pcre2test: realloc(%" SIZ_FORM ") failed\n", dbuffer_size);
6967*22dc650dSSadaf Ebrahimi     exit(1);
6968*22dc650dSSadaf Ebrahimi     }
6969*22dc650dSSadaf Ebrahimi   }
6970*22dc650dSSadaf Ebrahimi SETCASTPTR(q, dbuffer);  /* Sets q8, q16, or q32, as appropriate. */
6971*22dc650dSSadaf Ebrahimi 
6972*22dc650dSSadaf Ebrahimi /* Scan the data line, interpreting data escapes, and put the result into a
6973*22dc650dSSadaf Ebrahimi buffer of the appropriate width. In UTF mode, input is always UTF-8; otherwise,
6974*22dc650dSSadaf Ebrahimi in 16- and 32-bit modes, it can be forced to UTF-8 by the utf8_input modifier.
6975*22dc650dSSadaf Ebrahimi */
6976*22dc650dSSadaf Ebrahimi 
6977*22dc650dSSadaf Ebrahimi while ((c = *p++) != 0)
6978*22dc650dSSadaf Ebrahimi   {
6979*22dc650dSSadaf Ebrahimi   int32_t i = 0;
6980*22dc650dSSadaf Ebrahimi   size_t replen;
6981*22dc650dSSadaf Ebrahimi 
6982*22dc650dSSadaf Ebrahimi   /* ] may mark the end of a replicated sequence */
6983*22dc650dSSadaf Ebrahimi 
6984*22dc650dSSadaf Ebrahimi   if (c == ']' && start_rep != NULL)
6985*22dc650dSSadaf Ebrahimi     {
6986*22dc650dSSadaf Ebrahimi     PCRE2_SIZE d;
6987*22dc650dSSadaf Ebrahimi     long li;
6988*22dc650dSSadaf Ebrahimi     char *endptr;
6989*22dc650dSSadaf Ebrahimi 
6990*22dc650dSSadaf Ebrahimi     if (*p++ != '{')
6991*22dc650dSSadaf Ebrahimi       {
6992*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Expected '{' after \\[....]\n");
6993*22dc650dSSadaf Ebrahimi       return PR_OK;
6994*22dc650dSSadaf Ebrahimi       }
6995*22dc650dSSadaf Ebrahimi 
6996*22dc650dSSadaf Ebrahimi     li = strtol((const char *)p, &endptr, 10);
6997*22dc650dSSadaf Ebrahimi     if (S32OVERFLOW(li))
6998*22dc650dSSadaf Ebrahimi       {
6999*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Repeat count too large\n");
7000*22dc650dSSadaf Ebrahimi       return PR_OK;
7001*22dc650dSSadaf Ebrahimi       }
7002*22dc650dSSadaf Ebrahimi 
7003*22dc650dSSadaf Ebrahimi     p = (uint8_t *)endptr;
7004*22dc650dSSadaf Ebrahimi     if (*p++ != '}')
7005*22dc650dSSadaf Ebrahimi       {
7006*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Expected '}' after \\[...]{...\n");
7007*22dc650dSSadaf Ebrahimi       return PR_OK;
7008*22dc650dSSadaf Ebrahimi       }
7009*22dc650dSSadaf Ebrahimi 
7010*22dc650dSSadaf Ebrahimi     i = (int32_t)li;
7011*22dc650dSSadaf Ebrahimi     if (i-- <= 0)
7012*22dc650dSSadaf Ebrahimi       {
7013*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Zero or negative repeat not allowed\n");
7014*22dc650dSSadaf Ebrahimi       return PR_OK;
7015*22dc650dSSadaf Ebrahimi       }
7016*22dc650dSSadaf Ebrahimi 
7017*22dc650dSSadaf Ebrahimi     replen = CAST8VAR(q) - start_rep;
7018*22dc650dSSadaf Ebrahimi     if (PRIV(ckd_smul)(&d, replen, i))
7019*22dc650dSSadaf Ebrahimi       {
7020*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Expanded content too large\n");
7021*22dc650dSSadaf Ebrahimi       return PR_OK;
7022*22dc650dSSadaf Ebrahimi       }
7023*22dc650dSSadaf Ebrahimi     needlen += d;
7024*22dc650dSSadaf Ebrahimi 
7025*22dc650dSSadaf Ebrahimi     if (needlen >= dbuffer_size)
7026*22dc650dSSadaf Ebrahimi       {
7027*22dc650dSSadaf Ebrahimi       size_t qoffset = CAST8VAR(q) - dbuffer;
7028*22dc650dSSadaf Ebrahimi       size_t rep_offset = start_rep - dbuffer;
7029*22dc650dSSadaf Ebrahimi       while (needlen >= dbuffer_size)
7030*22dc650dSSadaf Ebrahimi         {
7031*22dc650dSSadaf Ebrahimi         if (dbuffer_size < SIZE_MAX/2) dbuffer_size *= 2;
7032*22dc650dSSadaf Ebrahimi           else dbuffer_size = needlen + 1;
7033*22dc650dSSadaf Ebrahimi         }
7034*22dc650dSSadaf Ebrahimi       dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size);
7035*22dc650dSSadaf Ebrahimi       if (dbuffer == NULL)
7036*22dc650dSSadaf Ebrahimi         {
7037*22dc650dSSadaf Ebrahimi         fprintf(stderr, "pcre2test: realloc(%" SIZ_FORM ") failed\n",
7038*22dc650dSSadaf Ebrahimi           dbuffer_size);
7039*22dc650dSSadaf Ebrahimi         exit(1);
7040*22dc650dSSadaf Ebrahimi         }
7041*22dc650dSSadaf Ebrahimi       SETCASTPTR(q, dbuffer + qoffset);
7042*22dc650dSSadaf Ebrahimi       start_rep = dbuffer + rep_offset;
7043*22dc650dSSadaf Ebrahimi       }
7044*22dc650dSSadaf Ebrahimi 
7045*22dc650dSSadaf Ebrahimi     while (i-- > 0)
7046*22dc650dSSadaf Ebrahimi       {
7047*22dc650dSSadaf Ebrahimi       memcpy(CAST8VAR(q), start_rep, replen);
7048*22dc650dSSadaf Ebrahimi       SETPLUS(q, replen/code_unit_size);
7049*22dc650dSSadaf Ebrahimi       }
7050*22dc650dSSadaf Ebrahimi 
7051*22dc650dSSadaf Ebrahimi     start_rep = NULL;
7052*22dc650dSSadaf Ebrahimi     continue;
7053*22dc650dSSadaf Ebrahimi     }
7054*22dc650dSSadaf Ebrahimi 
7055*22dc650dSSadaf Ebrahimi   /* Handle a non-escaped character. In non-UTF 32-bit mode with utf8_input
7056*22dc650dSSadaf Ebrahimi   set, do the fudge for setting the top bit. */
7057*22dc650dSSadaf Ebrahimi 
7058*22dc650dSSadaf Ebrahimi   if (c != '\\' || subject_literal)
7059*22dc650dSSadaf Ebrahimi     {
7060*22dc650dSSadaf Ebrahimi     uint32_t topbit = 0;
7061*22dc650dSSadaf Ebrahimi     if (test_mode == PCRE32_MODE && c == 0xff && *p != 0)
7062*22dc650dSSadaf Ebrahimi       {
7063*22dc650dSSadaf Ebrahimi       topbit = 0x80000000;
7064*22dc650dSSadaf Ebrahimi       c = *p++;
7065*22dc650dSSadaf Ebrahimi       }
7066*22dc650dSSadaf Ebrahimi     if ((utf || (pat_patctl.control & CTL_UTF8_INPUT) != 0) &&
7067*22dc650dSSadaf Ebrahimi       HASUTF8EXTRALEN(c)) { GETUTF8INC(c, p); }
7068*22dc650dSSadaf Ebrahimi     c |= topbit;
7069*22dc650dSSadaf Ebrahimi     }
7070*22dc650dSSadaf Ebrahimi 
7071*22dc650dSSadaf Ebrahimi   /* Handle backslash escapes */
7072*22dc650dSSadaf Ebrahimi 
7073*22dc650dSSadaf Ebrahimi   else switch ((c = *p++))
7074*22dc650dSSadaf Ebrahimi     {
7075*22dc650dSSadaf Ebrahimi     case '\\': break;
7076*22dc650dSSadaf Ebrahimi     case 'a': c = CHAR_BEL; break;
7077*22dc650dSSadaf Ebrahimi     case 'b': c = '\b'; break;
7078*22dc650dSSadaf Ebrahimi     case 'e': c = CHAR_ESC; break;
7079*22dc650dSSadaf Ebrahimi     case 'f': c = '\f'; break;
7080*22dc650dSSadaf Ebrahimi     case 'n': c = '\n'; break;
7081*22dc650dSSadaf Ebrahimi     case 'r': c = '\r'; break;
7082*22dc650dSSadaf Ebrahimi     case 't': c = '\t'; break;
7083*22dc650dSSadaf Ebrahimi     case 'v': c = '\v'; break;
7084*22dc650dSSadaf Ebrahimi 
7085*22dc650dSSadaf Ebrahimi     case '0': case '1': case '2': case '3':
7086*22dc650dSSadaf Ebrahimi     case '4': case '5': case '6': case '7':
7087*22dc650dSSadaf Ebrahimi     c -= '0';
7088*22dc650dSSadaf Ebrahimi     while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
7089*22dc650dSSadaf Ebrahimi       c = c * 8 + *p++ - '0';
7090*22dc650dSSadaf Ebrahimi     break;
7091*22dc650dSSadaf Ebrahimi 
7092*22dc650dSSadaf Ebrahimi     case 'o':
7093*22dc650dSSadaf Ebrahimi     if (*p == '{')
7094*22dc650dSSadaf Ebrahimi       {
7095*22dc650dSSadaf Ebrahimi       uint8_t *pt = p;
7096*22dc650dSSadaf Ebrahimi       c = 0;
7097*22dc650dSSadaf Ebrahimi       for (pt++; isdigit(*pt) && *pt != '8' && *pt != '9'; pt++)
7098*22dc650dSSadaf Ebrahimi         {
7099*22dc650dSSadaf Ebrahimi         if (++i == 12)
7100*22dc650dSSadaf Ebrahimi           fprintf(outfile, "** Too many octal digits in \\o{...} item; "
7101*22dc650dSSadaf Ebrahimi                            "using only the first twelve.\n");
7102*22dc650dSSadaf Ebrahimi         else c = c * 8 + *pt - '0';
7103*22dc650dSSadaf Ebrahimi         }
7104*22dc650dSSadaf Ebrahimi       if (*pt == '}') p = pt + 1;
7105*22dc650dSSadaf Ebrahimi         else fprintf(outfile, "** Missing } after \\o{ (assumed)\n");
7106*22dc650dSSadaf Ebrahimi       }
7107*22dc650dSSadaf Ebrahimi     break;
7108*22dc650dSSadaf Ebrahimi 
7109*22dc650dSSadaf Ebrahimi     case 'x':
7110*22dc650dSSadaf Ebrahimi     if (*p == '{')
7111*22dc650dSSadaf Ebrahimi       {
7112*22dc650dSSadaf Ebrahimi       uint8_t *pt = p;
7113*22dc650dSSadaf Ebrahimi       c = 0;
7114*22dc650dSSadaf Ebrahimi 
7115*22dc650dSSadaf Ebrahimi       /* We used to have "while (isxdigit(*(++pt)))" here, but it fails
7116*22dc650dSSadaf Ebrahimi       when isxdigit() is a macro that refers to its argument more than
7117*22dc650dSSadaf Ebrahimi       once. This is banned by the C Standard, but apparently happens in at
7118*22dc650dSSadaf Ebrahimi       least one MacOS environment. */
7119*22dc650dSSadaf Ebrahimi 
7120*22dc650dSSadaf Ebrahimi       for (pt++; isxdigit(*pt); pt++)
7121*22dc650dSSadaf Ebrahimi         {
7122*22dc650dSSadaf Ebrahimi         if (++i == 9)
7123*22dc650dSSadaf Ebrahimi           fprintf(outfile, "** Too many hex digits in \\x{...} item; "
7124*22dc650dSSadaf Ebrahimi                            "using only the first eight.\n");
7125*22dc650dSSadaf Ebrahimi         else c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'a' - 10);
7126*22dc650dSSadaf Ebrahimi         }
7127*22dc650dSSadaf Ebrahimi       if (*pt == '}')
7128*22dc650dSSadaf Ebrahimi         {
7129*22dc650dSSadaf Ebrahimi         p = pt + 1;
7130*22dc650dSSadaf Ebrahimi         break;
7131*22dc650dSSadaf Ebrahimi         }
7132*22dc650dSSadaf Ebrahimi       /* Not correct form for \x{...}; fall through */
7133*22dc650dSSadaf Ebrahimi       }
7134*22dc650dSSadaf Ebrahimi 
7135*22dc650dSSadaf Ebrahimi     /* \x without {} always defines just one byte in 8-bit mode. This
7136*22dc650dSSadaf Ebrahimi     allows UTF-8 characters to be constructed byte by byte, and also allows
7137*22dc650dSSadaf Ebrahimi     invalid UTF-8 sequences to be made. Just copy the byte in UTF-8 mode.
7138*22dc650dSSadaf Ebrahimi     Otherwise, pass it down as data. */
7139*22dc650dSSadaf Ebrahimi 
7140*22dc650dSSadaf Ebrahimi     c = 0;
7141*22dc650dSSadaf Ebrahimi     while (i++ < 2 && isxdigit(*p))
7142*22dc650dSSadaf Ebrahimi       {
7143*22dc650dSSadaf Ebrahimi       c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10);
7144*22dc650dSSadaf Ebrahimi       p++;
7145*22dc650dSSadaf Ebrahimi       }
7146*22dc650dSSadaf Ebrahimi #if defined SUPPORT_PCRE2_8
7147*22dc650dSSadaf Ebrahimi     if (utf && (test_mode == PCRE8_MODE))
7148*22dc650dSSadaf Ebrahimi       {
7149*22dc650dSSadaf Ebrahimi       *q8++ = c;
7150*22dc650dSSadaf Ebrahimi       continue;
7151*22dc650dSSadaf Ebrahimi       }
7152*22dc650dSSadaf Ebrahimi #endif
7153*22dc650dSSadaf Ebrahimi     break;
7154*22dc650dSSadaf Ebrahimi 
7155*22dc650dSSadaf Ebrahimi     case 0:     /* \ followed by EOF allows for an empty line */
7156*22dc650dSSadaf Ebrahimi     p--;
7157*22dc650dSSadaf Ebrahimi     continue;
7158*22dc650dSSadaf Ebrahimi 
7159*22dc650dSSadaf Ebrahimi     case '=':   /* \= terminates the data, starts modifiers */
7160*22dc650dSSadaf Ebrahimi     goto ENDSTRING;
7161*22dc650dSSadaf Ebrahimi 
7162*22dc650dSSadaf Ebrahimi     case '[':   /* \[ introduces a replicated character sequence */
7163*22dc650dSSadaf Ebrahimi     if (start_rep != NULL)
7164*22dc650dSSadaf Ebrahimi       {
7165*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Nested replication is not supported\n");
7166*22dc650dSSadaf Ebrahimi       return PR_OK;
7167*22dc650dSSadaf Ebrahimi       }
7168*22dc650dSSadaf Ebrahimi     start_rep = CAST8VAR(q);
7169*22dc650dSSadaf Ebrahimi     continue;
7170*22dc650dSSadaf Ebrahimi 
7171*22dc650dSSadaf Ebrahimi     default:
7172*22dc650dSSadaf Ebrahimi     if (isalnum(c))
7173*22dc650dSSadaf Ebrahimi       {
7174*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Unrecognized escape sequence \"\\%c\"\n", c);
7175*22dc650dSSadaf Ebrahimi       return PR_OK;
7176*22dc650dSSadaf Ebrahimi       }
7177*22dc650dSSadaf Ebrahimi     }
7178*22dc650dSSadaf Ebrahimi 
7179*22dc650dSSadaf Ebrahimi   /* We now have a character value in c that may be greater than 255.
7180*22dc650dSSadaf Ebrahimi   In 8-bit mode we convert to UTF-8 if we are in UTF mode. Values greater
7181*22dc650dSSadaf Ebrahimi   than 127 in UTF mode must have come from \x{...} or octal constructs
7182*22dc650dSSadaf Ebrahimi   because values from \x.. get this far only in non-UTF mode. */
7183*22dc650dSSadaf Ebrahimi 
7184*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
7185*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE8_MODE)
7186*22dc650dSSadaf Ebrahimi     {
7187*22dc650dSSadaf Ebrahimi     if (utf)
7188*22dc650dSSadaf Ebrahimi       {
7189*22dc650dSSadaf Ebrahimi       if (c > 0x7fffffff)
7190*22dc650dSSadaf Ebrahimi         {
7191*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Character \\x{%x} is greater than 0x7fffffff "
7192*22dc650dSSadaf Ebrahimi           "and so cannot be converted to UTF-8\n", c);
7193*22dc650dSSadaf Ebrahimi         return PR_OK;
7194*22dc650dSSadaf Ebrahimi         }
7195*22dc650dSSadaf Ebrahimi       q8 += ord2utf8(c, q8);
7196*22dc650dSSadaf Ebrahimi       }
7197*22dc650dSSadaf Ebrahimi     else
7198*22dc650dSSadaf Ebrahimi       {
7199*22dc650dSSadaf Ebrahimi       if (c > 0xffu)
7200*22dc650dSSadaf Ebrahimi         {
7201*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Character \\x{%x} is greater than 255 "
7202*22dc650dSSadaf Ebrahimi           "and UTF-8 mode is not enabled.\n", c);
7203*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Truncation will probably give the wrong "
7204*22dc650dSSadaf Ebrahimi           "result.\n");
7205*22dc650dSSadaf Ebrahimi         }
7206*22dc650dSSadaf Ebrahimi       *q8++ = (uint8_t)c;
7207*22dc650dSSadaf Ebrahimi       }
7208*22dc650dSSadaf Ebrahimi     }
7209*22dc650dSSadaf Ebrahimi #endif
7210*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
7211*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE16_MODE)
7212*22dc650dSSadaf Ebrahimi     {
7213*22dc650dSSadaf Ebrahimi     if (utf)
7214*22dc650dSSadaf Ebrahimi       {
7215*22dc650dSSadaf Ebrahimi       if (c > 0x10ffffu)
7216*22dc650dSSadaf Ebrahimi         {
7217*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Failed: character \\x{%x} is greater than "
7218*22dc650dSSadaf Ebrahimi           "0x10ffff and so cannot be converted to UTF-16\n", c);
7219*22dc650dSSadaf Ebrahimi         return PR_OK;
7220*22dc650dSSadaf Ebrahimi         }
7221*22dc650dSSadaf Ebrahimi       else if (c >= 0x10000u)
7222*22dc650dSSadaf Ebrahimi         {
7223*22dc650dSSadaf Ebrahimi         c-= 0x10000u;
7224*22dc650dSSadaf Ebrahimi         *q16++ = 0xD800 | (c >> 10);
7225*22dc650dSSadaf Ebrahimi         *q16++ = 0xDC00 | (c & 0x3ff);
7226*22dc650dSSadaf Ebrahimi         }
7227*22dc650dSSadaf Ebrahimi       else
7228*22dc650dSSadaf Ebrahimi         *q16++ = c;
7229*22dc650dSSadaf Ebrahimi       }
7230*22dc650dSSadaf Ebrahimi     else
7231*22dc650dSSadaf Ebrahimi       {
7232*22dc650dSSadaf Ebrahimi       if (c > 0xffffu)
7233*22dc650dSSadaf Ebrahimi         {
7234*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Character \\x{%x} is greater than 0xffff "
7235*22dc650dSSadaf Ebrahimi           "and UTF-16 mode is not enabled.\n", c);
7236*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Truncation will probably give the wrong "
7237*22dc650dSSadaf Ebrahimi           "result.\n");
7238*22dc650dSSadaf Ebrahimi         }
7239*22dc650dSSadaf Ebrahimi 
7240*22dc650dSSadaf Ebrahimi       *q16++ = (uint16_t)c;
7241*22dc650dSSadaf Ebrahimi       }
7242*22dc650dSSadaf Ebrahimi     }
7243*22dc650dSSadaf Ebrahimi #endif
7244*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
7245*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE32_MODE)
7246*22dc650dSSadaf Ebrahimi     {
7247*22dc650dSSadaf Ebrahimi     *q32++ = c;
7248*22dc650dSSadaf Ebrahimi     }
7249*22dc650dSSadaf Ebrahimi #endif
7250*22dc650dSSadaf Ebrahimi   }
7251*22dc650dSSadaf Ebrahimi 
7252*22dc650dSSadaf Ebrahimi ENDSTRING:
7253*22dc650dSSadaf Ebrahimi SET(*q, 0);
7254*22dc650dSSadaf Ebrahimi len = CASTVAR(uint8_t *, q) - dbuffer;    /* Length in bytes */
7255*22dc650dSSadaf Ebrahimi ulen = len/code_unit_size;                /* Length in code units */
7256*22dc650dSSadaf Ebrahimi arg_ulen = ulen;                          /* Value to use in match arg */
7257*22dc650dSSadaf Ebrahimi 
7258*22dc650dSSadaf Ebrahimi /* If the string was terminated by \= we must now interpret modifiers. */
7259*22dc650dSSadaf Ebrahimi 
7260*22dc650dSSadaf Ebrahimi if (p[-1] != 0 && !decode_modifiers(p, CTX_DAT, NULL, &dat_datctl))
7261*22dc650dSSadaf Ebrahimi   return PR_OK;
7262*22dc650dSSadaf Ebrahimi 
7263*22dc650dSSadaf Ebrahimi /* Setting substitute_{skip,fail} implies a substitute callout. */
7264*22dc650dSSadaf Ebrahimi 
7265*22dc650dSSadaf Ebrahimi if (dat_datctl.substitute_skip != 0 || dat_datctl.substitute_stop != 0)
7266*22dc650dSSadaf Ebrahimi   dat_datctl.control2 |= CTL2_SUBSTITUTE_CALLOUT;
7267*22dc650dSSadaf Ebrahimi 
7268*22dc650dSSadaf Ebrahimi /* Check for mutually exclusive modifiers. At present, these are all in the
7269*22dc650dSSadaf Ebrahimi first control word. */
7270*22dc650dSSadaf Ebrahimi 
7271*22dc650dSSadaf Ebrahimi for (k = 0; k < sizeof(exclusive_dat_controls)/sizeof(uint32_t); k++)
7272*22dc650dSSadaf Ebrahimi   {
7273*22dc650dSSadaf Ebrahimi   c = dat_datctl.control & exclusive_dat_controls[k];
7274*22dc650dSSadaf Ebrahimi   if (c != 0 && c != (c & (~c+1)))
7275*22dc650dSSadaf Ebrahimi     {
7276*22dc650dSSadaf Ebrahimi     show_controls(c, 0, "** Not allowed together:");
7277*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\n");
7278*22dc650dSSadaf Ebrahimi     return PR_OK;
7279*22dc650dSSadaf Ebrahimi     }
7280*22dc650dSSadaf Ebrahimi   }
7281*22dc650dSSadaf Ebrahimi 
7282*22dc650dSSadaf Ebrahimi if (pat_patctl.replacement[0] != 0)
7283*22dc650dSSadaf Ebrahimi   {
7284*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control2 & CTL2_SUBSTITUTE_CALLOUT) != 0 &&
7285*22dc650dSSadaf Ebrahimi       (dat_datctl.control & CTL_NULLCONTEXT) != 0)
7286*22dc650dSSadaf Ebrahimi     {
7287*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Replacement callouts are not supported with null_context.\n");
7288*22dc650dSSadaf Ebrahimi     return PR_OK;
7289*22dc650dSSadaf Ebrahimi     }
7290*22dc650dSSadaf Ebrahimi 
7291*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control & CTL_ALLCAPTURES) != 0)
7292*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Ignored with replacement text: allcaptures\n");
7293*22dc650dSSadaf Ebrahimi   }
7294*22dc650dSSadaf Ebrahimi 
7295*22dc650dSSadaf Ebrahimi /* Warn for modifiers that are ignored for DFA. */
7296*22dc650dSSadaf Ebrahimi 
7297*22dc650dSSadaf Ebrahimi if ((dat_datctl.control & CTL_DFA) != 0)
7298*22dc650dSSadaf Ebrahimi   {
7299*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control & CTL_ALLCAPTURES) != 0)
7300*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Ignored for DFA matching: allcaptures\n");
7301*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control2 & CTL2_HEAPFRAMES_SIZE) != 0)
7302*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Ignored for DFA matching: heapframes_size\n");
7303*22dc650dSSadaf Ebrahimi   }
7304*22dc650dSSadaf Ebrahimi 
7305*22dc650dSSadaf Ebrahimi /* We now have the subject in dbuffer, with len containing the byte length, and
7306*22dc650dSSadaf Ebrahimi ulen containing the code unit length, with a copy in arg_ulen for use in match
7307*22dc650dSSadaf Ebrahimi function arguments (this gets changed to PCRE2_ZERO_TERMINATED when the
7308*22dc650dSSadaf Ebrahimi zero_terminate modifier is present).
7309*22dc650dSSadaf Ebrahimi 
7310*22dc650dSSadaf Ebrahimi Move the data to the end of the buffer so that a read over the end can be
7311*22dc650dSSadaf Ebrahimi caught by valgrind or other means. If we have explicit valgrind support, mark
7312*22dc650dSSadaf Ebrahimi the unused start of the buffer unaddressable. If we are using the POSIX
7313*22dc650dSSadaf Ebrahimi interface, or testing zero-termination, we must include the terminating zero in
7314*22dc650dSSadaf Ebrahimi the usable data. */
7315*22dc650dSSadaf Ebrahimi 
7316*22dc650dSSadaf Ebrahimi c = code_unit_size * (((pat_patctl.control & CTL_POSIX) +
7317*22dc650dSSadaf Ebrahimi                        (dat_datctl.control & CTL_ZERO_TERMINATE) != 0)? 1:0);
7318*22dc650dSSadaf Ebrahimi pp = memmove(dbuffer + dbuffer_size - len - c, dbuffer, len + c);
7319*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_VALGRIND
7320*22dc650dSSadaf Ebrahimi   VALGRIND_MAKE_MEM_NOACCESS(dbuffer, dbuffer_size - (len + c));
7321*22dc650dSSadaf Ebrahimi #endif
7322*22dc650dSSadaf Ebrahimi 
7323*22dc650dSSadaf Ebrahimi /* Now pp points to the subject string, but if null_subject was specified, set
7324*22dc650dSSadaf Ebrahimi it to NULL to test PCRE2's behaviour. */
7325*22dc650dSSadaf Ebrahimi 
7326*22dc650dSSadaf Ebrahimi if ((dat_datctl.control2 & CTL2_NULL_SUBJECT) != 0) pp = NULL;
7327*22dc650dSSadaf Ebrahimi 
7328*22dc650dSSadaf Ebrahimi /* POSIX matching is only possible in 8-bit mode, and it does not support
7329*22dc650dSSadaf Ebrahimi timing or other fancy features. Some were checked at compile time, but we need
7330*22dc650dSSadaf Ebrahimi to check the match-time settings here. */
7331*22dc650dSSadaf Ebrahimi 
7332*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
7333*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_POSIX) != 0)
7334*22dc650dSSadaf Ebrahimi   {
7335*22dc650dSSadaf Ebrahimi   int rc;
7336*22dc650dSSadaf Ebrahimi   int eflags = 0;
7337*22dc650dSSadaf Ebrahimi   regmatch_t *pmatch = NULL;
7338*22dc650dSSadaf Ebrahimi   const char *msg = "** Ignored with POSIX interface:";
7339*22dc650dSSadaf Ebrahimi 
7340*22dc650dSSadaf Ebrahimi   if (dat_datctl.cerror[0] != CFORE_UNSET || dat_datctl.cerror[1] != CFORE_UNSET)
7341*22dc650dSSadaf Ebrahimi     prmsg(&msg, "callout_error");
7342*22dc650dSSadaf Ebrahimi   if (dat_datctl.cfail[0] != CFORE_UNSET || dat_datctl.cfail[1] != CFORE_UNSET)
7343*22dc650dSSadaf Ebrahimi     prmsg(&msg, "callout_fail");
7344*22dc650dSSadaf Ebrahimi   if (dat_datctl.copy_numbers[0] >= 0 || dat_datctl.copy_names[0] != 0)
7345*22dc650dSSadaf Ebrahimi     prmsg(&msg, "copy");
7346*22dc650dSSadaf Ebrahimi   if (dat_datctl.get_numbers[0] >= 0 || dat_datctl.get_names[0] != 0)
7347*22dc650dSSadaf Ebrahimi     prmsg(&msg, "get");
7348*22dc650dSSadaf Ebrahimi   if (dat_datctl.jitstack != 0) prmsg(&msg, "jitstack");
7349*22dc650dSSadaf Ebrahimi   if (dat_datctl.offset != 0) prmsg(&msg, "offset");
7350*22dc650dSSadaf Ebrahimi 
7351*22dc650dSSadaf Ebrahimi   if ((dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS) != 0)
7352*22dc650dSSadaf Ebrahimi     {
7353*22dc650dSSadaf Ebrahimi     fprintf(outfile, "%s", msg);
7354*22dc650dSSadaf Ebrahimi     show_match_options(dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS);
7355*22dc650dSSadaf Ebrahimi     msg = "";
7356*22dc650dSSadaf Ebrahimi     }
7357*22dc650dSSadaf Ebrahimi 
7358*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS) != 0 ||
7359*22dc650dSSadaf Ebrahimi       (dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2) != 0)
7360*22dc650dSSadaf Ebrahimi     {
7361*22dc650dSSadaf Ebrahimi     show_controls(dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS,
7362*22dc650dSSadaf Ebrahimi                   dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2, msg);
7363*22dc650dSSadaf Ebrahimi     msg = "";
7364*22dc650dSSadaf Ebrahimi     }
7365*22dc650dSSadaf Ebrahimi 
7366*22dc650dSSadaf Ebrahimi   if (msg[0] == 0) fprintf(outfile, "\n");
7367*22dc650dSSadaf Ebrahimi 
7368*22dc650dSSadaf Ebrahimi   if (dat_datctl.oveccount > 0)
7369*22dc650dSSadaf Ebrahimi     {
7370*22dc650dSSadaf Ebrahimi     pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * dat_datctl.oveccount);
7371*22dc650dSSadaf Ebrahimi     if (pmatch == NULL)
7372*22dc650dSSadaf Ebrahimi       {
7373*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Failed to get memory for recording matching "
7374*22dc650dSSadaf Ebrahimi         "information (size set = %du)\n", dat_datctl.oveccount);
7375*22dc650dSSadaf Ebrahimi       return PR_OK;
7376*22dc650dSSadaf Ebrahimi       }
7377*22dc650dSSadaf Ebrahimi     }
7378*22dc650dSSadaf Ebrahimi 
7379*22dc650dSSadaf Ebrahimi   if (dat_datctl.startend[0] != CFORE_UNSET)
7380*22dc650dSSadaf Ebrahimi     {
7381*22dc650dSSadaf Ebrahimi     pmatch[0].rm_so = dat_datctl.startend[0];
7382*22dc650dSSadaf Ebrahimi     pmatch[0].rm_eo = (dat_datctl.startend[1] != 0)?
7383*22dc650dSSadaf Ebrahimi       dat_datctl.startend[1] : len;
7384*22dc650dSSadaf Ebrahimi     eflags |= REG_STARTEND;
7385*22dc650dSSadaf Ebrahimi     }
7386*22dc650dSSadaf Ebrahimi 
7387*22dc650dSSadaf Ebrahimi   if ((dat_datctl.options & PCRE2_NOTBOL) != 0) eflags |= REG_NOTBOL;
7388*22dc650dSSadaf Ebrahimi   if ((dat_datctl.options & PCRE2_NOTEOL) != 0) eflags |= REG_NOTEOL;
7389*22dc650dSSadaf Ebrahimi   if ((dat_datctl.options & PCRE2_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY;
7390*22dc650dSSadaf Ebrahimi 
7391*22dc650dSSadaf Ebrahimi   rc = regexec(&preg, (const char *)pp, dat_datctl.oveccount, pmatch, eflags);
7392*22dc650dSSadaf Ebrahimi   if (rc != 0)
7393*22dc650dSSadaf Ebrahimi     {
7394*22dc650dSSadaf Ebrahimi     (void)regerror(rc, &preg, (char *)pbuffer8, pbuffer8_size);
7395*22dc650dSSadaf Ebrahimi     fprintf(outfile, "No match: POSIX code %d: %s\n", rc, pbuffer8);
7396*22dc650dSSadaf Ebrahimi     }
7397*22dc650dSSadaf Ebrahimi   else if ((pat_patctl.control & CTL_POSIX_NOSUB) != 0)
7398*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Matched with REG_NOSUB\n");
7399*22dc650dSSadaf Ebrahimi   else if (dat_datctl.oveccount == 0)
7400*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Matched without capture\n");
7401*22dc650dSSadaf Ebrahimi   else
7402*22dc650dSSadaf Ebrahimi     {
7403*22dc650dSSadaf Ebrahimi     size_t i, j;
7404*22dc650dSSadaf Ebrahimi     size_t last_printed = (size_t)dat_datctl.oveccount;
7405*22dc650dSSadaf Ebrahimi     for (i = 0; i < (size_t)dat_datctl.oveccount; i++)
7406*22dc650dSSadaf Ebrahimi       {
7407*22dc650dSSadaf Ebrahimi       if (pmatch[i].rm_so >= 0)
7408*22dc650dSSadaf Ebrahimi         {
7409*22dc650dSSadaf Ebrahimi         PCRE2_SIZE start = pmatch[i].rm_so;
7410*22dc650dSSadaf Ebrahimi         PCRE2_SIZE end = pmatch[i].rm_eo;
7411*22dc650dSSadaf Ebrahimi         for (j = last_printed + 1; j < i; j++)
7412*22dc650dSSadaf Ebrahimi           fprintf(outfile, "%2d: <unset>\n", (int)j);
7413*22dc650dSSadaf Ebrahimi         last_printed = i;
7414*22dc650dSSadaf Ebrahimi         if (start > end)
7415*22dc650dSSadaf Ebrahimi           {
7416*22dc650dSSadaf Ebrahimi           start = pmatch[i].rm_eo;
7417*22dc650dSSadaf Ebrahimi           end = pmatch[i].rm_so;
7418*22dc650dSSadaf Ebrahimi           fprintf(outfile, "Start of matched string is beyond its end - "
7419*22dc650dSSadaf Ebrahimi             "displaying from end to start.\n");
7420*22dc650dSSadaf Ebrahimi           }
7421*22dc650dSSadaf Ebrahimi         fprintf(outfile, "%2d: ", (int)i);
7422*22dc650dSSadaf Ebrahimi         PCHARSV(pp, start, end - start, utf, outfile);
7423*22dc650dSSadaf Ebrahimi         fprintf(outfile, "\n");
7424*22dc650dSSadaf Ebrahimi 
7425*22dc650dSSadaf Ebrahimi         if ((i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0) ||
7426*22dc650dSSadaf Ebrahimi             (dat_datctl.control & CTL_ALLAFTERTEXT) != 0)
7427*22dc650dSSadaf Ebrahimi           {
7428*22dc650dSSadaf Ebrahimi           fprintf(outfile, "%2d+ ", (int)i);
7429*22dc650dSSadaf Ebrahimi           /* Note: don't use the start/end variables here because we want to
7430*22dc650dSSadaf Ebrahimi           show the text from what is reported as the end. */
7431*22dc650dSSadaf Ebrahimi           PCHARSV(pp, pmatch[i].rm_eo, len - pmatch[i].rm_eo, utf, outfile);
7432*22dc650dSSadaf Ebrahimi           fprintf(outfile, "\n"); }
7433*22dc650dSSadaf Ebrahimi         }
7434*22dc650dSSadaf Ebrahimi       }
7435*22dc650dSSadaf Ebrahimi     }
7436*22dc650dSSadaf Ebrahimi   free(pmatch);
7437*22dc650dSSadaf Ebrahimi   return PR_OK;
7438*22dc650dSSadaf Ebrahimi   }
7439*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_PCRE2_8 */
7440*22dc650dSSadaf Ebrahimi 
7441*22dc650dSSadaf Ebrahimi  /* Handle matching via the native interface. Check for consistency of
7442*22dc650dSSadaf Ebrahimi modifiers. */
7443*22dc650dSSadaf Ebrahimi 
7444*22dc650dSSadaf Ebrahimi if (dat_datctl.startend[0] != CFORE_UNSET)
7445*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** \\=posix_startend ignored for non-POSIX matching\n");
7446*22dc650dSSadaf Ebrahimi 
7447*22dc650dSSadaf Ebrahimi /* ALLUSEDTEXT is not supported with JIT, but JIT is not used with DFA
7448*22dc650dSSadaf Ebrahimi matching, even if the JIT compiler was used. */
7449*22dc650dSSadaf Ebrahimi 
7450*22dc650dSSadaf Ebrahimi if ((dat_datctl.control & (CTL_ALLUSEDTEXT|CTL_DFA)) == CTL_ALLUSEDTEXT &&
7451*22dc650dSSadaf Ebrahimi     FLD(compiled_code, executable_jit) != NULL)
7452*22dc650dSSadaf Ebrahimi   {
7453*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** Showing all consulted text is not supported by JIT: ignored\n");
7454*22dc650dSSadaf Ebrahimi   dat_datctl.control &= ~CTL_ALLUSEDTEXT;
7455*22dc650dSSadaf Ebrahimi   }
7456*22dc650dSSadaf Ebrahimi 
7457*22dc650dSSadaf Ebrahimi /* Handle passing the subject as zero-terminated. */
7458*22dc650dSSadaf Ebrahimi 
7459*22dc650dSSadaf Ebrahimi if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)
7460*22dc650dSSadaf Ebrahimi   arg_ulen = PCRE2_ZERO_TERMINATED;
7461*22dc650dSSadaf Ebrahimi 
7462*22dc650dSSadaf Ebrahimi /* The nullcontext modifier is used to test calling pcre2_[jit_]match() with a
7463*22dc650dSSadaf Ebrahimi NULL context. */
7464*22dc650dSSadaf Ebrahimi 
7465*22dc650dSSadaf Ebrahimi use_dat_context = ((dat_datctl.control & CTL_NULLCONTEXT) != 0)?
7466*22dc650dSSadaf Ebrahimi   NULL : PTR(dat_context);
7467*22dc650dSSadaf Ebrahimi 
7468*22dc650dSSadaf Ebrahimi /* Enable display of malloc/free if wanted. We can do this only if either the
7469*22dc650dSSadaf Ebrahimi pattern or the subject is processed with a context. */
7470*22dc650dSSadaf Ebrahimi 
7471*22dc650dSSadaf Ebrahimi show_memory = (dat_datctl.control & CTL_MEMORY) != 0;
7472*22dc650dSSadaf Ebrahimi 
7473*22dc650dSSadaf Ebrahimi if (show_memory &&
7474*22dc650dSSadaf Ebrahimi     (pat_patctl.control & dat_datctl.control & CTL_NULLCONTEXT) != 0)
7475*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** \\=memory requires either a pattern or a subject "
7476*22dc650dSSadaf Ebrahimi     "context: ignored\n");
7477*22dc650dSSadaf Ebrahimi 
7478*22dc650dSSadaf Ebrahimi /* Create and assign a JIT stack if requested. */
7479*22dc650dSSadaf Ebrahimi 
7480*22dc650dSSadaf Ebrahimi if (dat_datctl.jitstack != 0)
7481*22dc650dSSadaf Ebrahimi   {
7482*22dc650dSSadaf Ebrahimi   if (dat_datctl.jitstack != jit_stack_size)
7483*22dc650dSSadaf Ebrahimi     {
7484*22dc650dSSadaf Ebrahimi     PCRE2_JIT_STACK_FREE(jit_stack);
7485*22dc650dSSadaf Ebrahimi     PCRE2_JIT_STACK_CREATE(jit_stack, 1, dat_datctl.jitstack * 1024, NULL);
7486*22dc650dSSadaf Ebrahimi     jit_stack_size = dat_datctl.jitstack;
7487*22dc650dSSadaf Ebrahimi     }
7488*22dc650dSSadaf Ebrahimi   PCRE2_JIT_STACK_ASSIGN(dat_context, jit_callback, jit_stack);
7489*22dc650dSSadaf Ebrahimi   }
7490*22dc650dSSadaf Ebrahimi 
7491*22dc650dSSadaf Ebrahimi /* Or de-assign */
7492*22dc650dSSadaf Ebrahimi 
7493*22dc650dSSadaf Ebrahimi else if (jit_stack != NULL)
7494*22dc650dSSadaf Ebrahimi   {
7495*22dc650dSSadaf Ebrahimi   PCRE2_JIT_STACK_ASSIGN(dat_context, NULL, NULL);
7496*22dc650dSSadaf Ebrahimi   PCRE2_JIT_STACK_FREE(jit_stack);
7497*22dc650dSSadaf Ebrahimi   jit_stack = NULL;
7498*22dc650dSSadaf Ebrahimi   jit_stack_size = 0;
7499*22dc650dSSadaf Ebrahimi   }
7500*22dc650dSSadaf Ebrahimi 
7501*22dc650dSSadaf Ebrahimi /* When no JIT stack is assigned, we must ensure that there is a JIT callback
7502*22dc650dSSadaf Ebrahimi if we want to verify that JIT was actually used. */
7503*22dc650dSSadaf Ebrahimi 
7504*22dc650dSSadaf Ebrahimi if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_stack == NULL)
7505*22dc650dSSadaf Ebrahimi    {
7506*22dc650dSSadaf Ebrahimi    PCRE2_JIT_STACK_ASSIGN(dat_context, jit_callback, NULL);
7507*22dc650dSSadaf Ebrahimi    }
7508*22dc650dSSadaf Ebrahimi 
7509*22dc650dSSadaf Ebrahimi /* Adjust match_data according to size of offsets required. A size of zero
7510*22dc650dSSadaf Ebrahimi causes a new match data block to be obtained that exactly fits the pattern. */
7511*22dc650dSSadaf Ebrahimi 
7512*22dc650dSSadaf Ebrahimi if (dat_datctl.oveccount == 0)
7513*22dc650dSSadaf Ebrahimi   {
7514*22dc650dSSadaf Ebrahimi   PCRE2_MATCH_DATA_FREE(match_data);
7515*22dc650dSSadaf Ebrahimi   PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(match_data, compiled_code,
7516*22dc650dSSadaf Ebrahimi     general_context);
7517*22dc650dSSadaf Ebrahimi   PCRE2_GET_OVECTOR_COUNT(max_oveccount, match_data);
7518*22dc650dSSadaf Ebrahimi   }
7519*22dc650dSSadaf Ebrahimi else if (dat_datctl.oveccount <= max_oveccount)
7520*22dc650dSSadaf Ebrahimi   {
7521*22dc650dSSadaf Ebrahimi   SETFLD(match_data, oveccount, dat_datctl.oveccount);
7522*22dc650dSSadaf Ebrahimi   }
7523*22dc650dSSadaf Ebrahimi else
7524*22dc650dSSadaf Ebrahimi   {
7525*22dc650dSSadaf Ebrahimi   max_oveccount = dat_datctl.oveccount;
7526*22dc650dSSadaf Ebrahimi   PCRE2_MATCH_DATA_FREE(match_data);
7527*22dc650dSSadaf Ebrahimi   PCRE2_MATCH_DATA_CREATE(match_data, max_oveccount, general_context);
7528*22dc650dSSadaf Ebrahimi   }
7529*22dc650dSSadaf Ebrahimi 
7530*22dc650dSSadaf Ebrahimi if (CASTVAR(void *, match_data) == NULL)
7531*22dc650dSSadaf Ebrahimi   {
7532*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** Failed to get memory for recording matching "
7533*22dc650dSSadaf Ebrahimi     "information (size requested: %d)\n", dat_datctl.oveccount);
7534*22dc650dSSadaf Ebrahimi   max_oveccount = 0;
7535*22dc650dSSadaf Ebrahimi   return PR_OK;
7536*22dc650dSSadaf Ebrahimi   }
7537*22dc650dSSadaf Ebrahimi 
7538*22dc650dSSadaf Ebrahimi ovector = FLD(match_data, ovector);
7539*22dc650dSSadaf Ebrahimi PCRE2_GET_OVECTOR_COUNT(oveccount, match_data);
7540*22dc650dSSadaf Ebrahimi 
7541*22dc650dSSadaf Ebrahimi /* Replacement processing is ignored for DFA matching. */
7542*22dc650dSSadaf Ebrahimi 
7543*22dc650dSSadaf Ebrahimi if (dat_datctl.replacement[0] != 0 && (dat_datctl.control & CTL_DFA) != 0)
7544*22dc650dSSadaf Ebrahimi   {
7545*22dc650dSSadaf Ebrahimi   fprintf(outfile, "** Ignored for DFA matching: replace\n");
7546*22dc650dSSadaf Ebrahimi   dat_datctl.replacement[0] = 0;
7547*22dc650dSSadaf Ebrahimi   }
7548*22dc650dSSadaf Ebrahimi 
7549*22dc650dSSadaf Ebrahimi /* If a replacement string is provided, call pcre2_substitute() instead of or
7550*22dc650dSSadaf Ebrahimi after one of the matching functions. First we have to convert the replacement
7551*22dc650dSSadaf Ebrahimi string to the appropriate width. */
7552*22dc650dSSadaf Ebrahimi 
7553*22dc650dSSadaf Ebrahimi if (dat_datctl.replacement[0] != 0)
7554*22dc650dSSadaf Ebrahimi   {
7555*22dc650dSSadaf Ebrahimi   int rc;
7556*22dc650dSSadaf Ebrahimi   uint8_t *pr;
7557*22dc650dSSadaf Ebrahimi   uint8_t rbuffer[REPLACE_BUFFSIZE];
7558*22dc650dSSadaf Ebrahimi   uint8_t nbuffer[REPLACE_BUFFSIZE];
7559*22dc650dSSadaf Ebrahimi   uint8_t *rbptr;
7560*22dc650dSSadaf Ebrahimi   uint32_t xoptions;
7561*22dc650dSSadaf Ebrahimi   uint32_t emoption;  /* External match option */
7562*22dc650dSSadaf Ebrahimi   PCRE2_SIZE j, rlen, nsize, erroroffset;
7563*22dc650dSSadaf Ebrahimi   BOOL badutf = FALSE;
7564*22dc650dSSadaf Ebrahimi 
7565*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
7566*22dc650dSSadaf Ebrahimi   uint8_t *r8 = NULL;
7567*22dc650dSSadaf Ebrahimi #endif
7568*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
7569*22dc650dSSadaf Ebrahimi   uint16_t *r16 = NULL;
7570*22dc650dSSadaf Ebrahimi #endif
7571*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
7572*22dc650dSSadaf Ebrahimi   uint32_t *r32 = NULL;
7573*22dc650dSSadaf Ebrahimi #endif
7574*22dc650dSSadaf Ebrahimi 
7575*22dc650dSSadaf Ebrahimi   /* Fill the ovector with junk to detect elements that do not get set
7576*22dc650dSSadaf Ebrahimi   when they should be (relevant only when "allvector" is specified). */
7577*22dc650dSSadaf Ebrahimi 
7578*22dc650dSSadaf Ebrahimi   for (j = 0; j < 2*oveccount; j++) ovector[j] = JUNK_OFFSET;
7579*22dc650dSSadaf Ebrahimi 
7580*22dc650dSSadaf Ebrahimi   if (timeitm)
7581*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Timing is not supported with replace: ignored\n");
7582*22dc650dSSadaf Ebrahimi 
7583*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control & CTL_ALTGLOBAL) != 0)
7584*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** Altglobal is not supported with replace: ignored\n");
7585*22dc650dSSadaf Ebrahimi 
7586*22dc650dSSadaf Ebrahimi   /* Check for a test that does substitution after an initial external match.
7587*22dc650dSSadaf Ebrahimi   If this is set, we run the external match, but leave the interpretation of
7588*22dc650dSSadaf Ebrahimi   its output to pcre2_substitute(). */
7589*22dc650dSSadaf Ebrahimi 
7590*22dc650dSSadaf Ebrahimi   emoption = ((dat_datctl.control2 & CTL2_SUBSTITUTE_MATCHED) == 0)? 0 :
7591*22dc650dSSadaf Ebrahimi     PCRE2_SUBSTITUTE_MATCHED;
7592*22dc650dSSadaf Ebrahimi 
7593*22dc650dSSadaf Ebrahimi   if (emoption != 0)
7594*22dc650dSSadaf Ebrahimi     {
7595*22dc650dSSadaf Ebrahimi     if ((pat_patctl.control & CTL_JITFAST) != 0)
7596*22dc650dSSadaf Ebrahimi       {
7597*22dc650dSSadaf Ebrahimi       PCRE2_JIT_MATCH(rc, compiled_code, pp, arg_ulen, dat_datctl.offset,
7598*22dc650dSSadaf Ebrahimi         dat_datctl.options, match_data, use_dat_context);
7599*22dc650dSSadaf Ebrahimi       }
7600*22dc650dSSadaf Ebrahimi     else
7601*22dc650dSSadaf Ebrahimi       {
7602*22dc650dSSadaf Ebrahimi       PCRE2_MATCH(rc, compiled_code, pp, arg_ulen, dat_datctl.offset,
7603*22dc650dSSadaf Ebrahimi         dat_datctl.options, match_data, use_dat_context);
7604*22dc650dSSadaf Ebrahimi       }
7605*22dc650dSSadaf Ebrahimi     }
7606*22dc650dSSadaf Ebrahimi 
7607*22dc650dSSadaf Ebrahimi   xoptions = emoption |
7608*22dc650dSSadaf Ebrahimi              (((dat_datctl.control & CTL_GLOBAL) == 0)? 0 :
7609*22dc650dSSadaf Ebrahimi                 PCRE2_SUBSTITUTE_GLOBAL) |
7610*22dc650dSSadaf Ebrahimi              (((dat_datctl.control2 & CTL2_SUBSTITUTE_EXTENDED) == 0)? 0 :
7611*22dc650dSSadaf Ebrahimi                 PCRE2_SUBSTITUTE_EXTENDED) |
7612*22dc650dSSadaf Ebrahimi              (((dat_datctl.control2 & CTL2_SUBSTITUTE_LITERAL) == 0)? 0 :
7613*22dc650dSSadaf Ebrahimi                 PCRE2_SUBSTITUTE_LITERAL) |
7614*22dc650dSSadaf Ebrahimi              (((dat_datctl.control2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) == 0)? 0 :
7615*22dc650dSSadaf Ebrahimi                 PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) |
7616*22dc650dSSadaf Ebrahimi              (((dat_datctl.control2 & CTL2_SUBSTITUTE_REPLACEMENT_ONLY) == 0)? 0 :
7617*22dc650dSSadaf Ebrahimi                 PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) |
7618*22dc650dSSadaf Ebrahimi              (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNKNOWN_UNSET) == 0)? 0 :
7619*22dc650dSSadaf Ebrahimi                 PCRE2_SUBSTITUTE_UNKNOWN_UNSET) |
7620*22dc650dSSadaf Ebrahimi              (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNSET_EMPTY) == 0)? 0 :
7621*22dc650dSSadaf Ebrahimi                 PCRE2_SUBSTITUTE_UNSET_EMPTY);
7622*22dc650dSSadaf Ebrahimi 
7623*22dc650dSSadaf Ebrahimi   SETCASTPTR(r, rbuffer);  /* Sets r8, r16, or r32, as appropriate. */
7624*22dc650dSSadaf Ebrahimi   pr = dat_datctl.replacement;
7625*22dc650dSSadaf Ebrahimi 
7626*22dc650dSSadaf Ebrahimi   /* If the replacement starts with '[<number>]' we interpret that as length
7627*22dc650dSSadaf Ebrahimi   value for the replacement buffer. */
7628*22dc650dSSadaf Ebrahimi 
7629*22dc650dSSadaf Ebrahimi   nsize = REPLACE_BUFFSIZE/code_unit_size;
7630*22dc650dSSadaf Ebrahimi   if (*pr == '[')
7631*22dc650dSSadaf Ebrahimi     {
7632*22dc650dSSadaf Ebrahimi     PCRE2_SIZE n = 0;
7633*22dc650dSSadaf Ebrahimi     while ((c = *(++pr)) >= CHAR_0 && c <= CHAR_9) n = n * 10 + c - CHAR_0;
7634*22dc650dSSadaf Ebrahimi     if (*pr++ != ']')
7635*22dc650dSSadaf Ebrahimi       {
7636*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Bad buffer size in replacement string\n");
7637*22dc650dSSadaf Ebrahimi       return PR_OK;
7638*22dc650dSSadaf Ebrahimi       }
7639*22dc650dSSadaf Ebrahimi     if (n > nsize)
7640*22dc650dSSadaf Ebrahimi       {
7641*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Replacement buffer setting (%" SIZ_FORM ") is too "
7642*22dc650dSSadaf Ebrahimi         "large (max %" SIZ_FORM ")\n", n, nsize);
7643*22dc650dSSadaf Ebrahimi       return PR_OK;
7644*22dc650dSSadaf Ebrahimi       }
7645*22dc650dSSadaf Ebrahimi     nsize = n;
7646*22dc650dSSadaf Ebrahimi     }
7647*22dc650dSSadaf Ebrahimi 
7648*22dc650dSSadaf Ebrahimi   /* Now copy the replacement string to a buffer of the appropriate width. No
7649*22dc650dSSadaf Ebrahimi   escape processing is done for replacements. In UTF mode, check for an invalid
7650*22dc650dSSadaf Ebrahimi   UTF-8 input string, and if it is invalid, just copy its code units without
7651*22dc650dSSadaf Ebrahimi   UTF interpretation. This provides a means of checking that an invalid string
7652*22dc650dSSadaf Ebrahimi   is detected. Otherwise, UTF-8 can be used to include wide characters in a
7653*22dc650dSSadaf Ebrahimi   replacement. */
7654*22dc650dSSadaf Ebrahimi 
7655*22dc650dSSadaf Ebrahimi   if (utf) badutf = valid_utf(pr, strlen((const char *)pr), &erroroffset);
7656*22dc650dSSadaf Ebrahimi 
7657*22dc650dSSadaf Ebrahimi   /* Not UTF or invalid UTF-8: just copy the code units. */
7658*22dc650dSSadaf Ebrahimi 
7659*22dc650dSSadaf Ebrahimi   if (!utf || badutf)
7660*22dc650dSSadaf Ebrahimi     {
7661*22dc650dSSadaf Ebrahimi     while ((c = *pr++) != 0)
7662*22dc650dSSadaf Ebrahimi       {
7663*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
7664*22dc650dSSadaf Ebrahimi       if (test_mode == PCRE8_MODE) *r8++ = c;
7665*22dc650dSSadaf Ebrahimi #endif
7666*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
7667*22dc650dSSadaf Ebrahimi       if (test_mode == PCRE16_MODE) *r16++ = c;
7668*22dc650dSSadaf Ebrahimi #endif
7669*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
7670*22dc650dSSadaf Ebrahimi       if (test_mode == PCRE32_MODE) *r32++ = c;
7671*22dc650dSSadaf Ebrahimi #endif
7672*22dc650dSSadaf Ebrahimi       }
7673*22dc650dSSadaf Ebrahimi     }
7674*22dc650dSSadaf Ebrahimi 
7675*22dc650dSSadaf Ebrahimi   /* Valid UTF-8 replacement string */
7676*22dc650dSSadaf Ebrahimi 
7677*22dc650dSSadaf Ebrahimi   else while ((c = *pr++) != 0)
7678*22dc650dSSadaf Ebrahimi     {
7679*22dc650dSSadaf Ebrahimi     if (HASUTF8EXTRALEN(c)) { GETUTF8INC(c, pr); }
7680*22dc650dSSadaf Ebrahimi 
7681*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
7682*22dc650dSSadaf Ebrahimi     if (test_mode == PCRE8_MODE) r8 += ord2utf8(c, r8);
7683*22dc650dSSadaf Ebrahimi #endif
7684*22dc650dSSadaf Ebrahimi 
7685*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
7686*22dc650dSSadaf Ebrahimi     if (test_mode == PCRE16_MODE)
7687*22dc650dSSadaf Ebrahimi       {
7688*22dc650dSSadaf Ebrahimi       if (c >= 0x10000u)
7689*22dc650dSSadaf Ebrahimi         {
7690*22dc650dSSadaf Ebrahimi         c-= 0x10000u;
7691*22dc650dSSadaf Ebrahimi         *r16++ = 0xD800 | (c >> 10);
7692*22dc650dSSadaf Ebrahimi         *r16++ = 0xDC00 | (c & 0x3ff);
7693*22dc650dSSadaf Ebrahimi         }
7694*22dc650dSSadaf Ebrahimi       else *r16++ = c;
7695*22dc650dSSadaf Ebrahimi       }
7696*22dc650dSSadaf Ebrahimi #endif
7697*22dc650dSSadaf Ebrahimi 
7698*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
7699*22dc650dSSadaf Ebrahimi     if (test_mode == PCRE32_MODE) *r32++ = c;
7700*22dc650dSSadaf Ebrahimi #endif
7701*22dc650dSSadaf Ebrahimi     }
7702*22dc650dSSadaf Ebrahimi 
7703*22dc650dSSadaf Ebrahimi   SET(*r, 0);
7704*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)
7705*22dc650dSSadaf Ebrahimi     rlen = PCRE2_ZERO_TERMINATED;
7706*22dc650dSSadaf Ebrahimi   else
7707*22dc650dSSadaf Ebrahimi     rlen = (CASTVAR(uint8_t *, r) - rbuffer)/code_unit_size;
7708*22dc650dSSadaf Ebrahimi 
7709*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control2 & CTL2_SUBSTITUTE_CALLOUT) != 0)
7710*22dc650dSSadaf Ebrahimi     {
7711*22dc650dSSadaf Ebrahimi     PCRE2_SET_SUBSTITUTE_CALLOUT(dat_context, substitute_callout_function, NULL);
7712*22dc650dSSadaf Ebrahimi     }
7713*22dc650dSSadaf Ebrahimi   else
7714*22dc650dSSadaf Ebrahimi     {
7715*22dc650dSSadaf Ebrahimi     PCRE2_SET_SUBSTITUTE_CALLOUT(dat_context, NULL, NULL);  /* No callout */
7716*22dc650dSSadaf Ebrahimi     }
7717*22dc650dSSadaf Ebrahimi 
7718*22dc650dSSadaf Ebrahimi   /* There is a special option to set the replacement to NULL in order to test
7719*22dc650dSSadaf Ebrahimi   that case. */
7720*22dc650dSSadaf Ebrahimi 
7721*22dc650dSSadaf Ebrahimi   rbptr = ((dat_datctl.control2 & CTL2_NULL_REPLACEMENT) == 0)? rbuffer : NULL;
7722*22dc650dSSadaf Ebrahimi 
7723*22dc650dSSadaf Ebrahimi   PCRE2_SUBSTITUTE(rc, compiled_code, pp, arg_ulen, dat_datctl.offset,
7724*22dc650dSSadaf Ebrahimi     dat_datctl.options|xoptions, match_data, use_dat_context,
7725*22dc650dSSadaf Ebrahimi     rbptr, rlen, nbuffer, &nsize);
7726*22dc650dSSadaf Ebrahimi 
7727*22dc650dSSadaf Ebrahimi   if (rc < 0)
7728*22dc650dSSadaf Ebrahimi     {
7729*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Failed: error %d", rc);
7730*22dc650dSSadaf Ebrahimi     if (rc != PCRE2_ERROR_NOMEMORY && nsize != PCRE2_UNSET)
7731*22dc650dSSadaf Ebrahimi       fprintf(outfile, " at offset %ld in replacement", (long int)nsize);
7732*22dc650dSSadaf Ebrahimi     fprintf(outfile, ": ");
7733*22dc650dSSadaf Ebrahimi     if (!print_error_message(rc, "", "")) return PR_ABEND;
7734*22dc650dSSadaf Ebrahimi     if (rc == PCRE2_ERROR_NOMEMORY &&
7735*22dc650dSSadaf Ebrahimi         (xoptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)
7736*22dc650dSSadaf Ebrahimi       fprintf(outfile, ": %ld code units are needed", (long int)nsize);
7737*22dc650dSSadaf Ebrahimi     }
7738*22dc650dSSadaf Ebrahimi   else
7739*22dc650dSSadaf Ebrahimi     {
7740*22dc650dSSadaf Ebrahimi     fprintf(outfile, "%2d: ", rc);
7741*22dc650dSSadaf Ebrahimi     PCHARSV(nbuffer, 0, nsize, utf, outfile);
7742*22dc650dSSadaf Ebrahimi     }
7743*22dc650dSSadaf Ebrahimi 
7744*22dc650dSSadaf Ebrahimi   fprintf(outfile, "\n");
7745*22dc650dSSadaf Ebrahimi   show_memory = FALSE;
7746*22dc650dSSadaf Ebrahimi 
7747*22dc650dSSadaf Ebrahimi   /* Show final ovector contents and resulting heapframe size if requested. */
7748*22dc650dSSadaf Ebrahimi 
7749*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0)
7750*22dc650dSSadaf Ebrahimi     show_ovector(ovector, oveccount);
7751*22dc650dSSadaf Ebrahimi 
7752*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control2 & CTL2_HEAPFRAMES_SIZE) != 0 &&
7753*22dc650dSSadaf Ebrahimi       (dat_datctl.control & CTL_DFA) == 0)
7754*22dc650dSSadaf Ebrahimi     show_heapframes_size();
7755*22dc650dSSadaf Ebrahimi 
7756*22dc650dSSadaf Ebrahimi   return PR_OK;
7757*22dc650dSSadaf Ebrahimi   }   /* End of substitution handling */
7758*22dc650dSSadaf Ebrahimi 
7759*22dc650dSSadaf Ebrahimi /* When a replacement string is not provided, run a loop for global matching
7760*22dc650dSSadaf Ebrahimi with one of the basic matching functions. For altglobal (or first time round
7761*22dc650dSSadaf Ebrahimi the loop), set an "unset" value for the previous match info. */
7762*22dc650dSSadaf Ebrahimi 
7763*22dc650dSSadaf Ebrahimi ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET;
7764*22dc650dSSadaf Ebrahimi 
7765*22dc650dSSadaf Ebrahimi for (gmatched = 0;; gmatched++)
7766*22dc650dSSadaf Ebrahimi   {
7767*22dc650dSSadaf Ebrahimi   PCRE2_SIZE j;
7768*22dc650dSSadaf Ebrahimi   int capcount;
7769*22dc650dSSadaf Ebrahimi 
7770*22dc650dSSadaf Ebrahimi   /* Fill the ovector with junk to detect elements that do not get set
7771*22dc650dSSadaf Ebrahimi   when they should be. */
7772*22dc650dSSadaf Ebrahimi 
7773*22dc650dSSadaf Ebrahimi   for (j = 0; j < 2*oveccount; j++) ovector[j] = JUNK_OFFSET;
7774*22dc650dSSadaf Ebrahimi 
7775*22dc650dSSadaf Ebrahimi   /* When matching is via pcre2_match(), we will detect the use of JIT via the
7776*22dc650dSSadaf Ebrahimi   stack callback function. */
7777*22dc650dSSadaf Ebrahimi 
7778*22dc650dSSadaf Ebrahimi   jit_was_used = (pat_patctl.control & CTL_JITFAST) != 0;
7779*22dc650dSSadaf Ebrahimi 
7780*22dc650dSSadaf Ebrahimi   /* Do timing if required. */
7781*22dc650dSSadaf Ebrahimi 
7782*22dc650dSSadaf Ebrahimi   if (timeitm > 0)
7783*22dc650dSSadaf Ebrahimi     {
7784*22dc650dSSadaf Ebrahimi     int i;
7785*22dc650dSSadaf Ebrahimi     clock_t start_time, time_taken;
7786*22dc650dSSadaf Ebrahimi 
7787*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control & CTL_DFA) != 0)
7788*22dc650dSSadaf Ebrahimi       {
7789*22dc650dSSadaf Ebrahimi       if ((dat_datctl.options & PCRE2_DFA_RESTART) != 0)
7790*22dc650dSSadaf Ebrahimi         {
7791*22dc650dSSadaf Ebrahimi         fprintf(outfile, "Timing DFA restarts is not supported\n");
7792*22dc650dSSadaf Ebrahimi         return PR_OK;
7793*22dc650dSSadaf Ebrahimi         }
7794*22dc650dSSadaf Ebrahimi       if (dfa_workspace == NULL)
7795*22dc650dSSadaf Ebrahimi         dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));
7796*22dc650dSSadaf Ebrahimi       start_time = clock();
7797*22dc650dSSadaf Ebrahimi       for (i = 0; i < timeitm; i++)
7798*22dc650dSSadaf Ebrahimi         {
7799*22dc650dSSadaf Ebrahimi         PCRE2_DFA_MATCH(capcount, compiled_code, pp, arg_ulen,
7800*22dc650dSSadaf Ebrahimi           dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
7801*22dc650dSSadaf Ebrahimi           use_dat_context, dfa_workspace, DFA_WS_DIMENSION);
7802*22dc650dSSadaf Ebrahimi         }
7803*22dc650dSSadaf Ebrahimi       }
7804*22dc650dSSadaf Ebrahimi 
7805*22dc650dSSadaf Ebrahimi     else if ((pat_patctl.control & CTL_JITFAST) != 0)
7806*22dc650dSSadaf Ebrahimi       {
7807*22dc650dSSadaf Ebrahimi       start_time = clock();
7808*22dc650dSSadaf Ebrahimi       for (i = 0; i < timeitm; i++)
7809*22dc650dSSadaf Ebrahimi         {
7810*22dc650dSSadaf Ebrahimi         PCRE2_JIT_MATCH(capcount, compiled_code, pp, arg_ulen,
7811*22dc650dSSadaf Ebrahimi           dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
7812*22dc650dSSadaf Ebrahimi           use_dat_context);
7813*22dc650dSSadaf Ebrahimi         }
7814*22dc650dSSadaf Ebrahimi       }
7815*22dc650dSSadaf Ebrahimi 
7816*22dc650dSSadaf Ebrahimi     else
7817*22dc650dSSadaf Ebrahimi       {
7818*22dc650dSSadaf Ebrahimi       start_time = clock();
7819*22dc650dSSadaf Ebrahimi       for (i = 0; i < timeitm; i++)
7820*22dc650dSSadaf Ebrahimi         {
7821*22dc650dSSadaf Ebrahimi         PCRE2_MATCH(capcount, compiled_code, pp, arg_ulen,
7822*22dc650dSSadaf Ebrahimi           dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
7823*22dc650dSSadaf Ebrahimi           use_dat_context);
7824*22dc650dSSadaf Ebrahimi         }
7825*22dc650dSSadaf Ebrahimi       }
7826*22dc650dSSadaf Ebrahimi     total_match_time += (time_taken = clock() - start_time);
7827*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Match time %7.4f microseconds\n",
7828*22dc650dSSadaf Ebrahimi       ((1000000 / CLOCKS_PER_SEC) * (double)time_taken) / timeitm);
7829*22dc650dSSadaf Ebrahimi     }
7830*22dc650dSSadaf Ebrahimi 
7831*22dc650dSSadaf Ebrahimi   /* Find the heap, match and depth limits if requested. The depth and heap
7832*22dc650dSSadaf Ebrahimi   limits are not relevant for JIT. The return from check_match_limit() is the
7833*22dc650dSSadaf Ebrahimi   return from the final call to pcre2_match() or pcre2_dfa_match(). */
7834*22dc650dSSadaf Ebrahimi 
7835*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control & (CTL_FINDLIMITS|CTL_FINDLIMITS_NOHEAP)) != 0)
7836*22dc650dSSadaf Ebrahimi     {
7837*22dc650dSSadaf Ebrahimi     capcount = 0;  /* This stops compiler warnings */
7838*22dc650dSSadaf Ebrahimi 
7839*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control & CTL_FINDLIMITS_NOHEAP) == 0 &&
7840*22dc650dSSadaf Ebrahimi         (FLD(compiled_code, executable_jit) == NULL ||
7841*22dc650dSSadaf Ebrahimi           (dat_datctl.options & PCRE2_NO_JIT) != 0))
7842*22dc650dSSadaf Ebrahimi       {
7843*22dc650dSSadaf Ebrahimi       (void)check_match_limit(pp, arg_ulen, PCRE2_ERROR_HEAPLIMIT, "heap");
7844*22dc650dSSadaf Ebrahimi       }
7845*22dc650dSSadaf Ebrahimi 
7846*22dc650dSSadaf Ebrahimi     capcount = check_match_limit(pp, arg_ulen, PCRE2_ERROR_MATCHLIMIT,
7847*22dc650dSSadaf Ebrahimi       "match");
7848*22dc650dSSadaf Ebrahimi 
7849*22dc650dSSadaf Ebrahimi     if (FLD(compiled_code, executable_jit) == NULL ||
7850*22dc650dSSadaf Ebrahimi         (dat_datctl.options & PCRE2_NO_JIT) != 0 ||
7851*22dc650dSSadaf Ebrahimi         (dat_datctl.control & CTL_DFA) != 0)
7852*22dc650dSSadaf Ebrahimi       {
7853*22dc650dSSadaf Ebrahimi       capcount = check_match_limit(pp, arg_ulen, PCRE2_ERROR_DEPTHLIMIT,
7854*22dc650dSSadaf Ebrahimi         "depth");
7855*22dc650dSSadaf Ebrahimi       }
7856*22dc650dSSadaf Ebrahimi 
7857*22dc650dSSadaf Ebrahimi     if (capcount == 0)
7858*22dc650dSSadaf Ebrahimi       {
7859*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Matched, but offsets vector is too small to show all matches\n");
7860*22dc650dSSadaf Ebrahimi       capcount = dat_datctl.oveccount;
7861*22dc650dSSadaf Ebrahimi       }
7862*22dc650dSSadaf Ebrahimi     }
7863*22dc650dSSadaf Ebrahimi 
7864*22dc650dSSadaf Ebrahimi   /* Otherwise just run a single match, setting up a callout if required (the
7865*22dc650dSSadaf Ebrahimi   default). There is a copy of the pattern in pbuffer8 for use by callouts. */
7866*22dc650dSSadaf Ebrahimi 
7867*22dc650dSSadaf Ebrahimi   else
7868*22dc650dSSadaf Ebrahimi     {
7869*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control & CTL_CALLOUT_NONE) == 0)
7870*22dc650dSSadaf Ebrahimi       {
7871*22dc650dSSadaf Ebrahimi       PCRE2_SET_CALLOUT(dat_context, callout_function,
7872*22dc650dSSadaf Ebrahimi         (void *)(&dat_datctl.callout_data));
7873*22dc650dSSadaf Ebrahimi       first_callout = TRUE;
7874*22dc650dSSadaf Ebrahimi       last_callout_mark = NULL;
7875*22dc650dSSadaf Ebrahimi       callout_count = 0;
7876*22dc650dSSadaf Ebrahimi       }
7877*22dc650dSSadaf Ebrahimi     else
7878*22dc650dSSadaf Ebrahimi       {
7879*22dc650dSSadaf Ebrahimi       PCRE2_SET_CALLOUT(dat_context, NULL, NULL);  /* No callout */
7880*22dc650dSSadaf Ebrahimi       }
7881*22dc650dSSadaf Ebrahimi 
7882*22dc650dSSadaf Ebrahimi     /* Run a single DFA or NFA match. */
7883*22dc650dSSadaf Ebrahimi 
7884*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control & CTL_DFA) != 0)
7885*22dc650dSSadaf Ebrahimi       {
7886*22dc650dSSadaf Ebrahimi       if (dfa_workspace == NULL)
7887*22dc650dSSadaf Ebrahimi         dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));
7888*22dc650dSSadaf Ebrahimi       if (dfa_matched++ == 0)
7889*22dc650dSSadaf Ebrahimi         dfa_workspace[0] = -1;  /* To catch bad restart */
7890*22dc650dSSadaf Ebrahimi       PCRE2_DFA_MATCH(capcount, compiled_code, pp, arg_ulen,
7891*22dc650dSSadaf Ebrahimi         dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
7892*22dc650dSSadaf Ebrahimi         use_dat_context, dfa_workspace, DFA_WS_DIMENSION);
7893*22dc650dSSadaf Ebrahimi       if (capcount == 0)
7894*22dc650dSSadaf Ebrahimi         {
7895*22dc650dSSadaf Ebrahimi         fprintf(outfile, "Matched, but offsets vector is too small to show all matches\n");
7896*22dc650dSSadaf Ebrahimi         capcount = dat_datctl.oveccount;
7897*22dc650dSSadaf Ebrahimi         }
7898*22dc650dSSadaf Ebrahimi       }
7899*22dc650dSSadaf Ebrahimi     else
7900*22dc650dSSadaf Ebrahimi       {
7901*22dc650dSSadaf Ebrahimi       if ((pat_patctl.control & CTL_JITFAST) != 0)
7902*22dc650dSSadaf Ebrahimi         PCRE2_JIT_MATCH(capcount, compiled_code, pp, arg_ulen, dat_datctl.offset,
7903*22dc650dSSadaf Ebrahimi           dat_datctl.options | g_notempty, match_data, use_dat_context);
7904*22dc650dSSadaf Ebrahimi       else
7905*22dc650dSSadaf Ebrahimi         PCRE2_MATCH(capcount, compiled_code, pp, arg_ulen, dat_datctl.offset,
7906*22dc650dSSadaf Ebrahimi           dat_datctl.options | g_notempty, match_data, use_dat_context);
7907*22dc650dSSadaf Ebrahimi       if (capcount == 0)
7908*22dc650dSSadaf Ebrahimi         {
7909*22dc650dSSadaf Ebrahimi         fprintf(outfile, "Matched, but too many substrings\n");
7910*22dc650dSSadaf Ebrahimi         capcount = dat_datctl.oveccount;
7911*22dc650dSSadaf Ebrahimi         }
7912*22dc650dSSadaf Ebrahimi       }
7913*22dc650dSSadaf Ebrahimi     }
7914*22dc650dSSadaf Ebrahimi 
7915*22dc650dSSadaf Ebrahimi   /* The result of the match is now in capcount. First handle a successful
7916*22dc650dSSadaf Ebrahimi   match. If pp was forced to be NULL (to test NULL handling) it will have been
7917*22dc650dSSadaf Ebrahimi   treated as an empty string if the length was zero. So re-create that for
7918*22dc650dSSadaf Ebrahimi   outputting. */
7919*22dc650dSSadaf Ebrahimi 
7920*22dc650dSSadaf Ebrahimi   if (capcount >= 0)
7921*22dc650dSSadaf Ebrahimi     {
7922*22dc650dSSadaf Ebrahimi     int i;
7923*22dc650dSSadaf Ebrahimi 
7924*22dc650dSSadaf Ebrahimi     if (pp == NULL) pp = (uint8_t *)"";
7925*22dc650dSSadaf Ebrahimi 
7926*22dc650dSSadaf Ebrahimi     if (capcount > (int)oveccount)   /* Check for lunatic return value */
7927*22dc650dSSadaf Ebrahimi       {
7928*22dc650dSSadaf Ebrahimi       fprintf(outfile,
7929*22dc650dSSadaf Ebrahimi         "** PCRE2 error: returned count %d is too big for ovector count %d\n",
7930*22dc650dSSadaf Ebrahimi         capcount, oveccount);
7931*22dc650dSSadaf Ebrahimi       capcount = oveccount;
7932*22dc650dSSadaf Ebrahimi       if ((dat_datctl.control & CTL_ANYGLOB) != 0)
7933*22dc650dSSadaf Ebrahimi         {
7934*22dc650dSSadaf Ebrahimi         fprintf(outfile, "** Global loop abandoned\n");
7935*22dc650dSSadaf Ebrahimi         dat_datctl.control &= ~CTL_ANYGLOB;        /* Break g/G loop */
7936*22dc650dSSadaf Ebrahimi         }
7937*22dc650dSSadaf Ebrahimi       }
7938*22dc650dSSadaf Ebrahimi 
7939*22dc650dSSadaf Ebrahimi     /* If PCRE2_COPY_MATCHED_SUBJECT was set, check that things are as they
7940*22dc650dSSadaf Ebrahimi     should be, but not for fast JIT, where it isn't supported. */
7941*22dc650dSSadaf Ebrahimi 
7942*22dc650dSSadaf Ebrahimi     if ((dat_datctl.options & PCRE2_COPY_MATCHED_SUBJECT) != 0 &&
7943*22dc650dSSadaf Ebrahimi         (pat_patctl.control & CTL_JITFAST) == 0)
7944*22dc650dSSadaf Ebrahimi       {
7945*22dc650dSSadaf Ebrahimi       if ((FLD(match_data, flags) & PCRE2_MD_COPIED_SUBJECT) == 0)
7946*22dc650dSSadaf Ebrahimi         fprintf(outfile,
7947*22dc650dSSadaf Ebrahimi           "** PCRE2 error: flag not set after copy_matched_subject\n");
7948*22dc650dSSadaf Ebrahimi 
7949*22dc650dSSadaf Ebrahimi       if (CASTFLD(void *, match_data, subject) == pp)
7950*22dc650dSSadaf Ebrahimi         fprintf(outfile,
7951*22dc650dSSadaf Ebrahimi           "** PCRE2 error: copy_matched_subject has not copied\n");
7952*22dc650dSSadaf Ebrahimi 
7953*22dc650dSSadaf Ebrahimi       if (memcmp(CASTFLD(void *, match_data, subject), pp, ulen) != 0)
7954*22dc650dSSadaf Ebrahimi         fprintf(outfile,
7955*22dc650dSSadaf Ebrahimi           "** PCRE2 error: copy_matched_subject mismatch\n");
7956*22dc650dSSadaf Ebrahimi       }
7957*22dc650dSSadaf Ebrahimi 
7958*22dc650dSSadaf Ebrahimi     /* If this is not the first time round a global loop, check that the
7959*22dc650dSSadaf Ebrahimi     returned string has changed. If it has not, check for an empty string match
7960*22dc650dSSadaf Ebrahimi     at different starting offset from the previous match. This is a failed test
7961*22dc650dSSadaf Ebrahimi     retry for null-matching patterns that don't match at their starting offset,
7962*22dc650dSSadaf Ebrahimi     for example /(?<=\G.)/. A repeated match at the same point is not such a
7963*22dc650dSSadaf Ebrahimi     pattern, and must be discarded, and we then proceed to seek a non-null
7964*22dc650dSSadaf Ebrahimi     match at the current point. For any other repeated match, there is a bug
7965*22dc650dSSadaf Ebrahimi     somewhere and we must break the loop because it will go on for ever. We
7966*22dc650dSSadaf Ebrahimi     know that there are always at least two elements in the ovector. */
7967*22dc650dSSadaf Ebrahimi 
7968*22dc650dSSadaf Ebrahimi     if (gmatched > 0 && ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1])
7969*22dc650dSSadaf Ebrahimi       {
7970*22dc650dSSadaf Ebrahimi       if (ovector[0] == ovector[1] && ovecsave[2] != dat_datctl.offset)
7971*22dc650dSSadaf Ebrahimi         {
7972*22dc650dSSadaf Ebrahimi         g_notempty = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
7973*22dc650dSSadaf Ebrahimi         ovecsave[2] = dat_datctl.offset;
7974*22dc650dSSadaf Ebrahimi         continue;    /* Back to the top of the loop */
7975*22dc650dSSadaf Ebrahimi         }
7976*22dc650dSSadaf Ebrahimi       fprintf(outfile,
7977*22dc650dSSadaf Ebrahimi         "** PCRE2 error: global repeat returned the same string as previous\n");
7978*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Global loop abandoned\n");
7979*22dc650dSSadaf Ebrahimi       dat_datctl.control &= ~CTL_ANYGLOB;        /* Break g/G loop */
7980*22dc650dSSadaf Ebrahimi       }
7981*22dc650dSSadaf Ebrahimi 
7982*22dc650dSSadaf Ebrahimi     /* "allcaptures" requests showing of all captures in the pattern, to check
7983*22dc650dSSadaf Ebrahimi     unset ones at the end. It may be set on the pattern or the data. Implement
7984*22dc650dSSadaf Ebrahimi     by setting capcount to the maximum. This is not relevant for DFA matching,
7985*22dc650dSSadaf Ebrahimi     so ignore it (warning given above). */
7986*22dc650dSSadaf Ebrahimi 
7987*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control & (CTL_ALLCAPTURES|CTL_DFA)) == CTL_ALLCAPTURES)
7988*22dc650dSSadaf Ebrahimi       {
7989*22dc650dSSadaf Ebrahimi       capcount = maxcapcount + 1;   /* Allow for full match */
7990*22dc650dSSadaf Ebrahimi       if (capcount > (int)oveccount) capcount = oveccount;
7991*22dc650dSSadaf Ebrahimi       }
7992*22dc650dSSadaf Ebrahimi 
7993*22dc650dSSadaf Ebrahimi     /* "allvector" request showing the entire ovector. */
7994*22dc650dSSadaf Ebrahimi 
7995*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0) capcount = oveccount;
7996*22dc650dSSadaf Ebrahimi 
7997*22dc650dSSadaf Ebrahimi     /* Output the captured substrings. Note that, for the matched string,
7998*22dc650dSSadaf Ebrahimi     the use of \K in an assertion can make the start later than the end. */
7999*22dc650dSSadaf Ebrahimi 
8000*22dc650dSSadaf Ebrahimi     for (i = 0; i < 2*capcount; i += 2)
8001*22dc650dSSadaf Ebrahimi       {
8002*22dc650dSSadaf Ebrahimi       PCRE2_SIZE lleft, lmiddle, lright;
8003*22dc650dSSadaf Ebrahimi       PCRE2_SIZE start = ovector[i];
8004*22dc650dSSadaf Ebrahimi       PCRE2_SIZE end = ovector[i+1];
8005*22dc650dSSadaf Ebrahimi 
8006*22dc650dSSadaf Ebrahimi       if (start > end)
8007*22dc650dSSadaf Ebrahimi         {
8008*22dc650dSSadaf Ebrahimi         start = ovector[i+1];
8009*22dc650dSSadaf Ebrahimi         end = ovector[i];
8010*22dc650dSSadaf Ebrahimi         fprintf(outfile, "Start of matched string is beyond its end - "
8011*22dc650dSSadaf Ebrahimi           "displaying from end to start.\n");
8012*22dc650dSSadaf Ebrahimi         }
8013*22dc650dSSadaf Ebrahimi 
8014*22dc650dSSadaf Ebrahimi       fprintf(outfile, "%2d: ", i/2);
8015*22dc650dSSadaf Ebrahimi 
8016*22dc650dSSadaf Ebrahimi       /* Check for an unset group */
8017*22dc650dSSadaf Ebrahimi 
8018*22dc650dSSadaf Ebrahimi       if (start == PCRE2_UNSET && end == PCRE2_UNSET)
8019*22dc650dSSadaf Ebrahimi         {
8020*22dc650dSSadaf Ebrahimi         fprintf(outfile, "<unset>\n");
8021*22dc650dSSadaf Ebrahimi         continue;
8022*22dc650dSSadaf Ebrahimi         }
8023*22dc650dSSadaf Ebrahimi 
8024*22dc650dSSadaf Ebrahimi       /* Check for silly offsets, in particular, values that have not been
8025*22dc650dSSadaf Ebrahimi       set when they should have been. However, if we are past the end of the
8026*22dc650dSSadaf Ebrahimi       captures for this pattern ("allvector" causes this), or if we are DFA
8027*22dc650dSSadaf Ebrahimi       matching, it isn't an error if the entry is unchanged. */
8028*22dc650dSSadaf Ebrahimi 
8029*22dc650dSSadaf Ebrahimi       if (start > ulen || end > ulen)
8030*22dc650dSSadaf Ebrahimi         {
8031*22dc650dSSadaf Ebrahimi         if (((dat_datctl.control & CTL_DFA) != 0 ||
8032*22dc650dSSadaf Ebrahimi               i >= (int)(2*maxcapcount + 2)) &&
8033*22dc650dSSadaf Ebrahimi             start == JUNK_OFFSET && end == JUNK_OFFSET)
8034*22dc650dSSadaf Ebrahimi           fprintf(outfile, "<unchanged>\n");
8035*22dc650dSSadaf Ebrahimi         else
8036*22dc650dSSadaf Ebrahimi           fprintf(outfile, "ERROR: bad value(s) for offset(s): 0x%lx 0x%lx\n",
8037*22dc650dSSadaf Ebrahimi             (unsigned long int)start, (unsigned long int)end);
8038*22dc650dSSadaf Ebrahimi         continue;
8039*22dc650dSSadaf Ebrahimi         }
8040*22dc650dSSadaf Ebrahimi 
8041*22dc650dSSadaf Ebrahimi       /* When JIT is not being used, ALLUSEDTEXT may be set. (It if is set with
8042*22dc650dSSadaf Ebrahimi       JIT, it is disabled above, with a comment.) When the match is done by the
8043*22dc650dSSadaf Ebrahimi       interpreter, leftchar and rightchar are available, and if ALLUSEDTEXT is
8044*22dc650dSSadaf Ebrahimi       set, and if the leftmost consulted character is before the start of the
8045*22dc650dSSadaf Ebrahimi       match or the rightmost consulted character is past the end of the match,
8046*22dc650dSSadaf Ebrahimi       we want to show all consulted characters for the main matched string, and
8047*22dc650dSSadaf Ebrahimi       indicate which were lookarounds. */
8048*22dc650dSSadaf Ebrahimi 
8049*22dc650dSSadaf Ebrahimi       if (i == 0)
8050*22dc650dSSadaf Ebrahimi         {
8051*22dc650dSSadaf Ebrahimi         BOOL showallused;
8052*22dc650dSSadaf Ebrahimi         PCRE2_SIZE leftchar, rightchar;
8053*22dc650dSSadaf Ebrahimi 
8054*22dc650dSSadaf Ebrahimi         if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0)
8055*22dc650dSSadaf Ebrahimi           {
8056*22dc650dSSadaf Ebrahimi           leftchar = FLD(match_data, leftchar);
8057*22dc650dSSadaf Ebrahimi           rightchar = FLD(match_data, rightchar);
8058*22dc650dSSadaf Ebrahimi           showallused = i == 0 && (leftchar < start || rightchar > end);
8059*22dc650dSSadaf Ebrahimi           }
8060*22dc650dSSadaf Ebrahimi         else showallused = FALSE;
8061*22dc650dSSadaf Ebrahimi 
8062*22dc650dSSadaf Ebrahimi         if (showallused)
8063*22dc650dSSadaf Ebrahimi           {
8064*22dc650dSSadaf Ebrahimi           PCHARS(lleft, pp, leftchar, start - leftchar, utf, outfile);
8065*22dc650dSSadaf Ebrahimi           PCHARS(lmiddle, pp, start, end - start, utf, outfile);
8066*22dc650dSSadaf Ebrahimi           PCHARS(lright, pp, end, rightchar - end, utf, outfile);
8067*22dc650dSSadaf Ebrahimi           if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)
8068*22dc650dSSadaf Ebrahimi             fprintf(outfile, " (JIT)");
8069*22dc650dSSadaf Ebrahimi           fprintf(outfile, "\n    ");
8070*22dc650dSSadaf Ebrahimi           for (j = 0; j < lleft; j++) fprintf(outfile, "<");
8071*22dc650dSSadaf Ebrahimi           for (j = 0; j < lmiddle; j++) fprintf(outfile, " ");
8072*22dc650dSSadaf Ebrahimi           for (j = 0; j < lright; j++) fprintf(outfile, ">");
8073*22dc650dSSadaf Ebrahimi           }
8074*22dc650dSSadaf Ebrahimi 
8075*22dc650dSSadaf Ebrahimi         /* When a pattern contains \K, the start of match position may be
8076*22dc650dSSadaf Ebrahimi         different to the start of the matched string. When this is the case,
8077*22dc650dSSadaf Ebrahimi         show it when requested. */
8078*22dc650dSSadaf Ebrahimi 
8079*22dc650dSSadaf Ebrahimi         else if ((dat_datctl.control & CTL_STARTCHAR) != 0)
8080*22dc650dSSadaf Ebrahimi           {
8081*22dc650dSSadaf Ebrahimi           PCRE2_SIZE startchar;
8082*22dc650dSSadaf Ebrahimi           PCRE2_GET_STARTCHAR(startchar, match_data);
8083*22dc650dSSadaf Ebrahimi           PCHARS(lleft, pp, startchar, start - startchar, utf, outfile);
8084*22dc650dSSadaf Ebrahimi           PCHARSV(pp, start, end - start, utf, outfile);
8085*22dc650dSSadaf Ebrahimi           if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)
8086*22dc650dSSadaf Ebrahimi             fprintf(outfile, " (JIT)");
8087*22dc650dSSadaf Ebrahimi           if (startchar != start)
8088*22dc650dSSadaf Ebrahimi             {
8089*22dc650dSSadaf Ebrahimi             fprintf(outfile, "\n    ");
8090*22dc650dSSadaf Ebrahimi             for (j = 0; j < lleft; j++) fprintf(outfile, "^");
8091*22dc650dSSadaf Ebrahimi             }
8092*22dc650dSSadaf Ebrahimi           }
8093*22dc650dSSadaf Ebrahimi 
8094*22dc650dSSadaf Ebrahimi         /* Otherwise, just show the matched string. */
8095*22dc650dSSadaf Ebrahimi 
8096*22dc650dSSadaf Ebrahimi         else
8097*22dc650dSSadaf Ebrahimi           {
8098*22dc650dSSadaf Ebrahimi           PCHARSV(pp, start, end - start, utf, outfile);
8099*22dc650dSSadaf Ebrahimi           if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)
8100*22dc650dSSadaf Ebrahimi             fprintf(outfile, " (JIT)");
8101*22dc650dSSadaf Ebrahimi           }
8102*22dc650dSSadaf Ebrahimi         }
8103*22dc650dSSadaf Ebrahimi 
8104*22dc650dSSadaf Ebrahimi       /* Not the main matched string. Just show it unadorned. */
8105*22dc650dSSadaf Ebrahimi 
8106*22dc650dSSadaf Ebrahimi       else
8107*22dc650dSSadaf Ebrahimi         {
8108*22dc650dSSadaf Ebrahimi         PCHARSV(pp, start, end - start, utf, outfile);
8109*22dc650dSSadaf Ebrahimi         }
8110*22dc650dSSadaf Ebrahimi 
8111*22dc650dSSadaf Ebrahimi       fprintf(outfile, "\n");
8112*22dc650dSSadaf Ebrahimi 
8113*22dc650dSSadaf Ebrahimi       /* Note: don't use the start/end variables here because we want to
8114*22dc650dSSadaf Ebrahimi       show the text from what is reported as the end. */
8115*22dc650dSSadaf Ebrahimi 
8116*22dc650dSSadaf Ebrahimi       if ((dat_datctl.control & CTL_ALLAFTERTEXT) != 0 ||
8117*22dc650dSSadaf Ebrahimi           (i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0))
8118*22dc650dSSadaf Ebrahimi         {
8119*22dc650dSSadaf Ebrahimi         fprintf(outfile, "%2d+ ", i/2);
8120*22dc650dSSadaf Ebrahimi         PCHARSV(pp, ovector[i+1], ulen - ovector[i+1], utf, outfile);
8121*22dc650dSSadaf Ebrahimi         fprintf(outfile, "\n");
8122*22dc650dSSadaf Ebrahimi         }
8123*22dc650dSSadaf Ebrahimi       }
8124*22dc650dSSadaf Ebrahimi 
8125*22dc650dSSadaf Ebrahimi     /* Output (*MARK) data if requested */
8126*22dc650dSSadaf Ebrahimi 
8127*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control & CTL_MARK) != 0 &&
8128*22dc650dSSadaf Ebrahimi          TESTFLD(match_data, mark, !=, NULL))
8129*22dc650dSSadaf Ebrahimi       {
8130*22dc650dSSadaf Ebrahimi       fprintf(outfile, "MK: ");
8131*22dc650dSSadaf Ebrahimi       PCHARSV(CASTFLD(void *, match_data, mark), -1, -1, utf, outfile);
8132*22dc650dSSadaf Ebrahimi       fprintf(outfile, "\n");
8133*22dc650dSSadaf Ebrahimi       }
8134*22dc650dSSadaf Ebrahimi 
8135*22dc650dSSadaf Ebrahimi     /* Process copy/get strings */
8136*22dc650dSSadaf Ebrahimi 
8137*22dc650dSSadaf Ebrahimi     if (!copy_and_get(utf, capcount)) return PR_ABEND;
8138*22dc650dSSadaf Ebrahimi 
8139*22dc650dSSadaf Ebrahimi     }    /* End of handling a successful match */
8140*22dc650dSSadaf Ebrahimi 
8141*22dc650dSSadaf Ebrahimi   /* There was a partial match. The value of ovector[0] is the bumpalong point,
8142*22dc650dSSadaf Ebrahimi   that is, startchar, not any \K point that might have been passed. When JIT is
8143*22dc650dSSadaf Ebrahimi   not in use, "allusedtext" may be set, in which case we indicate the leftmost
8144*22dc650dSSadaf Ebrahimi   consulted character. */
8145*22dc650dSSadaf Ebrahimi 
8146*22dc650dSSadaf Ebrahimi   else if (capcount == PCRE2_ERROR_PARTIAL)
8147*22dc650dSSadaf Ebrahimi     {
8148*22dc650dSSadaf Ebrahimi     PCRE2_SIZE leftchar;
8149*22dc650dSSadaf Ebrahimi     int backlength;
8150*22dc650dSSadaf Ebrahimi     int rubriclength = 0;
8151*22dc650dSSadaf Ebrahimi 
8152*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0)
8153*22dc650dSSadaf Ebrahimi       {
8154*22dc650dSSadaf Ebrahimi       leftchar = FLD(match_data, leftchar);
8155*22dc650dSSadaf Ebrahimi       }
8156*22dc650dSSadaf Ebrahimi     else leftchar = ovector[0];
8157*22dc650dSSadaf Ebrahimi 
8158*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Partial match");
8159*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control & CTL_MARK) != 0 &&
8160*22dc650dSSadaf Ebrahimi          TESTFLD(match_data, mark, !=, NULL))
8161*22dc650dSSadaf Ebrahimi       {
8162*22dc650dSSadaf Ebrahimi       fprintf(outfile, ", mark=");
8163*22dc650dSSadaf Ebrahimi       PCHARS(rubriclength, CASTFLD(void *, match_data, mark), -1, -1, utf,
8164*22dc650dSSadaf Ebrahimi         outfile);
8165*22dc650dSSadaf Ebrahimi       rubriclength += 7;
8166*22dc650dSSadaf Ebrahimi       }
8167*22dc650dSSadaf Ebrahimi     fprintf(outfile, ": ");
8168*22dc650dSSadaf Ebrahimi     rubriclength += 15;
8169*22dc650dSSadaf Ebrahimi 
8170*22dc650dSSadaf Ebrahimi     PCHARS(backlength, pp, leftchar, ovector[0] - leftchar, utf, outfile);
8171*22dc650dSSadaf Ebrahimi     PCHARSV(pp, ovector[0], ovector[1] - ovector[0], utf, outfile);
8172*22dc650dSSadaf Ebrahimi 
8173*22dc650dSSadaf Ebrahimi     if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)
8174*22dc650dSSadaf Ebrahimi       fprintf(outfile, " (JIT)");
8175*22dc650dSSadaf Ebrahimi     fprintf(outfile, "\n");
8176*22dc650dSSadaf Ebrahimi 
8177*22dc650dSSadaf Ebrahimi     if (backlength != 0)
8178*22dc650dSSadaf Ebrahimi       {
8179*22dc650dSSadaf Ebrahimi       int i;
8180*22dc650dSSadaf Ebrahimi       for (i = 0; i < rubriclength; i++) fprintf(outfile, " ");
8181*22dc650dSSadaf Ebrahimi       for (i = 0; i < backlength; i++) fprintf(outfile, "<");
8182*22dc650dSSadaf Ebrahimi       fprintf(outfile, "\n");
8183*22dc650dSSadaf Ebrahimi       }
8184*22dc650dSSadaf Ebrahimi 
8185*22dc650dSSadaf Ebrahimi     if (ulen != ovector[1])
8186*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** ovector[1] is not equal to the subject length: "
8187*22dc650dSSadaf Ebrahimi         "%ld != %ld\n", (unsigned long int)ovector[1], (unsigned long int)ulen);
8188*22dc650dSSadaf Ebrahimi 
8189*22dc650dSSadaf Ebrahimi     /* Process copy/get strings */
8190*22dc650dSSadaf Ebrahimi 
8191*22dc650dSSadaf Ebrahimi     if (!copy_and_get(utf, 1)) return PR_ABEND;
8192*22dc650dSSadaf Ebrahimi 
8193*22dc650dSSadaf Ebrahimi     /* "allvector" outputs the entire vector */
8194*22dc650dSSadaf Ebrahimi 
8195*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0)
8196*22dc650dSSadaf Ebrahimi       show_ovector(ovector, oveccount);
8197*22dc650dSSadaf Ebrahimi 
8198*22dc650dSSadaf Ebrahimi     break;  /* Out of the /g loop */
8199*22dc650dSSadaf Ebrahimi     }       /* End of handling partial match */
8200*22dc650dSSadaf Ebrahimi 
8201*22dc650dSSadaf Ebrahimi   /* Failed to match. If this is a /g or /G loop, we might previously have
8202*22dc650dSSadaf Ebrahimi   set g_notempty (to PCRE2_NOTEMPTY_ATSTART|PCRE2_ANCHORED) after a null match.
8203*22dc650dSSadaf Ebrahimi   If that is the case, this is not necessarily the end. We want to advance the
8204*22dc650dSSadaf Ebrahimi   start offset, and continue. We won't be at the end of the string - that was
8205*22dc650dSSadaf Ebrahimi   checked before setting g_notempty. We achieve the effect by pretending that a
8206*22dc650dSSadaf Ebrahimi   single character was matched.
8207*22dc650dSSadaf Ebrahimi 
8208*22dc650dSSadaf Ebrahimi   Complication arises in the case when the newline convention is "any", "crlf",
8209*22dc650dSSadaf Ebrahimi   or "anycrlf". If the previous match was at the end of a line terminated by
8210*22dc650dSSadaf Ebrahimi   CRLF, an advance of one character just passes the CR, whereas we should
8211*22dc650dSSadaf Ebrahimi   prefer the longer newline sequence, as does the code in pcre2_match().
8212*22dc650dSSadaf Ebrahimi 
8213*22dc650dSSadaf Ebrahimi   Otherwise, in the case of UTF-8 or UTF-16 matching, the advance must be one
8214*22dc650dSSadaf Ebrahimi   character, not one byte. */
8215*22dc650dSSadaf Ebrahimi 
8216*22dc650dSSadaf Ebrahimi   else if (g_notempty != 0)   /* There was a previous null match */
8217*22dc650dSSadaf Ebrahimi     {
8218*22dc650dSSadaf Ebrahimi     uint16_t nl = FLD(compiled_code, newline_convention);
8219*22dc650dSSadaf Ebrahimi     PCRE2_SIZE start_offset = dat_datctl.offset;    /* Where the match was */
8220*22dc650dSSadaf Ebrahimi     PCRE2_SIZE end_offset = start_offset + 1;
8221*22dc650dSSadaf Ebrahimi 
8222*22dc650dSSadaf Ebrahimi     if ((nl == PCRE2_NEWLINE_CRLF || nl == PCRE2_NEWLINE_ANY ||
8223*22dc650dSSadaf Ebrahimi          nl == PCRE2_NEWLINE_ANYCRLF) &&
8224*22dc650dSSadaf Ebrahimi         start_offset < ulen - 1 &&
8225*22dc650dSSadaf Ebrahimi         CODE_UNIT(pp, start_offset) == '\r' &&
8226*22dc650dSSadaf Ebrahimi         CODE_UNIT(pp, end_offset) == '\n')
8227*22dc650dSSadaf Ebrahimi       end_offset++;
8228*22dc650dSSadaf Ebrahimi 
8229*22dc650dSSadaf Ebrahimi     else if (utf && test_mode != PCRE32_MODE)
8230*22dc650dSSadaf Ebrahimi       {
8231*22dc650dSSadaf Ebrahimi       if (test_mode == PCRE8_MODE)
8232*22dc650dSSadaf Ebrahimi         {
8233*22dc650dSSadaf Ebrahimi         for (; end_offset < ulen; end_offset++)
8234*22dc650dSSadaf Ebrahimi           if ((((PCRE2_SPTR8)pp)[end_offset] & 0xc0) != 0x80) break;
8235*22dc650dSSadaf Ebrahimi         }
8236*22dc650dSSadaf Ebrahimi       else  /* 16-bit mode */
8237*22dc650dSSadaf Ebrahimi         {
8238*22dc650dSSadaf Ebrahimi         for (; end_offset < ulen; end_offset++)
8239*22dc650dSSadaf Ebrahimi           if ((((PCRE2_SPTR16)pp)[end_offset] & 0xfc00) != 0xdc00) break;
8240*22dc650dSSadaf Ebrahimi         }
8241*22dc650dSSadaf Ebrahimi       }
8242*22dc650dSSadaf Ebrahimi 
8243*22dc650dSSadaf Ebrahimi     SETFLDVEC(match_data, ovector, 0, start_offset);
8244*22dc650dSSadaf Ebrahimi     SETFLDVEC(match_data, ovector, 1, end_offset);
8245*22dc650dSSadaf Ebrahimi     }  /* End of handling null match in a global loop */
8246*22dc650dSSadaf Ebrahimi 
8247*22dc650dSSadaf Ebrahimi   /* A "normal" match failure. There will be a negative error number in
8248*22dc650dSSadaf Ebrahimi   capcount. */
8249*22dc650dSSadaf Ebrahimi 
8250*22dc650dSSadaf Ebrahimi   else
8251*22dc650dSSadaf Ebrahimi     {
8252*22dc650dSSadaf Ebrahimi     switch(capcount)
8253*22dc650dSSadaf Ebrahimi       {
8254*22dc650dSSadaf Ebrahimi       case PCRE2_ERROR_NOMATCH:
8255*22dc650dSSadaf Ebrahimi       if (gmatched == 0)
8256*22dc650dSSadaf Ebrahimi         {
8257*22dc650dSSadaf Ebrahimi         fprintf(outfile, "No match");
8258*22dc650dSSadaf Ebrahimi         if ((dat_datctl.control & CTL_MARK) != 0 &&
8259*22dc650dSSadaf Ebrahimi              TESTFLD(match_data, mark, !=, NULL))
8260*22dc650dSSadaf Ebrahimi           {
8261*22dc650dSSadaf Ebrahimi           fprintf(outfile, ", mark = ");
8262*22dc650dSSadaf Ebrahimi           PCHARSV(CASTFLD(void *, match_data, mark), -1, -1, utf, outfile);
8263*22dc650dSSadaf Ebrahimi           }
8264*22dc650dSSadaf Ebrahimi         if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)
8265*22dc650dSSadaf Ebrahimi           fprintf(outfile, " (JIT)");
8266*22dc650dSSadaf Ebrahimi         fprintf(outfile, "\n");
8267*22dc650dSSadaf Ebrahimi 
8268*22dc650dSSadaf Ebrahimi         /* "allvector" outputs the entire vector */
8269*22dc650dSSadaf Ebrahimi 
8270*22dc650dSSadaf Ebrahimi         if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0)
8271*22dc650dSSadaf Ebrahimi           show_ovector(ovector, oveccount);
8272*22dc650dSSadaf Ebrahimi         }
8273*22dc650dSSadaf Ebrahimi       break;
8274*22dc650dSSadaf Ebrahimi 
8275*22dc650dSSadaf Ebrahimi       case PCRE2_ERROR_BADUTFOFFSET:
8276*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Error %d (bad UTF-%d offset)\n", capcount, test_mode);
8277*22dc650dSSadaf Ebrahimi       break;
8278*22dc650dSSadaf Ebrahimi 
8279*22dc650dSSadaf Ebrahimi       default:
8280*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Failed: error %d: ", capcount);
8281*22dc650dSSadaf Ebrahimi       if (!print_error_message(capcount, "", "")) return PR_ABEND;
8282*22dc650dSSadaf Ebrahimi       if (capcount <= PCRE2_ERROR_UTF8_ERR1 &&
8283*22dc650dSSadaf Ebrahimi           capcount >= PCRE2_ERROR_UTF32_ERR2)
8284*22dc650dSSadaf Ebrahimi         {
8285*22dc650dSSadaf Ebrahimi         PCRE2_SIZE startchar;
8286*22dc650dSSadaf Ebrahimi         PCRE2_GET_STARTCHAR(startchar, match_data);
8287*22dc650dSSadaf Ebrahimi         fprintf(outfile, " at offset %" SIZ_FORM, startchar);
8288*22dc650dSSadaf Ebrahimi         }
8289*22dc650dSSadaf Ebrahimi       fprintf(outfile, "\n");
8290*22dc650dSSadaf Ebrahimi       break;
8291*22dc650dSSadaf Ebrahimi       }
8292*22dc650dSSadaf Ebrahimi 
8293*22dc650dSSadaf Ebrahimi     break;  /* Out of the /g loop */
8294*22dc650dSSadaf Ebrahimi     }       /* End of failed match handling */
8295*22dc650dSSadaf Ebrahimi 
8296*22dc650dSSadaf Ebrahimi   /* Control reaches here in two circumstances: (a) after a match, and (b)
8297*22dc650dSSadaf Ebrahimi   after a non-match that immediately followed a match on an empty string when
8298*22dc650dSSadaf Ebrahimi   doing a global search. Such a match is done with PCRE2_NOTEMPTY_ATSTART and
8299*22dc650dSSadaf Ebrahimi   PCRE2_ANCHORED set in g_notempty. The code above turns it into a fake match
8300*22dc650dSSadaf Ebrahimi   of one character. So effectively we get here only after a match. If we
8301*22dc650dSSadaf Ebrahimi   are not doing a global search, we are done. */
8302*22dc650dSSadaf Ebrahimi 
8303*22dc650dSSadaf Ebrahimi   if ((dat_datctl.control & CTL_ANYGLOB) == 0) break; else
8304*22dc650dSSadaf Ebrahimi     {
8305*22dc650dSSadaf Ebrahimi     PCRE2_SIZE match_offset = FLD(match_data, ovector)[0];
8306*22dc650dSSadaf Ebrahimi     PCRE2_SIZE end_offset = FLD(match_data, ovector)[1];
8307*22dc650dSSadaf Ebrahimi 
8308*22dc650dSSadaf Ebrahimi     /* We must now set up for the next iteration of a global search. If we have
8309*22dc650dSSadaf Ebrahimi     matched an empty string, first check to see if we are at the end of the
8310*22dc650dSSadaf Ebrahimi     subject. If so, the loop is over. Otherwise, mimic what Perl's /g option
8311*22dc650dSSadaf Ebrahimi     does. Set PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED and try the match again
8312*22dc650dSSadaf Ebrahimi     at the same point. If this fails it will be picked up above, where a fake
8313*22dc650dSSadaf Ebrahimi     match is set up so that at this point we advance to the next character.
8314*22dc650dSSadaf Ebrahimi 
8315*22dc650dSSadaf Ebrahimi     However, in order to cope with patterns that never match at their starting
8316*22dc650dSSadaf Ebrahimi     offset (e.g. /(?<=\G.)/) we don't do this when the match offset is greater
8317*22dc650dSSadaf Ebrahimi     than the starting offset. This means there will be a retry with the
8318*22dc650dSSadaf Ebrahimi     starting offset at the match offset. If this returns the same match again,
8319*22dc650dSSadaf Ebrahimi     it is picked up above and ignored, and the special action is then taken. */
8320*22dc650dSSadaf Ebrahimi 
8321*22dc650dSSadaf Ebrahimi     if (match_offset == end_offset)
8322*22dc650dSSadaf Ebrahimi       {
8323*22dc650dSSadaf Ebrahimi       if (end_offset == ulen) break;           /* End of subject */
8324*22dc650dSSadaf Ebrahimi       if (match_offset <= dat_datctl.offset)
8325*22dc650dSSadaf Ebrahimi         g_notempty = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
8326*22dc650dSSadaf Ebrahimi       }
8327*22dc650dSSadaf Ebrahimi 
8328*22dc650dSSadaf Ebrahimi     /* However, even after matching a non-empty string, there is still one
8329*22dc650dSSadaf Ebrahimi     tricky case. If a pattern contains \K within a lookbehind assertion at the
8330*22dc650dSSadaf Ebrahimi     start, the end of the matched string can be at the offset where the match
8331*22dc650dSSadaf Ebrahimi     started. In the case of a normal /g iteration without special action, this
8332*22dc650dSSadaf Ebrahimi     leads to a loop that keeps on returning the same substring. The loop would
8333*22dc650dSSadaf Ebrahimi     be caught above, but we really want to move on to the next match. */
8334*22dc650dSSadaf Ebrahimi 
8335*22dc650dSSadaf Ebrahimi     else
8336*22dc650dSSadaf Ebrahimi       {
8337*22dc650dSSadaf Ebrahimi       g_notempty = 0;   /* Set for a "normal" repeat */
8338*22dc650dSSadaf Ebrahimi       if ((dat_datctl.control & CTL_GLOBAL) != 0)
8339*22dc650dSSadaf Ebrahimi         {
8340*22dc650dSSadaf Ebrahimi         PCRE2_SIZE startchar;
8341*22dc650dSSadaf Ebrahimi         PCRE2_GET_STARTCHAR(startchar, match_data);
8342*22dc650dSSadaf Ebrahimi         if (end_offset <= startchar)
8343*22dc650dSSadaf Ebrahimi           {
8344*22dc650dSSadaf Ebrahimi           if (startchar >= ulen) break;       /* End of subject */
8345*22dc650dSSadaf Ebrahimi           end_offset = startchar + 1;
8346*22dc650dSSadaf Ebrahimi           if (utf && test_mode != PCRE32_MODE)
8347*22dc650dSSadaf Ebrahimi             {
8348*22dc650dSSadaf Ebrahimi             if (test_mode == PCRE8_MODE)
8349*22dc650dSSadaf Ebrahimi               {
8350*22dc650dSSadaf Ebrahimi               for (; end_offset < ulen; end_offset++)
8351*22dc650dSSadaf Ebrahimi                 if ((((PCRE2_SPTR8)pp)[end_offset] & 0xc0) != 0x80) break;
8352*22dc650dSSadaf Ebrahimi               }
8353*22dc650dSSadaf Ebrahimi             else  /* 16-bit mode */
8354*22dc650dSSadaf Ebrahimi               {
8355*22dc650dSSadaf Ebrahimi               for (; end_offset < ulen; end_offset++)
8356*22dc650dSSadaf Ebrahimi                 if ((((PCRE2_SPTR16)pp)[end_offset] & 0xfc00) != 0xdc00) break;
8357*22dc650dSSadaf Ebrahimi               }
8358*22dc650dSSadaf Ebrahimi             }
8359*22dc650dSSadaf Ebrahimi           }
8360*22dc650dSSadaf Ebrahimi         }
8361*22dc650dSSadaf Ebrahimi       }
8362*22dc650dSSadaf Ebrahimi 
8363*22dc650dSSadaf Ebrahimi     /* For a normal global (/g) iteration, save the current ovector[0,1] and
8364*22dc650dSSadaf Ebrahimi     the starting offset so that we can check that they do change each time.
8365*22dc650dSSadaf Ebrahimi     Otherwise a matching bug that returns the same string causes an infinite
8366*22dc650dSSadaf Ebrahimi     loop. It has happened! Then update the start offset, leaving other
8367*22dc650dSSadaf Ebrahimi     parameters alone. */
8368*22dc650dSSadaf Ebrahimi 
8369*22dc650dSSadaf Ebrahimi     if ((dat_datctl.control & CTL_GLOBAL) != 0)
8370*22dc650dSSadaf Ebrahimi       {
8371*22dc650dSSadaf Ebrahimi       ovecsave[0] = ovector[0];
8372*22dc650dSSadaf Ebrahimi       ovecsave[1] = ovector[1];
8373*22dc650dSSadaf Ebrahimi       ovecsave[2] = dat_datctl.offset;
8374*22dc650dSSadaf Ebrahimi       dat_datctl.offset = end_offset;
8375*22dc650dSSadaf Ebrahimi       }
8376*22dc650dSSadaf Ebrahimi 
8377*22dc650dSSadaf Ebrahimi     /* For altglobal, just update the pointer and length. */
8378*22dc650dSSadaf Ebrahimi 
8379*22dc650dSSadaf Ebrahimi     else
8380*22dc650dSSadaf Ebrahimi       {
8381*22dc650dSSadaf Ebrahimi       pp += end_offset * code_unit_size;
8382*22dc650dSSadaf Ebrahimi       len -= end_offset * code_unit_size;
8383*22dc650dSSadaf Ebrahimi       ulen -= end_offset;
8384*22dc650dSSadaf Ebrahimi       if (arg_ulen != PCRE2_ZERO_TERMINATED) arg_ulen -= end_offset;
8385*22dc650dSSadaf Ebrahimi       }
8386*22dc650dSSadaf Ebrahimi     }
8387*22dc650dSSadaf Ebrahimi   }  /* End of global loop */
8388*22dc650dSSadaf Ebrahimi 
8389*22dc650dSSadaf Ebrahimi /* All matching is done; show the resulting heapframe size if requested. */
8390*22dc650dSSadaf Ebrahimi 
8391*22dc650dSSadaf Ebrahimi if ((dat_datctl.control2 & CTL2_HEAPFRAMES_SIZE) != 0 &&
8392*22dc650dSSadaf Ebrahimi     (dat_datctl.control & CTL_DFA) == 0)
8393*22dc650dSSadaf Ebrahimi   show_heapframes_size();
8394*22dc650dSSadaf Ebrahimi 
8395*22dc650dSSadaf Ebrahimi show_memory = FALSE;
8396*22dc650dSSadaf Ebrahimi return PR_OK;
8397*22dc650dSSadaf Ebrahimi }
8398*22dc650dSSadaf Ebrahimi 
8399*22dc650dSSadaf Ebrahimi 
8400*22dc650dSSadaf Ebrahimi 
8401*22dc650dSSadaf Ebrahimi 
8402*22dc650dSSadaf Ebrahimi /*************************************************
8403*22dc650dSSadaf Ebrahimi *               Print PCRE2 version              *
8404*22dc650dSSadaf Ebrahimi *************************************************/
8405*22dc650dSSadaf Ebrahimi 
8406*22dc650dSSadaf Ebrahimi static void
print_version(FILE * f,BOOL include_mode)8407*22dc650dSSadaf Ebrahimi print_version(FILE *f, BOOL include_mode)
8408*22dc650dSSadaf Ebrahimi {
8409*22dc650dSSadaf Ebrahimi char buf[16];
8410*22dc650dSSadaf Ebrahimi VERSION_TYPE *vp;
8411*22dc650dSSadaf Ebrahimi fprintf(f, "PCRE2 version ");
8412*22dc650dSSadaf Ebrahimi for (vp = version; *vp != 0; vp++) fprintf(f, "%c", *vp);
8413*22dc650dSSadaf Ebrahimi if (include_mode)
8414*22dc650dSSadaf Ebrahimi   {
8415*22dc650dSSadaf Ebrahimi   sprintf(buf, "%d-bit", test_mode);
8416*22dc650dSSadaf Ebrahimi   fprintf(f, " (%s)", buf);
8417*22dc650dSSadaf Ebrahimi   }
8418*22dc650dSSadaf Ebrahimi fprintf(f, "\n");
8419*22dc650dSSadaf Ebrahimi }
8420*22dc650dSSadaf Ebrahimi 
8421*22dc650dSSadaf Ebrahimi 
8422*22dc650dSSadaf Ebrahimi 
8423*22dc650dSSadaf Ebrahimi /*************************************************
8424*22dc650dSSadaf Ebrahimi *               Print Unicode version            *
8425*22dc650dSSadaf Ebrahimi *************************************************/
8426*22dc650dSSadaf Ebrahimi 
8427*22dc650dSSadaf Ebrahimi static void
print_unicode_version(FILE * f)8428*22dc650dSSadaf Ebrahimi print_unicode_version(FILE *f)
8429*22dc650dSSadaf Ebrahimi {
8430*22dc650dSSadaf Ebrahimi VERSION_TYPE *vp;
8431*22dc650dSSadaf Ebrahimi fprintf(f, "Unicode version ");
8432*22dc650dSSadaf Ebrahimi for (vp = uversion; *vp != 0; vp++) fprintf(f, "%c", *vp);
8433*22dc650dSSadaf Ebrahimi }
8434*22dc650dSSadaf Ebrahimi 
8435*22dc650dSSadaf Ebrahimi 
8436*22dc650dSSadaf Ebrahimi 
8437*22dc650dSSadaf Ebrahimi /*************************************************
8438*22dc650dSSadaf Ebrahimi *               Print JIT target                 *
8439*22dc650dSSadaf Ebrahimi *************************************************/
8440*22dc650dSSadaf Ebrahimi 
8441*22dc650dSSadaf Ebrahimi static void
print_jit_target(FILE * f)8442*22dc650dSSadaf Ebrahimi print_jit_target(FILE *f)
8443*22dc650dSSadaf Ebrahimi {
8444*22dc650dSSadaf Ebrahimi VERSION_TYPE *vp;
8445*22dc650dSSadaf Ebrahimi for (vp = jittarget; *vp != 0; vp++) fprintf(f, "%c", *vp);
8446*22dc650dSSadaf Ebrahimi }
8447*22dc650dSSadaf Ebrahimi 
8448*22dc650dSSadaf Ebrahimi 
8449*22dc650dSSadaf Ebrahimi 
8450*22dc650dSSadaf Ebrahimi /*************************************************
8451*22dc650dSSadaf Ebrahimi *       Print newline configuration              *
8452*22dc650dSSadaf Ebrahimi *************************************************/
8453*22dc650dSSadaf Ebrahimi 
8454*22dc650dSSadaf Ebrahimi /* Output is always to stdout.
8455*22dc650dSSadaf Ebrahimi 
8456*22dc650dSSadaf Ebrahimi Arguments:
8457*22dc650dSSadaf Ebrahimi   rc         the return code from PCRE2_CONFIG_NEWLINE
8458*22dc650dSSadaf Ebrahimi   isc        TRUE if called from "-C newline"
8459*22dc650dSSadaf Ebrahimi Returns:     nothing
8460*22dc650dSSadaf Ebrahimi */
8461*22dc650dSSadaf Ebrahimi 
8462*22dc650dSSadaf Ebrahimi static void
print_newline_config(uint32_t optval,BOOL isc)8463*22dc650dSSadaf Ebrahimi print_newline_config(uint32_t optval, BOOL isc)
8464*22dc650dSSadaf Ebrahimi {
8465*22dc650dSSadaf Ebrahimi if (!isc) printf("  Default newline sequence is ");
8466*22dc650dSSadaf Ebrahimi if (optval < sizeof(newlines)/sizeof(char *))
8467*22dc650dSSadaf Ebrahimi   printf("%s\n", newlines[optval]);
8468*22dc650dSSadaf Ebrahimi else
8469*22dc650dSSadaf Ebrahimi   printf("a non-standard value: %d\n", optval);
8470*22dc650dSSadaf Ebrahimi }
8471*22dc650dSSadaf Ebrahimi 
8472*22dc650dSSadaf Ebrahimi 
8473*22dc650dSSadaf Ebrahimi 
8474*22dc650dSSadaf Ebrahimi /*************************************************
8475*22dc650dSSadaf Ebrahimi *             Usage function                     *
8476*22dc650dSSadaf Ebrahimi *************************************************/
8477*22dc650dSSadaf Ebrahimi 
8478*22dc650dSSadaf Ebrahimi static void
usage(void)8479*22dc650dSSadaf Ebrahimi usage(void)
8480*22dc650dSSadaf Ebrahimi {
8481*22dc650dSSadaf Ebrahimi printf("Usage:     pcre2test [options] [<input file> [<output file>]]\n\n");
8482*22dc650dSSadaf Ebrahimi printf("Input and output default to stdin and stdout.\n");
8483*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
8484*22dc650dSSadaf Ebrahimi printf("If input is a terminal, readline() is used to read from it.\n");
8485*22dc650dSSadaf Ebrahimi #else
8486*22dc650dSSadaf Ebrahimi printf("This version of pcre2test is not linked with readline().\n");
8487*22dc650dSSadaf Ebrahimi #endif
8488*22dc650dSSadaf Ebrahimi printf("\nOptions:\n");
8489*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
8490*22dc650dSSadaf Ebrahimi printf("  -8            use the 8-bit library\n");
8491*22dc650dSSadaf Ebrahimi #endif
8492*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
8493*22dc650dSSadaf Ebrahimi printf("  -16           use the 16-bit library\n");
8494*22dc650dSSadaf Ebrahimi #endif
8495*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
8496*22dc650dSSadaf Ebrahimi printf("  -32           use the 32-bit library\n");
8497*22dc650dSSadaf Ebrahimi #endif
8498*22dc650dSSadaf Ebrahimi printf("  -ac           set default pattern modifier PCRE2_AUTO_CALLOUT\n");
8499*22dc650dSSadaf Ebrahimi printf("  -AC           as -ac, but also set subject 'callout_extra' modifier\n");
8500*22dc650dSSadaf Ebrahimi printf("  -b            set default pattern modifier 'fullbincode'\n");
8501*22dc650dSSadaf Ebrahimi printf("  -C            show PCRE2 compile-time options and exit\n");
8502*22dc650dSSadaf Ebrahimi printf("  -C arg        show a specific compile-time option and exit with its\n");
8503*22dc650dSSadaf Ebrahimi printf("                  value if numeric (else 0). The arg can be:\n");
8504*22dc650dSSadaf Ebrahimi printf("     backslash-C    use of \\C is enabled [0, 1]\n");
8505*22dc650dSSadaf Ebrahimi printf("     bsr            \\R type [ANYCRLF, ANY]\n");
8506*22dc650dSSadaf Ebrahimi printf("     ebcdic         compiled for EBCDIC character code [0,1]\n");
8507*22dc650dSSadaf Ebrahimi printf("     ebcdic-nl      NL code if compiled for EBCDIC\n");
8508*22dc650dSSadaf Ebrahimi printf("     jit            just-in-time compiler supported [0, 1]\n");
8509*22dc650dSSadaf Ebrahimi printf("     linksize       internal link size [2, 3, 4]\n");
8510*22dc650dSSadaf Ebrahimi printf("     newline        newline type [CR, LF, CRLF, ANYCRLF, ANY, NUL]\n");
8511*22dc650dSSadaf Ebrahimi printf("     pcre2-8        8 bit library support enabled [0, 1]\n");
8512*22dc650dSSadaf Ebrahimi printf("     pcre2-16       16 bit library support enabled [0, 1]\n");
8513*22dc650dSSadaf Ebrahimi printf("     pcre2-32       32 bit library support enabled [0, 1]\n");
8514*22dc650dSSadaf Ebrahimi printf("     unicode        Unicode and UTF support enabled [0, 1]\n");
8515*22dc650dSSadaf Ebrahimi printf("  -d            set default pattern modifier 'debug'\n");
8516*22dc650dSSadaf Ebrahimi printf("  -dfa          set default subject modifier 'dfa'\n");
8517*22dc650dSSadaf Ebrahimi printf("  -error <n,m,..>  show messages for error numbers, then exit\n");
8518*22dc650dSSadaf Ebrahimi printf("  -help         show usage information\n");
8519*22dc650dSSadaf Ebrahimi printf("  -i            set default pattern modifier 'info'\n");
8520*22dc650dSSadaf Ebrahimi printf("  -jit          set default pattern modifier 'jit'\n");
8521*22dc650dSSadaf Ebrahimi printf("  -jitfast      set default pattern modifier 'jitfast'\n");
8522*22dc650dSSadaf Ebrahimi printf("  -jitverify    set default pattern modifier 'jitverify'\n");
8523*22dc650dSSadaf Ebrahimi printf("  -LM           list pattern and subject modifiers, then exit\n");
8524*22dc650dSSadaf Ebrahimi printf("  -LP           list non-script properties, then exit\n");
8525*22dc650dSSadaf Ebrahimi printf("  -LS           list supported scripts, then exit\n");
8526*22dc650dSSadaf Ebrahimi printf("  -q            quiet: do not output PCRE2 version number at start\n");
8527*22dc650dSSadaf Ebrahimi printf("  -pattern <s>  set default pattern modifier fields\n");
8528*22dc650dSSadaf Ebrahimi printf("  -subject <s>  set default subject modifier fields\n");
8529*22dc650dSSadaf Ebrahimi printf("  -S <n>        set stack size to <n> mebibytes\n");
8530*22dc650dSSadaf Ebrahimi printf("  -t [<n>]      time compilation and execution, repeating <n> times\n");
8531*22dc650dSSadaf Ebrahimi printf("  -tm [<n>]     time execution (matching) only, repeating <n> times\n");
8532*22dc650dSSadaf Ebrahimi printf("  -T            same as -t, but show total times at the end\n");
8533*22dc650dSSadaf Ebrahimi printf("  -TM           same as -tm, but show total time at the end\n");
8534*22dc650dSSadaf Ebrahimi printf("  -v|--version  show PCRE2 version and exit\n");
8535*22dc650dSSadaf Ebrahimi }
8536*22dc650dSSadaf Ebrahimi 
8537*22dc650dSSadaf Ebrahimi 
8538*22dc650dSSadaf Ebrahimi 
8539*22dc650dSSadaf Ebrahimi /*************************************************
8540*22dc650dSSadaf Ebrahimi *             Handle -C option                   *
8541*22dc650dSSadaf Ebrahimi *************************************************/
8542*22dc650dSSadaf Ebrahimi 
8543*22dc650dSSadaf Ebrahimi /* This option outputs configuration options and sets an appropriate return
8544*22dc650dSSadaf Ebrahimi code when asked for a single option. The code is abstracted into a separate
8545*22dc650dSSadaf Ebrahimi function because of its size. Use whichever pcre2_config() function is
8546*22dc650dSSadaf Ebrahimi available.
8547*22dc650dSSadaf Ebrahimi 
8548*22dc650dSSadaf Ebrahimi Argument:   an option name or NULL
8549*22dc650dSSadaf Ebrahimi Returns:    the return code
8550*22dc650dSSadaf Ebrahimi */
8551*22dc650dSSadaf Ebrahimi 
8552*22dc650dSSadaf Ebrahimi static int
c_option(const char * arg)8553*22dc650dSSadaf Ebrahimi c_option(const char *arg)
8554*22dc650dSSadaf Ebrahimi {
8555*22dc650dSSadaf Ebrahimi uint32_t optval;
8556*22dc650dSSadaf Ebrahimi unsigned int i = COPTLISTCOUNT;
8557*22dc650dSSadaf Ebrahimi int yield = 0;
8558*22dc650dSSadaf Ebrahimi 
8559*22dc650dSSadaf Ebrahimi if (arg != NULL && arg[0] != CHAR_MINUS)
8560*22dc650dSSadaf Ebrahimi   {
8561*22dc650dSSadaf Ebrahimi   for (i = 0; i < COPTLISTCOUNT; i++)
8562*22dc650dSSadaf Ebrahimi     if (strcmp(arg, coptlist[i].name) == 0) break;
8563*22dc650dSSadaf Ebrahimi 
8564*22dc650dSSadaf Ebrahimi   if (i >= COPTLISTCOUNT)
8565*22dc650dSSadaf Ebrahimi     {
8566*22dc650dSSadaf Ebrahimi     fprintf(stderr, "** Unknown -C option '%s'\n", arg);
8567*22dc650dSSadaf Ebrahimi     return 0;
8568*22dc650dSSadaf Ebrahimi     }
8569*22dc650dSSadaf Ebrahimi 
8570*22dc650dSSadaf Ebrahimi   switch (coptlist[i].type)
8571*22dc650dSSadaf Ebrahimi     {
8572*22dc650dSSadaf Ebrahimi     case CONF_BSR:
8573*22dc650dSSadaf Ebrahimi     (void)PCRE2_CONFIG(coptlist[i].value, &optval);
8574*22dc650dSSadaf Ebrahimi     printf("%s\n", (optval == PCRE2_BSR_ANYCRLF)? "ANYCRLF" : "ANY");
8575*22dc650dSSadaf Ebrahimi     break;
8576*22dc650dSSadaf Ebrahimi 
8577*22dc650dSSadaf Ebrahimi     case CONF_FIX:
8578*22dc650dSSadaf Ebrahimi     yield = coptlist[i].value;
8579*22dc650dSSadaf Ebrahimi     printf("%d\n", yield);
8580*22dc650dSSadaf Ebrahimi     break;
8581*22dc650dSSadaf Ebrahimi 
8582*22dc650dSSadaf Ebrahimi     case CONF_FIZ:
8583*22dc650dSSadaf Ebrahimi     optval = coptlist[i].value;
8584*22dc650dSSadaf Ebrahimi     printf("%d\n", optval);
8585*22dc650dSSadaf Ebrahimi     break;
8586*22dc650dSSadaf Ebrahimi 
8587*22dc650dSSadaf Ebrahimi     case CONF_INT:
8588*22dc650dSSadaf Ebrahimi     (void)PCRE2_CONFIG(coptlist[i].value, &yield);
8589*22dc650dSSadaf Ebrahimi     printf("%d\n", yield);
8590*22dc650dSSadaf Ebrahimi     break;
8591*22dc650dSSadaf Ebrahimi 
8592*22dc650dSSadaf Ebrahimi     case CONF_NL:
8593*22dc650dSSadaf Ebrahimi     (void)PCRE2_CONFIG(coptlist[i].value, &optval);
8594*22dc650dSSadaf Ebrahimi     print_newline_config(optval, TRUE);
8595*22dc650dSSadaf Ebrahimi     break;
8596*22dc650dSSadaf Ebrahimi     }
8597*22dc650dSSadaf Ebrahimi 
8598*22dc650dSSadaf Ebrahimi /* For VMS, return the value by setting a symbol, for certain values only. This
8599*22dc650dSSadaf Ebrahimi is contributed code which the PCRE2 developers have no means of testing. */
8600*22dc650dSSadaf Ebrahimi 
8601*22dc650dSSadaf Ebrahimi #ifdef __VMS
8602*22dc650dSSadaf Ebrahimi 
8603*22dc650dSSadaf Ebrahimi /* This is the original code provided by the first VMS contributor. */
8604*22dc650dSSadaf Ebrahimi #ifdef NEVER
8605*22dc650dSSadaf Ebrahimi   if (copytlist[i].type == CONF_FIX || coptlist[i].type == CONF_INT)
8606*22dc650dSSadaf Ebrahimi     {
8607*22dc650dSSadaf Ebrahimi     char ucname[16];
8608*22dc650dSSadaf Ebrahimi     strcpy(ucname, coptlist[i].name);
8609*22dc650dSSadaf Ebrahimi     for (i = 0; ucname[i] != 0; i++) ucname[i] = toupper[ucname[i]];
8610*22dc650dSSadaf Ebrahimi     vms_setsymbol(ucname, 0, optval);
8611*22dc650dSSadaf Ebrahimi     }
8612*22dc650dSSadaf Ebrahimi #endif
8613*22dc650dSSadaf Ebrahimi 
8614*22dc650dSSadaf Ebrahimi /* This is the new code, provided by a second VMS contributor. */
8615*22dc650dSSadaf Ebrahimi 
8616*22dc650dSSadaf Ebrahimi   if (coptlist[i].type == CONF_FIX || coptlist[i].type == CONF_INT)
8617*22dc650dSSadaf Ebrahimi     {
8618*22dc650dSSadaf Ebrahimi     char nam_buf[22], val_buf[4];
8619*22dc650dSSadaf Ebrahimi     $DESCRIPTOR(nam, nam_buf);
8620*22dc650dSSadaf Ebrahimi     $DESCRIPTOR(val, val_buf);
8621*22dc650dSSadaf Ebrahimi 
8622*22dc650dSSadaf Ebrahimi     strcpy(nam_buf, coptlist[i].name);
8623*22dc650dSSadaf Ebrahimi     nam.dsc$w_length = strlen(nam_buf);
8624*22dc650dSSadaf Ebrahimi     sprintf(val_buf, "%d", yield);
8625*22dc650dSSadaf Ebrahimi     val.dsc$w_length = strlen(val_buf);
8626*22dc650dSSadaf Ebrahimi     lib$set_symbol(&nam, &val);
8627*22dc650dSSadaf Ebrahimi     }
8628*22dc650dSSadaf Ebrahimi #endif  /* __VMS */
8629*22dc650dSSadaf Ebrahimi 
8630*22dc650dSSadaf Ebrahimi   return yield;
8631*22dc650dSSadaf Ebrahimi   }
8632*22dc650dSSadaf Ebrahimi 
8633*22dc650dSSadaf Ebrahimi /* No argument for -C: output all configuration information. */
8634*22dc650dSSadaf Ebrahimi 
8635*22dc650dSSadaf Ebrahimi print_version(stdout, FALSE);
8636*22dc650dSSadaf Ebrahimi printf("Compiled with\n");
8637*22dc650dSSadaf Ebrahimi 
8638*22dc650dSSadaf Ebrahimi #ifdef EBCDIC
8639*22dc650dSSadaf Ebrahimi printf("  EBCDIC code support: LF is 0x%02x\n", CHAR_LF);
8640*22dc650dSSadaf Ebrahimi #if defined NATIVE_ZOS
8641*22dc650dSSadaf Ebrahimi printf("  EBCDIC code page %s or similar\n", pcrz_cpversion());
8642*22dc650dSSadaf Ebrahimi #endif
8643*22dc650dSSadaf Ebrahimi #endif
8644*22dc650dSSadaf Ebrahimi 
8645*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_COMPILED_WIDTHS, &optval);
8646*22dc650dSSadaf Ebrahimi if (optval & 1) printf("  8-bit support\n");
8647*22dc650dSSadaf Ebrahimi if (optval & 2) printf("  16-bit support\n");
8648*22dc650dSSadaf Ebrahimi if (optval & 4) printf("  32-bit support\n");
8649*22dc650dSSadaf Ebrahimi 
8650*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_VALGRIND
8651*22dc650dSSadaf Ebrahimi printf("  Valgrind support\n");
8652*22dc650dSSadaf Ebrahimi #endif
8653*22dc650dSSadaf Ebrahimi 
8654*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_UNICODE, &optval);
8655*22dc650dSSadaf Ebrahimi if (optval != 0)
8656*22dc650dSSadaf Ebrahimi   {
8657*22dc650dSSadaf Ebrahimi   printf("  UTF and UCP support (");
8658*22dc650dSSadaf Ebrahimi   print_unicode_version(stdout);
8659*22dc650dSSadaf Ebrahimi   printf(")\n");
8660*22dc650dSSadaf Ebrahimi   }
8661*22dc650dSSadaf Ebrahimi else printf("  No Unicode support\n");
8662*22dc650dSSadaf Ebrahimi 
8663*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_JIT, &optval);
8664*22dc650dSSadaf Ebrahimi if (optval != 0)
8665*22dc650dSSadaf Ebrahimi   {
8666*22dc650dSSadaf Ebrahimi   printf("  Just-in-time compiler support: ");
8667*22dc650dSSadaf Ebrahimi   print_jit_target(stdout);
8668*22dc650dSSadaf Ebrahimi   printf("\n");
8669*22dc650dSSadaf Ebrahimi   }
8670*22dc650dSSadaf Ebrahimi else
8671*22dc650dSSadaf Ebrahimi   {
8672*22dc650dSSadaf Ebrahimi   printf("  No just-in-time compiler support\n");
8673*22dc650dSSadaf Ebrahimi   }
8674*22dc650dSSadaf Ebrahimi 
8675*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_NEWLINE, &optval);
8676*22dc650dSSadaf Ebrahimi print_newline_config(optval, FALSE);
8677*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_BSR, &optval);
8678*22dc650dSSadaf Ebrahimi printf("  \\R matches %s\n",
8679*22dc650dSSadaf Ebrahimi   (optval == PCRE2_BSR_ANYCRLF)? "CR, LF, or CRLF only" :
8680*22dc650dSSadaf Ebrahimi                                  "all Unicode newlines");
8681*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_NEVER_BACKSLASH_C, &optval);
8682*22dc650dSSadaf Ebrahimi printf("  \\C is %ssupported\n", optval? "not ":"");
8683*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_LINKSIZE, &optval);
8684*22dc650dSSadaf Ebrahimi printf("  Internal link size = %d\n", optval);
8685*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_PARENSLIMIT, &optval);
8686*22dc650dSSadaf Ebrahimi printf("  Parentheses nest limit = %d\n", optval);
8687*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_HEAPLIMIT, &optval);
8688*22dc650dSSadaf Ebrahimi printf("  Default heap limit = %d kibibytes\n", optval);
8689*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, &optval);
8690*22dc650dSSadaf Ebrahimi printf("  Default match limit = %d\n", optval);
8691*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_DEPTHLIMIT, &optval);
8692*22dc650dSSadaf Ebrahimi printf("  Default depth limit = %d\n", optval);
8693*22dc650dSSadaf Ebrahimi 
8694*22dc650dSSadaf Ebrahimi #if defined SUPPORT_LIBREADLINE
8695*22dc650dSSadaf Ebrahimi printf("  pcre2test has libreadline support\n");
8696*22dc650dSSadaf Ebrahimi #elif defined SUPPORT_LIBEDIT
8697*22dc650dSSadaf Ebrahimi printf("  pcre2test has libedit support\n");
8698*22dc650dSSadaf Ebrahimi #else
8699*22dc650dSSadaf Ebrahimi printf("  pcre2test has neither libreadline nor libedit support\n");
8700*22dc650dSSadaf Ebrahimi #endif
8701*22dc650dSSadaf Ebrahimi 
8702*22dc650dSSadaf Ebrahimi return 0;
8703*22dc650dSSadaf Ebrahimi }
8704*22dc650dSSadaf Ebrahimi 
8705*22dc650dSSadaf Ebrahimi 
8706*22dc650dSSadaf Ebrahimi /*************************************************
8707*22dc650dSSadaf Ebrahimi *      Format one property/script list item      *
8708*22dc650dSSadaf Ebrahimi *************************************************/
8709*22dc650dSSadaf Ebrahimi 
8710*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
8711*22dc650dSSadaf Ebrahimi static void
format_list_item(int16_t * ff,char * buff,BOOL isscript)8712*22dc650dSSadaf Ebrahimi format_list_item(int16_t *ff, char *buff, BOOL isscript)
8713*22dc650dSSadaf Ebrahimi {
8714*22dc650dSSadaf Ebrahimi int count;
8715*22dc650dSSadaf Ebrahimi int maxi = 0;
8716*22dc650dSSadaf Ebrahimi const char *maxs = "";
8717*22dc650dSSadaf Ebrahimi size_t max = 0;
8718*22dc650dSSadaf Ebrahimi 
8719*22dc650dSSadaf Ebrahimi for (count = 0; ff[count] >= 0; count++) {}
8720*22dc650dSSadaf Ebrahimi 
8721*22dc650dSSadaf Ebrahimi /* Find the name to put first. For scripts, any 3-character name is chosen.
8722*22dc650dSSadaf Ebrahimi For non-scripts, or if there is no 3-character name, take the longest. */
8723*22dc650dSSadaf Ebrahimi 
8724*22dc650dSSadaf Ebrahimi for (int i = 0; ff[i] >= 0; i++)
8725*22dc650dSSadaf Ebrahimi   {
8726*22dc650dSSadaf Ebrahimi   const char *s = PRIV(utt_names) + ff[i];
8727*22dc650dSSadaf Ebrahimi   size_t len = strlen(s);
8728*22dc650dSSadaf Ebrahimi   if (isscript && len == 3)
8729*22dc650dSSadaf Ebrahimi     {
8730*22dc650dSSadaf Ebrahimi     maxi = i;
8731*22dc650dSSadaf Ebrahimi     max = len;
8732*22dc650dSSadaf Ebrahimi     maxs = s;
8733*22dc650dSSadaf Ebrahimi     break;
8734*22dc650dSSadaf Ebrahimi     }
8735*22dc650dSSadaf Ebrahimi   else if (len > max)
8736*22dc650dSSadaf Ebrahimi     {
8737*22dc650dSSadaf Ebrahimi     max = len;
8738*22dc650dSSadaf Ebrahimi     maxi = i;
8739*22dc650dSSadaf Ebrahimi     maxs = s;
8740*22dc650dSSadaf Ebrahimi     }
8741*22dc650dSSadaf Ebrahimi   }
8742*22dc650dSSadaf Ebrahimi 
8743*22dc650dSSadaf Ebrahimi strcpy(buff, maxs);
8744*22dc650dSSadaf Ebrahimi buff += max;
8745*22dc650dSSadaf Ebrahimi 
8746*22dc650dSSadaf Ebrahimi if (count > 1)
8747*22dc650dSSadaf Ebrahimi   {
8748*22dc650dSSadaf Ebrahimi   const char *sep = " (";
8749*22dc650dSSadaf Ebrahimi   for (int i = 0; i < count; i++)
8750*22dc650dSSadaf Ebrahimi     {
8751*22dc650dSSadaf Ebrahimi     if (i == maxi) continue;
8752*22dc650dSSadaf Ebrahimi     buff += sprintf(buff, "%s%s", sep, PRIV(utt_names) + ff[i]);
8753*22dc650dSSadaf Ebrahimi     sep = ", ";
8754*22dc650dSSadaf Ebrahimi     }
8755*22dc650dSSadaf Ebrahimi   (void)sprintf(buff, ")");
8756*22dc650dSSadaf Ebrahimi   }
8757*22dc650dSSadaf Ebrahimi }
8758*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_UNICODE */
8759*22dc650dSSadaf Ebrahimi 
8760*22dc650dSSadaf Ebrahimi 
8761*22dc650dSSadaf Ebrahimi 
8762*22dc650dSSadaf Ebrahimi /*************************************************
8763*22dc650dSSadaf Ebrahimi *        Display scripts or properties           *
8764*22dc650dSSadaf Ebrahimi *************************************************/
8765*22dc650dSSadaf Ebrahimi 
8766*22dc650dSSadaf Ebrahimi #define MAX_SYNONYMS 5
8767*22dc650dSSadaf Ebrahimi 
8768*22dc650dSSadaf Ebrahimi static void
display_properties(BOOL wantscripts)8769*22dc650dSSadaf Ebrahimi display_properties(BOOL wantscripts)
8770*22dc650dSSadaf Ebrahimi {
8771*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_UNICODE
8772*22dc650dSSadaf Ebrahimi (void)wantscripts;
8773*22dc650dSSadaf Ebrahimi printf("** This version of PCRE2 was compiled without Unicode support.\n");
8774*22dc650dSSadaf Ebrahimi #else
8775*22dc650dSSadaf Ebrahimi 
8776*22dc650dSSadaf Ebrahimi uint16_t seentypes[1024];
8777*22dc650dSSadaf Ebrahimi uint16_t seenvalues[1024];
8778*22dc650dSSadaf Ebrahimi int seencount = 0;
8779*22dc650dSSadaf Ebrahimi int16_t found[256][MAX_SYNONYMS + 1];
8780*22dc650dSSadaf Ebrahimi int fc = 0;
8781*22dc650dSSadaf Ebrahimi int colwidth = 40;
8782*22dc650dSSadaf Ebrahimi int n = wantscripts? ucp_Script_Count : ucp_Bprop_Count;
8783*22dc650dSSadaf Ebrahimi 
8784*22dc650dSSadaf Ebrahimi for (size_t i = 0; i < PRIV(utt_size); i++)
8785*22dc650dSSadaf Ebrahimi   {
8786*22dc650dSSadaf Ebrahimi   int k;
8787*22dc650dSSadaf Ebrahimi   int m = 0;
8788*22dc650dSSadaf Ebrahimi   int16_t *fv;
8789*22dc650dSSadaf Ebrahimi   const ucp_type_table *t = PRIV(utt) + i;
8790*22dc650dSSadaf Ebrahimi   unsigned int value = t->value;
8791*22dc650dSSadaf Ebrahimi 
8792*22dc650dSSadaf Ebrahimi   if (wantscripts)
8793*22dc650dSSadaf Ebrahimi     {
8794*22dc650dSSadaf Ebrahimi     if (t->type != PT_SC && t->type != PT_SCX) continue;
8795*22dc650dSSadaf Ebrahimi     }
8796*22dc650dSSadaf Ebrahimi   else
8797*22dc650dSSadaf Ebrahimi     {
8798*22dc650dSSadaf Ebrahimi     if (t->type != PT_BOOL) continue;
8799*22dc650dSSadaf Ebrahimi     }
8800*22dc650dSSadaf Ebrahimi 
8801*22dc650dSSadaf Ebrahimi   for (k = 0; k < seencount; k++)
8802*22dc650dSSadaf Ebrahimi     {
8803*22dc650dSSadaf Ebrahimi     if (t->type == seentypes[k] && t->value == seenvalues[k]) break;
8804*22dc650dSSadaf Ebrahimi     }
8805*22dc650dSSadaf Ebrahimi   if (k < seencount) continue;
8806*22dc650dSSadaf Ebrahimi 
8807*22dc650dSSadaf Ebrahimi   seentypes[seencount] = t->type;
8808*22dc650dSSadaf Ebrahimi   seenvalues[seencount++] = t->value;
8809*22dc650dSSadaf Ebrahimi 
8810*22dc650dSSadaf Ebrahimi   fv = found[fc++];
8811*22dc650dSSadaf Ebrahimi   fv[m++] = t->name_offset;
8812*22dc650dSSadaf Ebrahimi 
8813*22dc650dSSadaf Ebrahimi   for (size_t j = i + 1; j < PRIV(utt_size); j++)
8814*22dc650dSSadaf Ebrahimi     {
8815*22dc650dSSadaf Ebrahimi     const ucp_type_table *tt = PRIV(utt) + j;
8816*22dc650dSSadaf Ebrahimi     if (tt->type != t->type || tt->value != value) continue;
8817*22dc650dSSadaf Ebrahimi     if (m >= MAX_SYNONYMS)
8818*22dc650dSSadaf Ebrahimi       printf("** Too many synonyms: %s ignored\n",
8819*22dc650dSSadaf Ebrahimi         PRIV(utt_names) + tt->name_offset);
8820*22dc650dSSadaf Ebrahimi     else fv[m++] = tt->name_offset;
8821*22dc650dSSadaf Ebrahimi     }
8822*22dc650dSSadaf Ebrahimi 
8823*22dc650dSSadaf Ebrahimi   fv[m] = -1;
8824*22dc650dSSadaf Ebrahimi   }
8825*22dc650dSSadaf Ebrahimi 
8826*22dc650dSSadaf Ebrahimi printf("-------------------------- SUPPORTED %s --------------------------\n\n",
8827*22dc650dSSadaf Ebrahimi   wantscripts? "SCRIPTS" : "PROPERTIES");
8828*22dc650dSSadaf Ebrahimi 
8829*22dc650dSSadaf Ebrahimi if (!wantscripts) printf(
8830*22dc650dSSadaf Ebrahimi "This release of PCRE2 supports Unicode's general category properties such\n"
8831*22dc650dSSadaf Ebrahimi "as Lu (upper case letter), bi-directional properties such as Bidi_Class,\n"
8832*22dc650dSSadaf Ebrahimi "and the following binary (yes/no) properties:\n\n");
8833*22dc650dSSadaf Ebrahimi 
8834*22dc650dSSadaf Ebrahimi 
8835*22dc650dSSadaf Ebrahimi for (int k = 0; k < (n+1)/2; k++)
8836*22dc650dSSadaf Ebrahimi   {
8837*22dc650dSSadaf Ebrahimi   int x;
8838*22dc650dSSadaf Ebrahimi   char buff1[128];
8839*22dc650dSSadaf Ebrahimi   char buff2[128];
8840*22dc650dSSadaf Ebrahimi 
8841*22dc650dSSadaf Ebrahimi   format_list_item(found[k], buff1, wantscripts);
8842*22dc650dSSadaf Ebrahimi   x = k + (n+1)/2;
8843*22dc650dSSadaf Ebrahimi   if (x < n) format_list_item(found[x], buff2, wantscripts);
8844*22dc650dSSadaf Ebrahimi     else buff2[0] = 0;
8845*22dc650dSSadaf Ebrahimi 
8846*22dc650dSSadaf Ebrahimi   x = printf("%s", buff1);
8847*22dc650dSSadaf Ebrahimi   while (x++ < colwidth) printf(" ");
8848*22dc650dSSadaf Ebrahimi   printf("%s\n", buff2);
8849*22dc650dSSadaf Ebrahimi   }
8850*22dc650dSSadaf Ebrahimi 
8851*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_UNICODE */
8852*22dc650dSSadaf Ebrahimi }
8853*22dc650dSSadaf Ebrahimi 
8854*22dc650dSSadaf Ebrahimi 
8855*22dc650dSSadaf Ebrahimi 
8856*22dc650dSSadaf Ebrahimi /*************************************************
8857*22dc650dSSadaf Ebrahimi *              Display one modifier              *
8858*22dc650dSSadaf Ebrahimi *************************************************/
8859*22dc650dSSadaf Ebrahimi 
8860*22dc650dSSadaf Ebrahimi static void
display_one_modifier(modstruct * m,BOOL for_pattern)8861*22dc650dSSadaf Ebrahimi display_one_modifier(modstruct *m, BOOL for_pattern)
8862*22dc650dSSadaf Ebrahimi {
8863*22dc650dSSadaf Ebrahimi uint32_t c = (!for_pattern && (m->which == MOD_PND || m->which == MOD_PNDP))?
8864*22dc650dSSadaf Ebrahimi   '*' : ' ';
8865*22dc650dSSadaf Ebrahimi printf("%c%s", c, m->name);
8866*22dc650dSSadaf Ebrahimi for (size_t i = 0; i < C1MODLISTCOUNT; i++)
8867*22dc650dSSadaf Ebrahimi   {
8868*22dc650dSSadaf Ebrahimi   if (strcmp(m->name, c1modlist[i].fullname) == 0)
8869*22dc650dSSadaf Ebrahimi     printf(" (%c)", c1modlist[i].onechar);
8870*22dc650dSSadaf Ebrahimi   }
8871*22dc650dSSadaf Ebrahimi }
8872*22dc650dSSadaf Ebrahimi 
8873*22dc650dSSadaf Ebrahimi 
8874*22dc650dSSadaf Ebrahimi 
8875*22dc650dSSadaf Ebrahimi /*************************************************
8876*22dc650dSSadaf Ebrahimi *       Display pattern or subject modifiers     *
8877*22dc650dSSadaf Ebrahimi *************************************************/
8878*22dc650dSSadaf Ebrahimi 
8879*22dc650dSSadaf Ebrahimi /* In order to print in two columns, first scan without printing to get a list
8880*22dc650dSSadaf Ebrahimi of the modifiers that are required.
8881*22dc650dSSadaf Ebrahimi 
8882*22dc650dSSadaf Ebrahimi Arguments:
8883*22dc650dSSadaf Ebrahimi   for_pattern   TRUE for pattern modifiers, FALSE for subject modifiers
8884*22dc650dSSadaf Ebrahimi   title         string to be used in title
8885*22dc650dSSadaf Ebrahimi 
8886*22dc650dSSadaf Ebrahimi Returns:        nothing
8887*22dc650dSSadaf Ebrahimi */
8888*22dc650dSSadaf Ebrahimi 
8889*22dc650dSSadaf Ebrahimi static void
display_selected_modifiers(BOOL for_pattern,const char * title)8890*22dc650dSSadaf Ebrahimi display_selected_modifiers(BOOL for_pattern, const char *title)
8891*22dc650dSSadaf Ebrahimi {
8892*22dc650dSSadaf Ebrahimi uint32_t i, j;
8893*22dc650dSSadaf Ebrahimi uint32_t n = 0;
8894*22dc650dSSadaf Ebrahimi uint32_t list[MODLISTCOUNT];
8895*22dc650dSSadaf Ebrahimi uint32_t extra[MODLISTCOUNT];
8896*22dc650dSSadaf Ebrahimi 
8897*22dc650dSSadaf Ebrahimi for (i = 0; i < MODLISTCOUNT; i++)
8898*22dc650dSSadaf Ebrahimi   {
8899*22dc650dSSadaf Ebrahimi   BOOL is_pattern = TRUE;
8900*22dc650dSSadaf Ebrahimi   modstruct *m = modlist + i;
8901*22dc650dSSadaf Ebrahimi 
8902*22dc650dSSadaf Ebrahimi   switch (m->which)
8903*22dc650dSSadaf Ebrahimi     {
8904*22dc650dSSadaf Ebrahimi     case MOD_CTC:       /* Compile context */
8905*22dc650dSSadaf Ebrahimi     case MOD_PAT:       /* Pattern */
8906*22dc650dSSadaf Ebrahimi     case MOD_PATP:      /* Pattern, OK for Perl-compatible test */
8907*22dc650dSSadaf Ebrahimi     break;
8908*22dc650dSSadaf Ebrahimi 
8909*22dc650dSSadaf Ebrahimi     /* The MOD_PND and MOD_PNDP modifiers are precisely those that affect
8910*22dc650dSSadaf Ebrahimi     subjects, but can be given with a pattern. We list them as subject
8911*22dc650dSSadaf Ebrahimi     modifiers, but marked with an asterisk.*/
8912*22dc650dSSadaf Ebrahimi 
8913*22dc650dSSadaf Ebrahimi     case MOD_CTM:       /* Match context */
8914*22dc650dSSadaf Ebrahimi     case MOD_DAT:       /* Subject line */
8915*22dc650dSSadaf Ebrahimi     case MOD_DATP:      /* Subject line, OK for Perl-compatible test */
8916*22dc650dSSadaf Ebrahimi     case MOD_PND:       /* As PD, but not default pattern */
8917*22dc650dSSadaf Ebrahimi     case MOD_PNDP:      /* As PND, OK for Perl-compatible test */
8918*22dc650dSSadaf Ebrahimi     is_pattern = FALSE;
8919*22dc650dSSadaf Ebrahimi     break;
8920*22dc650dSSadaf Ebrahimi 
8921*22dc650dSSadaf Ebrahimi     default: printf("** Unknown type for modifier '%s'\n", m->name);
8922*22dc650dSSadaf Ebrahimi     /* Fall through */
8923*22dc650dSSadaf Ebrahimi     case MOD_PD:        /* Pattern or subject */
8924*22dc650dSSadaf Ebrahimi     case MOD_PDP:       /* As PD, OK for Perl-compatible test */
8925*22dc650dSSadaf Ebrahimi     is_pattern = for_pattern;
8926*22dc650dSSadaf Ebrahimi     break;
8927*22dc650dSSadaf Ebrahimi     }
8928*22dc650dSSadaf Ebrahimi 
8929*22dc650dSSadaf Ebrahimi   if (for_pattern == is_pattern)
8930*22dc650dSSadaf Ebrahimi     {
8931*22dc650dSSadaf Ebrahimi     extra[n] = 0;
8932*22dc650dSSadaf Ebrahimi     for (size_t k = 0; k < C1MODLISTCOUNT; k++)
8933*22dc650dSSadaf Ebrahimi       {
8934*22dc650dSSadaf Ebrahimi       if (strcmp(m->name, c1modlist[k].fullname) == 0)
8935*22dc650dSSadaf Ebrahimi         {
8936*22dc650dSSadaf Ebrahimi         extra[n] += 4;
8937*22dc650dSSadaf Ebrahimi         break;
8938*22dc650dSSadaf Ebrahimi         }
8939*22dc650dSSadaf Ebrahimi       }
8940*22dc650dSSadaf Ebrahimi     list[n++] = i;
8941*22dc650dSSadaf Ebrahimi     }
8942*22dc650dSSadaf Ebrahimi   }
8943*22dc650dSSadaf Ebrahimi 
8944*22dc650dSSadaf Ebrahimi /* Now print from the list in two columns. */
8945*22dc650dSSadaf Ebrahimi 
8946*22dc650dSSadaf Ebrahimi printf("-------------- %s MODIFIERS --------------\n", title);
8947*22dc650dSSadaf Ebrahimi 
8948*22dc650dSSadaf Ebrahimi for (i = 0, j = (n+1)/2; i < (n+1)/2; i++, j++)
8949*22dc650dSSadaf Ebrahimi   {
8950*22dc650dSSadaf Ebrahimi   modstruct *m = modlist + list[i];
8951*22dc650dSSadaf Ebrahimi   display_one_modifier(m, for_pattern);
8952*22dc650dSSadaf Ebrahimi   if (j < n)
8953*22dc650dSSadaf Ebrahimi     {
8954*22dc650dSSadaf Ebrahimi     uint32_t k = 27 - strlen(m->name) - extra[i];
8955*22dc650dSSadaf Ebrahimi     while (k-- > 0) printf(" ");
8956*22dc650dSSadaf Ebrahimi     display_one_modifier(modlist + list[j], for_pattern);
8957*22dc650dSSadaf Ebrahimi     }
8958*22dc650dSSadaf Ebrahimi   printf("\n");
8959*22dc650dSSadaf Ebrahimi   }
8960*22dc650dSSadaf Ebrahimi }
8961*22dc650dSSadaf Ebrahimi 
8962*22dc650dSSadaf Ebrahimi 
8963*22dc650dSSadaf Ebrahimi 
8964*22dc650dSSadaf Ebrahimi /*************************************************
8965*22dc650dSSadaf Ebrahimi *          Display the list of modifiers         *
8966*22dc650dSSadaf Ebrahimi *************************************************/
8967*22dc650dSSadaf Ebrahimi 
8968*22dc650dSSadaf Ebrahimi static void
display_modifiers(void)8969*22dc650dSSadaf Ebrahimi display_modifiers(void)
8970*22dc650dSSadaf Ebrahimi {
8971*22dc650dSSadaf Ebrahimi printf(
8972*22dc650dSSadaf Ebrahimi   "An asterisk on a subject modifier means that it may be given on a pattern\n"
8973*22dc650dSSadaf Ebrahimi   "line, in order to apply to all subjects matched by that pattern. Modifiers\n"
8974*22dc650dSSadaf Ebrahimi   "that are listed for both patterns and subjects have different effects in\n"
8975*22dc650dSSadaf Ebrahimi   "each case.\n\n");
8976*22dc650dSSadaf Ebrahimi display_selected_modifiers(TRUE, "PATTERN");
8977*22dc650dSSadaf Ebrahimi printf("\n");
8978*22dc650dSSadaf Ebrahimi display_selected_modifiers(FALSE, "SUBJECT");
8979*22dc650dSSadaf Ebrahimi }
8980*22dc650dSSadaf Ebrahimi 
8981*22dc650dSSadaf Ebrahimi 
8982*22dc650dSSadaf Ebrahimi 
8983*22dc650dSSadaf Ebrahimi /*************************************************
8984*22dc650dSSadaf Ebrahimi *                Main Program                    *
8985*22dc650dSSadaf Ebrahimi *************************************************/
8986*22dc650dSSadaf Ebrahimi 
8987*22dc650dSSadaf Ebrahimi int
main(int argc,char ** argv)8988*22dc650dSSadaf Ebrahimi main(int argc, char **argv)
8989*22dc650dSSadaf Ebrahimi {
8990*22dc650dSSadaf Ebrahimi uint32_t temp;
8991*22dc650dSSadaf Ebrahimi uint32_t yield = 0;
8992*22dc650dSSadaf Ebrahimi uint32_t op = 1;
8993*22dc650dSSadaf Ebrahimi BOOL notdone = TRUE;
8994*22dc650dSSadaf Ebrahimi BOOL quiet = FALSE;
8995*22dc650dSSadaf Ebrahimi BOOL showtotaltimes = FALSE;
8996*22dc650dSSadaf Ebrahimi BOOL skipping = FALSE;
8997*22dc650dSSadaf Ebrahimi char *arg_subject = NULL;
8998*22dc650dSSadaf Ebrahimi char *arg_pattern = NULL;
8999*22dc650dSSadaf Ebrahimi char *arg_error = NULL;
9000*22dc650dSSadaf Ebrahimi 
9001*22dc650dSSadaf Ebrahimi /* The offsets to the options and control bits fields of the pattern and data
9002*22dc650dSSadaf Ebrahimi control blocks must be the same so that common options and controls such as
9003*22dc650dSSadaf Ebrahimi "anchored" or "memory" can work for either of them from a single table entry.
9004*22dc650dSSadaf Ebrahimi We cannot test this till runtime because "offsetof" does not work in the
9005*22dc650dSSadaf Ebrahimi preprocessor. */
9006*22dc650dSSadaf Ebrahimi 
9007*22dc650dSSadaf Ebrahimi if (PO(options) != DO(options) || PO(control) != DO(control) ||
9008*22dc650dSSadaf Ebrahimi     PO(control2) != DO(control2))
9009*22dc650dSSadaf Ebrahimi   {
9010*22dc650dSSadaf Ebrahimi   fprintf(stderr, "** Coding error: "
9011*22dc650dSSadaf Ebrahimi     "options and control offsets for pattern and data must be the same.\n");
9012*22dc650dSSadaf Ebrahimi   return 1;
9013*22dc650dSSadaf Ebrahimi   }
9014*22dc650dSSadaf Ebrahimi 
9015*22dc650dSSadaf Ebrahimi /* Get the PCRE2 and Unicode version number and JIT target information, at the
9016*22dc650dSSadaf Ebrahimi same time checking that a request for the length gives the same answer. Also
9017*22dc650dSSadaf Ebrahimi check lengths for non-string items. */
9018*22dc650dSSadaf Ebrahimi 
9019*22dc650dSSadaf Ebrahimi if (PCRE2_CONFIG(PCRE2_CONFIG_VERSION, NULL) !=
9020*22dc650dSSadaf Ebrahimi     PCRE2_CONFIG(PCRE2_CONFIG_VERSION, version) ||
9021*22dc650dSSadaf Ebrahimi 
9022*22dc650dSSadaf Ebrahimi     PCRE2_CONFIG(PCRE2_CONFIG_UNICODE_VERSION, NULL) !=
9023*22dc650dSSadaf Ebrahimi     PCRE2_CONFIG(PCRE2_CONFIG_UNICODE_VERSION, uversion) ||
9024*22dc650dSSadaf Ebrahimi 
9025*22dc650dSSadaf Ebrahimi     PCRE2_CONFIG(PCRE2_CONFIG_JITTARGET, NULL) !=
9026*22dc650dSSadaf Ebrahimi     PCRE2_CONFIG(PCRE2_CONFIG_JITTARGET, jittarget) ||
9027*22dc650dSSadaf Ebrahimi 
9028*22dc650dSSadaf Ebrahimi     PCRE2_CONFIG(PCRE2_CONFIG_UNICODE, NULL) != sizeof(uint32_t) ||
9029*22dc650dSSadaf Ebrahimi     PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, NULL) != sizeof(uint32_t))
9030*22dc650dSSadaf Ebrahimi   {
9031*22dc650dSSadaf Ebrahimi   fprintf(stderr, "** Error in pcre2_config(): bad length\n");
9032*22dc650dSSadaf Ebrahimi   return 1;
9033*22dc650dSSadaf Ebrahimi   }
9034*22dc650dSSadaf Ebrahimi 
9035*22dc650dSSadaf Ebrahimi /* Check that bad options are diagnosed. */
9036*22dc650dSSadaf Ebrahimi 
9037*22dc650dSSadaf Ebrahimi if (PCRE2_CONFIG(999, NULL) != PCRE2_ERROR_BADOPTION ||
9038*22dc650dSSadaf Ebrahimi     PCRE2_CONFIG(999, &temp) != PCRE2_ERROR_BADOPTION)
9039*22dc650dSSadaf Ebrahimi   {
9040*22dc650dSSadaf Ebrahimi   fprintf(stderr, "** Error in pcre2_config(): bad option not diagnosed\n");
9041*22dc650dSSadaf Ebrahimi   return 1;
9042*22dc650dSSadaf Ebrahimi   }
9043*22dc650dSSadaf Ebrahimi 
9044*22dc650dSSadaf Ebrahimi /* This configuration option is now obsolete, but running a quick check ensures
9045*22dc650dSSadaf Ebrahimi that its code is covered. */
9046*22dc650dSSadaf Ebrahimi 
9047*22dc650dSSadaf Ebrahimi (void)PCRE2_CONFIG(PCRE2_CONFIG_STACKRECURSE, &temp);
9048*22dc650dSSadaf Ebrahimi 
9049*22dc650dSSadaf Ebrahimi /* Get buffers from malloc() so that valgrind will check their misuse when
9050*22dc650dSSadaf Ebrahimi debugging. They grow automatically when very long lines are read. The 16-
9051*22dc650dSSadaf Ebrahimi and 32-bit buffers (pbuffer16, pbuffer32) are obtained only if needed. */
9052*22dc650dSSadaf Ebrahimi 
9053*22dc650dSSadaf Ebrahimi buffer = (uint8_t *)malloc(pbuffer8_size);
9054*22dc650dSSadaf Ebrahimi pbuffer8 = (uint8_t *)malloc(pbuffer8_size);
9055*22dc650dSSadaf Ebrahimi 
9056*22dc650dSSadaf Ebrahimi /* The following  _setmode() stuff is some Windows magic that tells its runtime
9057*22dc650dSSadaf Ebrahimi library to translate CRLF into a single LF character. At least, that's what
9058*22dc650dSSadaf Ebrahimi I've been told: never having used Windows I take this all on trust. Originally
9059*22dc650dSSadaf Ebrahimi it set 0x8000, but then I was advised that _O_BINARY was better. */
9060*22dc650dSSadaf Ebrahimi 
9061*22dc650dSSadaf Ebrahimi #if defined(_WIN32) || defined(WIN32)
9062*22dc650dSSadaf Ebrahimi _setmode( _fileno( stdout ), _O_BINARY );
9063*22dc650dSSadaf Ebrahimi #endif
9064*22dc650dSSadaf Ebrahimi 
9065*22dc650dSSadaf Ebrahimi /* Initialization that does not depend on the running mode. */
9066*22dc650dSSadaf Ebrahimi 
9067*22dc650dSSadaf Ebrahimi locale_name[0] = 0;
9068*22dc650dSSadaf Ebrahimi 
9069*22dc650dSSadaf Ebrahimi memset(&def_patctl, 0, sizeof(patctl));
9070*22dc650dSSadaf Ebrahimi def_patctl.convert_type = CONVERT_UNSET;
9071*22dc650dSSadaf Ebrahimi 
9072*22dc650dSSadaf Ebrahimi memset(&def_datctl, 0, sizeof(datctl));
9073*22dc650dSSadaf Ebrahimi def_datctl.oveccount = DEFAULT_OVECCOUNT;
9074*22dc650dSSadaf Ebrahimi def_datctl.copy_numbers[0] = -1;
9075*22dc650dSSadaf Ebrahimi def_datctl.get_numbers[0] = -1;
9076*22dc650dSSadaf Ebrahimi def_datctl.startend[0] = def_datctl.startend[1] = CFORE_UNSET;
9077*22dc650dSSadaf Ebrahimi def_datctl.cerror[0] = def_datctl.cerror[1] = CFORE_UNSET;
9078*22dc650dSSadaf Ebrahimi def_datctl.cfail[0] = def_datctl.cfail[1] = CFORE_UNSET;
9079*22dc650dSSadaf Ebrahimi 
9080*22dc650dSSadaf Ebrahimi /* Scan command line options. */
9081*22dc650dSSadaf Ebrahimi 
9082*22dc650dSSadaf Ebrahimi while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0)
9083*22dc650dSSadaf Ebrahimi   {
9084*22dc650dSSadaf Ebrahimi   char *endptr;
9085*22dc650dSSadaf Ebrahimi   char *arg = argv[op];
9086*22dc650dSSadaf Ebrahimi   unsigned long uli;
9087*22dc650dSSadaf Ebrahimi 
9088*22dc650dSSadaf Ebrahimi   /* List modifiers and exit. */
9089*22dc650dSSadaf Ebrahimi 
9090*22dc650dSSadaf Ebrahimi   if (strcmp(arg, "-LM") == 0)
9091*22dc650dSSadaf Ebrahimi     {
9092*22dc650dSSadaf Ebrahimi     display_modifiers();
9093*22dc650dSSadaf Ebrahimi     goto EXIT;
9094*22dc650dSSadaf Ebrahimi     }
9095*22dc650dSSadaf Ebrahimi 
9096*22dc650dSSadaf Ebrahimi   /* List properties and exit */
9097*22dc650dSSadaf Ebrahimi 
9098*22dc650dSSadaf Ebrahimi   if (strcmp(arg, "-LP") == 0)
9099*22dc650dSSadaf Ebrahimi     {
9100*22dc650dSSadaf Ebrahimi     display_properties(FALSE);
9101*22dc650dSSadaf Ebrahimi     goto EXIT;
9102*22dc650dSSadaf Ebrahimi     }
9103*22dc650dSSadaf Ebrahimi 
9104*22dc650dSSadaf Ebrahimi   /* List scripts and exit */
9105*22dc650dSSadaf Ebrahimi 
9106*22dc650dSSadaf Ebrahimi   if (strcmp(arg, "-LS") == 0)
9107*22dc650dSSadaf Ebrahimi     {
9108*22dc650dSSadaf Ebrahimi     display_properties(TRUE);
9109*22dc650dSSadaf Ebrahimi     goto EXIT;
9110*22dc650dSSadaf Ebrahimi     }
9111*22dc650dSSadaf Ebrahimi 
9112*22dc650dSSadaf Ebrahimi   /* Display and/or set return code for configuration options. */
9113*22dc650dSSadaf Ebrahimi 
9114*22dc650dSSadaf Ebrahimi   if (strcmp(arg, "-C") == 0)
9115*22dc650dSSadaf Ebrahimi     {
9116*22dc650dSSadaf Ebrahimi     yield = c_option(argv[op + 1]);
9117*22dc650dSSadaf Ebrahimi     goto EXIT;
9118*22dc650dSSadaf Ebrahimi     }
9119*22dc650dSSadaf Ebrahimi 
9120*22dc650dSSadaf Ebrahimi   /* Select operating mode. Ensure that pcre2_config() is called in 16-bit
9121*22dc650dSSadaf Ebrahimi   and 32-bit modes because that won't happen naturally when 8-bit is also
9122*22dc650dSSadaf Ebrahimi   configured. Also call some other functions that are not otherwise used. This
9123*22dc650dSSadaf Ebrahimi   means that a coverage report won't claim there are uncalled functions. */
9124*22dc650dSSadaf Ebrahimi 
9125*22dc650dSSadaf Ebrahimi   if (strcmp(arg, "-8") == 0)
9126*22dc650dSSadaf Ebrahimi     {
9127*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
9128*22dc650dSSadaf Ebrahimi     test_mode = PCRE8_MODE;
9129*22dc650dSSadaf Ebrahimi     (void)pcre2_set_bsr_8(pat_context8, 999);
9130*22dc650dSSadaf Ebrahimi     (void)pcre2_set_newline_8(pat_context8, 999);
9131*22dc650dSSadaf Ebrahimi #else
9132*22dc650dSSadaf Ebrahimi     fprintf(stderr,
9133*22dc650dSSadaf Ebrahimi       "** This version of PCRE2 was built without 8-bit support\n");
9134*22dc650dSSadaf Ebrahimi     exit(1);
9135*22dc650dSSadaf Ebrahimi #endif
9136*22dc650dSSadaf Ebrahimi     }
9137*22dc650dSSadaf Ebrahimi 
9138*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-16") == 0)
9139*22dc650dSSadaf Ebrahimi     {
9140*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
9141*22dc650dSSadaf Ebrahimi     test_mode = PCRE16_MODE;
9142*22dc650dSSadaf Ebrahimi     (void)pcre2_config_16(PCRE2_CONFIG_VERSION, NULL);
9143*22dc650dSSadaf Ebrahimi     (void)pcre2_set_bsr_16(pat_context16, 999);
9144*22dc650dSSadaf Ebrahimi     (void)pcre2_set_newline_16(pat_context16, 999);
9145*22dc650dSSadaf Ebrahimi #else
9146*22dc650dSSadaf Ebrahimi     fprintf(stderr,
9147*22dc650dSSadaf Ebrahimi       "** This version of PCRE2 was built without 16-bit support\n");
9148*22dc650dSSadaf Ebrahimi     exit(1);
9149*22dc650dSSadaf Ebrahimi #endif
9150*22dc650dSSadaf Ebrahimi     }
9151*22dc650dSSadaf Ebrahimi 
9152*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-32") == 0)
9153*22dc650dSSadaf Ebrahimi     {
9154*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
9155*22dc650dSSadaf Ebrahimi     test_mode = PCRE32_MODE;
9156*22dc650dSSadaf Ebrahimi     (void)pcre2_config_32(PCRE2_CONFIG_VERSION, NULL);
9157*22dc650dSSadaf Ebrahimi     (void)pcre2_set_bsr_32(pat_context32, 999);
9158*22dc650dSSadaf Ebrahimi     (void)pcre2_set_newline_32(pat_context32, 999);
9159*22dc650dSSadaf Ebrahimi #else
9160*22dc650dSSadaf Ebrahimi     fprintf(stderr,
9161*22dc650dSSadaf Ebrahimi       "** This version of PCRE2 was built without 32-bit support\n");
9162*22dc650dSSadaf Ebrahimi     exit(1);
9163*22dc650dSSadaf Ebrahimi #endif
9164*22dc650dSSadaf Ebrahimi     }
9165*22dc650dSSadaf Ebrahimi 
9166*22dc650dSSadaf Ebrahimi   /* Set quiet (no version verification) */
9167*22dc650dSSadaf Ebrahimi 
9168*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-q") == 0) quiet = TRUE;
9169*22dc650dSSadaf Ebrahimi 
9170*22dc650dSSadaf Ebrahimi   /* Set system stack size */
9171*22dc650dSSadaf Ebrahimi 
9172*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-S") == 0 && argc > 2 &&
9173*22dc650dSSadaf Ebrahimi       ((uli = strtoul(argv[op+1], &endptr, 10)), *endptr == 0))
9174*22dc650dSSadaf Ebrahimi     {
9175*22dc650dSSadaf Ebrahimi #if defined(_WIN32) || defined(WIN32) || defined(__HAIKU__) || defined(NATIVE_ZOS) || defined(__VMS)
9176*22dc650dSSadaf Ebrahimi     fprintf(stderr, "pcre2test: -S is not supported on this OS\n");
9177*22dc650dSSadaf Ebrahimi     exit(1);
9178*22dc650dSSadaf Ebrahimi #else
9179*22dc650dSSadaf Ebrahimi     int rc;
9180*22dc650dSSadaf Ebrahimi     uint32_t stack_size;
9181*22dc650dSSadaf Ebrahimi     struct rlimit rlim;
9182*22dc650dSSadaf Ebrahimi     if (U32OVERFLOW(uli))
9183*22dc650dSSadaf Ebrahimi       {
9184*22dc650dSSadaf Ebrahimi       fprintf(stderr, "** Argument for -S is too big\n");
9185*22dc650dSSadaf Ebrahimi       exit(1);
9186*22dc650dSSadaf Ebrahimi       }
9187*22dc650dSSadaf Ebrahimi     stack_size = (uint32_t)uli;
9188*22dc650dSSadaf Ebrahimi     getrlimit(RLIMIT_STACK, &rlim);
9189*22dc650dSSadaf Ebrahimi     rlim.rlim_cur = stack_size * 1024 * 1024;
9190*22dc650dSSadaf Ebrahimi     if (rlim.rlim_cur > rlim.rlim_max)
9191*22dc650dSSadaf Ebrahimi       {
9192*22dc650dSSadaf Ebrahimi       fprintf(stderr,
9193*22dc650dSSadaf Ebrahimi         "pcre2test: requested stack size %luMiB is greater than hard limit ",
9194*22dc650dSSadaf Ebrahimi           (unsigned long int)stack_size);
9195*22dc650dSSadaf Ebrahimi       if (rlim.rlim_max % (1024*1024) == 0) fprintf(stderr, "%luMiB\n",
9196*22dc650dSSadaf Ebrahimi         (unsigned long int)(rlim.rlim_max/(1024 * 1024)));
9197*22dc650dSSadaf Ebrahimi       else if (rlim.rlim_max % 1024 == 0) fprintf(stderr, "%luKiB\n",
9198*22dc650dSSadaf Ebrahimi         (unsigned long int)(rlim.rlim_max/1024));
9199*22dc650dSSadaf Ebrahimi       else fprintf(stderr, "%lu bytes\n", (unsigned long int)(rlim.rlim_max));
9200*22dc650dSSadaf Ebrahimi       exit(1);
9201*22dc650dSSadaf Ebrahimi       }
9202*22dc650dSSadaf Ebrahimi     rc = setrlimit(RLIMIT_STACK, &rlim);
9203*22dc650dSSadaf Ebrahimi     if (rc != 0)
9204*22dc650dSSadaf Ebrahimi       {
9205*22dc650dSSadaf Ebrahimi       fprintf(stderr, "pcre2test: setting stack size %luMiB failed: %s\n",
9206*22dc650dSSadaf Ebrahimi         (unsigned long int)stack_size, strerror(errno));
9207*22dc650dSSadaf Ebrahimi       exit(1);
9208*22dc650dSSadaf Ebrahimi       }
9209*22dc650dSSadaf Ebrahimi     op++;
9210*22dc650dSSadaf Ebrahimi     argc--;
9211*22dc650dSSadaf Ebrahimi #endif
9212*22dc650dSSadaf Ebrahimi     }
9213*22dc650dSSadaf Ebrahimi 
9214*22dc650dSSadaf Ebrahimi   /* Set some common pattern and subject controls */
9215*22dc650dSSadaf Ebrahimi 
9216*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-AC") == 0)
9217*22dc650dSSadaf Ebrahimi     {
9218*22dc650dSSadaf Ebrahimi     def_patctl.options |= PCRE2_AUTO_CALLOUT;
9219*22dc650dSSadaf Ebrahimi     def_datctl.control2 |= CTL2_CALLOUT_EXTRA;
9220*22dc650dSSadaf Ebrahimi     }
9221*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-ac") == 0)  def_patctl.options |= PCRE2_AUTO_CALLOUT;
9222*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-b") == 0)   def_patctl.control |= CTL_FULLBINCODE;
9223*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-d") == 0)   def_patctl.control |= CTL_DEBUG;
9224*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-dfa") == 0) def_datctl.control |= CTL_DFA;
9225*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-i") == 0)   def_patctl.control |= CTL_INFO;
9226*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-jit") == 0 || strcmp(arg, "-jitverify") == 0 ||
9227*22dc650dSSadaf Ebrahimi            strcmp(arg, "-jitfast") == 0)
9228*22dc650dSSadaf Ebrahimi     {
9229*22dc650dSSadaf Ebrahimi     if (arg[4] == 'v') def_patctl.control |= CTL_JITVERIFY;
9230*22dc650dSSadaf Ebrahimi       else if (arg[4] == 'f') def_patctl.control |= CTL_JITFAST;
9231*22dc650dSSadaf Ebrahimi     def_patctl.jit = JIT_DEFAULT;  /* full & partial */
9232*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
9233*22dc650dSSadaf Ebrahimi     fprintf(stderr, "** Warning: JIT support is not available: "
9234*22dc650dSSadaf Ebrahimi                     "-jit[fast|verify] calls functions that do nothing.\n");
9235*22dc650dSSadaf Ebrahimi #endif
9236*22dc650dSSadaf Ebrahimi     }
9237*22dc650dSSadaf Ebrahimi 
9238*22dc650dSSadaf Ebrahimi   /* Set timing parameters */
9239*22dc650dSSadaf Ebrahimi 
9240*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-t") == 0 || strcmp(arg, "-tm") == 0 ||
9241*22dc650dSSadaf Ebrahimi            strcmp(arg, "-T") == 0 || strcmp(arg, "-TM") == 0)
9242*22dc650dSSadaf Ebrahimi     {
9243*22dc650dSSadaf Ebrahimi     int both = arg[2] == 0;
9244*22dc650dSSadaf Ebrahimi     showtotaltimes = arg[1] == 'T';
9245*22dc650dSSadaf Ebrahimi     if (argc > 2 && (uli = strtoul(argv[op+1], &endptr, 10), *endptr == 0))
9246*22dc650dSSadaf Ebrahimi       {
9247*22dc650dSSadaf Ebrahimi       if (uli == 0)
9248*22dc650dSSadaf Ebrahimi         {
9249*22dc650dSSadaf Ebrahimi         fprintf(stderr, "** Argument for %s must not be zero\n", arg);
9250*22dc650dSSadaf Ebrahimi         exit(1);
9251*22dc650dSSadaf Ebrahimi         }
9252*22dc650dSSadaf Ebrahimi       if (U32OVERFLOW(uli))
9253*22dc650dSSadaf Ebrahimi         {
9254*22dc650dSSadaf Ebrahimi         fprintf(stderr, "** Argument for %s is too big\n", arg);
9255*22dc650dSSadaf Ebrahimi         exit(1);
9256*22dc650dSSadaf Ebrahimi         }
9257*22dc650dSSadaf Ebrahimi       timeitm = (int)uli;
9258*22dc650dSSadaf Ebrahimi       op++;
9259*22dc650dSSadaf Ebrahimi       argc--;
9260*22dc650dSSadaf Ebrahimi       }
9261*22dc650dSSadaf Ebrahimi     else timeitm = LOOPREPEAT;
9262*22dc650dSSadaf Ebrahimi     if (both) timeit = timeitm;
9263*22dc650dSSadaf Ebrahimi     }
9264*22dc650dSSadaf Ebrahimi 
9265*22dc650dSSadaf Ebrahimi   /* Give help */
9266*22dc650dSSadaf Ebrahimi 
9267*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-help") == 0 ||
9268*22dc650dSSadaf Ebrahimi            strcmp(arg, "--help") == 0)
9269*22dc650dSSadaf Ebrahimi     {
9270*22dc650dSSadaf Ebrahimi     usage();
9271*22dc650dSSadaf Ebrahimi     goto EXIT;
9272*22dc650dSSadaf Ebrahimi     }
9273*22dc650dSSadaf Ebrahimi 
9274*22dc650dSSadaf Ebrahimi   /* Show version */
9275*22dc650dSSadaf Ebrahimi 
9276*22dc650dSSadaf Ebrahimi   else if (memcmp(arg, "-v", 2) == 0 ||
9277*22dc650dSSadaf Ebrahimi            strcmp(arg, "--version") == 0)
9278*22dc650dSSadaf Ebrahimi     {
9279*22dc650dSSadaf Ebrahimi     print_version(stdout, FALSE);
9280*22dc650dSSadaf Ebrahimi     goto EXIT;
9281*22dc650dSSadaf Ebrahimi     }
9282*22dc650dSSadaf Ebrahimi 
9283*22dc650dSSadaf Ebrahimi   /* The following options save their data for processing once we know what
9284*22dc650dSSadaf Ebrahimi   the running mode is. */
9285*22dc650dSSadaf Ebrahimi 
9286*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-error") == 0)
9287*22dc650dSSadaf Ebrahimi     {
9288*22dc650dSSadaf Ebrahimi     arg_error = argv[op+1];
9289*22dc650dSSadaf Ebrahimi     goto CHECK_VALUE_EXISTS;
9290*22dc650dSSadaf Ebrahimi     }
9291*22dc650dSSadaf Ebrahimi 
9292*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-subject") == 0)
9293*22dc650dSSadaf Ebrahimi     {
9294*22dc650dSSadaf Ebrahimi     arg_subject = argv[op+1];
9295*22dc650dSSadaf Ebrahimi     goto CHECK_VALUE_EXISTS;
9296*22dc650dSSadaf Ebrahimi     }
9297*22dc650dSSadaf Ebrahimi 
9298*22dc650dSSadaf Ebrahimi   else if (strcmp(arg, "-pattern") == 0)
9299*22dc650dSSadaf Ebrahimi     {
9300*22dc650dSSadaf Ebrahimi     arg_pattern = argv[op+1];
9301*22dc650dSSadaf Ebrahimi     CHECK_VALUE_EXISTS:
9302*22dc650dSSadaf Ebrahimi     if (argc <= 2)
9303*22dc650dSSadaf Ebrahimi       {
9304*22dc650dSSadaf Ebrahimi       fprintf(stderr, "** Missing value for %s\n", arg);
9305*22dc650dSSadaf Ebrahimi       yield = 1;
9306*22dc650dSSadaf Ebrahimi       goto EXIT;
9307*22dc650dSSadaf Ebrahimi       }
9308*22dc650dSSadaf Ebrahimi     op++;
9309*22dc650dSSadaf Ebrahimi     argc--;
9310*22dc650dSSadaf Ebrahimi     }
9311*22dc650dSSadaf Ebrahimi 
9312*22dc650dSSadaf Ebrahimi   /* Unrecognized option */
9313*22dc650dSSadaf Ebrahimi 
9314*22dc650dSSadaf Ebrahimi   else
9315*22dc650dSSadaf Ebrahimi     {
9316*22dc650dSSadaf Ebrahimi     fprintf(stderr, "** Unknown or malformed option '%s'\n", arg);
9317*22dc650dSSadaf Ebrahimi     usage();
9318*22dc650dSSadaf Ebrahimi     yield = 1;
9319*22dc650dSSadaf Ebrahimi     goto EXIT;
9320*22dc650dSSadaf Ebrahimi     }
9321*22dc650dSSadaf Ebrahimi   op++;
9322*22dc650dSSadaf Ebrahimi   argc--;
9323*22dc650dSSadaf Ebrahimi   }
9324*22dc650dSSadaf Ebrahimi 
9325*22dc650dSSadaf Ebrahimi /* If -error was present, get the error numbers, show the messages, and exit.
9326*22dc650dSSadaf Ebrahimi We wait to do this until we know which mode we are in. */
9327*22dc650dSSadaf Ebrahimi 
9328*22dc650dSSadaf Ebrahimi if (arg_error != NULL)
9329*22dc650dSSadaf Ebrahimi   {
9330*22dc650dSSadaf Ebrahimi   int len;
9331*22dc650dSSadaf Ebrahimi   int errcode;
9332*22dc650dSSadaf Ebrahimi   char *endptr;
9333*22dc650dSSadaf Ebrahimi 
9334*22dc650dSSadaf Ebrahimi /* Ensure the relevant non-8-bit buffer is available. Ensure that it is at
9335*22dc650dSSadaf Ebrahimi least 128 code units, because it is used for retrieving error messages. */
9336*22dc650dSSadaf Ebrahimi 
9337*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
9338*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE16_MODE)
9339*22dc650dSSadaf Ebrahimi     {
9340*22dc650dSSadaf Ebrahimi     pbuffer16_size = 256;
9341*22dc650dSSadaf Ebrahimi     pbuffer16 = (uint16_t *)malloc(pbuffer16_size);
9342*22dc650dSSadaf Ebrahimi     if (pbuffer16 == NULL)
9343*22dc650dSSadaf Ebrahimi       {
9344*22dc650dSSadaf Ebrahimi       fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer16\n",
9345*22dc650dSSadaf Ebrahimi         pbuffer16_size);
9346*22dc650dSSadaf Ebrahimi       yield = 1;
9347*22dc650dSSadaf Ebrahimi       goto EXIT;
9348*22dc650dSSadaf Ebrahimi       }
9349*22dc650dSSadaf Ebrahimi     }
9350*22dc650dSSadaf Ebrahimi #endif
9351*22dc650dSSadaf Ebrahimi 
9352*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
9353*22dc650dSSadaf Ebrahimi   if (test_mode == PCRE32_MODE)
9354*22dc650dSSadaf Ebrahimi     {
9355*22dc650dSSadaf Ebrahimi     pbuffer32_size = 512;
9356*22dc650dSSadaf Ebrahimi     pbuffer32 = (uint32_t *)malloc(pbuffer32_size);
9357*22dc650dSSadaf Ebrahimi     if (pbuffer32 == NULL)
9358*22dc650dSSadaf Ebrahimi       {
9359*22dc650dSSadaf Ebrahimi       fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer32\n",
9360*22dc650dSSadaf Ebrahimi         pbuffer32_size);
9361*22dc650dSSadaf Ebrahimi       yield = 1;
9362*22dc650dSSadaf Ebrahimi       goto EXIT;
9363*22dc650dSSadaf Ebrahimi       }
9364*22dc650dSSadaf Ebrahimi     }
9365*22dc650dSSadaf Ebrahimi #endif
9366*22dc650dSSadaf Ebrahimi 
9367*22dc650dSSadaf Ebrahimi   /* Loop along a list of error numbers. */
9368*22dc650dSSadaf Ebrahimi 
9369*22dc650dSSadaf Ebrahimi   for (;;)
9370*22dc650dSSadaf Ebrahimi     {
9371*22dc650dSSadaf Ebrahimi     errcode = strtol(arg_error, &endptr, 10);
9372*22dc650dSSadaf Ebrahimi     if (*endptr != 0 && *endptr != CHAR_COMMA)
9373*22dc650dSSadaf Ebrahimi       {
9374*22dc650dSSadaf Ebrahimi       fprintf(stderr, "** '%s' is not a valid error number list\n", arg_error);
9375*22dc650dSSadaf Ebrahimi       yield = 1;
9376*22dc650dSSadaf Ebrahimi       goto EXIT;
9377*22dc650dSSadaf Ebrahimi       }
9378*22dc650dSSadaf Ebrahimi     printf("Error %d: ", errcode);
9379*22dc650dSSadaf Ebrahimi     PCRE2_GET_ERROR_MESSAGE(len, errcode, pbuffer);
9380*22dc650dSSadaf Ebrahimi     if (len < 0)
9381*22dc650dSSadaf Ebrahimi       {
9382*22dc650dSSadaf Ebrahimi       switch (len)
9383*22dc650dSSadaf Ebrahimi         {
9384*22dc650dSSadaf Ebrahimi         case PCRE2_ERROR_BADDATA:
9385*22dc650dSSadaf Ebrahimi         printf("PCRE2_ERROR_BADDATA (unknown error number)");
9386*22dc650dSSadaf Ebrahimi         break;
9387*22dc650dSSadaf Ebrahimi 
9388*22dc650dSSadaf Ebrahimi         case PCRE2_ERROR_NOMEMORY:
9389*22dc650dSSadaf Ebrahimi         printf("PCRE2_ERROR_NOMEMORY (buffer too small)");
9390*22dc650dSSadaf Ebrahimi         break;
9391*22dc650dSSadaf Ebrahimi 
9392*22dc650dSSadaf Ebrahimi         default:
9393*22dc650dSSadaf Ebrahimi         printf("Unexpected return (%d) from pcre2_get_error_message()", len);
9394*22dc650dSSadaf Ebrahimi         break;
9395*22dc650dSSadaf Ebrahimi         }
9396*22dc650dSSadaf Ebrahimi       }
9397*22dc650dSSadaf Ebrahimi     else
9398*22dc650dSSadaf Ebrahimi       {
9399*22dc650dSSadaf Ebrahimi       PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, stdout);
9400*22dc650dSSadaf Ebrahimi       }
9401*22dc650dSSadaf Ebrahimi     printf("\n");
9402*22dc650dSSadaf Ebrahimi     if (*endptr == 0) goto EXIT;
9403*22dc650dSSadaf Ebrahimi     arg_error = endptr + 1;
9404*22dc650dSSadaf Ebrahimi     }
9405*22dc650dSSadaf Ebrahimi   /* Control never reaches here */
9406*22dc650dSSadaf Ebrahimi   }  /* End of -error handling */
9407*22dc650dSSadaf Ebrahimi 
9408*22dc650dSSadaf Ebrahimi /* Initialize things that cannot be done until we know which test mode we are
9409*22dc650dSSadaf Ebrahimi running in. Exercise the general context copying and match data size functions,
9410*22dc650dSSadaf Ebrahimi which are not otherwise used. */
9411*22dc650dSSadaf Ebrahimi 
9412*22dc650dSSadaf Ebrahimi code_unit_size = test_mode/8;
9413*22dc650dSSadaf Ebrahimi max_oveccount = DEFAULT_OVECCOUNT;
9414*22dc650dSSadaf Ebrahimi 
9415*22dc650dSSadaf Ebrahimi /* Use macros to save a lot of duplication. */
9416*22dc650dSSadaf Ebrahimi 
9417*22dc650dSSadaf Ebrahimi #define CREATECONTEXTS \
9418*22dc650dSSadaf Ebrahimi   G(general_context,BITS) = G(pcre2_general_context_create_,BITS)(&my_malloc, &my_free, NULL); \
9419*22dc650dSSadaf Ebrahimi   G(general_context_copy,BITS) = G(pcre2_general_context_copy_,BITS)(G(general_context,BITS)); \
9420*22dc650dSSadaf Ebrahimi   G(default_pat_context,BITS) = G(pcre2_compile_context_create_,BITS)(G(general_context,BITS)); \
9421*22dc650dSSadaf Ebrahimi   G(pat_context,BITS) = G(pcre2_compile_context_copy_,BITS)(G(default_pat_context,BITS)); \
9422*22dc650dSSadaf Ebrahimi   G(default_dat_context,BITS) = G(pcre2_match_context_create_,BITS)(G(general_context,BITS)); \
9423*22dc650dSSadaf Ebrahimi   G(dat_context,BITS) = G(pcre2_match_context_copy_,BITS)(G(default_dat_context,BITS)); \
9424*22dc650dSSadaf Ebrahimi   G(default_con_context,BITS) = G(pcre2_convert_context_create_,BITS)(G(general_context,BITS)); \
9425*22dc650dSSadaf Ebrahimi   G(con_context,BITS) = G(pcre2_convert_context_copy_,BITS)(G(default_con_context,BITS)); \
9426*22dc650dSSadaf Ebrahimi   G(match_data,BITS) = G(pcre2_match_data_create_,BITS)(max_oveccount, G(general_context,BITS))
9427*22dc650dSSadaf Ebrahimi 
9428*22dc650dSSadaf Ebrahimi #define CONTEXTTESTS \
9429*22dc650dSSadaf Ebrahimi   (void)G(pcre2_set_compile_extra_options_,BITS)(G(pat_context,BITS), 0); \
9430*22dc650dSSadaf Ebrahimi   (void)G(pcre2_set_max_pattern_length_,BITS)(G(pat_context,BITS), 0); \
9431*22dc650dSSadaf Ebrahimi   (void)G(pcre2_set_max_pattern_compiled_length_,BITS)(G(pat_context,BITS), 0); \
9432*22dc650dSSadaf Ebrahimi   (void)G(pcre2_set_max_varlookbehind_,BITS)(G(pat_context,BITS), 0); \
9433*22dc650dSSadaf Ebrahimi   (void)G(pcre2_set_offset_limit_,BITS)(G(dat_context,BITS), 0); \
9434*22dc650dSSadaf Ebrahimi   (void)G(pcre2_get_match_data_size_,BITS)(G(match_data,BITS))
9435*22dc650dSSadaf Ebrahimi 
9436*22dc650dSSadaf Ebrahimi /* Call the appropriate functions for the current mode, and exercise some
9437*22dc650dSSadaf Ebrahimi functions that are not otherwise called. */
9438*22dc650dSSadaf Ebrahimi 
9439*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
9440*22dc650dSSadaf Ebrahimi #undef BITS
9441*22dc650dSSadaf Ebrahimi #define BITS 8
9442*22dc650dSSadaf Ebrahimi if (test_mode == PCRE8_MODE)
9443*22dc650dSSadaf Ebrahimi   {
9444*22dc650dSSadaf Ebrahimi   CREATECONTEXTS;
9445*22dc650dSSadaf Ebrahimi   CONTEXTTESTS;
9446*22dc650dSSadaf Ebrahimi   }
9447*22dc650dSSadaf Ebrahimi #endif
9448*22dc650dSSadaf Ebrahimi 
9449*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
9450*22dc650dSSadaf Ebrahimi #undef BITS
9451*22dc650dSSadaf Ebrahimi #define BITS 16
9452*22dc650dSSadaf Ebrahimi if (test_mode == PCRE16_MODE)
9453*22dc650dSSadaf Ebrahimi   {
9454*22dc650dSSadaf Ebrahimi   CREATECONTEXTS;
9455*22dc650dSSadaf Ebrahimi   CONTEXTTESTS;
9456*22dc650dSSadaf Ebrahimi   }
9457*22dc650dSSadaf Ebrahimi #endif
9458*22dc650dSSadaf Ebrahimi 
9459*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
9460*22dc650dSSadaf Ebrahimi #undef BITS
9461*22dc650dSSadaf Ebrahimi #define BITS 32
9462*22dc650dSSadaf Ebrahimi if (test_mode == PCRE32_MODE)
9463*22dc650dSSadaf Ebrahimi   {
9464*22dc650dSSadaf Ebrahimi   CREATECONTEXTS;
9465*22dc650dSSadaf Ebrahimi   CONTEXTTESTS;
9466*22dc650dSSadaf Ebrahimi   }
9467*22dc650dSSadaf Ebrahimi #endif
9468*22dc650dSSadaf Ebrahimi 
9469*22dc650dSSadaf Ebrahimi /* Set a default parentheses nest limit that is large enough to run the
9470*22dc650dSSadaf Ebrahimi standard tests (this also exercises the function). */
9471*22dc650dSSadaf Ebrahimi 
9472*22dc650dSSadaf Ebrahimi PCRE2_SET_PARENS_NEST_LIMIT(default_pat_context, PARENS_NEST_DEFAULT);
9473*22dc650dSSadaf Ebrahimi 
9474*22dc650dSSadaf Ebrahimi /* Handle command line modifier settings, sending any error messages to
9475*22dc650dSSadaf Ebrahimi stderr. We need to know the mode before modifying the context, and it is tidier
9476*22dc650dSSadaf Ebrahimi to do them all in the same way. */
9477*22dc650dSSadaf Ebrahimi 
9478*22dc650dSSadaf Ebrahimi outfile = stderr;
9479*22dc650dSSadaf Ebrahimi if ((arg_pattern != NULL &&
9480*22dc650dSSadaf Ebrahimi     !decode_modifiers((uint8_t *)arg_pattern, CTX_DEFPAT, &def_patctl, NULL)) ||
9481*22dc650dSSadaf Ebrahimi     (arg_subject != NULL &&
9482*22dc650dSSadaf Ebrahimi     !decode_modifiers((uint8_t *)arg_subject, CTX_DEFDAT, NULL, &def_datctl)))
9483*22dc650dSSadaf Ebrahimi   {
9484*22dc650dSSadaf Ebrahimi   yield = 1;
9485*22dc650dSSadaf Ebrahimi   goto EXIT;
9486*22dc650dSSadaf Ebrahimi   }
9487*22dc650dSSadaf Ebrahimi 
9488*22dc650dSSadaf Ebrahimi /* Sort out the input and output files, defaulting to stdin/stdout. */
9489*22dc650dSSadaf Ebrahimi 
9490*22dc650dSSadaf Ebrahimi infile = stdin;
9491*22dc650dSSadaf Ebrahimi outfile = stdout;
9492*22dc650dSSadaf Ebrahimi 
9493*22dc650dSSadaf Ebrahimi if (argc > 1 && strcmp(argv[op], "-") != 0)
9494*22dc650dSSadaf Ebrahimi   {
9495*22dc650dSSadaf Ebrahimi   infile = fopen(argv[op], INPUT_MODE);
9496*22dc650dSSadaf Ebrahimi   if (infile == NULL)
9497*22dc650dSSadaf Ebrahimi     {
9498*22dc650dSSadaf Ebrahimi     printf("** Failed to open '%s': %s\n", argv[op], strerror(errno));
9499*22dc650dSSadaf Ebrahimi     yield = 1;
9500*22dc650dSSadaf Ebrahimi     goto EXIT;
9501*22dc650dSSadaf Ebrahimi     }
9502*22dc650dSSadaf Ebrahimi   }
9503*22dc650dSSadaf Ebrahimi 
9504*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
9505*22dc650dSSadaf Ebrahimi if (INTERACTIVE(infile)) using_history();
9506*22dc650dSSadaf Ebrahimi #endif
9507*22dc650dSSadaf Ebrahimi 
9508*22dc650dSSadaf Ebrahimi if (argc > 2)
9509*22dc650dSSadaf Ebrahimi   {
9510*22dc650dSSadaf Ebrahimi   outfile = fopen(argv[op+1], OUTPUT_MODE);
9511*22dc650dSSadaf Ebrahimi   if (outfile == NULL)
9512*22dc650dSSadaf Ebrahimi     {
9513*22dc650dSSadaf Ebrahimi     printf("** Failed to open '%s': %s\n", argv[op+1], strerror(errno));
9514*22dc650dSSadaf Ebrahimi     yield = 1;
9515*22dc650dSSadaf Ebrahimi     goto EXIT;
9516*22dc650dSSadaf Ebrahimi     }
9517*22dc650dSSadaf Ebrahimi   }
9518*22dc650dSSadaf Ebrahimi 
9519*22dc650dSSadaf Ebrahimi /* Output a heading line unless quiet, then process input lines. */
9520*22dc650dSSadaf Ebrahimi 
9521*22dc650dSSadaf Ebrahimi if (!quiet) print_version(outfile, TRUE);
9522*22dc650dSSadaf Ebrahimi 
9523*22dc650dSSadaf Ebrahimi SET(compiled_code, NULL);
9524*22dc650dSSadaf Ebrahimi 
9525*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
9526*22dc650dSSadaf Ebrahimi preg.re_pcre2_code = NULL;
9527*22dc650dSSadaf Ebrahimi preg.re_match_data = NULL;
9528*22dc650dSSadaf Ebrahimi #endif
9529*22dc650dSSadaf Ebrahimi 
9530*22dc650dSSadaf Ebrahimi while (notdone)
9531*22dc650dSSadaf Ebrahimi   {
9532*22dc650dSSadaf Ebrahimi   uint8_t *p;
9533*22dc650dSSadaf Ebrahimi   int rc = PR_OK;
9534*22dc650dSSadaf Ebrahimi   BOOL expectdata = TEST(compiled_code, !=, NULL);
9535*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
9536*22dc650dSSadaf Ebrahimi   expectdata |= preg.re_pcre2_code != NULL;
9537*22dc650dSSadaf Ebrahimi #endif
9538*22dc650dSSadaf Ebrahimi 
9539*22dc650dSSadaf Ebrahimi   if (extend_inputline(infile, buffer, expectdata? "data> " : "  re> ") == NULL)
9540*22dc650dSSadaf Ebrahimi     break;
9541*22dc650dSSadaf Ebrahimi   if (!INTERACTIVE(infile)) fprintf(outfile, "%s", (char *)buffer);
9542*22dc650dSSadaf Ebrahimi   fflush(outfile);
9543*22dc650dSSadaf Ebrahimi   p = buffer;
9544*22dc650dSSadaf Ebrahimi 
9545*22dc650dSSadaf Ebrahimi   /* If we have a pattern set up for testing, or we are skipping after a
9546*22dc650dSSadaf Ebrahimi   compile failure, a blank line terminates this test. */
9547*22dc650dSSadaf Ebrahimi 
9548*22dc650dSSadaf Ebrahimi   if (expectdata || skipping)
9549*22dc650dSSadaf Ebrahimi     {
9550*22dc650dSSadaf Ebrahimi     while (isspace(*p)) p++;
9551*22dc650dSSadaf Ebrahimi     if (*p == 0)
9552*22dc650dSSadaf Ebrahimi       {
9553*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
9554*22dc650dSSadaf Ebrahimi       if (preg.re_pcre2_code != NULL)
9555*22dc650dSSadaf Ebrahimi         {
9556*22dc650dSSadaf Ebrahimi         regfree(&preg);
9557*22dc650dSSadaf Ebrahimi         preg.re_pcre2_code = NULL;
9558*22dc650dSSadaf Ebrahimi         preg.re_match_data = NULL;
9559*22dc650dSSadaf Ebrahimi         }
9560*22dc650dSSadaf Ebrahimi #endif  /* SUPPORT_PCRE2_8 */
9561*22dc650dSSadaf Ebrahimi       if (TEST(compiled_code, !=, NULL))
9562*22dc650dSSadaf Ebrahimi         {
9563*22dc650dSSadaf Ebrahimi         SUB1(pcre2_code_free, compiled_code);
9564*22dc650dSSadaf Ebrahimi         SET(compiled_code, NULL);
9565*22dc650dSSadaf Ebrahimi         }
9566*22dc650dSSadaf Ebrahimi       skipping = FALSE;
9567*22dc650dSSadaf Ebrahimi       setlocale(LC_CTYPE, "C");
9568*22dc650dSSadaf Ebrahimi       }
9569*22dc650dSSadaf Ebrahimi 
9570*22dc650dSSadaf Ebrahimi     /* Otherwise, if we are not skipping, and the line is not a data comment
9571*22dc650dSSadaf Ebrahimi     line starting with "\=", process a data line. */
9572*22dc650dSSadaf Ebrahimi 
9573*22dc650dSSadaf Ebrahimi     else if (!skipping && !(p[0] == '\\' && p[1] == '=' && isspace(p[2])))
9574*22dc650dSSadaf Ebrahimi       {
9575*22dc650dSSadaf Ebrahimi       rc = process_data();
9576*22dc650dSSadaf Ebrahimi       }
9577*22dc650dSSadaf Ebrahimi     }
9578*22dc650dSSadaf Ebrahimi 
9579*22dc650dSSadaf Ebrahimi   /* We do not have a pattern set up for testing. Lines starting with # are
9580*22dc650dSSadaf Ebrahimi   either comments or special commands. Blank lines are ignored. Otherwise, the
9581*22dc650dSSadaf Ebrahimi   line must start with a valid delimiter. It is then processed as a pattern
9582*22dc650dSSadaf Ebrahimi   line. A copy of the pattern is left in pbuffer8 for use by callouts. Under
9583*22dc650dSSadaf Ebrahimi   valgrind, make the unused part of the buffer undefined, to catch overruns. */
9584*22dc650dSSadaf Ebrahimi 
9585*22dc650dSSadaf Ebrahimi   else if (*p == '#')
9586*22dc650dSSadaf Ebrahimi     {
9587*22dc650dSSadaf Ebrahimi     if (isspace(p[1]) || p[1] == '!' || p[1] == 0) continue;
9588*22dc650dSSadaf Ebrahimi     rc = process_command();
9589*22dc650dSSadaf Ebrahimi     }
9590*22dc650dSSadaf Ebrahimi 
9591*22dc650dSSadaf Ebrahimi   else if (strchr("/!\"'`%&-=_:;,@~", *p) != NULL)
9592*22dc650dSSadaf Ebrahimi     {
9593*22dc650dSSadaf Ebrahimi     rc = process_pattern();
9594*22dc650dSSadaf Ebrahimi     dfa_matched = 0;
9595*22dc650dSSadaf Ebrahimi     }
9596*22dc650dSSadaf Ebrahimi 
9597*22dc650dSSadaf Ebrahimi   else
9598*22dc650dSSadaf Ebrahimi     {
9599*22dc650dSSadaf Ebrahimi     while (isspace(*p)) p++;
9600*22dc650dSSadaf Ebrahimi     if (*p != 0)
9601*22dc650dSSadaf Ebrahimi       {
9602*22dc650dSSadaf Ebrahimi       fprintf(outfile, "** Invalid pattern delimiter '%c' (x%x).\n", *buffer,
9603*22dc650dSSadaf Ebrahimi         *buffer);
9604*22dc650dSSadaf Ebrahimi       rc = PR_SKIP;
9605*22dc650dSSadaf Ebrahimi       }
9606*22dc650dSSadaf Ebrahimi     }
9607*22dc650dSSadaf Ebrahimi 
9608*22dc650dSSadaf Ebrahimi   if (rc == PR_SKIP && !INTERACTIVE(infile)) skipping = TRUE;
9609*22dc650dSSadaf Ebrahimi   else if (rc == PR_ABEND)
9610*22dc650dSSadaf Ebrahimi     {
9611*22dc650dSSadaf Ebrahimi     fprintf(outfile, "** pcre2test run abandoned\n");
9612*22dc650dSSadaf Ebrahimi     yield = 1;
9613*22dc650dSSadaf Ebrahimi     goto EXIT;
9614*22dc650dSSadaf Ebrahimi     }
9615*22dc650dSSadaf Ebrahimi   }
9616*22dc650dSSadaf Ebrahimi 
9617*22dc650dSSadaf Ebrahimi /* Finish off a normal run. */
9618*22dc650dSSadaf Ebrahimi 
9619*22dc650dSSadaf Ebrahimi if (INTERACTIVE(infile)) fprintf(outfile, "\n");
9620*22dc650dSSadaf Ebrahimi 
9621*22dc650dSSadaf Ebrahimi if (showtotaltimes)
9622*22dc650dSSadaf Ebrahimi   {
9623*22dc650dSSadaf Ebrahimi   const char *pad = "";
9624*22dc650dSSadaf Ebrahimi   fprintf(outfile, "--------------------------------------\n");
9625*22dc650dSSadaf Ebrahimi   if (timeit > 0)
9626*22dc650dSSadaf Ebrahimi     {
9627*22dc650dSSadaf Ebrahimi     fprintf(outfile, "Total compile time %8.2f microseconds\n",
9628*22dc650dSSadaf Ebrahimi       ((1000000 / CLOCKS_PER_SEC) * (double)total_compile_time) / timeit);
9629*22dc650dSSadaf Ebrahimi     if (total_jit_compile_time > 0)
9630*22dc650dSSadaf Ebrahimi       fprintf(outfile, "Total JIT compile  %8.2f microseconds\n",
9631*22dc650dSSadaf Ebrahimi         ((1000000 / CLOCKS_PER_SEC) * (double)total_jit_compile_time) / \
9632*22dc650dSSadaf Ebrahimi         timeit);
9633*22dc650dSSadaf Ebrahimi     pad = "  ";
9634*22dc650dSSadaf Ebrahimi     }
9635*22dc650dSSadaf Ebrahimi   fprintf(outfile, "Total match time %s%8.2f microseconds\n", pad,
9636*22dc650dSSadaf Ebrahimi     ((1000000 / CLOCKS_PER_SEC) * (double)total_match_time) / timeitm);
9637*22dc650dSSadaf Ebrahimi   }
9638*22dc650dSSadaf Ebrahimi 
9639*22dc650dSSadaf Ebrahimi 
9640*22dc650dSSadaf Ebrahimi EXIT:
9641*22dc650dSSadaf Ebrahimi 
9642*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
9643*22dc650dSSadaf Ebrahimi if (infile != NULL && INTERACTIVE(infile)) clear_history();
9644*22dc650dSSadaf Ebrahimi #endif
9645*22dc650dSSadaf Ebrahimi 
9646*22dc650dSSadaf Ebrahimi if (infile != NULL && infile != stdin) fclose(infile);
9647*22dc650dSSadaf Ebrahimi if (outfile != NULL && outfile != stdout) fclose(outfile);
9648*22dc650dSSadaf Ebrahimi 
9649*22dc650dSSadaf Ebrahimi free(buffer);
9650*22dc650dSSadaf Ebrahimi free(dbuffer);
9651*22dc650dSSadaf Ebrahimi free(pbuffer8);
9652*22dc650dSSadaf Ebrahimi free(dfa_workspace);
9653*22dc650dSSadaf Ebrahimi free(tables3);
9654*22dc650dSSadaf Ebrahimi PCRE2_MAKETABLES_FREE(general_context, (void *)locale_tables);
9655*22dc650dSSadaf Ebrahimi PCRE2_MATCH_DATA_FREE(match_data);
9656*22dc650dSSadaf Ebrahimi SUB1(pcre2_code_free, compiled_code);
9657*22dc650dSSadaf Ebrahimi 
9658*22dc650dSSadaf Ebrahimi while(patstacknext-- > 0)
9659*22dc650dSSadaf Ebrahimi   {
9660*22dc650dSSadaf Ebrahimi   SET(compiled_code, patstack[patstacknext]);
9661*22dc650dSSadaf Ebrahimi   SUB1(pcre2_code_free, compiled_code);
9662*22dc650dSSadaf Ebrahimi   }
9663*22dc650dSSadaf Ebrahimi 
9664*22dc650dSSadaf Ebrahimi PCRE2_JIT_FREE_UNUSED_MEMORY(general_context);
9665*22dc650dSSadaf Ebrahimi if (jit_stack != NULL)
9666*22dc650dSSadaf Ebrahimi   {
9667*22dc650dSSadaf Ebrahimi   PCRE2_JIT_STACK_FREE(jit_stack);
9668*22dc650dSSadaf Ebrahimi   }
9669*22dc650dSSadaf Ebrahimi 
9670*22dc650dSSadaf Ebrahimi #define FREECONTEXTS \
9671*22dc650dSSadaf Ebrahimi   G(pcre2_general_context_free_,BITS)(G(general_context,BITS)); \
9672*22dc650dSSadaf Ebrahimi   G(pcre2_general_context_free_,BITS)(G(general_context_copy,BITS)); \
9673*22dc650dSSadaf Ebrahimi   G(pcre2_compile_context_free_,BITS)(G(pat_context,BITS)); \
9674*22dc650dSSadaf Ebrahimi   G(pcre2_compile_context_free_,BITS)(G(default_pat_context,BITS)); \
9675*22dc650dSSadaf Ebrahimi   G(pcre2_match_context_free_,BITS)(G(dat_context,BITS)); \
9676*22dc650dSSadaf Ebrahimi   G(pcre2_match_context_free_,BITS)(G(default_dat_context,BITS)); \
9677*22dc650dSSadaf Ebrahimi   G(pcre2_convert_context_free_,BITS)(G(default_con_context,BITS)); \
9678*22dc650dSSadaf Ebrahimi   G(pcre2_convert_context_free_,BITS)(G(con_context,BITS));
9679*22dc650dSSadaf Ebrahimi 
9680*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_8
9681*22dc650dSSadaf Ebrahimi #undef BITS
9682*22dc650dSSadaf Ebrahimi #define BITS 8
9683*22dc650dSSadaf Ebrahimi if (preg.re_pcre2_code != NULL) regfree(&preg);
9684*22dc650dSSadaf Ebrahimi FREECONTEXTS;
9685*22dc650dSSadaf Ebrahimi #endif
9686*22dc650dSSadaf Ebrahimi 
9687*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_16
9688*22dc650dSSadaf Ebrahimi #undef BITS
9689*22dc650dSSadaf Ebrahimi #define BITS 16
9690*22dc650dSSadaf Ebrahimi free(pbuffer16);
9691*22dc650dSSadaf Ebrahimi FREECONTEXTS;
9692*22dc650dSSadaf Ebrahimi #endif
9693*22dc650dSSadaf Ebrahimi 
9694*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_PCRE2_32
9695*22dc650dSSadaf Ebrahimi #undef BITS
9696*22dc650dSSadaf Ebrahimi #define BITS 32
9697*22dc650dSSadaf Ebrahimi free(pbuffer32);
9698*22dc650dSSadaf Ebrahimi FREECONTEXTS;
9699*22dc650dSSadaf Ebrahimi #endif
9700*22dc650dSSadaf Ebrahimi 
9701*22dc650dSSadaf Ebrahimi #if defined(__VMS)
9702*22dc650dSSadaf Ebrahimi   yield = SS$_NORMAL;  /* Return values via DCL symbols */
9703*22dc650dSSadaf Ebrahimi #endif
9704*22dc650dSSadaf Ebrahimi 
9705*22dc650dSSadaf Ebrahimi return yield;
9706*22dc650dSSadaf Ebrahimi }
9707*22dc650dSSadaf Ebrahimi 
9708*22dc650dSSadaf Ebrahimi /* End of pcre2test.c */
9709