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

Contents of /code/trunk/pcretest.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 558 - (hide annotations) (download)
Tue Oct 26 15:26:45 2010 UTC (2 years, 6 months ago) by ph10
File MIME type: text/plain
File size: 87035 byte(s)
Fix missing code for missing strtoul() and strerror(). 

1 nigel 3 /*************************************************
2     * PCRE testing program *
3     *************************************************/
4    
5 nigel 63 /* This program was hacked up as a tester for PCRE. I really should have
6     written it more tidily in the first place. Will I ever learn? It has grown and
7 nigel 77 been extended and consequently is now rather, er, *very* untidy in places.
8 nigel 63
9 nigel 75 -----------------------------------------------------------------------------
10     Redistribution and use in source and binary forms, with or without
11     modification, are permitted provided that the following conditions are met:
12    
13     * Redistributions of source code must retain the above copyright notice,
14     this list of conditions and the following disclaimer.
15    
16     * Redistributions in binary form must reproduce the above copyright
17     notice, this list of conditions and the following disclaimer in the
18     documentation and/or other materials provided with the distribution.
19    
20     * Neither the name of the University of Cambridge nor the names of its
21     contributors may be used to endorse or promote products derived from
22     this software without specific prior written permission.
23    
24     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27     ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34     POSSIBILITY OF SUCH DAMAGE.
35     -----------------------------------------------------------------------------
36     */
37    
38    
39 ph10 200 #ifdef HAVE_CONFIG_H
40 ph10 236 #include "config.h"
41 ph10 200 #endif
42 ph10 199
43 nigel 3 #include <ctype.h>
44     #include <stdio.h>
45     #include <string.h>
46     #include <stdlib.h>
47     #include <time.h>
48 nigel 25 #include <locale.h>
49 nigel 75 #include <errno.h>
50 nigel 3
51 ph10 287 #ifdef SUPPORT_LIBREADLINE
52 ph10 343 #ifdef HAVE_UNISTD_H
53 ph10 287 #include <unistd.h>
54 ph10 343 #endif
55 ph10 287 #include <readline/readline.h>
56     #include <readline/history.h>
57     #endif
58 nigel 93
59 ph10 287
60 nigel 93 /* A number of things vary for Windows builds. Originally, pcretest opened its
61     input and output without "b"; then I was told that "b" was needed in some
62     environments, so it was added for release 5.0 to both the input and output. (It
63     makes no difference on Unix-like systems.) Later I was told that it is wrong
64     for the input on Windows. I've now abstracted the modes into two macros that
65     are set here, to make it easier to fiddle with them, and removed "b" from the
66     input mode under Windows. */
67    
68     #if defined(_WIN32) || defined(WIN32)
69     #include <io.h> /* For _setmode() */
70     #include <fcntl.h> /* For _O_BINARY */
71     #define INPUT_MODE "r"
72     #define OUTPUT_MODE "wb"
73    
74 ph10 411 #ifndef isatty
75     #define isatty _isatty /* This is what Windows calls them, I'm told, */
76     #endif /* though in some environments they seem to */
77     /* be already defined, hence the #ifndefs. */
78     #ifndef fileno
79 ph10 343 #define fileno _fileno
80 ph10 411 #endif
81 ph10 343
82 nigel 93 #else
83     #include <sys/time.h> /* These two includes are needed */
84     #include <sys/resource.h> /* for setrlimit(). */
85     #define INPUT_MODE "rb"
86     #define OUTPUT_MODE "wb"
87 nigel 91 #endif
88    
89 nigel 93
90 ph10 145 /* We have to include pcre_internal.h because we need the internal info for
91     displaying the results of pcre_study() and we also need to know about the
92     internal macros, structures, and other internal data values; pcretest has
93     "inside information" compared to a program that strictly follows the PCRE API.
94 nigel 37
95 ph10 145 Although pcre_internal.h does itself include pcre.h, we explicitly include it
96     here before pcre_internal.h so that the PCRE_EXP_xxx macros get set
97     appropriately for an application, not for building PCRE. */
98 nigel 77
99 ph10 145 #include "pcre.h"
100 nigel 77 #include "pcre_internal.h"
101    
102 ph10 351 /* We need access to some of the data tables that PCRE uses. So as not to have
103     to keep two copies, we include the source file here, changing the names of the
104     external symbols to prevent clashes. */
105 nigel 77
106 ph10 351 #define _pcre_ucp_gentype ucp_gentype
107 nigel 85 #define _pcre_utf8_table1 utf8_table1
108     #define _pcre_utf8_table1_size utf8_table1_size
109     #define _pcre_utf8_table2 utf8_table2
110     #define _pcre_utf8_table3 utf8_table3
111     #define _pcre_utf8_table4 utf8_table4
112     #define _pcre_utt utt
113     #define _pcre_utt_size utt_size
114 ph10 240 #define _pcre_utt_names utt_names
115 nigel 85 #define _pcre_OP_lengths OP_lengths
116    
117     #include "pcre_tables.c"
118    
119     /* We also need the pcre_printint() function for printing out compiled
120     patterns. This function is in a separate file so that it can be included in
121 ph10 507 pcre_compile.c when that module is compiled with debugging enabled. It needs to
122 ph10 498 know which case is being compiled. */
123 nigel 85
124 ph10 498 #define COMPILING_PCRETEST
125     #include "pcre_printint.src"
126    
127     /* The definition of the macro PRINTABLE, which determines whether to print an
128 nigel 93 output character as-is or as a hex value when showing compiled patterns, is
129 ph10 498 contained in the printint.src file. We uses it here also, in cases when the
130     locale has not been explicitly changed, so as to get consistent output from
131     systems that differ in their output from isprint() even in the "C" locale. */
132 nigel 93
133     #define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c))
134 nigel 85
135 nigel 37 /* It is possible to compile this test program without including support for
136     testing the POSIX interface, though this is not available via the standard
137     Makefile. */
138    
139     #if !defined NOPOSIX
140 nigel 3 #include "pcreposix.h"
141 nigel 37 #endif
142 nigel 3
143 ph10 107 /* It is also possible, for the benefit of the version currently imported into
144     Exim, to build pcretest without support for UTF8 (define NOUTF8), without the
145     interface to the DFA matcher (NODFA), and without the doublecheck of the old
146     "info" function (define NOINFOCHECK). In fact, we automatically cut out the
147     UTF8 support if PCRE is built without it. */
148 nigel 79
149 ph10 107 #ifndef SUPPORT_UTF8
150     #ifndef NOUTF8
151     #define NOUTF8
152     #endif
153     #endif
154 nigel 79
155 ph10 107
156 nigel 85 /* Other parameters */
157    
158 nigel 3 #ifndef CLOCKS_PER_SEC
159     #ifdef CLK_TCK
160     #define CLOCKS_PER_SEC CLK_TCK
161     #else
162     #define CLOCKS_PER_SEC 100
163     #endif
164     #endif
165    
166 nigel 93 /* This is the default loop count for timing. */
167    
168 nigel 75 #define LOOPREPEAT 500000
169 nigel 3
170 nigel 85 /* Static variables */
171    
172 nigel 3 static FILE *outfile;
173     static int log_store = 0;
174 nigel 63 static int callout_count;
175     static int callout_extra;
176     static int callout_fail_count;
177     static int callout_fail_id;
178 ph10 210 static int debug_lengths;
179 nigel 63 static int first_callout;
180 nigel 93 static int locale_set = 0;
181 nigel 73 static int show_malloc;
182 nigel 67 static int use_utf8;
183 nigel 43 static size_t gotten_store;
184 nigel 3
185 nigel 91 /* The buffers grow automatically if very long input lines are encountered. */
186    
187     static int buffer_size = 50000;
188     static uschar *buffer = NULL;
189     static uschar *dbuffer = NULL;
190 nigel 75 static uschar *pbuffer = NULL;
191 nigel 3
192 nigel 75
193 ph10 541 /*************************************************
194     * Alternate character tables *
195     *************************************************/
196 nigel 49
197 ph10 545 /* By default, the "tables" pointer when calling PCRE is set to NULL, thereby
198     using the default tables of the library. However, the T option can be used to
199     select alternate sets of tables, for different kinds of testing. Note also that
200 ph10 541 the L (locale) option also adjusts the tables. */
201    
202 ph10 545 /* This is the set of tables distributed as default with PCRE. It recognizes
203 ph10 541 only ASCII characters. */
204    
205     static const unsigned char tables0[] = {
206    
207     /* This table is a lower casing table. */
208    
209     0, 1, 2, 3, 4, 5, 6, 7,
210     8, 9, 10, 11, 12, 13, 14, 15,
211     16, 17, 18, 19, 20, 21, 22, 23,
212     24, 25, 26, 27, 28, 29, 30, 31,
213     32, 33, 34, 35, 36, 37, 38, 39,
214     40, 41, 42, 43, 44, 45, 46, 47,
215     48, 49, 50, 51, 52, 53, 54, 55,
216     56, 57, 58, 59, 60, 61, 62, 63,
217     64, 97, 98, 99,100,101,102,103,
218     104,105,106,107,108,109,110,111,
219     112,113,114,115,116,117,118,119,
220     120,121,122, 91, 92, 93, 94, 95,
221     96, 97, 98, 99,100,101,102,103,
222     104,105,106,107,108,109,110,111,
223     112,113,114,115,116,117,118,119,
224     120,121,122,123,124,125,126,127,
225     128,129,130,131,132,133,134,135,
226     136,137,138,139,140,141,142,143,
227     144,145,146,147,148,149,150,151,
228     152,153,154,155,156,157,158,159,
229     160,161,162,163,164,165,166,167,
230     168,169,170,171,172,173,174,175,
231     176,177,178,179,180,181,182,183,
232     184,185,186,187,188,189,190,191,
233     192,193,194,195,196,197,198,199,
234     200,201,202,203,204,205,206,207,
235     208,209,210,211,212,213,214,215,
236     216,217,218,219,220,221,222,223,
237     224,225,226,227,228,229,230,231,
238     232,233,234,235,236,237,238,239,
239     240,241,242,243,244,245,246,247,
240     248,249,250,251,252,253,254,255,
241    
242     /* This table is a case flipping table. */
243    
244     0, 1, 2, 3, 4, 5, 6, 7,
245     8, 9, 10, 11, 12, 13, 14, 15,
246     16, 17, 18, 19, 20, 21, 22, 23,
247     24, 25, 26, 27, 28, 29, 30, 31,
248     32, 33, 34, 35, 36, 37, 38, 39,
249     40, 41, 42, 43, 44, 45, 46, 47,
250     48, 49, 50, 51, 52, 53, 54, 55,
251     56, 57, 58, 59, 60, 61, 62, 63,
252     64, 97, 98, 99,100,101,102,103,
253     104,105,106,107,108,109,110,111,
254     112,113,114,115,116,117,118,119,
255     120,121,122, 91, 92, 93, 94, 95,
256     96, 65, 66, 67, 68, 69, 70, 71,
257     72, 73, 74, 75, 76, 77, 78, 79,
258     80, 81, 82, 83, 84, 85, 86, 87,
259     88, 89, 90,123,124,125,126,127,
260     128,129,130,131,132,133,134,135,
261     136,137,138,139,140,141,142,143,
262     144,145,146,147,148,149,150,151,
263     152,153,154,155,156,157,158,159,
264     160,161,162,163,164,165,166,167,
265     168,169,170,171,172,173,174,175,
266     176,177,178,179,180,181,182,183,
267     184,185,186,187,188,189,190,191,
268     192,193,194,195,196,197,198,199,
269     200,201,202,203,204,205,206,207,
270     208,209,210,211,212,213,214,215,
271     216,217,218,219,220,221,222,223,
272     224,225,226,227,228,229,230,231,
273     232,233,234,235,236,237,238,239,
274     240,241,242,243,244,245,246,247,
275     248,249,250,251,252,253,254,255,
276    
277     /* This table contains bit maps for various character classes. Each map is 32
278     bytes long and the bits run from the least significant end of each byte. The
279     classes that have their own maps are: space, xdigit, digit, upper, lower, word,
280     graph, print, punct, and cntrl. Other classes are built from combinations. */
281    
282     0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
283     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
284     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
285     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
286    
287     0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
288     0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
289     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
290     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
291    
292     0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
293     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
294     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
295     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
296    
297     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
298     0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
299     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
300     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
301    
302     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
303     0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
304     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
305     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
306    
307     0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
308     0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
309     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
310     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
311    
312     0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
313     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
314     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
315     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
316    
317     0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
318     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
319     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
320     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
321    
322     0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
323     0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
324     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
325     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
326    
327     0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
328     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
329     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
330     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
331    
332     /* This table identifies various classes of character by individual bits:
333     0x01 white space character
334     0x02 letter
335     0x04 decimal digit
336     0x08 hexadecimal digit
337     0x10 alphanumeric or '_'
338     0x80 regular expression metacharacter or binary zero
339     */
340    
341     0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
342     0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
343     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
344     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
345     0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
346     0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
347     0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
348     0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
349     0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
350     0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
351     0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
352     0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */
353     0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
354     0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
355     0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
356     0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
357     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
358     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
359     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
360     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
361     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
362     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
363     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
364     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
365     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
366     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
367     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
368     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
369     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
370     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
371     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
372     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
373    
374 ph10 545 /* This is a set of tables that came orginally from a Windows user. It seems to
375     be at least an approximation of ISO 8859. In particular, there are characters
376 ph10 541 greater than 128 that are marked as spaces, letters, etc. */
377    
378     static const unsigned char tables1[] = {
379     0,1,2,3,4,5,6,7,
380     8,9,10,11,12,13,14,15,
381     16,17,18,19,20,21,22,23,
382     24,25,26,27,28,29,30,31,
383     32,33,34,35,36,37,38,39,
384     40,41,42,43,44,45,46,47,
385     48,49,50,51,52,53,54,55,
386     56,57,58,59,60,61,62,63,
387     64,97,98,99,100,101,102,103,
388     104,105,106,107,108,109,110,111,
389     112,113,114,115,116,117,118,119,
390     120,121,122,91,92,93,94,95,
391     96,97,98,99,100,101,102,103,
392     104,105,106,107,108,109,110,111,
393     112,113,114,115,116,117,118,119,
394     120,121,122,123,124,125,126,127,
395     128,129,130,131,132,133,134,135,
396     136,137,138,139,140,141,142,143,
397     144,145,146,147,148,149,150,151,
398     152,153,154,155,156,157,158,159,
399     160,161,162,163,164,165,166,167,
400     168,169,170,171,172,173,174,175,
401     176,177,178,179,180,181,182,183,
402     184,185,186,187,188,189,190,191,
403     224,225,226,227,228,229,230,231,
404     232,233,234,235,236,237,238,239,
405     240,241,242,243,244,245,246,215,
406     248,249,250,251,252,253,254,223,
407     224,225,226,227,228,229,230,231,
408     232,233,234,235,236,237,238,239,
409     240,241,242,243,244,245,246,247,
410     248,249,250,251,252,253,254,255,
411     0,1,2,3,4,5,6,7,
412     8,9,10,11,12,13,14,15,
413     16,17,18,19,20,21,22,23,
414     24,25,26,27,28,29,30,31,
415     32,33,34,35,36,37,38,39,
416     40,41,42,43,44,45,46,47,
417     48,49,50,51,52,53,54,55,
418     56,57,58,59,60,61,62,63,
419     64,97,98,99,100,101,102,103,
420     104,105,106,107,108,109,110,111,
421     112,113,114,115,116,117,118,119,
422     120,121,122,91,92,93,94,95,
423     96,65,66,67,68,69,70,71,
424     72,73,74,75,76,77,78,79,
425     80,81,82,83,84,85,86,87,
426     88,89,90,123,124,125,126,127,
427     128,129,130,131,132,133,134,135,
428     136,137,138,139,140,141,142,143,
429     144,145,146,147,148,149,150,151,
430     152,153,154,155,156,157,158,159,
431     160,161,162,163,164,165,166,167,
432     168,169,170,171,172,173,174,175,
433     176,177,178,179,180,181,182,183,
434     184,185,186,187,188,189,190,191,
435     224,225,226,227,228,229,230,231,
436     232,233,234,235,236,237,238,239,
437     240,241,242,243,244,245,246,215,
438     248,249,250,251,252,253,254,223,
439     192,193,194,195,196,197,198,199,
440     200,201,202,203,204,205,206,207,
441     208,209,210,211,212,213,214,247,
442     216,217,218,219,220,221,222,255,
443     0,62,0,0,1,0,0,0,
444     0,0,0,0,0,0,0,0,
445     32,0,0,0,1,0,0,0,
446     0,0,0,0,0,0,0,0,
447     0,0,0,0,0,0,255,3,
448     126,0,0,0,126,0,0,0,
449     0,0,0,0,0,0,0,0,
450     0,0,0,0,0,0,0,0,
451     0,0,0,0,0,0,255,3,
452     0,0,0,0,0,0,0,0,
453     0,0,0,0,0,0,12,2,
454     0,0,0,0,0,0,0,0,
455     0,0,0,0,0,0,0,0,
456     254,255,255,7,0,0,0,0,
457     0,0,0,0,0,0,0,0,
458     255,255,127,127,0,0,0,0,
459     0,0,0,0,0,0,0,0,
460     0,0,0,0,254,255,255,7,
461     0,0,0,0,0,4,32,4,
462     0,0,0,128,255,255,127,255,
463     0,0,0,0,0,0,255,3,
464     254,255,255,135,254,255,255,7,
465     0,0,0,0,0,4,44,6,
466     255,255,127,255,255,255,127,255,
467     0,0,0,0,254,255,255,255,
468     255,255,255,255,255,255,255,127,
469     0,0,0,0,254,255,255,255,
470     255,255,255,255,255,255,255,255,
471     0,2,0,0,255,255,255,255,
472     255,255,255,255,255,255,255,127,
473     0,0,0,0,255,255,255,255,
474     255,255,255,255,255,255,255,255,
475     0,0,0,0,254,255,0,252,
476     1,0,0,248,1,0,0,120,
477     0,0,0,0,254,255,255,255,
478     0,0,128,0,0,0,128,0,
479     255,255,255,255,0,0,0,0,
480     0,0,0,0,0,0,0,128,
481     255,255,255,255,0,0,0,0,
482     0,0,0,0,0,0,0,0,
483     128,0,0,0,0,0,0,0,
484     0,1,1,0,1,1,0,0,
485     0,0,0,0,0,0,0,0,
486     0,0,0,0,0,0,0,0,
487     1,0,0,0,128,0,0,0,
488     128,128,128,128,0,0,128,0,
489     28,28,28,28,28,28,28,28,
490     28,28,0,0,0,0,0,128,
491     0,26,26,26,26,26,26,18,
492     18,18,18,18,18,18,18,18,
493     18,18,18,18,18,18,18,18,
494     18,18,18,128,128,0,128,16,
495     0,26,26,26,26,26,26,18,
496     18,18,18,18,18,18,18,18,
497     18,18,18,18,18,18,18,18,
498     18,18,18,128,128,0,0,0,
499     0,0,0,0,0,1,0,0,
500     0,0,0,0,0,0,0,0,
501     0,0,0,0,0,0,0,0,
502     0,0,0,0,0,0,0,0,
503     1,0,0,0,0,0,0,0,
504     0,0,18,0,0,0,0,0,
505     0,0,20,20,0,18,0,0,
506     0,20,18,0,0,0,0,0,
507     18,18,18,18,18,18,18,18,
508     18,18,18,18,18,18,18,18,
509     18,18,18,18,18,18,18,0,
510     18,18,18,18,18,18,18,18,
511     18,18,18,18,18,18,18,18,
512     18,18,18,18,18,18,18,18,
513     18,18,18,18,18,18,18,0,
514     18,18,18,18,18,18,18,18
515     };
516    
517    
518    
519 ph10 558
520     #ifndef HAVE_STRERROR
521 nigel 49 /*************************************************
522 ph10 558 * Provide strerror() for non-ANSI libraries *
523     *************************************************/
524    
525     /* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror()
526     in their libraries, but can provide the same facility by this simple
527     alternative function. */
528    
529     extern int sys_nerr;
530     extern char *sys_errlist[];
531    
532     char *
533     strerror(int n)
534     {
535     if (n < 0 || n >= sys_nerr) return "unknown error number";
536     return sys_errlist[n];
537     }
538     #endif /* HAVE_STRERROR */
539    
540    
541    
542    
543     /*************************************************
544 nigel 91 * Read or extend an input line *
545     *************************************************/
546    
547     /* Input lines are read into buffer, but both patterns and data lines can be
548     continued over multiple input lines. In addition, if the buffer fills up, we
549     want to automatically expand it so as to be able to handle extremely large
550     lines that are needed for certain stress tests. When the input buffer is
551     expanded, the other two buffers must also be expanded likewise, and the
552     contents of pbuffer, which are a copy of the input for callouts, must be
553     preserved (for when expansion happens for a data line). This is not the most
554     optimal way of handling this, but hey, this is just a test program!
555    
556     Arguments:
557     f the file to read
558     start where in buffer to start (this *must* be within buffer)
559 ph10 287 prompt for stdin or readline()
560 nigel 91
561     Returns: pointer to the start of new data
562     could be a copy of start, or could be moved
563     NULL if no data read and EOF reached
564     */
565    
566     static uschar *
567 ph10 287 extend_inputline(FILE *f, uschar *start, const char *prompt)
568 nigel 91 {
569     uschar *here = start;
570    
571     for (;;)
572     {
573 ph10 530 int rlen = (int)(buffer_size - (here - buffer));
574 nigel 93
575 nigel 91 if (rlen > 1000)
576     {
577     int dlen;
578 ph10 289
579 ph10 287 /* If libreadline support is required, use readline() to read a line if the
580     input is a terminal. Note that readline() removes the trailing newline, so
581     we must put it back again, to be compatible with fgets(). */
582 ph10 289
583 ph10 287 #ifdef SUPPORT_LIBREADLINE
584     if (isatty(fileno(f)))
585     {
586 ph10 289 size_t len;
587 ph10 287 char *s = readline(prompt);
588     if (s == NULL) return (here == start)? NULL : start;
589     len = strlen(s);
590 ph10 289 if (len > 0) add_history(s);
591 ph10 287 if (len > rlen - 1) len = rlen - 1;
592     memcpy(here, s, len);
593     here[len] = '\n';
594 ph10 289 here[len+1] = 0;
595     free(s);
596 ph10 287 }
597 ph10 289 else
598     #endif
599    
600 ph10 287 /* Read the next line by normal means, prompting if the file is stdin. */
601 ph10 289
602 ph10 287 {
603 ph10 516 if (f == stdin) printf("%s", prompt);
604 ph10 287 if (fgets((char *)here, rlen, f) == NULL)
605     return (here == start)? NULL : start;
606 ph10 289 }
607    
608 nigel 91 dlen = (int)strlen((char *)here);
609     if (dlen > 0 && here[dlen - 1] == '\n') return start;
610     here += dlen;
611     }
612    
613     else
614     {
615     int new_buffer_size = 2*buffer_size;
616     uschar *new_buffer = (unsigned char *)malloc(new_buffer_size);
617     uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size);
618     uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size);
619    
620     if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)
621     {
622     fprintf(stderr, "pcretest: malloc(%d) failed\n", new_buffer_size);
623     exit(1);
624     }
625    
626     memcpy(new_buffer, buffer, buffer_size);
627     memcpy(new_pbuffer, pbuffer, buffer_size);
628    
629     buffer_size = new_buffer_size;
630    
631     start = new_buffer + (start - buffer);
632     here = new_buffer + (here - buffer);
633    
634     free(buffer);
635     free(dbuffer);
636     free(pbuffer);
637    
638     buffer = new_buffer;
639     dbuffer = new_dbuffer;
640     pbuffer = new_pbuffer;
641     }
642     }
643    
644     return NULL; /* Control never gets here */
645     }
646    
647    
648    
649    
650    
651    
652    
653     /*************************************************
654 nigel 63 * Read number from string *
655     *************************************************/
656    
657     /* We don't use strtoul() because SunOS4 doesn't have it. Rather than mess
658     around with conditional compilation, just do the job by hand. It is only used
659 nigel 93 for unpicking arguments, so just keep it simple.
660 nigel 63
661     Arguments:
662     str string to be converted
663     endptr where to put the end pointer
664    
665     Returns: the unsigned long
666     */
667    
668     static int
669     get_value(unsigned char *str, unsigned char **endptr)
670     {
671     int result = 0;
672     while(*str != 0 && isspace(*str)) str++;
673     while (isdigit(*str)) result = result * 10 + (int)(*str++ - '0');
674     *endptr = str;
675     return(result);
676     }
677    
678    
679    
680 nigel 49
681     /*************************************************
682     * Convert UTF-8 string to value *
683     *************************************************/
684    
685     /* This function takes one or more bytes that represents a UTF-8 character,
686     and returns the value of the character.
687    
688     Argument:
689 nigel 91 utf8bytes a pointer to the byte vector
690     vptr a pointer to an int to receive the value
691 nigel 49
692 nigel 91 Returns: > 0 => the number of bytes consumed
693     -6 to 0 => malformed UTF-8 character at offset = (-return)
694 nigel 49 */
695    
696 nigel 79 #if !defined NOUTF8
697    
698 nigel 67 static int
699 nigel 91 utf82ord(unsigned char *utf8bytes, int *vptr)
700 nigel 49 {
701 nigel 91 int c = *utf8bytes++;
702 nigel 49 int d = c;
703     int i, j, s;
704    
705     for (i = -1; i < 6; i++) /* i is number of additional bytes */
706     {
707     if ((d & 0x80) == 0) break;
708     d <<= 1;
709     }
710    
711     if (i == -1) { *vptr = c; return 1; } /* ascii character */
712     if (i == 0 || i == 6) return 0; /* invalid UTF-8 */
713    
714     /* i now has a value in the range 1-5 */
715    
716 nigel 59 s = 6*i;
717 nigel 85 d = (c & utf8_table3[i]) << s;
718 nigel 49
719     for (j = 0; j < i; j++)
720     {
721 nigel 91 c = *utf8bytes++;
722 nigel 49 if ((c & 0xc0) != 0x80) return -(j+1);
723 nigel 59 s -= 6;
724 nigel 49 d |= (c & 0x3f) << s;
725     }
726    
727     /* Check that encoding was the correct unique one */
728    
729 nigel 85 for (j = 0; j < utf8_table1_size; j++)
730     if (d <= utf8_table1[j]) break;
731 nigel 49 if (j != i) return -(i+1);
732    
733     /* Valid value */
734    
735     *vptr = d;
736     return i+1;
737     }
738    
739 nigel 79 #endif
740 nigel 49
741    
742 nigel 79
743 nigel 63 /*************************************************
744 nigel 85 * Convert character value to UTF-8 *
745     *************************************************/
746    
747     /* This function takes an integer value in the range 0 - 0x7fffffff
748     and encodes it as a UTF-8 character in 0 to 6 bytes.
749    
750     Arguments:
751     cvalue the character value
752 nigel 91 utf8bytes pointer to buffer for result - at least 6 bytes long
753 nigel 85
754     Returns: number of characters placed in the buffer
755     */
756    
757 nigel 93 #if !defined NOUTF8
758    
759 nigel 85 static int
760 nigel 91 ord2utf8(int cvalue, uschar *utf8bytes)
761 nigel 85 {
762     register int i, j;
763     for (i = 0; i < utf8_table1_size; i++)
764     if (cvalue <= utf8_table1[i]) break;
765 nigel 91 utf8bytes += i;
766 nigel 85 for (j = i; j > 0; j--)
767     {
768 nigel 91 *utf8bytes-- = 0x80 | (cvalue & 0x3f);
769 nigel 85 cvalue >>= 6;
770     }
771 nigel 91 *utf8bytes = utf8_table2[i] | cvalue;
772 nigel 85 return i + 1;
773     }
774    
775 nigel 93 #endif
776 nigel 85
777    
778 nigel 93
779 nigel 85 /*************************************************
780 nigel 63 * Print character string *
781     *************************************************/
782 nigel 49
783 nigel 63 /* Character string printing function. Must handle UTF-8 strings in utf8
784     mode. Yields number of characters printed. If handed a NULL file, just counts
785     chars without printing. */
786 nigel 49
787 nigel 63 static int pchars(unsigned char *p, int length, FILE *f)
788 nigel 3 {
789 nigel 85 int c = 0;
790 nigel 63 int yield = 0;
791 nigel 3
792 nigel 63 while (length-- > 0)
793 nigel 3 {
794 nigel 79 #if !defined NOUTF8
795 nigel 67 if (use_utf8)
796 nigel 63 {
797     int rc = utf82ord(p, &c);
798 nigel 3
799 nigel 63 if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */
800     {
801     length -= rc - 1;
802     p += rc;
803 nigel 93 if (PRINTHEX(c))
804 nigel 63 {
805     if (f != NULL) fprintf(f, "%c", c);
806     yield++;
807     }
808     else
809     {
810 nigel 93 int n = 4;
811     if (f != NULL) fprintf(f, "\\x{%02x}", c);
812     yield += (n <= 0x000000ff)? 2 :
813     (n <= 0x00000fff)? 3 :
814     (n <= 0x0000ffff)? 4 :
815     (n <= 0x000fffff)? 5 : 6;
816 nigel 63 }
817     continue;
818     }
819     }
820 nigel 79 #endif
821 nigel 3
822 nigel 63 /* Not UTF-8, or malformed UTF-8 */
823    
824 nigel 93 c = *p++;
825     if (PRINTHEX(c))
826 nigel 3 {
827 nigel 63 if (f != NULL) fprintf(f, "%c", c);
828     yield++;
829 nigel 3 }
830 nigel 63 else
831 nigel 3 {
832 nigel 63 if (f != NULL) fprintf(f, "\\x%02x", c);
833     yield += 4;
834     }
835     }
836 nigel 3
837 nigel 63 return yield;
838     }
839 nigel 23
840 nigel 3
841 nigel 23
842 nigel 63 /*************************************************
843     * Callout function *
844     *************************************************/
845 nigel 3
846 nigel 63 /* Called from PCRE as a result of the (?C) item. We print out where we are in
847     the match. Yield zero unless more callouts than the fail count, or the callout
848     data is not zero. */
849 nigel 3
850 nigel 63 static int callout(pcre_callout_block *cb)
851     {
852     FILE *f = (first_callout | callout_extra)? outfile : NULL;
853 nigel 75 int i, pre_start, post_start, subject_length;
854 nigel 3
855 nigel 63 if (callout_extra)
856     {
857     fprintf(f, "Callout %d: last capture = %d\n",
858     cb->callout_number, cb->capture_last);
859 nigel 3
860 nigel 63 for (i = 0; i < cb->capture_top * 2; i += 2)
861     {
862     if (cb->offset_vector[i] < 0)
863     fprintf(f, "%2d: <unset>\n", i/2);
864     else
865     {
866     fprintf(f, "%2d: ", i/2);
867     (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i],
868     cb->offset_vector[i+1] - cb->offset_vector[i], f);
869     fprintf(f, "\n");
870     }
871     }
872     }
873 nigel 3
874 nigel 63 /* Re-print the subject in canonical form, the first time or if giving full
875     datails. On subsequent calls in the same match, we use pchars just to find the
876     printed lengths of the substrings. */
877 nigel 3
878 nigel 63 if (f != NULL) fprintf(f, "--->");
879 nigel 3
880 nigel 63 pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f);
881     post_start = pchars((unsigned char *)(cb->subject + cb->start_match),
882     cb->current_position - cb->start_match, f);
883 nigel 3
884 nigel 75 subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);
885    
886 nigel 63 (void)pchars((unsigned char *)(cb->subject + cb->current_position),
887     cb->subject_length - cb->current_position, f);
888 nigel 3
889 nigel 63 if (f != NULL) fprintf(f, "\n");
890 nigel 9
891 nigel 63 /* Always print appropriate indicators, with callout number if not already
892 nigel 75 shown. For automatic callouts, show the pattern offset. */
893 nigel 3
894 nigel 75 if (cb->callout_number == 255)
895     {
896     fprintf(outfile, "%+3d ", cb->pattern_position);
897     if (cb->pattern_position > 99) fprintf(outfile, "\n ");
898     }
899     else
900     {
901     if (callout_extra) fprintf(outfile, " ");
902     else fprintf(outfile, "%3d ", cb->callout_number);
903     }
904 nigel 3
905 nigel 63 for (i = 0; i < pre_start; i++) fprintf(outfile, " ");
906     fprintf(outfile, "^");
907 nigel 3
908 nigel 63 if (post_start > 0)
909     {
910     for (i = 0; i < post_start - 1; i++) fprintf(outfile, " ");
911     fprintf(outfile, "^");
912 nigel 3 }
913    
914 nigel 75 for (i = 0; i < subject_length - pre_start - post_start + 4; i++)
915     fprintf(outfile, " ");
916    
917     fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length,
918     pbuffer + cb->pattern_position);
919    
920 nigel 63 fprintf(outfile, "\n");
921     first_callout = 0;
922 nigel 3
923 nigel 71 if (cb->callout_data != NULL)
924 nigel 49 {
925 nigel 71 int callout_data = *((int *)(cb->callout_data));
926     if (callout_data != 0)
927     {
928     fprintf(outfile, "Callout data = %d\n", callout_data);
929     return callout_data;
930     }
931 nigel 63 }
932 nigel 49
933 nigel 63 return (cb->callout_number != callout_fail_id)? 0 :
934     (++callout_count >= callout_fail_count)? 1 : 0;
935 nigel 3 }
936    
937    
938 nigel 63 /*************************************************
939 nigel 73 * Local malloc functions *
940 nigel 63 *************************************************/
941 nigel 3
942     /* Alternative malloc function, to test functionality and show the size of the
943     compiled re. */
944    
945     static void *new_malloc(size_t size)
946     {
947 nigel 73 void *block = malloc(size);
948 nigel 43 gotten_store = size;
949 nigel 73 if (show_malloc)
950 nigel 77 fprintf(outfile, "malloc %3d %p\n", (int)size, block);
951 nigel 73 return block;
952 nigel 3 }
953    
954 nigel 73 static void new_free(void *block)
955     {
956     if (show_malloc)
957     fprintf(outfile, "free %p\n", block);
958     free(block);
959     }
960 nigel 3
961    
962 nigel 73 /* For recursion malloc/free, to test stacking calls */
963    
964     static void *stack_malloc(size_t size)
965     {
966     void *block = malloc(size);
967     if (show_malloc)
968 nigel 77 fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block);
969 nigel 73 return block;
970     }
971    
972     static void stack_free(void *block)
973     {
974     if (show_malloc)
975     fprintf(outfile, "stack_free %p\n", block);
976     free(block);
977     }
978    
979    
980 nigel 63 /*************************************************
981     * Call pcre_fullinfo() *
982     *************************************************/
983 nigel 43
984     /* Get one piece of information from the pcre_fullinfo() function */
985    
986     static void new_info(pcre *re, pcre_extra *study, int option, void *ptr)
987     {
988     int rc;
989     if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)
990     fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);
991     }
992    
993    
994    
995 nigel 63 /*************************************************
996 nigel 75 * Byte flipping function *
997     *************************************************/
998    
999 nigel 91 static unsigned long int
1000     byteflip(unsigned long int value, int n)
1001 nigel 75 {
1002     if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
1003     return ((value & 0x000000ff) << 24) |
1004     ((value & 0x0000ff00) << 8) |
1005     ((value & 0x00ff0000) >> 8) |
1006     ((value & 0xff000000) >> 24);
1007     }
1008    
1009    
1010    
1011    
1012     /*************************************************
1013 nigel 87 * Check match or recursion limit *
1014     *************************************************/
1015    
1016     static int
1017     check_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len,
1018     int start_offset, int options, int *use_offsets, int use_size_offsets,
1019     int flag, unsigned long int *limit, int errnumber, const char *msg)
1020     {
1021     int count;
1022     int min = 0;
1023     int mid = 64;
1024     int max = -1;
1025    
1026     extra->flags |= flag;
1027    
1028     for (;;)
1029     {
1030     *limit = mid;
1031    
1032     count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options,
1033     use_offsets, use_size_offsets);
1034    
1035     if (count == errnumber)
1036     {
1037     /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */
1038     min = mid;
1039     mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2;
1040     }
1041    
1042     else if (count >= 0 || count == PCRE_ERROR_NOMATCH ||
1043     count == PCRE_ERROR_PARTIAL)
1044     {
1045     if (mid == min + 1)
1046     {
1047     fprintf(outfile, "Minimum %s limit = %d\n", msg, mid);
1048     break;
1049     }
1050     /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */
1051     max = mid;
1052     mid = (min + mid)/2;
1053     }
1054     else break; /* Some other error */
1055     }
1056    
1057     extra->flags &= ~flag;
1058     return count;
1059     }
1060    
1061    
1062    
1063     /*************************************************
1064 ph10 227 * Case-independent strncmp() function *
1065     *************************************************/
1066    
1067     /*
1068     Arguments:
1069     s first string
1070     t second string
1071     n number of characters to compare
1072    
1073     Returns: < 0, = 0, or > 0, according to the comparison
1074     */
1075    
1076     static int
1077     strncmpic(uschar *s, uschar *t, int n)
1078     {
1079     while (n--)
1080     {
1081     int c = tolower(*s++) - tolower(*t++);
1082     if (c) return c;
1083     }
1084     return 0;
1085     }
1086    
1087    
1088    
1089     /*************************************************
1090 nigel 91 * Check newline indicator *
1091     *************************************************/
1092    
1093 ph10 518 /* This is used both at compile and run-time to check for <xxx> escapes. Print
1094     a message and return 0 if there is no match.
1095 nigel 91
1096     Arguments:
1097     p points after the leading '<'
1098     f file for error message
1099    
1100     Returns: appropriate PCRE_NEWLINE_xxx flags, or 0
1101     */
1102    
1103     static int
1104     check_newline(uschar *p, FILE *f)
1105     {
1106 ph10 227 if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
1107     if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
1108     if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
1109     if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
1110     if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
1111 ph10 231 if (strncmpic(p, (uschar *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;
1112     if (strncmpic(p, (uschar *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;
1113 nigel 91 fprintf(f, "Unknown newline type at: <%s\n", p);
1114     return 0;
1115     }
1116    
1117    
1118    
1119     /*************************************************
1120 nigel 93 * Usage function *
1121     *************************************************/
1122    
1123     static void
1124     usage(void)
1125     {
1126 ph10 287 printf("Usage: pcretest [options] [<input file> [<output file>]]\n\n");
1127     printf("Input and output default to stdin and stdout.\n");
1128     #ifdef SUPPORT_LIBREADLINE
1129     printf("If input is a terminal, readline() is used to read from it.\n");
1130     #else
1131     printf("This version of pcretest is not linked with readline().\n");
1132     #endif
1133     printf("\nOptions:\n");
1134 nigel 93 printf(" -b show compiled code (bytecode)\n");
1135     printf(" -C show PCRE compile-time options and exit\n");
1136     printf(" -d debug: show compiled code and information (-b and -i)\n");
1137     #if !defined NODFA
1138     printf(" -dfa force DFA matching for all subjects\n");
1139     #endif
1140     printf(" -help show usage information\n");
1141     printf(" -i show information about compiled patterns\n"
1142 ph10 386 " -M find MATCH_LIMIT minimum for each subject\n"
1143 nigel 93 " -m output memory used information\n"
1144     " -o <n> set size of offsets vector to <n>\n");
1145     #if !defined NOPOSIX
1146     printf(" -p use POSIX interface\n");
1147     #endif
1148     printf(" -q quiet: do not output PCRE version number at start\n");
1149     printf(" -S <n> set stack size to <n> megabytes\n");
1150     printf(" -s output store (memory) used information\n"
1151     " -t time compilation and execution\n");
1152     printf(" -t <n> time compilation and execution, repeating <n> times\n");
1153     printf(" -tm time execution (matching) only\n");
1154     printf(" -tm <n> time execution (matching) only, repeating <n> times\n");
1155     }
1156    
1157    
1158    
1159     /*************************************************
1160 nigel 63 * Main Program *
1161     *************************************************/
1162 nigel 43
1163 nigel 3 /* Read lines from named file or stdin and write to named file or stdout; lines
1164     consist of a regular expression, in delimiters and optionally followed by
1165     options, followed by a set of test data, terminated by an empty line. */
1166    
1167     int main(int argc, char **argv)
1168     {
1169     FILE *infile = stdin;
1170     int options = 0;
1171     int study_options = 0;
1172 ph10 386 int default_find_match_limit = FALSE;
1173 nigel 3 int op = 1;
1174     int timeit = 0;
1175 nigel 93 int timeitm = 0;
1176 nigel 3 int showinfo = 0;
1177 nigel 31 int showstore = 0;
1178 nigel 87 int quiet = 0;
1179 nigel 53 int size_offsets = 45;
1180     int size_offsets_max;
1181 nigel 77 int *offsets = NULL;
1182 nigel 53 #if !defined NOPOSIX
1183 nigel 3 int posix = 0;
1184 nigel 53 #endif
1185 nigel 3 int debug = 0;
1186 nigel 11 int done = 0;
1187 nigel 77 int all_use_dfa = 0;
1188     int yield = 0;
1189 nigel 91 int stack_size;
1190 nigel 3
1191 nigel 91 /* These vectors store, end-to-end, a list of captured substring names. Assume
1192     that 1024 is plenty long enough for the few names we'll be testing. */
1193 nigel 69
1194 nigel 91 uschar copynames[1024];
1195     uschar getnames[1024];
1196    
1197     uschar *copynamesptr;
1198     uschar *getnamesptr;
1199    
1200 nigel 69 /* Get buffers from malloc() so that Electric Fence will check their misuse
1201 nigel 91 when I am debugging. They grow automatically when very long lines are read. */
1202 nigel 69
1203 nigel 91 buffer = (unsigned char *)malloc(buffer_size);
1204     dbuffer = (unsigned char *)malloc(buffer_size);
1205     pbuffer = (unsigned char *)malloc(buffer_size);
1206 nigel 69
1207 nigel 93 /* The outfile variable is static so that new_malloc can use it. */
1208 nigel 3
1209 nigel 93 outfile = stdout;
1210    
1211     /* The following _setmode() stuff is some Windows magic that tells its runtime
1212     library to translate CRLF into a single LF character. At least, that's what
1213     I've been told: never having used Windows I take this all on trust. Originally
1214     it set 0x8000, but then I was advised that _O_BINARY was better. */
1215    
1216 nigel 75 #if defined(_WIN32) || defined(WIN32)
1217 nigel 93 _setmode( _fileno( stdout ), _O_BINARY );
1218     #endif
1219 nigel 75
1220 nigel 3 /* Scan options */
1221    
1222     while (argc > 1 && argv[op][0] == '-')
1223     {
1224 nigel 63 unsigned char *endptr;
1225 nigel 53
1226 nigel 31 if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0)
1227     showstore = 1;
1228 nigel 87 else if (strcmp(argv[op], "-q") == 0) quiet = 1;
1229 nigel 93 else if (strcmp(argv[op], "-b") == 0) debug = 1;
1230 nigel 3 else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
1231     else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;
1232 ph10 392 else if (strcmp(argv[op], "-M") == 0) default_find_match_limit = TRUE;
1233 nigel 79 #if !defined NODFA
1234 nigel 77 else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;
1235 nigel 79 #endif
1236 nigel 53 else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&
1237 nigel 65 ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)),
1238     *endptr == 0))
1239 nigel 53 {
1240     op++;
1241     argc--;
1242     }
1243 nigel 93 else if (strcmp(argv[op], "-t") == 0 || strcmp(argv[op], "-tm") == 0)
1244     {
1245     int both = argv[op][2] == 0;
1246     int temp;
1247     if (argc > 2 && (temp = get_value((unsigned char *)argv[op+1], &endptr),
1248     *endptr == 0))
1249     {
1250     timeitm = temp;
1251     op++;
1252     argc--;
1253     }
1254     else timeitm = LOOPREPEAT;
1255     if (both) timeit = timeitm;
1256     }
1257 nigel 91 else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&
1258     ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)),
1259     *endptr == 0))
1260     {
1261 nigel 93 #if defined(_WIN32) || defined(WIN32)
1262 nigel 91 printf("PCRE: -S not supported on this OS\n");
1263     exit(1);
1264     #else
1265     int rc;
1266     struct rlimit rlim;
1267     getrlimit(RLIMIT_STACK, &rlim);
1268     rlim.rlim_cur = stack_size * 1024 * 1024;
1269     rc = setrlimit(RLIMIT_STACK, &rlim);
1270     if (rc != 0)
1271     {
1272     printf("PCRE: setrlimit() failed with error %d\n", rc);
1273     exit(1);
1274     }
1275     op++;
1276     argc--;
1277     #endif
1278     }
1279 nigel 53 #if !defined NOPOSIX
1280 nigel 3 else if (strcmp(argv[op], "-p") == 0) posix = 1;
1281 nigel 53 #endif
1282 nigel 63 else if (strcmp(argv[op], "-C") == 0)
1283     {
1284     int rc;
1285 ph10 392 unsigned long int lrc;
1286 nigel 63 printf("PCRE version %s\n", pcre_version());
1287     printf("Compiled with\n");
1288     (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
1289     printf(" %sUTF-8 support\n", rc? "" : "No ");
1290 nigel 75 (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
1291     printf(" %sUnicode properties support\n", rc? "" : "No ");
1292 nigel 63 (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
1293 ph10 391 /* Note that these values are always the ASCII values, even
1294 ph10 392 in EBCDIC environments. CR is 13 and NL is 10. */
1295 ph10 391 printf(" Newline sequence is %s\n", (rc == 13)? "CR" :
1296     (rc == 10)? "LF" : (rc == (13<<8 | 10))? "CRLF" :
1297 ph10 150 (rc == -2)? "ANYCRLF" :
1298 nigel 93 (rc == -1)? "ANY" : "???");
1299 ph10 231 (void)pcre_config(PCRE_CONFIG_BSR, &rc);
1300     printf(" \\R matches %s\n", rc? "CR, LF, or CRLF only" :
1301     "all Unicode newlines");
1302 nigel 63 (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);
1303     printf(" Internal link size = %d\n", rc);
1304     (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);
1305     printf(" POSIX malloc threshold = %d\n", rc);
1306 ph10 376 (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &lrc);
1307     printf(" Default match limit = %ld\n", lrc);
1308     (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &lrc);
1309     printf(" Default recursion depth limit = %ld\n", lrc);
1310 nigel 73 (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc);
1311     printf(" Match recursion uses %s\n", rc? "stack" : "heap");
1312 ph10 121 goto EXIT;
1313 nigel 63 }
1314 nigel 93 else if (strcmp(argv[op], "-help") == 0 ||
1315     strcmp(argv[op], "--help") == 0)
1316     {
1317     usage();
1318     goto EXIT;
1319     }
1320 nigel 3 else
1321     {
1322 nigel 53 printf("** Unknown or malformed option %s\n", argv[op]);
1323 nigel 93 usage();
1324 nigel 77 yield = 1;
1325     goto EXIT;
1326 nigel 3 }
1327     op++;
1328     argc--;
1329     }
1330    
1331 nigel 53 /* Get the store for the offsets vector, and remember what it was */
1332    
1333     size_offsets_max = size_offsets;
1334 nigel 71 offsets = (int *)malloc(size_offsets_max * sizeof(int));
1335 nigel 53 if (offsets == NULL)
1336     {
1337     printf("** Failed to get %d bytes of memory for offsets vector\n",
1338 ph10 151 (int)(size_offsets_max * sizeof(int)));
1339 nigel 77 yield = 1;
1340     goto EXIT;
1341 nigel 53 }
1342    
1343 nigel 3 /* Sort out the input and output files */
1344    
1345     if (argc > 1)
1346     {
1347 nigel 93 infile = fopen(argv[op], INPUT_MODE);
1348 nigel 3 if (infile == NULL)
1349     {
1350     printf("** Failed to open %s\n", argv[op]);
1351 nigel 77 yield = 1;
1352     goto EXIT;
1353 nigel 3 }
1354     }
1355    
1356     if (argc > 2)
1357     {
1358 nigel 93 outfile = fopen(argv[op+1], OUTPUT_MODE);
1359 nigel 3 if (outfile == NULL)
1360     {
1361     printf("** Failed to open %s\n", argv[op+1]);
1362 nigel 77 yield = 1;
1363     goto EXIT;
1364 nigel 3 }
1365     }
1366    
1367     /* Set alternative malloc function */
1368    
1369     pcre_malloc = new_malloc;
1370 nigel 73 pcre_free = new_free;
1371     pcre_stack_malloc = stack_malloc;
1372     pcre_stack_free = stack_free;
1373 nigel 3
1374 nigel 87 /* Heading line unless quiet, then prompt for first regex if stdin */
1375 nigel 3
1376 nigel 87 if (!quiet) fprintf(outfile, "PCRE version %s\n\n", pcre_version());
1377 nigel 3
1378     /* Main loop */
1379    
1380 nigel 11 while (!done)
1381 nigel 3 {
1382     pcre *re = NULL;
1383     pcre_extra *extra = NULL;
1384 nigel 37
1385     #if !defined NOPOSIX /* There are still compilers that require no indent */
1386 nigel 3 regex_t preg;
1387 nigel 45 int do_posix = 0;
1388 nigel 37 #endif
1389    
1390 nigel 7 const char *error;
1391 ph10 512 unsigned char *markptr;
1392 nigel 25 unsigned char *p, *pp, *ppp;
1393 nigel 75 unsigned char *to_file = NULL;
1394 nigel 53 const unsigned char *tables = NULL;
1395 nigel 75 unsigned long int true_size, true_study_size = 0;
1396     size_t size, regex_gotten_store;
1397 ph10 512 int do_mark = 0;
1398 nigel 3 int do_study = 0;
1399 nigel 25 int do_debug = debug;
1400 nigel 35 int do_G = 0;
1401     int do_g = 0;
1402 nigel 25 int do_showinfo = showinfo;
1403 nigel 35 int do_showrest = 0;
1404 nigel 75 int do_flip = 0;
1405 nigel 93 int erroroffset, len, delimiter, poffset;
1406 nigel 3
1407 nigel 67 use_utf8 = 0;
1408 ph10 211 debug_lengths = 1;
1409 nigel 63
1410 ph10 287 if (extend_inputline(infile, buffer, " re> ") == NULL) break;
1411 nigel 23 if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
1412 nigel 63 fflush(outfile);
1413 nigel 3
1414     p = buffer;
1415     while (isspace(*p)) p++;
1416     if (*p == 0) continue;
1417    
1418 nigel 75 /* See if the pattern is to be loaded pre-compiled from a file. */
1419 nigel 3
1420 nigel 75 if (*p == '<' && strchr((char *)(p+1), '<') == NULL)
1421     {
1422 nigel 91 unsigned long int magic, get_options;
1423 nigel 75 uschar sbuf[8];
1424     FILE *f;
1425    
1426     p++;
1427     pp = p + (int)strlen((char *)p);
1428     while (isspace(pp[-1])) pp--;
1429     *pp = 0;
1430    
1431     f = fopen((char *)p, "rb");
1432     if (f == NULL)
1433     {
1434     fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno));
1435     continue;
1436     }
1437    
1438     if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ;
1439    
1440     true_size =
1441     (sbuf[0] << 24) | (sbuf[1] << 16) | (sbuf[2] << 8) | sbuf[3];
1442     true_study_size =
1443     (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];
1444    
1445     re = (real_pcre *)new_malloc(true_size);
1446     regex_gotten_store = gotten_store;
1447    
1448     if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;
1449    
1450     magic = ((real_pcre *)re)->magic_number;
1451     if (magic != MAGIC_NUMBER)
1452     {
1453     if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER)
1454     {
1455     do_flip = 1;
1456     }
1457     else
1458     {
1459     fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p);
1460     fclose(f);
1461     continue;
1462     }
1463     }
1464    
1465     fprintf(outfile, "Compiled regex%s loaded from %s\n",
1466     do_flip? " (byte-inverted)" : "", p);
1467    
1468     /* Need to know if UTF-8 for printing data strings */
1469    
1470 nigel 91 new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
1471     use_utf8 = (get_options & PCRE_UTF8) != 0;
1472 nigel 75
1473     /* Now see if there is any following study data */
1474    
1475     if (true_study_size != 0)
1476     {
1477     pcre_study_data *psd;
1478    
1479     extra = (pcre_extra *)new_malloc(sizeof(pcre_extra) + true_study_size);
1480     extra->flags = PCRE_EXTRA_STUDY_DATA;
1481    
1482     psd = (pcre_study_data *)(((char *)extra) + sizeof(pcre_extra));
1483     extra->study_data = psd;
1484    
1485     if (fread(psd, 1, true_study_size, f) != true_study_size)
1486     {
1487     FAIL_READ:
1488     fprintf(outfile, "Failed to read data from %s\n", p);
1489     if (extra != NULL) new_free(extra);
1490     if (re != NULL) new_free(re);
1491     fclose(f);
1492     continue;
1493     }
1494     fprintf(outfile, "Study data loaded from %s\n", p);
1495     do_study = 1; /* To get the data output if requested */
1496     }
1497     else fprintf(outfile, "No study data\n");
1498    
1499     fclose(f);
1500     goto SHOW_INFO;
1501     }
1502    
1503     /* In-line pattern (the usual case). Get the delimiter and seek the end of
1504     the pattern; if is isn't complete, read more. */
1505    
1506 nigel 3 delimiter = *p++;
1507    
1508 nigel 29 if (isalnum(delimiter) || delimiter == '\\')
1509 nigel 3 {
1510 ph10 274 fprintf(outfile, "** Delimiter must not be alphanumeric or \\\n");
1511 nigel 3 goto SKIP_DATA;
1512     }
1513    
1514     pp = p;
1515 ph10 530 poffset = (int)(p - buffer);
1516 nigel 3
1517     for(;;)
1518     {
1519 nigel 29 while (*pp != 0)
1520     {
1521     if (*pp == '\\' && pp[1] != 0) pp++;
1522     else if (*pp == delimiter) break;
1523     pp++;
1524     }
1525 nigel 3 if (*pp != 0) break;
1526 ph10 287 if ((pp = extend_inputline(infile, pp, " > ")) == NULL)
1527 nigel 3 {
1528     fprintf(outfile, "** Unexpected EOF\n");
1529 nigel 11 done = 1;
1530     goto CONTINUE;
1531 nigel 3 }
1532 nigel 23 if (infile != stdin) fprintf(outfile, "%s", (char *)pp);
1533 nigel 3 }
1534    
1535 nigel 93 /* The buffer may have moved while being extended; reset the start of data
1536     pointer to the correct relative point in the buffer. */
1537    
1538     p = buffer + poffset;
1539    
1540 nigel 29 /* If the first character after the delimiter is backslash, make
1541     the pattern end with backslash. This is purely to provide a way
1542     of testing for the error message when a pattern ends with backslash. */
1543    
1544     if (pp[1] == '\\') *pp++ = '\\';
1545    
1546 nigel 75 /* Terminate the pattern at the delimiter, and save a copy of the pattern
1547     for callouts. */
1548 nigel 3
1549     *pp++ = 0;
1550 nigel 75 strcpy((char *)pbuffer, (char *)p);
1551 nigel 3
1552     /* Look for options after final delimiter */
1553    
1554     options = 0;
1555     study_options = 0;
1556 nigel 31 log_store = showstore; /* default from command line */
1557    
1558 nigel 3 while (*pp != 0)
1559     {
1560     switch (*pp++)
1561     {
1562 nigel 77 case 'f': options |= PCRE_FIRSTLINE; break;
1563 nigel 35 case 'g': do_g = 1; break;
1564 nigel 3 case 'i': options |= PCRE_CASELESS; break;
1565     case 'm': options |= PCRE_MULTILINE; break;
1566     case 's': options |= PCRE_DOTALL; break;
1567     case 'x': options |= PCRE_EXTENDED; break;
1568 nigel 25
1569 nigel 35 case '+': do_showrest = 1; break;
1570 nigel 3 case 'A': options |= PCRE_ANCHORED; break;
1571 nigel 93 case 'B': do_debug = 1; break;
1572 nigel 75 case 'C': options |= PCRE_AUTO_CALLOUT; break;
1573 nigel 25 case 'D': do_debug = do_showinfo = 1; break;
1574 nigel 3 case 'E': options |= PCRE_DOLLAR_ENDONLY; break;
1575 nigel 75 case 'F': do_flip = 1; break;
1576 nigel 35 case 'G': do_G = 1; break;
1577 nigel 25 case 'I': do_showinfo = 1; break;
1578 nigel 91 case 'J': options |= PCRE_DUPNAMES; break;
1579 ph10 512 case 'K': do_mark = 1; break;
1580 nigel 31 case 'M': log_store = 1; break;
1581 nigel 63 case 'N': options |= PCRE_NO_AUTO_CAPTURE; break;
1582 nigel 37
1583     #if !defined NOPOSIX
1584 nigel 3 case 'P': do_posix = 1; break;
1585 nigel 37 #endif
1586    
1587 nigel 3 case 'S': do_study = 1; break;
1588 nigel 19 case 'U': options |= PCRE_UNGREEDY; break;
1589 ph10 535 case 'W': options |= PCRE_UCP; break;
1590 nigel 3 case 'X': options |= PCRE_EXTRA; break;
1591 ph10 126 case 'Z': debug_lengths = 0; break;
1592 nigel 67 case '8': options |= PCRE_UTF8; use_utf8 = 1; break;
1593 nigel 71 case '?': options |= PCRE_NO_UTF8_CHECK; break;
1594 ph10 545
1595 ph10 541 case 'T':
1596     switch (*pp++)
1597     {
1598     case '0': tables = tables0; break;
1599     case '1': tables = tables1; break;
1600 ph10 545
1601 ph10 541 case '\r':
1602     case '\n':
1603 ph10 545 case ' ':
1604     case 0:
1605 ph10 541 fprintf(outfile, "** Missing table number after /T\n");
1606 ph10 545 goto SKIP_DATA;
1607    
1608     default:
1609 ph10 541 fprintf(outfile, "** Bad table number \"%c\" after /T\n", pp[-1]);
1610 ph10 545 goto SKIP_DATA;
1611 ph10 541 }
1612 ph10 545 break;
1613 nigel 25
1614     case 'L':
1615     ppp = pp;
1616 nigel 93 /* The '\r' test here is so that it works on Windows. */
1617     /* The '0' test is just in case this is an unterminated line. */
1618     while (*ppp != 0 && *ppp != '\n' && *ppp != '\r' && *ppp != ' ') ppp++;
1619 nigel 25 *ppp = 0;
1620     if (setlocale(LC_CTYPE, (const char *)pp) == NULL)
1621     {
1622     fprintf(outfile, "** Failed to set locale \"%s\"\n", pp);
1623     goto SKIP_DATA;
1624     }
1625 nigel 93 locale_set = 1;
1626 nigel 25 tables = pcre_maketables();
1627     pp = ppp;
1628     break;
1629    
1630 nigel 75 case '>':
1631     to_file = pp;
1632     while (*pp != 0) pp++;
1633     while (isspace(pp[-1])) pp--;
1634     *pp = 0;
1635     break;
1636    
1637 nigel 91 case '<':
1638     {
1639 ph10 518 if (strncmpic(pp, (uschar *)"JS>", 3) == 0)
1640 ph10 336 {
1641     options |= PCRE_JAVASCRIPT_COMPAT;
1642 ph10 345 pp += 3;
1643 ph10 336 }
1644     else
1645 ph10 345 {
1646 ph10 336 int x = check_newline(pp, outfile);
1647     if (x == 0) goto SKIP_DATA;
1648     options |= x;
1649     while (*pp++ != '>');
1650 ph10 345 }
1651 nigel 91 }
1652     break;
1653    
1654 nigel 77 case '\r': /* So that it works in Windows */
1655     case '\n':
1656     case ' ':
1657     break;
1658 nigel 75
1659 nigel 3 default:
1660     fprintf(outfile, "** Unknown option '%c'\n", pp[-1]);
1661     goto SKIP_DATA;
1662     }
1663     }
1664    
1665 nigel 11 /* Handle compiling via the POSIX interface, which doesn't support the
1666 nigel 25 timing, showing, or debugging options, nor the ability to pass over
1667     local character tables. */
1668 nigel 3
1669 nigel 37 #if !defined NOPOSIX
1670 nigel 3 if (posix || do_posix)
1671     {
1672     int rc;
1673     int cflags = 0;
1674 nigel 75
1675 nigel 3 if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE;
1676     if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE;
1677 nigel 77 if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL;
1678 nigel 87 if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB;
1679     if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8;
1680 ph10 518 if ((options & PCRE_UCP) != 0) cflags |= REG_UCP;
1681 ph10 461 if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY;
1682 nigel 87
1683 nigel 3 rc = regcomp(&preg, (char *)p, cflags);
1684    
1685     /* Compilation failed; go back for another re, skipping to blank line
1686     if non-interactive. */
1687    
1688     if (rc != 0)
1689     {
1690 nigel 91 (void)regerror(rc, &preg, (char *)buffer, buffer_size);
1691 nigel 3 fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer);
1692     goto SKIP_DATA;
1693     }
1694     }
1695    
1696     /* Handle compiling via the native interface */
1697    
1698     else
1699 nigel 37 #endif /* !defined NOPOSIX */
1700    
1701 nigel 3 {
1702 ph10 412 unsigned long int get_options;
1703 ph10 416
1704 nigel 93 if (timeit > 0)
1705 nigel 3 {
1706     register int i;
1707     clock_t time_taken;
1708     clock_t start_time = clock();
1709 nigel 93 for (i = 0; i < timeit; i++)
1710 nigel 3 {
1711 nigel 25 re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
1712 nigel 3 if (re != NULL) free(re);
1713     }
1714     time_taken = clock() - start_time;
1715 nigel 93 fprintf(outfile, "Compile time %.4f milliseconds\n",
1716     (((double)time_taken * 1000.0) / (double)timeit) /
1717 nigel 63 (double)CLOCKS_PER_SEC);
1718 nigel 3 }
1719    
1720 nigel 25 re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
1721 nigel 3
1722     /* Compilation failed; go back for another re, skipping to blank line
1723     if non-interactive. */
1724    
1725     if (re == NULL)
1726     {
1727     fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset);
1728     SKIP_DATA:
1729     if (infile != stdin)
1730     {
1731     for (;;)
1732     {
1733 ph10 287 if (extend_inputline(infile, buffer, NULL) == NULL)
1734 nigel 11 {
1735     done = 1;
1736     goto CONTINUE;
1737     }
1738 nigel 3 len = (int)strlen((char *)buffer);
1739     while (len > 0 && isspace(buffer[len-1])) len--;
1740     if (len == 0) break;
1741     }
1742     fprintf(outfile, "\n");
1743     }
1744 nigel 25 goto CONTINUE;
1745 nigel 3 }
1746 ph10 416
1747     /* Compilation succeeded. It is now possible to set the UTF-8 option from
1748     within the regex; check for this so that we know how to process the data
1749 ph10 412 lines. */
1750 ph10 416
1751 ph10 412 new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
1752     if ((get_options & PCRE_UTF8) != 0) use_utf8 = 1;
1753 nigel 3
1754 ph10 412 /* Print information if required. There are now two info-returning
1755     functions. The old one has a limited interface and returns only limited
1756     data. Check that it agrees with the newer one. */
1757 nigel 3
1758 nigel 63 if (log_store)
1759     fprintf(outfile, "Memory allocation (code space): %d\n",
1760     (int)(gotten_store -
1761     sizeof(real_pcre) -
1762     ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));
1763    
1764 nigel 75 /* Extract the size for possible writing before possibly flipping it,
1765     and remember the store that was got. */
1766    
1767     true_size = ((real_pcre *)re)->size;
1768     regex_gotten_store = gotten_store;
1769    
1770     /* If /S was present, study the regexp to generate additional info to
1771     help with the matching. */
1772    
1773     if (do_study)
1774     {
1775 nigel 93 if (timeit > 0)
1776 nigel 75 {
1777     register int i;
1778     clock_t time_taken;
1779     clock_t start_time = clock();
1780 nigel 93 for (i = 0; i < timeit; i++)
1781 nigel 75 extra = pcre_study(re, study_options, &error);
1782     time_taken = clock() - start_time;
1783     if (extra != NULL) free(extra);
1784 nigel 93 fprintf(outfile, " Study time %.4f milliseconds\n",
1785     (((double)time_taken * 1000.0) / (double)timeit) /
1786 nigel 75 (double)CLOCKS_PER_SEC);
1787     }
1788     extra = pcre_study(re, study_options, &error);
1789     if (error != NULL)
1790     fprintf(outfile, "Failed to study: %s\n", error);
1791     else if (extra != NULL)
1792     true_study_size = ((pcre_study_data *)(extra->study_data))->size;
1793     }
1794 ph10 512
1795 ph10 510 /* If /K was present, we set up for handling MARK data. */
1796 ph10 512
1797 ph10 510 if (do_mark)
1798     {
1799     if (extra == NULL)
1800     {
1801     extra = (pcre_extra *)malloc(sizeof(pcre_extra));
1802     extra->flags = 0;
1803     }
1804 ph10 512 extra->mark = &markptr;
1805 ph10 510 extra->flags |= PCRE_EXTRA_MARK;
1806 ph10 512 }
1807 nigel 75
1808     /* If the 'F' option was present, we flip the bytes of all the integer
1809     fields in the regex data block and the study block. This is to make it
1810     possible to test PCRE's handling of byte-flipped patterns, e.g. those
1811     compiled on a different architecture. */
1812    
1813     if (do_flip)
1814     {
1815     real_pcre *rre = (real_pcre *)re;
1816 ph10 259 rre->magic_number =
1817 ph10 255 byteflip(rre->magic_number, sizeof(rre->magic_number));
1818 nigel 75 rre->size = byteflip(rre->size, sizeof(rre->size));
1819     rre->options = byteflip(rre->options, sizeof(rre->options));
1820 ph10 255 rre->flags = (pcre_uint16)byteflip(rre->flags, sizeof(rre->flags));
1821 ph10 259 rre->top_bracket =
1822 ph10 255 (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));
1823 ph10 259 rre->top_backref =
1824 ph10 255 (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));
1825 ph10 259 rre->first_byte =
1826 ph10 255 (pcre_uint16)byteflip(rre->first_byte, sizeof(rre->first_byte));
1827 ph10 259 rre->req_byte =
1828 ph10 255 (pcre_uint16)byteflip(rre->req_byte, sizeof(rre->req_byte));
1829     rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,
1830 nigel 75 sizeof(rre->name_table_offset));
1831 ph10 255 rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,
1832 nigel 75 sizeof(rre->name_entry_size));
1833 ph10 259 rre->name_count = (pcre_uint16)byteflip(rre->name_count,
1834 ph10 255 sizeof(rre->name_count));
1835 nigel 75
1836     if (extra != NULL)
1837     {
1838     pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);
1839     rsd->size = byteflip(rsd->size, sizeof(rsd->size));
1840 ph10 455 rsd->flags = byteflip(rsd->flags, sizeof(rsd->flags));
1841     rsd->minlength = byteflip(rsd->minlength, sizeof(rsd->minlength));
1842 nigel 75 }
1843     }
1844    
1845     /* Extract information from the compiled data if required */
1846    
1847     SHOW_INFO:
1848    
1849 nigel 93 if (do_debug)
1850     {
1851     fprintf(outfile, "------------------------------------------------------------------\n");
1852 ph10 116 pcre_printint(re, outfile, debug_lengths);
1853 nigel 93 }
1854 ph10 416
1855 ph10 412 /* We already have the options in get_options (see above) */
1856 nigel 93
1857 nigel 25 if (do_showinfo)
1858 nigel 3 {
1859 ph10 412 unsigned long int all_options;
1860 nigel 79 #if !defined NOINFOCHECK
1861 nigel 43 int old_first_char, old_options, old_count;
1862 nigel 79 #endif
1863 ph10 226 int count, backrefmax, first_char, need_char, okpartial, jchanged,
1864 ph10 227 hascrorlf;
1865 nigel 63 int nameentrysize, namecount;
1866     const uschar *nametable;
1867 nigel 3
1868 nigel 43 new_info(re, NULL, PCRE_INFO_SIZE, &size);
1869     new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);
1870     new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax);
1871 nigel 63 new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char);
1872 nigel 43 new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char);
1873 nigel 63 new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
1874     new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount);
1875 nigel 67 new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable);
1876 ph10 172 new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial);
1877     new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);
1878 ph10 226 new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);
1879 nigel 43
1880 nigel 79 #if !defined NOINFOCHECK
1881 nigel 43 old_count = pcre_info(re, &old_options, &old_first_char);
1882 nigel 3 if (count < 0) fprintf(outfile,
1883 nigel 43 "Error %d from pcre_info()\n", count);
1884 nigel 3 else
1885     {
1886 nigel 43 if (old_count != count) fprintf(outfile,
1887     "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,
1888     old_count);
1889 nigel 37
1890 nigel 43 if (old_first_char != first_char) fprintf(outfile,
1891     "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",
1892     first_char, old_first_char);
1893 nigel 37
1894 nigel 53 if (old_options != (int)get_options) fprintf(outfile,
1895     "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",
1896     get_options, old_options);
1897 nigel 43 }
1898 nigel 79 #endif
1899 nigel 43
1900 nigel 75 if (size != regex_gotten_store) fprintf(outfile,
1901 nigel 43 "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n",
1902 nigel 77 (int)size, (int)regex_gotten_store);
1903 nigel 43
1904     fprintf(outfile, "Capturing subpattern count = %d\n", count);
1905     if (backrefmax > 0)
1906     fprintf(outfile, "Max back reference = %d\n", backrefmax);
1907 nigel 63
1908     if (namecount > 0)
1909     {
1910     fprintf(outfile, "Named capturing subpatterns:\n");
1911     while (namecount-- > 0)
1912     {
1913     fprintf(outfile, " %s %*s%3d\n", nametable + 2,
1914     nameentrysize - 3 - (int)strlen((char *)nametable + 2), "",
1915     GET2(nametable, 0));
1916     nametable += nameentrysize;
1917     }
1918     }
1919 ph10 172
1920 ph10 169 if (!okpartial) fprintf(outfile, "Partial matching not supported\n");
1921 ph10 227 if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n");
1922 nigel 63
1923 nigel 75 all_options = ((real_pcre *)re)->options;
1924 ph10 169 if (do_flip) all_options = byteflip(all_options, sizeof(all_options));
1925 nigel 75
1926 nigel 53 if (get_options == 0) fprintf(outfile, "No options\n");
1927 ph10 518 else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
1928 nigel 53 ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",
1929     ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",
1930     ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",
1931     ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "",
1932 nigel 77 ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "",
1933 nigel 53 ((get_options & PCRE_DOTALL) != 0)? " dotall" : "",
1934 ph10 231 ((get_options & PCRE_BSR_ANYCRLF) != 0)? " bsr_anycrlf" : "",
1935     ((get_options & PCRE_BSR_UNICODE) != 0)? " bsr_unicode" : "",
1936 nigel 53 ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
1937     ((get_options & PCRE_EXTRA) != 0)? " extra" : "",
1938     ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
1939 nigel 87 ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",
1940 nigel 71 ((get_options & PCRE_UTF8) != 0)? " utf8" : "",
1941 ph10 518 ((get_options & PCRE_UCP) != 0)? " ucp" : "",
1942 nigel 91 ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",
1943     ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");
1944 ph10 172
1945 ph10 169 if (jchanged) fprintf(outfile, "Duplicate name status changes\n");
1946 nigel 43
1947 nigel 93 switch (get_options & PCRE_NEWLINE_BITS)
1948 nigel 91 {
1949     case PCRE_NEWLINE_CR:
1950     fprintf(outfile, "Forced newline sequence: CR\n");
1951     break;
1952 nigel 43
1953 nigel 91 case PCRE_NEWLINE_LF:
1954     fprintf(outfile, "Forced newline sequence: LF\n");
1955     break;
1956    
1957     case PCRE_NEWLINE_CRLF:
1958     fprintf(outfile, "Forced newline sequence: CRLF\n");
1959     break;
1960    
1961 ph10 149 case PCRE_NEWLINE_ANYCRLF:
1962     fprintf(outfile, "Forced newline sequence: ANYCRLF\n");
1963     break;
1964    
1965 nigel 93 case PCRE_NEWLINE_ANY:
1966     fprintf(outfile, "Forced newline sequence: ANY\n");
1967     break;
1968    
1969 nigel 91 default:
1970     break;
1971     }
1972    
1973 nigel 43 if (first_char == -1)
1974     {
1975 nigel 91 fprintf(outfile, "First char at start or follows newline\n");
1976 nigel 43 }
1977     else if (first_char < 0)
1978     {
1979     fprintf(outfile, "No first char\n");
1980     }
1981     else
1982     {
1983 nigel 63 int ch = first_char & 255;
1984 nigel 67 const char *caseless = ((first_char & REQ_CASELESS) == 0)?
1985 nigel 63 "" : " (caseless)";
1986 nigel 93 if (PRINTHEX(ch))
1987 nigel 63 fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless);
1988 nigel 3 else
1989 nigel 63 fprintf(outfile, "First char = %d%s\n", ch, caseless);
1990 nigel 43 }
1991 nigel 37
1992 nigel 43 if (need_char < 0)
1993     {
1994     fprintf(outfile, "No need char\n");
1995 nigel 3 }
1996 nigel 43 else
1997     {
1998 nigel 63 int ch = need_char & 255;
1999 nigel 67 const char *caseless = ((need_char & REQ_CASELESS) == 0)?
2000 nigel 63 "" : " (caseless)";
2001 nigel 93 if (PRINTHEX(ch))
2002 nigel 63 fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless);
2003 nigel 43 else
2004 nigel 63 fprintf(outfile, "Need char = %d%s\n", ch, caseless);
2005 nigel 43 }
2006 nigel 75
2007     /* Don't output study size; at present it is in any case a fixed
2008     value, but it varies, depending on the computer architecture, and
2009     so messes up the test suite. (And with the /F option, it might be
2010     flipped.) */
2011    
2012     if (do_study)
2013     {
2014     if (extra == NULL)
2015     fprintf(outfile, "Study returned NULL\n");
2016     else
2017     {
2018     uschar *start_bits = NULL;
2019 ph10 455 int minlength;
2020 ph10 461
2021 ph10 455 new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength);
2022 ph10 461 fprintf(outfile, "Subject length lower bound = %d\n", minlength);
2023    
2024 nigel 75 new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);
2025     if (start_bits == NULL)
2026 ph10 455 fprintf(outfile, "No set of starting bytes\n");
2027 nigel 75 else
2028     {
2029     int i;
2030     int c = 24;
2031     fprintf(outfile, "Starting byte set: ");
2032     for (i = 0; i < 256; i++)
2033     {
2034     if ((start_bits[i/8] & (1<<(i&7))) != 0)
2035     {
2036     if (c > 75)
2037     {
2038     fprintf(outfile, "\n ");
2039     c = 2;
2040     }
2041 nigel 93 if (PRINTHEX(i) && i != ' ')
2042 nigel 75 {
2043     fprintf(outfile, "%c ", i);
2044     c += 2;
2045     }
2046     else
2047     {
2048     fprintf(outfile, "\\x%02x ", i);
2049     c += 5;
2050     }
2051     }
2052     }
2053     fprintf(outfile, "\n");
2054     }
2055     }
2056     }
2057 nigel 3 }
2058    
2059 nigel 75 /* If the '>' option was present, we write out the regex to a file, and
2060     that is all. The first 8 bytes of the file are the regex length and then
2061     the study length, in big-endian order. */
2062 nigel 3
2063 nigel 75 if (to_file != NULL)
2064 nigel 3 {
2065 nigel 75 FILE *f = fopen((char *)to_file, "wb");
2066     if (f == NULL)
2067 nigel 3 {
2068 nigel 75 fprintf(outfile, "Unable to open %s: %s\n", to_file, strerror(errno));
2069 nigel 3 }
2070 nigel 75 else
2071     {
2072     uschar sbuf[8];
2073 ph10 255 sbuf[0] = (uschar)((true_size >> 24) & 255);
2074     sbuf[1] = (uschar)((true_size >> 16) & 255);
2075     sbuf[2] = (uschar)((true_size >> 8) & 255);
2076     sbuf[3] = (uschar)((true_size) & 255);
2077 ph10 259
2078 ph10 255 sbuf[4] = (uschar)((true_study_size >> 24) & 255);
2079     sbuf[5] = (uschar)((true_study_size >> 16) & 255);
2080     sbuf[6] = (uschar)((true_study_size >> 8) & 255);
2081     sbuf[7] = (uschar)((true_study_size) & 255);
2082 nigel 3
2083 nigel 75 if (fwrite(sbuf, 1, 8, f) < 8 ||
2084     fwrite(re, 1, true_size, f) < true_size)
2085     {
2086     fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno));
2087     }
2088 nigel 3 else
2089     {
2090 nigel 75 fprintf(outfile, "Compiled regex written to %s\n", to_file);
2091     if (extra != NULL)
2092 nigel 3 {
2093 nigel 75 if (fwrite(extra->study_data, 1, true_study_size, f) <
2094     true_study_size)
2095 nigel 3 {
2096 nigel 75 fprintf(outfile, "Write error on %s: %s\n", to_file,
2097     strerror(errno));
2098 nigel 3 }
2099 nigel 75 else fprintf(outfile, "Study data written to %s\n", to_file);
2100 nigel 93
2101 nigel 3 }
2102     }
2103 nigel 75 fclose(f);
2104 nigel 3 }
2105 nigel 77
2106     new_free(re);
2107     if (extra != NULL) new_free(extra);
2108 ph10 545 if (locale_set)
2109 ph10 541 {
2110     new_free((void *)tables);
2111     setlocale(LC_CTYPE, "C");
2112 ph10 545 locale_set = 0;
2113     }
2114 nigel 75 continue; /* With next regex */
2115 nigel 3 }
2116 nigel 75 } /* End of non-POSIX compile */
2117 nigel 3
2118     /* Read data lines and test them */
2119    
2120     for (;;)
2121     {
2122 nigel 87 uschar *q;
2123 ph10 147 uschar *bptr;
2124 nigel 57 int *use_offsets = offsets;
2125 nigel 53 int use_size_offsets = size_offsets;
2126 nigel 63 int callout_data = 0;
2127     int callout_data_set = 0;
2128 nigel 3 int count, c;
2129 nigel 29 int copystrings = 0;
2130 ph10 386 int find_match_limit = default_find_match_limit;
2131 nigel 29 int getstrings = 0;
2132     int getlist = 0;
2133 nigel 39 int gmatched = 0;
2134 nigel 35 int start_offset = 0;
2135 nigel 41 int g_notempty = 0;
2136 nigel 77 int use_dfa = 0;
2137 nigel 3
2138     options = 0;
2139    
2140 nigel 91 *copynames = 0;
2141     *getnames = 0;
2142    
2143     copynamesptr = copynames;
2144     getnamesptr = getnames;
2145    
2146 nigel 63 pcre_callout = callout;
2147     first_callout = 1;
2148     callout_extra = 0;
2149     callout_count = 0;
2150     callout_fail_count = 999999;
2151     callout_fail_id = -1;
2152 nigel 73 show_malloc = 0;
2153 nigel 63
2154 nigel 91 if (extra != NULL) extra->flags &=
2155     ~(PCRE_EXTRA_MATCH_LIMIT|PCRE_EXTRA_MATCH_LIMIT_RECURSION);
2156    
2157     len = 0;
2158     for (;;)
2159 nigel 11 {
2160 ph10 287 if (extend_inputline(infile, buffer + len, "data> ") == NULL)
2161 nigel 91 {
2162 ph10 537 if (len > 0) /* Reached EOF without hitting a newline */
2163     {
2164 ph10 545 fprintf(outfile, "\n");
2165 ph10 537 break;
2166 ph10 545 }
2167 nigel 91 done = 1;
2168     goto CONTINUE;
2169     }
2170     if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
2171     len = (int)strlen((char *)buffer);
2172     if (buffer[len-1] == '\n') break;
2173 nigel 11 }
2174 nigel 3
2175     while (len > 0 && isspace(buffer[len-1])) len--;
2176     buffer[len] = 0;
2177     if (len == 0) break;
2178    
2179     p = buffer;
2180     while (isspace(*p)) p++;
2181    
2182 ph10 147 bptr = q = dbuffer;
2183 nigel 3 while ((c = *p++) != 0)
2184     {
2185     int i = 0;
2186     int n = 0;
2187 nigel 63
2188 nigel 3 if (c == '\\') switch ((c = *p++))
2189     {
2190     case 'a': c = 7; break;
2191     case 'b': c = '\b'; break;
2192     case 'e': c = 27; break;
2193     case 'f': c = '\f'; break;
2194     case 'n': c = '\n'; break;
2195     case 'r': c = '\r'; break;
2196     case 't': c = '\t'; break;
2197     case 'v': c = '\v'; break;
2198    
2199     case '0': case '1': case '2': case '3':
2200     case '4': case '5': case '6': case '7':
2201     c -= '0';
2202     while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
2203     c = c * 8 + *p++ - '0';
2204 nigel 91
2205     #if !defined NOUTF8
2206     if (use_utf8 && c > 255)
2207     {
2208     unsigned char buff8[8];
2209     int ii, utn;
2210     utn = ord2utf8(c, buff8);
2211     for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
2212     c = buff8[ii]; /* Last byte */
2213     }
2214     #endif
2215 nigel 3 break;
2216    
2217     case 'x':
2218 nigel 49
2219     /* Handle \x{..} specially - new Perl thing for utf8 */
2220    
2221 nigel 79 #if !defined NOUTF8
2222 nigel 49 if (*p == '{')
2223     {
2224     unsigned char *pt = p;
2225     c = 0;
2226     while (isxdigit(*(++pt)))
2227     c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W');
2228     if (*pt == '}')
2229     {
2230 nigel 67 unsigned char buff8[8];
2231 nigel 49 int ii, utn;
2232 ph10 355 if (use_utf8)
2233 ph10 358 {
2234 ph10 355 utn = ord2utf8(c, buff8);
2235     for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
2236     c = buff8[ii]; /* Last byte */
2237     }
2238     else
2239     {
2240 ph10 358 if (c > 255)
2241 ph10 355 fprintf(outfile, "** Character \\x{%x} is greater than 255 and "
2242     "UTF-8 mode is not enabled.\n"
2243     "** Truncation will probably give the wrong result.\n", c);
2244 ph10 358 }
2245 nigel 49 p = pt + 1;
2246     break;
2247     }
2248     /* Not correct form; fall through */
2249     }
2250 nigel 79 #endif
2251 nigel 49
2252     /* Ordinary \x */
2253    
2254 nigel 3 c = 0;
2255     while (i++ < 2 && isxdigit(*p))
2256     {
2257     c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W');
2258     p++;
2259     }
2260     break;
2261    
2262 nigel 75 case 0: /* \ followed by EOF allows for an empty line */
2263 nigel 3 p--;
2264     continue;
2265    
2266 nigel 75 case '>':
2267     while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0';
2268     continue;
2269    
2270 nigel 3 case 'A': /* Option setting */
2271     options |= PCRE_ANCHORED;
2272     continue;
2273    
2274     case 'B':
2275     options |= PCRE_NOTBOL;
2276     continue;
2277    
2278 nigel 29 case 'C':
2279 nigel 63 if (isdigit(*p)) /* Set copy string */
2280     {
2281     while(isdigit(*p)) n = n * 10 + *p++ - '0';
2282     copystrings |= 1 << n;
2283     }
2284     else if (isalnum(*p))
2285     {
2286 nigel 91 uschar *npp = copynamesptr;
2287 nigel 67 while (isalnum(*p)) *npp++ = *p++;
2288 nigel 91 *npp++ = 0;
2289 nigel 67 *npp = 0;
2290 nigel 91 n = pcre_get_stringnumber(re, (char *)copynamesptr);
2291 nigel 63 if (n < 0)
2292 nigel 91 fprintf(outfile, "no parentheses with name \"%s\"\n", copynamesptr);
2293     copynamesptr = npp;
2294 nigel 63 }
2295     else if (*p == '+')
2296     {
2297     callout_extra = 1;
2298     p++;
2299     }
2300     else if (*p == '-')
2301     {
2302     pcre_callout = NULL;
2303     p++;
2304     }
2305     else if (*p == '!')
2306     {
2307     callout_fail_id = 0;
2308     p++;
2309     while(isdigit(*p))
2310     callout_fail_id = callout_fail_id * 10 + *p++ - '0';
2311     callout_fail_count = 0;
2312     if (*p == '!')
2313     {
2314     p++;
2315     while(isdigit(*p))
2316     callout_fail_count = callout_fail_count * 10 + *p++ - '0';
2317     }
2318     }
2319     else if (*p == '*')
2320     {
2321     int sign = 1;
2322     callout_data = 0;
2323     if (*(++p) == '-') { sign = -1; p++; }
2324     while(isdigit(*p))
2325     callout_data = callout_data * 10 + *p++ - '0';
2326     callout_data *= sign;
2327     callout_data_set = 1;
2328     }
2329 nigel 29 continue;
2330    
2331 nigel 79 #if !defined NODFA
2332 nigel 77 case 'D':
2333 nigel 79 #if !defined NOPOSIX
2334 nigel 77 if (posix || do_posix)
2335     printf("** Can't use dfa matching in POSIX mode: \\D ignored\n");
2336     else
2337 nigel 79 #endif
2338 nigel 77 use_dfa = 1;
2339     continue;
2340 ph10 553 #endif
2341 nigel 77
2342 ph10 553 #if !defined NODFA
2343 nigel 77 case 'F':
2344     options |= PCRE_DFA_SHORTEST;
2345     continue;
2346 nigel 79 #endif
2347 nigel 77
2348 nigel 29 case 'G':
2349 nigel 63 if (isdigit(*p))
2350     {
2351     while(isdigit(*p)) n = n * 10 + *p++ - '0';
2352     getstrings |= 1 << n;
2353     }
2354     else if (isalnum(*p))
2355     {
2356 nigel 91 uschar *npp = getnamesptr;
2357 nigel 67 while (isalnum(*p)) *npp++ = *p++;
2358 nigel 91 *npp++ = 0;
2359 nigel 67 *npp = 0;
2360 nigel 91 n = pcre_get_stringnumber(re, (char *)getnamesptr);
2361 nigel 63 if (n < 0)
2362 nigel 91 fprintf(outfile, "no parentheses with name \"%s\"\n", getnamesptr);
2363     getnamesptr = npp;
2364 nigel 63 }
2365 nigel 29 continue;
2366    
2367     case 'L':
2368     getlist = 1;
2369     continue;
2370    
2371 nigel 63 case 'M':
2372     find_match_limit = 1;
2373     continue;
2374    
2375 nigel 37 case 'N':
2376 ph10 442 if ((options & PCRE_NOTEMPTY) != 0)
2377     options = (options & ~PCRE_NOTEMPTY) | PCRE_NOTEMPTY_ATSTART;
2378 ph10 461 else
2379 ph10 442 options |= PCRE_NOTEMPTY;
2380 nigel 37 continue;
2381    
2382 nigel 3 case 'O':
2383     while(isdigit(*p)) n = n * 10 + *p++ - '0';
2384 nigel 53 if (n > size_offsets_max)
2385     {
2386     size_offsets_max = n;
2387 nigel 57 free(offsets);
2388 nigel 71 use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int));
2389 nigel 53 if (offsets == NULL)
2390     {
2391     printf("** Failed to get %d bytes of memory for offsets vector\n",
2392 ph10 151 (int)(size_offsets_max * sizeof(int)));
2393 nigel 77 yield = 1;
2394     goto EXIT;
2395 nigel 53 }
2396     }
2397     use_size_offsets = n;
2398 nigel 63 if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */
2399 nigel 3 continue;
2400    
2401 nigel 75 case 'P':
2402 ph10 461 options |= ((options & PCRE_PARTIAL_SOFT) == 0)?
2403 ph10 427 PCRE_PARTIAL_SOFT : PCRE_PARTIAL_HARD;
2404 nigel 75 continue;
2405    
2406 nigel 91 case 'Q':
2407     while(isdigit(*p)) n = n * 10 + *p++ - '0';
2408     if (extra == NULL)
2409     {
2410     extra = (pcre_extra *)malloc(sizeof(pcre_extra));
2411     extra->flags = 0;
2412     }
2413     extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
2414     extra->match_limit_recursion = n;
2415     continue;
2416    
2417     case 'q':
2418     while(isdigit(*p)) n = n * 10 + *p++ - '0';
2419     if (extra == NULL)
2420     {
2421     extra = (pcre_extra *)malloc(sizeof(pcre_extra));
2422     extra->flags = 0;
2423     }
2424     extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
2425     extra->match_limit = n;
2426     continue;
2427    
2428 nigel 79 #if !defined NODFA
2429 nigel 77 case 'R':
2430     options |= PCRE_DFA_RESTART;
2431     continue;
2432 nigel 79 #endif
2433 nigel 77
2434 nigel 73 case 'S':
2435     show_malloc = 1;
2436     continue;
2437 ph10 392
2438 ph10 389 case 'Y':
2439     options |= PCRE_NO_START_OPTIMIZE;
2440 ph10 392 continue;
2441 nigel 73
2442 nigel 3 case 'Z':
2443     options |= PCRE_NOTEOL;
2444     continue;
2445 nigel 71
2446     case '?':
2447     options |= PCRE_NO_UTF8_CHECK;
2448     continue;
2449 nigel 91
2450     case '<':
2451     {
2452     int x = check_newline(p, outfile);
2453     if (x == 0) goto NEXT_DATA;
2454     options |= x;
2455     while (*p++ != '>');
2456     }
2457     continue;
2458 nigel 3 }
2459 nigel 9 *q++ = c;
2460 nigel 3 }
2461 nigel 9 *q = 0;
2462 ph10 530 len = (int)(q - dbuffer);
2463 ph10 545
2464 ph10 361 /* Move the data to the end of the buffer so that a read over the end of
2465 ph10 371 the buffer will be seen by valgrind, even if it doesn't cause a crash. If
2466 ph10 363 we are using the POSIX interface, we must include the terminating zero. */
2467 ph10 371
2468 ph10 363 #if !defined NOPOSIX
2469     if (posix || do_posix)
2470     {
2471     memmove(bptr + buffer_size - len - 1, bptr, len + 1);
2472 ph10 371 bptr += buffer_size - len - 1;
2473 ph10 363 }
2474 ph10 371 else
2475     #endif
2476 ph10 363 {
2477     memmove(bptr + buffer_size - len, bptr, len);
2478 ph10 371 bptr += buffer_size - len;
2479     }
2480 nigel 3
2481 nigel 77 if ((all_use_dfa || use_dfa) && find_match_limit)
2482     {
2483     printf("**Match limit not relevant for DFA matching: ignored\n");
2484     find_match_limit = 0;
2485     }
2486    
2487 nigel 3 /* Handle matching via the POSIX interface, which does not
2488 nigel 63 support timing or playing with the match limit or callout data. */
2489 nigel 3
2490 nigel 37 #if !defined NOPOSIX
2491 nigel 3 if (posix || do_posix)
2492     {
2493     int rc;
2494     int eflags = 0;
2495 nigel 63 regmatch_t *pmatch = NULL;
2496     if (use_size_offsets > 0)
2497 nigel 71 pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets);
2498 nigel 3 if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;
2499     if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;
2500 ph10 392 if ((options & PCRE_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY;
2501 nigel 3
2502 nigel 53 rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags);
2503 nigel 3
2504     if (rc != 0)
2505     {
2506 nigel 91 (void)regerror(rc, &preg, (char *)buffer, buffer_size);
2507 nigel 3 fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer);
2508     }
2509 nigel 87 else if ((((const pcre *)preg.re_pcre)->options & PCRE_NO_AUTO_CAPTURE)
2510     != 0)
2511     {
2512     fprintf(outfile, "Matched with REG_NOSUB\n");
2513     }
2514 nigel 3 else
2515     {
2516 nigel 7 size_t i;
2517 nigel 63 for (i = 0; i < (size_t)use_size_offsets; i++)
2518 nigel 3 {
2519     if (pmatch[i].rm_so >= 0)
2520     {
2521 nigel 23 fprintf(outfile, "%2d: ", (int)i);
2522 nigel 63 (void)pchars(dbuffer + pmatch[i].rm_so,
2523     pmatch[i].rm_eo - pmatch[i].rm_so, outfile);
2524 nigel 3 fprintf(outfile, "\n");
2525 nigel 35 if (i == 0 && do_showrest)
2526     {
2527     fprintf(outfile, " 0+ ");
2528 nigel 63 (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo,
2529     outfile);
2530 nigel 35 fprintf(outfile, "\n");
2531     }
2532 nigel 3 }
2533     }
2534     }
2535 nigel 53 free(pmatch);
2536 nigel 3 }
2537    
2538 nigel 35 /* Handle matching via the native interface - repeats for /g and /G */
2539 nigel 3
2540 nigel 37 else
2541     #endif /* !defined NOPOSIX */
2542    
2543 nigel 39 for (;; gmatched++) /* Loop for /g or /G */
2544 nigel 3 {
2545 ph10 512 markptr = NULL;
2546    
2547 nigel 93 if (timeitm > 0)
2548 nigel 3 {
2549     register int i;
2550     clock_t time_taken;
2551     clock_t start_time = clock();
2552 nigel 77
2553 nigel 79 #if !defined NODFA
2554 nigel 77 if (all_use_dfa || use_dfa)
2555     {
2556     int workspace[1000];
2557 nigel 93 for (i = 0; i < timeitm; i++)
2558 ph10 455 count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset,
2559 nigel 77 options | g_notempty, use_offsets, use_size_offsets, workspace,
2560     sizeof(workspace)/sizeof(int));
2561     }
2562     else
2563 nigel 79 #endif
2564 nigel 77
2565 nigel 93 for (i = 0; i < timeitm; i++)
2566 nigel 35 count = pcre_exec(re, extra, (char *)bptr, len,
2567 nigel 57 start_offset, options | g_notempty, use_offsets, use_size_offsets);
2568 nigel 77
2569 nigel 3 time_taken = clock() - start_time;
2570 nigel 93 fprintf(outfile, "Execute time %.4f milliseconds\n",
2571     (((double)time_taken * 1000.0) / (double)timeitm) /
2572 nigel 63 (double)CLOCKS_PER_SEC);
2573 nigel 3 }
2574    
2575 nigel 63 /* If find_match_limit is set, we want to do repeated matches with
2576 nigel 87 varying limits in order to find the minimum value for the match limit and
2577     for the recursion limit. */
2578 nigel 63
2579     if (find_match_limit)
2580     {
2581     if (extra == NULL)
2582     {
2583 nigel 71 extra = (pcre_extra *)malloc(sizeof(pcre_extra));
2584 nigel 63 extra->flags = 0;
2585     }
2586    
2587 nigel 91 (void)check_match_limit(re, extra, bptr, len, start_offset,
2588 nigel 87 options|g_notempty, use_offsets, use_size_offsets,
2589     PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit),
2590     PCRE_ERROR_MATCHLIMIT, "match()");
2591 nigel 63
2592 nigel 87 count = check_match_limit(re, extra, bptr, len, start_offset,
2593     options|g_notempty, use_offsets, use_size_offsets,
2594     PCRE_EXTRA_MATCH_LIMIT_RECURSION, &(extra->match_limit_recursion),
2595     PCRE_ERROR_RECURSIONLIMIT, "match() recursion");
2596 nigel 63 }
2597    
2598     /* If callout_data is set, use the interface with additional data */
2599    
2600     else if (callout_data_set)
2601     {
2602     if (extra == NULL)
2603     {
2604 nigel 71 extra = (pcre_extra *)malloc(sizeof(pcre_extra));
2605 nigel 63 extra->flags = 0;
2606     }
2607     extra->flags |= PCRE_EXTRA_CALLOUT_DATA;
2608 nigel 71 extra->callout_data = &callout_data;
2609 nigel 63 count = pcre_exec(re, extra, (char *)bptr, len, start_offset,
2610     options | g_notempty, use_offsets, use_size_offsets);
2611     extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;
2612     }
2613    
2614     /* The normal case is just to do the match once, with the default
2615     value of match_limit. */
2616    
2617 nigel 79 #if !defined NODFA
2618 nigel 77 else if (all_use_dfa || use_dfa)
2619     {
2620     int workspace[1000];
2621 ph10 455 count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset,
2622 nigel 77 options | g_notempty, use_offsets, use_size_offsets, workspace,
2623     sizeof(workspace)/sizeof(int));
2624     if (count == 0)
2625     {
2626     fprintf(outfile, "Matched, but too many subsidiary matches\n");
2627     count = use_size_offsets/2;
2628     }
2629     }
2630 nigel 79 #endif
2631 nigel 77
2632 nigel 75 else
2633     {
2634     count = pcre_exec(re, extra, (char *)bptr, len,
2635     start_offset, options | g_notempty, use_offsets, use_size_offsets);
2636 nigel 77 if (count == 0)
2637     {
2638     fprintf(outfile, "Matched, but too many substrings\n");
2639     count = use_size_offsets/3;
2640     }
2641 nigel 75 }
2642 nigel 3
2643 nigel 39 /* Matched */
2644    
2645 nigel 3 if (count >= 0)
2646     {
2647 nigel 93 int i, maxcount;
2648    
2649     #if !defined NODFA
2650     if (all_use_dfa || use_dfa) maxcount = use_size_offsets/2; else
2651     #endif
2652     maxcount = use_size_offsets/3;
2653    
2654     /* This is a check against a lunatic return value. */
2655    
2656     if (count > maxcount)
2657     {
2658     fprintf(outfile,
2659     "** PCRE error: returned count %d is too big for offset size %d\n",
2660     count, use_size_offsets);
2661     count = use_size_offsets/3;
2662     if (do_g || do_G)
2663     {
2664     fprintf(outfile, "** /%c loop abandoned\n", do_g? 'g' : 'G');
2665     do_g = do_G = FALSE; /* Break g/G loop */
2666     }
2667     }
2668    
2669 nigel 29 for (i = 0; i < count * 2; i += 2)
2670 nigel 3 {
2671 nigel 57 if (use_offsets[i] < 0)
2672 nigel 3 fprintf(outfile, "%2d: <unset>\n", i/2);
2673     else
2674     {
2675     fprintf(outfile, "%2d: ", i/2);
2676 nigel 63 (void)pchars(bptr + use_offsets[i],
2677     use_offsets[i+1] - use_offsets[i], outfile);
2678 nigel 3 fprintf(outfile, "\n");
2679 nigel 35 if (i == 0)
2680     {
2681     if (do_showrest)
2682     {
2683     fprintf(outfile, " 0+ ");
2684 nigel 63 (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1],
2685     outfile);
2686 nigel 35 fprintf(outfile, "\n");
2687     }
2688     }
2689 nigel 3 }
2690     }
2691 ph10 512
2692 ph10 510 if (markptr != NULL) fprintf(outfile, "MK: %s\n", markptr);
2693 nigel 29
2694     for (i = 0; i < 32; i++)
2695     {
2696     if ((copystrings & (1 << i)) != 0)
2697     {
2698 nigel 91 char copybuffer[256];
2699 nigel 57 int rc = pcre_copy_substring((char *)bptr, use_offsets, count,
2700 nigel 37 i, copybuffer, sizeof(copybuffer));
2701 nigel 29 if (rc < 0)
2702     fprintf(outfile, "copy substring %d failed %d\n", i, rc);
2703     else
2704 nigel 37 fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc);
2705 nigel 29 }
2706     }
2707    
2708 nigel 91 for (copynamesptr = copynames;
2709     *copynamesptr != 0;
2710     copynamesptr += (int)strlen((char*)copynamesptr) + 1)
2711     {
2712     char copybuffer[256];
2713     int rc = pcre_copy_named_substring(re, (char *)bptr, use_offsets,
2714     count, (char *)copynamesptr, copybuffer, sizeof(copybuffer));
2715     if (rc < 0)
2716     fprintf(outfile, "copy substring %s failed %d\n", copynamesptr, rc);
2717     else
2718     fprintf(outfile, " C %s (%d) %s\n", copybuffer, rc, copynamesptr);
2719     }
2720    
2721 nigel 29 for (i = 0; i < 32; i++)
2722     {
2723     if ((getstrings & (1 << i)) != 0)
2724     {
2725     const char *substring;
2726 nigel 57 int rc = pcre_get_substring((char *)bptr, use_offsets, count,
2727 nigel 29 i, &substring);
2728     if (rc < 0)
2729     fprintf(outfile, "get substring %d failed %d\n", i, rc);
2730     else
2731     {
2732     fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc);
2733 nigel 49 pcre_free_substring(substring);
2734 nigel 29 }
2735     }
2736     }
2737    
2738 nigel 91 for (getnamesptr = getnames;
2739     *getnamesptr != 0;
2740     getnamesptr += (int)strlen((char*)getnamesptr) + 1)
2741     {
2742     const char *substring;
2743     int rc = pcre_get_named_substring(re, (char *)bptr, use_offsets,
2744     count, (char *)getnamesptr, &substring);
2745     if (rc < 0)
2746     fprintf(outfile, "copy substring %s failed %d\n", getnamesptr, rc);
2747     else
2748     {
2749     fprintf(outfile, " G %s (%d) %s\n", substring, rc, getnamesptr);
2750     pcre_free_substring(substring);
2751     }
2752     }
2753    
2754 nigel 29 if (getlist)
2755     {
2756     const char **stringlist;
2757 nigel 57 int rc = pcre_get_substring_list((char *)bptr, use_offsets, count,
2758 nigel 29 &stringlist);
2759     if (rc < 0)
2760     fprintf(outfile, "get substring list failed %d\n", rc);
2761     else
2762     {
2763     for (i = 0; i < count; i++)
2764     fprintf(outfile, "%2dL %s\n", i, stringlist[i]);
2765     if (stringlist[i] != NULL)
2766     fprintf(outfile, "string list not terminated by NULL\n");
2767 nigel 49 /* free((void *)stringlist); */
2768     pcre_free_substring_list(stringlist);
2769 nigel 29 }
2770     }
2771 nigel 39 }
2772 nigel 29
2773 nigel 75 /* There was a partial match */
2774    
2775     else if (count == PCRE_ERROR_PARTIAL)
2776     {
2777 ph10 510 if (markptr == NULL) fprintf(outfile, "Partial match");
2778     else fprintf(outfile, "Partial match, mark=%s", markptr);
2779 ph10 426 if (use_size_offsets > 1)
2780     {
2781     fprintf(outfile, ": ");
2782     pchars(bptr + use_offsets[0], use_offsets[1] - use_offsets[0],
2783 ph10 461 outfile);
2784     }
2785 nigel 77 fprintf(outfile, "\n");
2786 nigel 75 break; /* Out of the /g loop */
2787     }
2788    
2789 nigel 41 /* Failed to match. If this is a /g or /G loop and we previously set
2790 ph10 143 g_notempty after a null match, this is not necessarily the end. We want
2791     to advance the start offset, and continue. We won't be at the end of the
2792     string - that was checked before setting g_notempty.
2793 nigel 39
2794 ph10 150 Complication arises in the case when the newline option is "any" or
2795 ph10 149 "anycrlf". If the previous match was at the end of a line terminated by
2796     CRLF, an advance of one character just passes the \r, whereas we should
2797     prefer the longer newline sequence, as does the code in pcre_exec().
2798     Fudge the offset value to achieve this.
2799 ph10 144
2800 ph10 143 Otherwise, in the case of UTF-8 matching, the advance must be one
2801     character, not one byte. */
2802    
2803 nigel 3 else
2804     {
2805 nigel 41 if (g_notempty != 0)
2806 nigel 35 {
2807 nigel 73 int onechar = 1;
2808 ph10 146 unsigned int obits = ((real_pcre *)re)->options;
2809 nigel 57 use_offsets[0] = start_offset;
2810 ph10 146 if ((obits & PCRE_NEWLINE_BITS) == 0)
2811     {
2812     int d;
2813     (void)pcre_config(PCRE_CONFIG_NEWLINE, &d);
2814 ph10 391 /* Note that these values are always the ASCII ones, even in
2815     EBCDIC environments. CR = 13, NL = 10. */
2816     obits = (d == 13)? PCRE_NEWLINE_CR :
2817     (d == 10)? PCRE_NEWLINE_LF :
2818     (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF :
2819 ph10 150 (d == -2)? PCRE_NEWLINE_ANYCRLF :
2820 ph10 146 (d == -1)? PCRE_NEWLINE_ANY : 0;
2821     }
2822 ph10 149 if (((obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANY ||
2823 ph10 150 (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANYCRLF)
2824 ph10 149 &&
2825 ph10 143 start_offset < len - 1 &&
2826     bptr[start_offset] == '\r' &&
2827     bptr[start_offset+1] == '\n')
2828 ph10 144 onechar++;
2829 ph10 143 else if (use_utf8)
2830 nigel 73 {
2831     while (start_offset + onechar < len)
2832     {
2833     int tb = bptr[start_offset+onechar];
2834     if (tb <= 127) break;
2835     tb &= 0xc0;
2836     if (tb != 0 && tb != 0xc0) onechar++;
2837     }
2838     }
2839     use_offsets[1] = start_offset + onechar;
2840 nigel 35 }
2841 nigel 41 else
2842     {
2843 nigel 73 if (count == PCRE_ERROR_NOMATCH)
2844 nigel 41 {
2845 ph10 512 if (gmatched == 0)
2846 ph10 510 {
2847     if (markptr == NULL) fprintf(outfile, "No match\n");
2848     else fprintf(outfile, "No match, mark = %s\n", markptr);
2849 ph10 512 }
2850 nigel 41 }
2851 nigel 73 else fprintf(outfile, "Error %d\n", count);
2852 nigel 41 break; /* Out of the /g loop */
2853     }
2854 nigel 3 }
2855 nigel 35
2856 nigel 39 /* If not /g or /G we are done */
2857    
2858     if (!do_g && !do_G) break;
2859    
2860 nigel 41 /* If we have matched an empty string, first check to see if we are at
2861 ph10 442 the end of the subject. If so, the /g loop is over. Otherwise, mimic what
2862     Perl's /g options does. This turns out to be rather cunning. First we set
2863     PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED and try the match again at the
2864 nigel 47 same point. If this fails (picked up above) we advance to the next
2865 ph10 143 character. */
2866 ph10 142
2867 nigel 41 g_notempty = 0;
2868 ph10 142
2869 nigel 57 if (use_offsets[0] == use_offsets[1])
2870 nigel 41 {
2871 nigel 57 if (use_offsets[0] == len) break;
2872 ph10 442 g_notempty = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED;
2873 nigel 41 }
2874 nigel 39
2875     /* For /g, update the start offset, leaving the rest alone */
2876    
2877 ph10 143 if (do_g) start_offset = use_offsets[1];
2878 nigel 39
2879     /* For /G, update the pointer and length */
2880    
2881     else
2882 nigel 35 {
2883 ph10 143 bptr += use_offsets[1];
2884     len -= use_offsets[1];
2885 nigel 35 }
2886 nigel 39 } /* End of loop for /g and /G */
2887 nigel 91
2888     NEXT_DATA: continue;
2889 nigel 39 } /* End of loop for data lines */
2890 nigel 3
2891 nigel 11 CONTINUE:
2892 nigel 37
2893     #if !defined NOPOSIX
2894 nigel 3 if (posix || do_posix) regfree(&preg);
2895 nigel 37 #endif
2896    
2897 nigel 77 if (re != NULL) new_free(re);
2898     if (extra != NULL) new_free(extra);
2899 ph10 541 if (locale_set)
2900 nigel 25 {
2901 nigel 77 new_free((void *)tables);
2902 nigel 25 setlocale(LC_CTYPE, "C");
2903 nigel 93 locale_set = 0;
2904 nigel 25 }
2905 nigel 3 }
2906    
2907 nigel 73 if (infile == stdin) fprintf(outfile, "\n");
2908 nigel 77
2909     EXIT:
2910    
2911     if (infile != NULL && infile != stdin) fclose(infile);
2912     if (outfile != NULL && outfile != stdout) fclose(outfile);
2913    
2914     free(buffer);
2915     free(dbuffer);
2916     free(pbuffer);
2917     free(offsets);
2918    
2919     return yield;
2920 nigel 3 }
2921    
2922 nigel 77 /* End of pcretest.c */

Properties

Name Value
svn:eol-style native
svn:keywords "Author Date Id Revision Url"

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12