NCBI C++ ToolKit
pcretest.c
Go to the documentation of this file.

Go to the SVN repository for this file.

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