~ubuntu-branches/ubuntu/hardy/exim4/hardy-proposed

« back to all changes in this revision

Viewing changes to src/pcre/pcretest.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Haber
  • Date: 2005-07-02 06:08:34 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050702060834-qk17pd52kb9nt3bj
Tags: 4.52-1
* new upstream version 4.51. (mh)
  * adapt 70_remove_exim-users_references
  * remove 37_gnutlsparams
  * adapt 36_pcre
  * adapt 31_eximmanpage
* fix package priorities to have them in sync with override again. (mh)
* Fix error in nb (Norwegian) translation.
  Thanks to Helge Hafting. (mh). Closes: #315775
* Standards-Version: 3.6.2, no changes needed. (mh)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Cambridge: exim/exim-src/src/pcre/pcretest.c,v 1.2 2005/06/15 08:57:10 ph10 Exp $ */
 
2
 
1
3
/*************************************************
2
4
*             PCRE testing program               *
3
5
*************************************************/
4
6
 
5
7
/* This program was hacked up as a tester for PCRE. I really should have
6
8
written it more tidily in the first place. Will I ever learn? It has grown and
7
 
been extended and consequently is now rather untidy in places. */
 
9
been extended and consequently is now rather, er, *very* untidy in places.
 
10
 
 
11
-----------------------------------------------------------------------------
 
12
Redistribution and use in source and binary forms, with or without
 
13
modification, are permitted provided that the following conditions are met:
 
14
 
 
15
    * Redistributions of source code must retain the above copyright notice,
 
16
      this list of conditions and the following disclaimer.
 
17
 
 
18
    * Redistributions in binary form must reproduce the above copyright
 
19
      notice, this list of conditions and the following disclaimer in the
 
20
      documentation and/or other materials provided with the distribution.
 
21
 
 
22
    * Neither the name of the University of Cambridge nor the names of its
 
23
      contributors may be used to endorse or promote products derived from
 
24
      this software without specific prior written permission.
 
25
 
 
26
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
27
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
28
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
29
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
30
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
31
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
32
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
33
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
34
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
35
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
36
POSSIBILITY OF SUCH DAMAGE.
 
37
-----------------------------------------------------------------------------
 
38
*/
 
39
 
8
40
 
9
41
#include <ctype.h>
10
42
#include <stdio.h>
12
44
#include <stdlib.h>
13
45
#include <time.h>
14
46
#include <locale.h>
15
 
 
16
 
/* We need the internal info for displaying the results of pcre_study(). Also
17
 
for getting the opcodes for showing compiled code. */
 
47
#include <errno.h>
18
48
 
19
49
#define PCRE_SPY        /* For Win32 build, import data, not export */
20
 
#include "internal.h"
 
50
 
 
51
/* We need the internal info for displaying the results of pcre_study() and
 
52
other internal data; pcretest also uses some of the fixed tables, and generally
 
53
has "inside information" compared to a program that strictly follows the PCRE
 
54
API. */
 
55
 
 
56
#include "pcre_internal.h"
 
57
 
21
58
 
22
59
/* It is possible to compile this test program without including support for
23
60
testing the POSIX interface, though this is not available via the standard
27
64
#include "pcreposix.h"
28
65
#endif
29
66
 
 
67
/* It is also possible, for the benefit of the version imported into Exim, to 
 
68
build pcretest without support for UTF8 (define NOUTF8), without the interface 
 
69
to the DFA matcher (NODFA), and without the doublecheck of the old "info"
 
70
function (define NOINFOCHECK). */
 
71
 
 
72
 
30
73
#ifndef CLOCKS_PER_SEC
31
74
#ifdef CLK_TCK
32
75
#define CLOCKS_PER_SEC CLK_TCK
35
78
#endif
36
79
#endif
37
80
 
38
 
#define LOOPREPEAT 50000
 
81
#define LOOPREPEAT 500000
39
82
 
40
83
#define BUFFER_SIZE 30000
 
84
#define PBUFFER_SIZE BUFFER_SIZE
41
85
#define DBUFFER_SIZE BUFFER_SIZE
42
86
 
43
87
 
52
96
static int use_utf8;
53
97
static size_t gotten_store;
54
98
 
55
 
 
56
 
static const int utf8_table1[] = {
57
 
  0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff};
58
 
 
59
 
static const int utf8_table2[] = {
60
 
  0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
61
 
 
62
 
static const int utf8_table3[] = {
63
 
  0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
64
 
 
65
 
 
66
 
 
67
 
/*************************************************
68
 
*         Print compiled regex                   *
69
 
*************************************************/
70
 
 
71
 
/* The code for doing this is held in a separate file that is also included in
72
 
pcre.c when it is compiled with the debug switch. It defines a function called
73
 
print_internals(), which uses a table of opcode lengths defined by the macro
74
 
OP_LENGTHS, whose name must be OP_lengths. */
75
 
 
76
 
static uschar OP_lengths[] = { OP_LENGTHS };
77
 
 
78
 
#include "printint.c"
 
99
static uschar *pbuffer = NULL;
79
100
 
80
101
 
81
102
 
106
127
 
107
128
 
108
129
 
109
 
/*************************************************
110
 
*       Convert character value to UTF-8         *
111
 
*************************************************/
112
 
 
113
 
/* This function takes an integer value in the range 0 - 0x7fffffff
114
 
and encodes it as a UTF-8 character in 0 to 6 bytes.
115
 
 
116
 
Arguments:
117
 
  cvalue     the character value
118
 
  buffer     pointer to buffer for result - at least 6 bytes long
119
 
 
120
 
Returns:     number of characters placed in the buffer
121
 
             -1 if input character is negative
122
 
             0 if input character is positive but too big (only when
123
 
             int is longer than 32 bits)
124
 
*/
125
 
 
126
 
static int
127
 
ord2utf8(int cvalue, unsigned char *buffer)
128
 
{
129
 
register int i, j;
130
 
for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++)
131
 
  if (cvalue <= utf8_table1[i]) break;
132
 
if (i >= sizeof(utf8_table1)/sizeof(int)) return 0;
133
 
if (cvalue < 0) return -1;
134
 
 
135
 
buffer += i;
136
 
for (j = i; j > 0; j--)
137
 
 {
138
 
 *buffer-- = 0x80 | (cvalue & 0x3f);
139
 
 cvalue >>= 6;
140
 
 }
141
 
*buffer = utf8_table2[i] | cvalue;
142
 
return i + 1;
143
 
}
144
 
 
145
130
 
146
131
/*************************************************
147
132
*            Convert UTF-8 string to value       *
158
143
           -6 to 0 => malformed UTF-8 character at offset = (-return)
159
144
*/
160
145
 
 
146
#if !defined NOUTF8
 
147
 
161
148
static int
162
149
utf82ord(unsigned char *buffer, int *vptr)
163
150
{
177
164
/* i now has a value in the range 1-5 */
178
165
 
179
166
s = 6*i;
180
 
d = (c & utf8_table3[i]) << s;
 
167
d = (c & _pcre_utf8_table3[i]) << s;
181
168
 
182
169
for (j = 0; j < i; j++)
183
170
  {
189
176
 
190
177
/* Check that encoding was the correct unique one */
191
178
 
192
 
for (j = 0; j < sizeof(utf8_table1)/sizeof(int); j++)
193
 
  if (d <= utf8_table1[j]) break;
 
179
for (j = 0; j < _pcre_utf8_table1_size; j++)
 
180
  if (d <= _pcre_utf8_table1[j]) break;
194
181
if (j != i) return -(i+1);
195
182
 
196
183
/* Valid value */
199
186
return i+1;
200
187
}
201
188
 
 
189
#endif
 
190
 
202
191
 
203
192
 
204
193
/*************************************************
216
205
 
217
206
while (length-- > 0)
218
207
  {
 
208
#if !defined NOUTF8   
219
209
  if (use_utf8)
220
210
    {
221
211
    int rc = utf82ord(p, &c);
238
228
      continue;
239
229
      }
240
230
    }
 
231
#endif
241
232
 
242
233
   /* Not UTF-8, or malformed UTF-8  */
243
234
 
269
260
static int callout(pcre_callout_block *cb)
270
261
{
271
262
FILE *f = (first_callout | callout_extra)? outfile : NULL;
272
 
int i, pre_start, post_start;
 
263
int i, pre_start, post_start, subject_length;
273
264
 
274
265
if (callout_extra)
275
266
  {
300
291
post_start = pchars((unsigned char *)(cb->subject + cb->start_match),
301
292
  cb->current_position - cb->start_match, f);
302
293
 
 
294
subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);
 
295
 
303
296
(void)pchars((unsigned char *)(cb->subject + cb->current_position),
304
297
  cb->subject_length - cb->current_position, f);
305
298
 
306
299
if (f != NULL) fprintf(f, "\n");
307
300
 
308
301
/* Always print appropriate indicators, with callout number if not already
309
 
shown */
 
302
shown. For automatic callouts, show the pattern offset. */
310
303
 
311
 
if (callout_extra) fprintf(outfile, "    ");
312
 
  else fprintf(outfile, "%3d ", cb->callout_number);
 
304
if (cb->callout_number == 255)
 
305
  {
 
306
  fprintf(outfile, "%+3d ", cb->pattern_position);
 
307
  if (cb->pattern_position > 99) fprintf(outfile, "\n    ");
 
308
  }
 
309
else
 
310
  {
 
311
  if (callout_extra) fprintf(outfile, "    ");
 
312
    else fprintf(outfile, "%3d ", cb->callout_number);
 
313
  }
313
314
 
314
315
for (i = 0; i < pre_start; i++) fprintf(outfile, " ");
315
316
fprintf(outfile, "^");
320
321
  fprintf(outfile, "^");
321
322
  }
322
323
 
 
324
for (i = 0; i < subject_length - pre_start - post_start + 4; i++)
 
325
  fprintf(outfile, " ");
 
326
 
 
327
fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length,
 
328
  pbuffer + cb->pattern_position);
 
329
 
323
330
fprintf(outfile, "\n");
324
331
first_callout = 0;
325
332
 
350
357
void *block = malloc(size);
351
358
gotten_store = size;
352
359
if (show_malloc)
353
 
  fprintf(outfile, "malloc       %3d %p\n", size, block);
 
360
  fprintf(outfile, "malloc       %3d %p\n", (int)size, block);
354
361
return block;
355
362
}
356
363
 
368
375
{
369
376
void *block = malloc(size);
370
377
if (show_malloc)
371
 
  fprintf(outfile, "stack_malloc %3d %p\n", size, block);
 
378
  fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block);
372
379
return block;
373
380
}
374
381
 
396
403
 
397
404
 
398
405
/*************************************************
 
406
*         Byte flipping function                 *
 
407
*************************************************/
 
408
 
 
409
static long int
 
410
byteflip(long int value, int n)
 
411
{
 
412
if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
 
413
return ((value & 0x000000ff) << 24) |
 
414
       ((value & 0x0000ff00) <<  8) |
 
415
       ((value & 0x00ff0000) >>  8) |
 
416
       ((value & 0xff000000) >> 24);
 
417
}
 
418
 
 
419
 
 
420
 
 
421
 
 
422
/*************************************************
399
423
*                Main Program                    *
400
424
*************************************************/
401
425
 
414
438
int showstore = 0;
415
439
int size_offsets = 45;
416
440
int size_offsets_max;
417
 
int *offsets;
 
441
int *offsets = NULL;
418
442
#if !defined NOPOSIX
419
443
int posix = 0;
420
444
#endif
421
445
int debug = 0;
422
446
int done = 0;
 
447
int all_use_dfa = 0;
 
448
int yield = 0;
423
449
 
424
450
unsigned char *buffer;
425
451
unsigned char *dbuffer;
429
455
 
430
456
buffer = (unsigned char *)malloc(BUFFER_SIZE);
431
457
dbuffer = (unsigned char *)malloc(DBUFFER_SIZE);
432
 
 
433
 
/* Static so that new_malloc can use it. */
 
458
pbuffer = (unsigned char *)malloc(PBUFFER_SIZE);
 
459
 
 
460
/* The outfile variable is static so that new_malloc can use it. The _setmode()
 
461
stuff is some magic that I don't understand, but which apparently does good
 
462
things in Windows. It's related to line terminations.  */
 
463
 
 
464
#if defined(_WIN32) || defined(WIN32)
 
465
_setmode( _fileno( stdout ), 0x8000 );
 
466
#endif  /* defined(_WIN32) || defined(WIN32) */
434
467
 
435
468
outfile = stdout;
436
469
 
445
478
  else if (strcmp(argv[op], "-t") == 0) timeit = 1;
446
479
  else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
447
480
  else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;
 
481
#if !defined NODFA   
 
482
  else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;
 
483
#endif
448
484
  else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&
449
485
      ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)),
450
486
        *endptr == 0))
462
498
    printf("Compiled with\n");
463
499
    (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
464
500
    printf("  %sUTF-8 support\n", rc? "" : "No ");
 
501
    (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
 
502
    printf("  %sUnicode properties support\n", rc? "" : "No ");
465
503
    (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
466
504
    printf("  Newline character is %s\n", (rc == '\r')? "CR" : "LF");
467
505
    (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);
479
517
    printf("** Unknown or malformed option %s\n", argv[op]);
480
518
    printf("Usage:   pcretest [-d] [-i] [-o <n>] [-p] [-s] [-t] [<input> [<output>]]\n");
481
519
    printf("  -C     show PCRE compile-time options and exit\n");
482
 
    printf("  -d     debug: show compiled code; implies -i\n"
483
 
           "  -i     show information about compiled pattern\n"
 
520
    printf("  -d     debug: show compiled code; implies -i\n");
 
521
#if !defined NODFA
 
522
    printf("  -dfa   force DFA matching for all subjects\n");
 
523
#endif
 
524
    printf("  -i     show information about compiled pattern\n"
 
525
           "  -m     output memory used information\n"
484
526
           "  -o <n> set size of offsets vector to <n>\n");
485
527
#if !defined NOPOSIX
486
528
    printf("  -p     use POSIX interface\n");
487
529
#endif
488
 
    printf("  -s     output store information\n"
 
530
    printf("  -s     output store (memory) used information\n"
489
531
           "  -t     time compilation and execution\n");
490
 
    return 1;
 
532
    yield = 1;
 
533
    goto EXIT;
491
534
    }
492
535
  op++;
493
536
  argc--;
501
544
  {
502
545
  printf("** Failed to get %d bytes of memory for offsets vector\n",
503
546
    size_offsets_max * sizeof(int));
504
 
  return 1;
 
547
  yield = 1;
 
548
  goto EXIT;
505
549
  }
506
550
 
507
551
/* Sort out the input and output files */
508
552
 
509
553
if (argc > 1)
510
554
  {
511
 
  infile = fopen(argv[op], "r");
 
555
  infile = fopen(argv[op], "rb");
512
556
  if (infile == NULL)
513
557
    {
514
558
    printf("** Failed to open %s\n", argv[op]);
515
 
    return 1;
 
559
    yield = 1;
 
560
    goto EXIT;
516
561
    }
517
562
  }
518
563
 
519
564
if (argc > 2)
520
565
  {
521
 
  outfile = fopen(argv[op+1], "w");
 
566
  outfile = fopen(argv[op+1], "wb");
522
567
  if (outfile == NULL)
523
568
    {
524
569
    printf("** Failed to open %s\n", argv[op+1]);
525
 
    return 1;
 
570
    yield = 1;
 
571
    goto EXIT;
526
572
    }
527
573
  }
528
574
 
551
597
 
552
598
  const char *error;
553
599
  unsigned char *p, *pp, *ppp;
 
600
  unsigned char *to_file = NULL;
554
601
  const unsigned char *tables = NULL;
 
602
  unsigned long int true_size, true_study_size = 0;
 
603
  size_t size, regex_gotten_store;
555
604
  int do_study = 0;
556
605
  int do_debug = debug;
557
606
  int do_G = 0;
558
607
  int do_g = 0;
559
608
  int do_showinfo = showinfo;
560
609
  int do_showrest = 0;
 
610
  int do_flip = 0;
561
611
  int erroroffset, len, delimiter;
562
612
 
563
613
  use_utf8 = 0;
571
621
  while (isspace(*p)) p++;
572
622
  if (*p == 0) continue;
573
623
 
574
 
  /* Get the delimiter and seek the end of the pattern; if is isn't
575
 
  complete, read more. */
 
624
  /* See if the pattern is to be loaded pre-compiled from a file. */
 
625
 
 
626
  if (*p == '<' && strchr((char *)(p+1), '<') == NULL)
 
627
    {
 
628
    unsigned long int magic;
 
629
    uschar sbuf[8];
 
630
    FILE *f;
 
631
 
 
632
    p++;
 
633
    pp = p + (int)strlen((char *)p);
 
634
    while (isspace(pp[-1])) pp--;
 
635
    *pp = 0;
 
636
 
 
637
    f = fopen((char *)p, "rb");
 
638
    if (f == NULL)
 
639
      {
 
640
      fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno));
 
641
      continue;
 
642
      }
 
643
 
 
644
    if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ;
 
645
 
 
646
    true_size =
 
647
      (sbuf[0] << 24) | (sbuf[1] << 16) | (sbuf[2] << 8) | sbuf[3];
 
648
    true_study_size =
 
649
      (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];
 
650
 
 
651
    re = (real_pcre *)new_malloc(true_size);
 
652
    regex_gotten_store = gotten_store;
 
653
 
 
654
    if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;
 
655
 
 
656
    magic = ((real_pcre *)re)->magic_number;
 
657
    if (magic != MAGIC_NUMBER)
 
658
      {
 
659
      if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER)
 
660
        {
 
661
        do_flip = 1;
 
662
        }
 
663
      else
 
664
        {
 
665
        fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p);
 
666
        fclose(f);
 
667
        continue;
 
668
        }
 
669
      }
 
670
 
 
671
    fprintf(outfile, "Compiled regex%s loaded from %s\n",
 
672
      do_flip? " (byte-inverted)" : "", p);
 
673
 
 
674
    /* Need to know if UTF-8 for printing data strings */
 
675
 
 
676
    new_info(re, NULL, PCRE_INFO_OPTIONS, &options);
 
677
    use_utf8 = (options & PCRE_UTF8) != 0;
 
678
 
 
679
    /* Now see if there is any following study data */
 
680
 
 
681
    if (true_study_size != 0)
 
682
      {
 
683
      pcre_study_data *psd;
 
684
 
 
685
      extra = (pcre_extra *)new_malloc(sizeof(pcre_extra) + true_study_size);
 
686
      extra->flags = PCRE_EXTRA_STUDY_DATA;
 
687
 
 
688
      psd = (pcre_study_data *)(((char *)extra) + sizeof(pcre_extra));
 
689
      extra->study_data = psd;
 
690
 
 
691
      if (fread(psd, 1, true_study_size, f) != true_study_size)
 
692
        {
 
693
        FAIL_READ:
 
694
        fprintf(outfile, "Failed to read data from %s\n", p);
 
695
        if (extra != NULL) new_free(extra);
 
696
        if (re != NULL) new_free(re);
 
697
        fclose(f);
 
698
        continue;
 
699
        }
 
700
      fprintf(outfile, "Study data loaded from %s\n", p);
 
701
      do_study = 1;     /* To get the data output if requested */
 
702
      }
 
703
    else fprintf(outfile, "No study data\n");
 
704
 
 
705
    fclose(f);
 
706
    goto SHOW_INFO;
 
707
    }
 
708
 
 
709
  /* In-line pattern (the usual case). Get the delimiter and seek the end of
 
710
  the pattern; if is isn't complete, read more. */
576
711
 
577
712
  delimiter = *p++;
578
713
 
617
752
 
618
753
  if (pp[1] == '\\') *pp++ = '\\';
619
754
 
620
 
  /* Terminate the pattern at the delimiter */
 
755
  /* Terminate the pattern at the delimiter, and save a copy of the pattern
 
756
  for callouts. */
621
757
 
622
758
  *pp++ = 0;
 
759
  strcpy((char *)pbuffer, (char *)p);
623
760
 
624
761
  /* Look for options after final delimiter */
625
762
 
631
768
    {
632
769
    switch (*pp++)
633
770
      {
 
771
      case 'f': options |= PCRE_FIRSTLINE; break;
634
772
      case 'g': do_g = 1; break;
635
773
      case 'i': options |= PCRE_CASELESS; break;
636
774
      case 'm': options |= PCRE_MULTILINE; break;
639
777
 
640
778
      case '+': do_showrest = 1; break;
641
779
      case 'A': options |= PCRE_ANCHORED; break;
 
780
      case 'C': options |= PCRE_AUTO_CALLOUT; break;
642
781
      case 'D': do_debug = do_showinfo = 1; break;
643
782
      case 'E': options |= PCRE_DOLLAR_ENDONLY; break;
 
783
      case 'F': do_flip = 1; break;
644
784
      case 'G': do_G = 1; break;
645
785
      case 'I': do_showinfo = 1; break;
646
786
      case 'M': log_store = 1; break;
658
798
 
659
799
      case 'L':
660
800
      ppp = pp;
661
 
      while (*ppp != '\n' && *ppp != ' ') ppp++;
 
801
      /* The '\r' test here is so that it works on Windows */
 
802
      while (*ppp != '\n' && *ppp != '\r' && *ppp != ' ') ppp++;
662
803
      *ppp = 0;
663
804
      if (setlocale(LC_CTYPE, (const char *)pp) == NULL)
664
805
        {
669
810
      pp = ppp;
670
811
      break;
671
812
 
672
 
      case '\n': case ' ': break;
 
813
      case '>':
 
814
      to_file = pp;
 
815
      while (*pp != 0) pp++;
 
816
      while (isspace(pp[-1])) pp--;
 
817
      *pp = 0;
 
818
      break;
 
819
 
 
820
      case '\r':                      /* So that it works in Windows */
 
821
      case '\n':
 
822
      case ' ':
 
823
      break;
 
824
 
673
825
      default:
674
826
      fprintf(outfile, "** Unknown option '%c'\n", pp[-1]);
675
827
      goto SKIP_DATA;
685
837
    {
686
838
    int rc;
687
839
    int cflags = 0;
 
840
 
688
841
    if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE;
689
842
    if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE;
 
843
    if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL;
690
844
    rc = regcomp(&preg, (char *)p, cflags);
691
845
 
692
846
    /* Compilation failed; go back for another re, skipping to blank line
759
913
              sizeof(real_pcre) -
760
914
              ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));
761
915
 
 
916
    /* Extract the size for possible writing before possibly flipping it,
 
917
    and remember the store that was got. */
 
918
 
 
919
    true_size = ((real_pcre *)re)->size;
 
920
    regex_gotten_store = gotten_store;
 
921
 
 
922
    /* If /S was present, study the regexp to generate additional info to
 
923
    help with the matching. */
 
924
 
 
925
    if (do_study)
 
926
      {
 
927
      if (timeit)
 
928
        {
 
929
        register int i;
 
930
        clock_t time_taken;
 
931
        clock_t start_time = clock();
 
932
        for (i = 0; i < LOOPREPEAT; i++)
 
933
          extra = pcre_study(re, study_options, &error);
 
934
        time_taken = clock() - start_time;
 
935
        if (extra != NULL) free(extra);
 
936
        fprintf(outfile, "  Study time %.3f milliseconds\n",
 
937
          (((double)time_taken * 1000.0) / (double)LOOPREPEAT) /
 
938
            (double)CLOCKS_PER_SEC);
 
939
        }
 
940
      extra = pcre_study(re, study_options, &error);
 
941
      if (error != NULL)
 
942
        fprintf(outfile, "Failed to study: %s\n", error);
 
943
      else if (extra != NULL)
 
944
        true_study_size = ((pcre_study_data *)(extra->study_data))->size;
 
945
      }
 
946
 
 
947
    /* If the 'F' option was present, we flip the bytes of all the integer
 
948
    fields in the regex data block and the study block. This is to make it
 
949
    possible to test PCRE's handling of byte-flipped patterns, e.g. those
 
950
    compiled on a different architecture. */
 
951
 
 
952
    if (do_flip)
 
953
      {
 
954
      real_pcre *rre = (real_pcre *)re;
 
955
      rre->magic_number = byteflip(rre->magic_number, sizeof(rre->magic_number));
 
956
      rre->size = byteflip(rre->size, sizeof(rre->size));
 
957
      rre->options = byteflip(rre->options, sizeof(rre->options));
 
958
      rre->top_bracket = byteflip(rre->top_bracket, sizeof(rre->top_bracket));
 
959
      rre->top_backref = byteflip(rre->top_backref, sizeof(rre->top_backref));
 
960
      rre->first_byte = byteflip(rre->first_byte, sizeof(rre->first_byte));
 
961
      rre->req_byte = byteflip(rre->req_byte, sizeof(rre->req_byte));
 
962
      rre->name_table_offset = byteflip(rre->name_table_offset,
 
963
        sizeof(rre->name_table_offset));
 
964
      rre->name_entry_size = byteflip(rre->name_entry_size,
 
965
        sizeof(rre->name_entry_size));
 
966
      rre->name_count = byteflip(rre->name_count, sizeof(rre->name_count));
 
967
 
 
968
      if (extra != NULL)
 
969
        {
 
970
        pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);
 
971
        rsd->size = byteflip(rsd->size, sizeof(rsd->size));
 
972
        rsd->options = byteflip(rsd->options, sizeof(rsd->options));
 
973
        }
 
974
      }
 
975
 
 
976
    /* Extract information from the compiled data if required */
 
977
 
 
978
    SHOW_INFO:
 
979
 
762
980
    if (do_showinfo)
763
981
      {
764
 
      unsigned long int get_options;
 
982
      unsigned long int get_options, all_options;
 
983
#if !defined NOINFOCHECK
765
984
      int old_first_char, old_options, old_count;
 
985
#endif
766
986
      int count, backrefmax, first_char, need_char;
767
987
      int nameentrysize, namecount;
768
988
      const uschar *nametable;
769
 
      size_t size;
770
989
 
771
990
      if (do_debug)
772
991
        {
773
992
        fprintf(outfile, "------------------------------------------------------------------\n");
774
 
        print_internals(re, outfile);
 
993
        _pcre_printint(re, outfile);
775
994
        }
776
995
 
777
996
      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
784
1003
      new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount);
785
1004
      new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable);
786
1005
 
 
1006
#if !defined NOINFOCHECK
787
1007
      old_count = pcre_info(re, &old_options, &old_first_char);
788
1008
      if (count < 0) fprintf(outfile,
789
1009
        "Error %d from pcre_info()\n", count);
801
1021
          "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",
802
1022
            get_options, old_options);
803
1023
        }
 
1024
#endif
804
1025
 
805
 
      if (size != gotten_store) fprintf(outfile,
 
1026
      if (size != regex_gotten_store) fprintf(outfile,
806
1027
        "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n",
807
 
        size, gotten_store);
 
1028
        (int)size, (int)regex_gotten_store);
808
1029
 
809
1030
      fprintf(outfile, "Capturing subpattern count = %d\n", count);
810
1031
      if (backrefmax > 0)
822
1043
          }
823
1044
        }
824
1045
 
 
1046
      /* The NOPARTIAL bit is a private bit in the options, so we have
 
1047
      to fish it out via out back door */
 
1048
 
 
1049
      all_options = ((real_pcre *)re)->options;
 
1050
      if (do_flip)
 
1051
        {
 
1052
        all_options = byteflip(all_options, sizeof(all_options));
 
1053
        }
 
1054
 
 
1055
      if ((all_options & PCRE_NOPARTIAL) != 0)
 
1056
        fprintf(outfile, "Partial matching not supported\n");
 
1057
 
825
1058
      if (get_options == 0) fprintf(outfile, "No options\n");
826
 
        else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s\n",
 
1059
        else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s\n",
827
1060
          ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",
828
1061
          ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",
829
1062
          ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",
830
1063
          ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "",
 
1064
          ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "",
831
1065
          ((get_options & PCRE_DOTALL) != 0)? " dotall" : "",
832
1066
          ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
833
1067
          ((get_options & PCRE_EXTRA) != 0)? " extra" : "",
871
1105
        else
872
1106
          fprintf(outfile, "Need char = %d%s\n", ch, caseless);
873
1107
        }
874
 
      }
875
 
 
876
 
    /* If /S was present, study the regexp to generate additional info to
877
 
    help with the matching. */
878
 
 
879
 
    if (do_study)
880
 
      {
881
 
      if (timeit)
882
 
        {
883
 
        register int i;
884
 
        clock_t time_taken;
885
 
        clock_t start_time = clock();
886
 
        for (i = 0; i < LOOPREPEAT; i++)
887
 
          extra = pcre_study(re, study_options, &error);
888
 
        time_taken = clock() - start_time;
889
 
        if (extra != NULL) free(extra);
890
 
        fprintf(outfile, "  Study time %.3f milliseconds\n",
891
 
          (((double)time_taken * 1000.0) / (double)LOOPREPEAT) /
892
 
            (double)CLOCKS_PER_SEC);
893
 
        }
894
 
 
895
 
      extra = pcre_study(re, study_options, &error);
896
 
      if (error != NULL)
897
 
        fprintf(outfile, "Failed to study: %s\n", error);
898
 
      else if (extra == NULL)
899
 
        fprintf(outfile, "Study returned NULL\n");
900
1108
 
901
1109
      /* Don't output study size; at present it is in any case a fixed
902
1110
      value, but it varies, depending on the computer architecture, and
903
 
      so messes up the test suite. */
904
 
 
905
 
      else if (do_showinfo)
906
 
        {
907
 
        size_t size;
908
 
        uschar *start_bits = NULL;
909
 
        new_info(re, extra, PCRE_INFO_STUDYSIZE, &size);
910
 
        new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);
911
 
        /* fprintf(outfile, "Study size = %d\n", size); */
912
 
        if (start_bits == NULL)
913
 
          fprintf(outfile, "No starting character set\n");
914
 
        else
915
 
          {
916
 
          int i;
917
 
          int c = 24;
918
 
          fprintf(outfile, "Starting character set: ");
919
 
          for (i = 0; i < 256; i++)
920
 
            {
921
 
            if ((start_bits[i/8] & (1<<(i%8))) != 0)
922
 
              {
923
 
              if (c > 75)
924
 
                {
925
 
                fprintf(outfile, "\n  ");
926
 
                c = 2;
927
 
                }
928
 
              if (isprint(i) && i != ' ')
929
 
                {
930
 
                fprintf(outfile, "%c ", i);
931
 
                c += 2;
932
 
                }
933
 
              else
934
 
                {
935
 
                fprintf(outfile, "\\x%02x ", i);
936
 
                c += 5;
937
 
                }
938
 
              }
939
 
            }
940
 
          fprintf(outfile, "\n");
941
 
          }
942
 
        }
943
 
      }
944
 
    }
 
1111
      so messes up the test suite. (And with the /F option, it might be
 
1112
      flipped.) */
 
1113
 
 
1114
      if (do_study)
 
1115
        {
 
1116
        if (extra == NULL)
 
1117
          fprintf(outfile, "Study returned NULL\n");
 
1118
        else
 
1119
          {
 
1120
          uschar *start_bits = NULL;
 
1121
          new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);
 
1122
 
 
1123
          if (start_bits == NULL)
 
1124
            fprintf(outfile, "No starting byte set\n");
 
1125
          else
 
1126
            {
 
1127
            int i;
 
1128
            int c = 24;
 
1129
            fprintf(outfile, "Starting byte set: ");
 
1130
            for (i = 0; i < 256; i++)
 
1131
              {
 
1132
              if ((start_bits[i/8] & (1<<(i&7))) != 0)
 
1133
                {
 
1134
                if (c > 75)
 
1135
                  {
 
1136
                  fprintf(outfile, "\n  ");
 
1137
                  c = 2;
 
1138
                  }
 
1139
                if (isprint(i) && i != ' ')
 
1140
                  {
 
1141
                  fprintf(outfile, "%c ", i);
 
1142
                  c += 2;
 
1143
                  }
 
1144
                else
 
1145
                  {
 
1146
                  fprintf(outfile, "\\x%02x ", i);
 
1147
                  c += 5;
 
1148
                  }
 
1149
                }
 
1150
              }
 
1151
            fprintf(outfile, "\n");
 
1152
            }
 
1153
          }
 
1154
        }
 
1155
      }
 
1156
 
 
1157
    /* If the '>' option was present, we write out the regex to a file, and
 
1158
    that is all. The first 8 bytes of the file are the regex length and then
 
1159
    the study length, in big-endian order. */
 
1160
 
 
1161
    if (to_file != NULL)
 
1162
      {
 
1163
      FILE *f = fopen((char *)to_file, "wb");
 
1164
      if (f == NULL)
 
1165
        {
 
1166
        fprintf(outfile, "Unable to open %s: %s\n", to_file, strerror(errno));
 
1167
        }
 
1168
      else
 
1169
        {
 
1170
        uschar sbuf[8];
 
1171
        sbuf[0] = (true_size >> 24)  & 255;
 
1172
        sbuf[1] = (true_size >> 16)  & 255;
 
1173
        sbuf[2] = (true_size >>  8)  & 255;
 
1174
        sbuf[3] = (true_size)  & 255;
 
1175
 
 
1176
        sbuf[4] = (true_study_size >> 24)  & 255;
 
1177
        sbuf[5] = (true_study_size >> 16)  & 255;
 
1178
        sbuf[6] = (true_study_size >>  8)  & 255;
 
1179
        sbuf[7] = (true_study_size)  & 255;
 
1180
 
 
1181
        if (fwrite(sbuf, 1, 8, f) < 8 ||
 
1182
            fwrite(re, 1, true_size, f) < true_size)
 
1183
          {
 
1184
          fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno));
 
1185
          }
 
1186
        else
 
1187
          {
 
1188
          fprintf(outfile, "Compiled regex written to %s\n", to_file);
 
1189
          if (extra != NULL)
 
1190
            {
 
1191
            if (fwrite(extra->study_data, 1, true_study_size, f) <
 
1192
                true_study_size)
 
1193
              {
 
1194
              fprintf(outfile, "Write error on %s: %s\n", to_file,
 
1195
                strerror(errno));
 
1196
              }
 
1197
            else fprintf(outfile, "Study data written to %s\n", to_file);
 
1198
            }
 
1199
          }
 
1200
        fclose(f);
 
1201
        }
 
1202
 
 
1203
      new_free(re);
 
1204
      if (extra != NULL) new_free(extra);
 
1205
      if (tables != NULL) new_free((void *)tables);
 
1206
      continue;  /* With next regex */
 
1207
      }
 
1208
    }        /* End of non-POSIX compile */
945
1209
 
946
1210
  /* Read data lines and test them */
947
1211
 
961
1225
    int gmatched = 0;
962
1226
    int start_offset = 0;
963
1227
    int g_notempty = 0;
 
1228
    int use_dfa = 0;
964
1229
 
965
1230
    options = 0;
966
1231
 
1016
1281
 
1017
1282
        /* Handle \x{..} specially - new Perl thing for utf8 */
1018
1283
 
 
1284
#if !defined NOUTF8
1019
1285
        if (*p == '{')
1020
1286
          {
1021
1287
          unsigned char *pt = p;
1026
1292
            {
1027
1293
            unsigned char buff8[8];
1028
1294
            int ii, utn;
1029
 
            utn = ord2utf8(c, buff8);
 
1295
            utn = _pcre_ord2utf8(c, buff8);
1030
1296
            for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
1031
1297
            c = buff8[ii];   /* Last byte */
1032
1298
            p = pt + 1;
1034
1300
            }
1035
1301
          /* Not correct form; fall through */
1036
1302
          }
 
1303
#endif
1037
1304
 
1038
1305
        /* Ordinary \x */
1039
1306
 
1045
1312
          }
1046
1313
        break;
1047
1314
 
1048
 
        case 0:   /* Allows for an empty line */
 
1315
        case 0:   /* \ followed by EOF allows for an empty line */
1049
1316
        p--;
1050
1317
        continue;
1051
1318
 
 
1319
        case '>':
 
1320
        while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0';
 
1321
        continue;
 
1322
 
1052
1323
        case 'A':  /* Option setting */
1053
1324
        options |= PCRE_ANCHORED;
1054
1325
        continue;
1110
1381
          }
1111
1382
        continue;
1112
1383
 
 
1384
#if !defined NODFA
 
1385
        case 'D':
 
1386
#if !defined NOPOSIX
 
1387
        if (posix || do_posix)
 
1388
          printf("** Can't use dfa matching in POSIX mode: \\D ignored\n");
 
1389
        else
 
1390
#endif
 
1391
          use_dfa = 1;
 
1392
        continue;
 
1393
 
 
1394
        case 'F':
 
1395
        options |= PCRE_DFA_SHORTEST;
 
1396
        continue;
 
1397
#endif
 
1398
 
1113
1399
        case 'G':
1114
1400
        if (isdigit(*p))
1115
1401
          {
1152
1438
            {
1153
1439
            printf("** Failed to get %d bytes of memory for offsets vector\n",
1154
1440
              size_offsets_max * sizeof(int));
1155
 
            return 1;
 
1441
            yield = 1;
 
1442
            goto EXIT;
1156
1443
            }
1157
1444
          }
1158
1445
        use_size_offsets = n;
1159
1446
        if (n == 0) use_offsets = NULL;   /* Ensures it can't write to it */
1160
1447
        continue;
1161
1448
 
 
1449
        case 'P':
 
1450
        options |= PCRE_PARTIAL;
 
1451
        continue;
 
1452
 
 
1453
#if !defined NODFA
 
1454
        case 'R':
 
1455
        options |= PCRE_DFA_RESTART;
 
1456
        continue;
 
1457
#endif
 
1458
 
1162
1459
        case 'S':
1163
1460
        show_malloc = 1;
1164
1461
        continue;
1176
1473
    *q = 0;
1177
1474
    len = q - dbuffer;
1178
1475
 
 
1476
    if ((all_use_dfa || use_dfa) && find_match_limit)
 
1477
      {
 
1478
      printf("**Match limit not relevant for DFA matching: ignored\n");
 
1479
      find_match_limit = 0;
 
1480
      }
 
1481
 
1179
1482
    /* Handle matching via the POSIX interface, which does not
1180
1483
    support timing or playing with the match limit or callout data. */
1181
1484
 
1233
1536
        register int i;
1234
1537
        clock_t time_taken;
1235
1538
        clock_t start_time = clock();
 
1539
 
 
1540
#if !defined NODFA
 
1541
        if (all_use_dfa || use_dfa)
 
1542
          {
 
1543
          int workspace[1000];
 
1544
          for (i = 0; i < LOOPREPEAT; i++)
 
1545
            count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset,
 
1546
              options | g_notempty, use_offsets, use_size_offsets, workspace,
 
1547
              sizeof(workspace)/sizeof(int));
 
1548
          }
 
1549
        else
 
1550
#endif
 
1551
 
1236
1552
        for (i = 0; i < LOOPREPEAT; i++)
1237
1553
          count = pcre_exec(re, extra, (char *)bptr, len,
1238
1554
            start_offset, options | g_notempty, use_offsets, use_size_offsets);
 
1555
 
1239
1556
        time_taken = clock() - start_time;
1240
1557
        fprintf(outfile, "Execute time %.3f milliseconds\n",
1241
1558
          (((double)time_taken * 1000.0) / (double)LOOPREPEAT) /
1269
1586
            min = mid;
1270
1587
            mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2;
1271
1588
            }
1272
 
          else if (count >= 0 || count == PCRE_ERROR_NOMATCH)
 
1589
          else if (count >= 0 || count == PCRE_ERROR_NOMATCH ||
 
1590
                                 count == PCRE_ERROR_PARTIAL)
1273
1591
            {
1274
1592
            if (mid == min + 1)
1275
1593
              {
1305
1623
      /* The normal case is just to do the match once, with the default
1306
1624
      value of match_limit. */
1307
1625
 
1308
 
      else count = pcre_exec(re, extra, (char *)bptr, len,
1309
 
        start_offset, options | g_notempty, use_offsets, use_size_offsets);
 
1626
#if !defined NODFA
 
1627
      else if (all_use_dfa || use_dfa)
 
1628
        {
 
1629
        int workspace[1000];
 
1630
        count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset,
 
1631
          options | g_notempty, use_offsets, use_size_offsets, workspace,
 
1632
          sizeof(workspace)/sizeof(int));
 
1633
        if (count == 0)
 
1634
          {
 
1635
          fprintf(outfile, "Matched, but too many subsidiary matches\n");
 
1636
          count = use_size_offsets/2;
 
1637
          }
 
1638
        }
 
1639
#endif
1310
1640
 
1311
 
      if (count == 0)
 
1641
      else
1312
1642
        {
1313
 
        fprintf(outfile, "Matched, but too many substrings\n");
1314
 
        count = use_size_offsets/3;
 
1643
        count = pcre_exec(re, extra, (char *)bptr, len,
 
1644
          start_offset, options | g_notempty, use_offsets, use_size_offsets);
 
1645
        if (count == 0)
 
1646
          {
 
1647
          fprintf(outfile, "Matched, but too many substrings\n");
 
1648
          count = use_size_offsets/3;
 
1649
          }
1315
1650
        }
1316
1651
 
1317
1652
      /* Matched */
1393
1728
          }
1394
1729
        }
1395
1730
 
 
1731
      /* There was a partial match */
 
1732
 
 
1733
      else if (count == PCRE_ERROR_PARTIAL)
 
1734
        {
 
1735
        fprintf(outfile, "Partial match");
 
1736
#if !defined NODFA
 
1737
        if ((all_use_dfa || use_dfa) && use_size_offsets > 2)
 
1738
          fprintf(outfile, ": %.*s", use_offsets[1] - use_offsets[0],
 
1739
            bptr + use_offsets[0]);
 
1740
#endif
 
1741
        fprintf(outfile, "\n");
 
1742
        break;  /* Out of the /g loop */
 
1743
        }
 
1744
 
1396
1745
      /* Failed to match. If this is a /g or /G loop and we previously set
1397
1746
      g_notempty after a null match, this is not necessarily the end.
1398
1747
      We want to advance the start offset, and continue. In the case of UTF-8
1467
1816
  if (posix || do_posix) regfree(&preg);
1468
1817
#endif
1469
1818
 
1470
 
  if (re != NULL) free(re);
1471
 
  if (extra != NULL) free(extra);
 
1819
  if (re != NULL) new_free(re);
 
1820
  if (extra != NULL) new_free(extra);
1472
1821
  if (tables != NULL)
1473
1822
    {
1474
 
    free((void *)tables);
 
1823
    new_free((void *)tables);
1475
1824
    setlocale(LC_CTYPE, "C");
1476
1825
    }
1477
1826
  }
1478
1827
 
1479
1828
if (infile == stdin) fprintf(outfile, "\n");
1480
 
return 0;
 
1829
 
 
1830
EXIT:
 
1831
 
 
1832
if (infile != NULL && infile != stdin) fclose(infile);
 
1833
if (outfile != NULL && outfile != stdout) fclose(outfile);
 
1834
 
 
1835
free(buffer);
 
1836
free(dbuffer);
 
1837
free(pbuffer);
 
1838
free(offsets);
 
1839
 
 
1840
return yield;
1481
1841
}
1482
1842
 
1483
 
/* End */
 
1843
/* End of pcretest.c */