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

Contents of /code/trunk/pcretest.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 27 - (show annotations) (download)
Sat Feb 24 21:38:49 2007 UTC (7 years, 1 month ago) by nigel
File MIME type: text/plain
File size: 21406 byte(s)
Load pcre-2.02 into code/trunk.

1 /*************************************************
2 * PCRE testing program *
3 *************************************************/
4
5 #include <ctype.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <time.h>
10 #include <locale.h>
11
12 /* Use the internal info for displaying the results of pcre_study(). */
13
14 #include "internal.h"
15 #include "pcreposix.h"
16
17 #ifndef CLOCKS_PER_SEC
18 #ifdef CLK_TCK
19 #define CLOCKS_PER_SEC CLK_TCK
20 #else
21 #define CLOCKS_PER_SEC 100
22 #endif
23 #endif
24
25 #define LOOPREPEAT 20000
26
27
28 static FILE *outfile;
29 static int log_store = 0;
30
31
32
33 /* Debugging function to print the internal form of the regex. This is the same
34 code as contained in pcre.c under the DEBUG macro. */
35
36 static const char *OP_names[] = {
37 "End", "\\A", "\\B", "\\b", "\\D", "\\d",
38 "\\S", "\\s", "\\W", "\\w", "\\Z", "\\z",
39 "Opt", "^", "$", "Any", "chars", "not",
40 "*", "*?", "+", "+?", "?", "??", "{", "{", "{",
41 "*", "*?", "+", "+?", "?", "??", "{", "{", "{",
42 "*", "*?", "+", "+?", "?", "??", "{", "{", "{",
43 "*", "*?", "+", "+?", "?", "??", "{", "{",
44 "class", "Ref",
45 "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not",
46 "AssertB", "AssertB not", "Reverse", "Once", "Cond", "Cref",
47 "Brazero", "Braminzero", "Bra"
48 };
49
50
51 static void print_internals(pcre *re, FILE *outfile)
52 {
53 unsigned char *code = ((real_pcre *)re)->code;
54
55 fprintf(outfile, "------------------------------------------------------------------\n");
56
57 for(;;)
58 {
59 int c;
60 int charlength;
61
62 fprintf(outfile, "%3d ", (int)(code - ((real_pcre *)re)->code));
63
64 if (*code >= OP_BRA)
65 {
66 fprintf(outfile, "%3d Bra %d", (code[1] << 8) + code[2], *code - OP_BRA);
67 code += 2;
68 }
69
70 else switch(*code)
71 {
72 case OP_END:
73 fprintf(outfile, " %s\n", OP_names[*code]);
74 fprintf(outfile, "------------------------------------------------------------------\n");
75 return;
76
77 case OP_OPT:
78 fprintf(outfile, " %.2x %s", code[1], OP_names[*code]);
79 code++;
80 break;
81
82 case OP_COND:
83 fprintf(outfile, "%3d Cond", (code[1] << 8) + code[2]);
84 code += 2;
85 break;
86
87 case OP_CREF:
88 fprintf(outfile, " %.2d %s", code[1], OP_names[*code]);
89 code++;
90 break;
91
92 case OP_CHARS:
93 charlength = *(++code);
94 fprintf(outfile, "%3d ", charlength);
95 while (charlength-- > 0)
96 if (isprint(c = *(++code))) fprintf(outfile, "%c", c);
97 else fprintf(outfile, "\\x%02x", c);
98 break;
99
100 case OP_KETRMAX:
101 case OP_KETRMIN:
102 case OP_ALT:
103 case OP_KET:
104 case OP_ASSERT:
105 case OP_ASSERT_NOT:
106 case OP_ASSERTBACK:
107 case OP_ASSERTBACK_NOT:
108 case OP_ONCE:
109 fprintf(outfile, "%3d %s", (code[1] << 8) + code[2], OP_names[*code]);
110 code += 2;
111 break;
112
113 case OP_REVERSE:
114 fprintf(outfile, "%3d %s", (code[1] << 8) + code[2], OP_names[*code]);
115 code += 2;
116 break;
117
118 case OP_STAR:
119 case OP_MINSTAR:
120 case OP_PLUS:
121 case OP_MINPLUS:
122 case OP_QUERY:
123 case OP_MINQUERY:
124 case OP_TYPESTAR:
125 case OP_TYPEMINSTAR:
126 case OP_TYPEPLUS:
127 case OP_TYPEMINPLUS:
128 case OP_TYPEQUERY:
129 case OP_TYPEMINQUERY:
130 if (*code >= OP_TYPESTAR)
131 fprintf(outfile, " %s", OP_names[code[1]]);
132 else if (isprint(c = code[1])) fprintf(outfile, " %c", c);
133 else fprintf(outfile, " \\x%02x", c);
134 fprintf(outfile, "%s", OP_names[*code++]);
135 break;
136
137 case OP_EXACT:
138 case OP_UPTO:
139 case OP_MINUPTO:
140 if (isprint(c = code[3])) fprintf(outfile, " %c{", c);
141 else fprintf(outfile, " \\x%02x{", c);
142 if (*code != OP_EXACT) fprintf(outfile, ",");
143 fprintf(outfile, "%d}", (code[1] << 8) + code[2]);
144 if (*code == OP_MINUPTO) fprintf(outfile, "?");
145 code += 3;
146 break;
147
148 case OP_TYPEEXACT:
149 case OP_TYPEUPTO:
150 case OP_TYPEMINUPTO:
151 fprintf(outfile, " %s{", OP_names[code[3]]);
152 if (*code != OP_TYPEEXACT) fprintf(outfile, "0,");
153 fprintf(outfile, "%d}", (code[1] << 8) + code[2]);
154 if (*code == OP_TYPEMINUPTO) fprintf(outfile, "?");
155 code += 3;
156 break;
157
158 case OP_NOT:
159 if (isprint(c = *(++code))) fprintf(outfile, " [^%c]", c);
160 else fprintf(outfile, " [^\\x%02x]", c);
161 break;
162
163 case OP_NOTSTAR:
164 case OP_NOTMINSTAR:
165 case OP_NOTPLUS:
166 case OP_NOTMINPLUS:
167 case OP_NOTQUERY:
168 case OP_NOTMINQUERY:
169 if (isprint(c = code[1])) fprintf(outfile, " [^%c]", c);
170 else fprintf(outfile, " [^\\x%02x]", c);
171 fprintf(outfile, "%s", OP_names[*code++]);
172 break;
173
174 case OP_NOTEXACT:
175 case OP_NOTUPTO:
176 case OP_NOTMINUPTO:
177 if (isprint(c = code[3])) fprintf(outfile, " [^%c]{", c);
178 else fprintf(outfile, " [^\\x%02x]{", c);
179 if (*code != OP_NOTEXACT) fprintf(outfile, ",");
180 fprintf(outfile, "%d}", (code[1] << 8) + code[2]);
181 if (*code == OP_NOTMINUPTO) fprintf(outfile, "?");
182 code += 3;
183 break;
184
185 case OP_REF:
186 fprintf(outfile, " \\%d", *(++code));
187 code++;
188 goto CLASS_REF_REPEAT;
189
190 case OP_CLASS:
191 {
192 int i, min, max;
193 code++;
194 fprintf(outfile, " [");
195
196 for (i = 0; i < 256; i++)
197 {
198 if ((code[i/8] & (1 << (i&7))) != 0)
199 {
200 int j;
201 for (j = i+1; j < 256; j++)
202 if ((code[j/8] & (1 << (j&7))) == 0) break;
203 if (i == '-' || i == ']') fprintf(outfile, "\\");
204 if (isprint(i)) fprintf(outfile, "%c", i); else fprintf(outfile, "\\x%02x", i);
205 if (--j > i)
206 {
207 fprintf(outfile, "-");
208 if (j == '-' || j == ']') fprintf(outfile, "\\");
209 if (isprint(j)) fprintf(outfile, "%c", j); else fprintf(outfile, "\\x%02x", j);
210 }
211 i = j;
212 }
213 }
214 fprintf(outfile, "]");
215 code += 32;
216
217 CLASS_REF_REPEAT:
218
219 switch(*code)
220 {
221 case OP_CRSTAR:
222 case OP_CRMINSTAR:
223 case OP_CRPLUS:
224 case OP_CRMINPLUS:
225 case OP_CRQUERY:
226 case OP_CRMINQUERY:
227 fprintf(outfile, "%s", OP_names[*code]);
228 break;
229
230 case OP_CRRANGE:
231 case OP_CRMINRANGE:
232 min = (code[1] << 8) + code[2];
233 max = (code[3] << 8) + code[4];
234 if (max == 0) fprintf(outfile, "{%d,}", min);
235 else fprintf(outfile, "{%d,%d}", min, max);
236 if (*code == OP_CRMINRANGE) fprintf(outfile, "?");
237 code += 4;
238 break;
239
240 default:
241 code--;
242 }
243 }
244 break;
245
246 /* Anything else is just a one-node item */
247
248 default:
249 fprintf(outfile, " %s", OP_names[*code]);
250 break;
251 }
252
253 code++;
254 fprintf(outfile, "\n");
255 }
256 }
257
258
259
260 /* Character string printing function. */
261
262 static void pchars(unsigned char *p, int length)
263 {
264 int c;
265 while (length-- > 0)
266 if (isprint(c = *(p++))) fprintf(outfile, "%c", c);
267 else fprintf(outfile, "\\x%02x", c);
268 }
269
270
271
272 /* Alternative malloc function, to test functionality and show the size of the
273 compiled re. */
274
275 static void *new_malloc(size_t size)
276 {
277 if (log_store) fprintf(outfile, "Store size request: %d\n", (int)size);
278 return malloc(size);
279 }
280
281
282
283 /* Read lines from named file or stdin and write to named file or stdout; lines
284 consist of a regular expression, in delimiters and optionally followed by
285 options, followed by a set of test data, terminated by an empty line. */
286
287 int main(int argc, char **argv)
288 {
289 FILE *infile = stdin;
290 int options = 0;
291 int study_options = 0;
292 int op = 1;
293 int timeit = 0;
294 int showinfo = 0;
295 int posix = 0;
296 int debug = 0;
297 int done = 0;
298 unsigned char buffer[30000];
299 unsigned char dbuffer[1024];
300
301 /* Static so that new_malloc can use it. */
302
303 outfile = stdout;
304
305 /* Scan options */
306
307 while (argc > 1 && argv[op][0] == '-')
308 {
309 if (strcmp(argv[op], "-s") == 0) log_store = 1;
310 else if (strcmp(argv[op], "-t") == 0) timeit = 1;
311 else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
312 else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;
313 else if (strcmp(argv[op], "-p") == 0) posix = 1;
314 else
315 {
316 printf("*** Unknown option %s\n", argv[op]);
317 printf("Usage: pcretest [-d] [-i] [-p] [-s] [-t] [<input> [<output>]]\n");
318 printf(" -d debug: show compiled code; implies -i\n"
319 " -i show information about compiled pattern\n"
320 " -p use POSIX interface\n"
321 " -s output store information\n"
322 " -t time compilation and execution\n");
323 return 1;
324 }
325 op++;
326 argc--;
327 }
328
329 /* Sort out the input and output files */
330
331 if (argc > 1)
332 {
333 infile = fopen(argv[op], "r");
334 if (infile == NULL)
335 {
336 printf("** Failed to open %s\n", argv[op]);
337 return 1;
338 }
339 }
340
341 if (argc > 2)
342 {
343 outfile = fopen(argv[op+1], "w");
344 if (outfile == NULL)
345 {
346 printf("** Failed to open %s\n", argv[op+1]);
347 return 1;
348 }
349 }
350
351 /* Set alternative malloc function */
352
353 pcre_malloc = new_malloc;
354
355 /* Heading line, then prompt for first regex if stdin */
356
357 fprintf(outfile, "PCRE version %s\n\n", pcre_version());
358
359 /* Main loop */
360
361 while (!done)
362 {
363 pcre *re = NULL;
364 pcre_extra *extra = NULL;
365 regex_t preg;
366 const char *error;
367 unsigned char *p, *pp, *ppp;
368 unsigned const char *tables = NULL;
369 int do_study = 0;
370 int do_debug = debug;
371 int do_showinfo = showinfo;
372 int do_posix = 0;
373 int erroroffset, len, delimiter;
374
375 if (infile == stdin) printf(" re> ");
376 if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) break;
377 if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
378
379 p = buffer;
380 while (isspace(*p)) p++;
381 if (*p == 0) continue;
382
383 /* Get the delimiter and seek the end of the pattern; if is isn't
384 complete, read more. */
385
386 delimiter = *p++;
387
388 if (isalnum(delimiter))
389 {
390 fprintf(outfile, "** Delimiter must not be alphameric\n");
391 goto SKIP_DATA;
392 }
393
394 pp = p;
395
396 for(;;)
397 {
398 while (*pp != 0 && *pp != delimiter) pp++;
399 if (*pp != 0) break;
400
401 len = sizeof(buffer) - (pp - buffer);
402 if (len < 256)
403 {
404 fprintf(outfile, "** Expression too long - missing delimiter?\n");
405 goto SKIP_DATA;
406 }
407
408 if (infile == stdin) printf(" > ");
409 if (fgets((char *)pp, len, infile) == NULL)
410 {
411 fprintf(outfile, "** Unexpected EOF\n");
412 done = 1;
413 goto CONTINUE;
414 }
415 if (infile != stdin) fprintf(outfile, "%s", (char *)pp);
416 }
417
418 /* Terminate the pattern at the delimiter */
419
420 *pp++ = 0;
421
422 /* Look for options after final delimiter */
423
424 options = 0;
425 study_options = 0;
426 while (*pp != 0)
427 {
428 switch (*pp++)
429 {
430 case 'i': options |= PCRE_CASELESS; break;
431 case 'm': options |= PCRE_MULTILINE; break;
432 case 's': options |= PCRE_DOTALL; break;
433 case 'x': options |= PCRE_EXTENDED; break;
434
435 case 'A': options |= PCRE_ANCHORED; break;
436 case 'D': do_debug = do_showinfo = 1; break;
437 case 'E': options |= PCRE_DOLLAR_ENDONLY; break;
438 case 'I': do_showinfo = 1; break;
439 case 'P': do_posix = 1; break;
440 case 'S': do_study = 1; break;
441 case 'U': options |= PCRE_UNGREEDY; break;
442 case 'X': options |= PCRE_EXTRA; break;
443
444 case 'L':
445 ppp = pp;
446 while (*ppp != '\n' && *ppp != ' ') ppp++;
447 *ppp = 0;
448 if (setlocale(LC_CTYPE, (const char *)pp) == NULL)
449 {
450 fprintf(outfile, "** Failed to set locale \"%s\"\n", pp);
451 goto SKIP_DATA;
452 }
453 tables = pcre_maketables();
454 pp = ppp;
455 break;
456
457 case '\n': case ' ': break;
458 default:
459 fprintf(outfile, "** Unknown option '%c'\n", pp[-1]);
460 goto SKIP_DATA;
461 }
462 }
463
464 /* Handle compiling via the POSIX interface, which doesn't support the
465 timing, showing, or debugging options, nor the ability to pass over
466 local character tables. */
467
468 if (posix || do_posix)
469 {
470 int rc;
471 int cflags = 0;
472 if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE;
473 if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE;
474 rc = regcomp(&preg, (char *)p, cflags);
475
476 /* Compilation failed; go back for another re, skipping to blank line
477 if non-interactive. */
478
479 if (rc != 0)
480 {
481 (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer));
482 fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer);
483 goto SKIP_DATA;
484 }
485 }
486
487 /* Handle compiling via the native interface */
488
489 else
490 {
491 if (timeit)
492 {
493 register int i;
494 clock_t time_taken;
495 clock_t start_time = clock();
496 for (i = 0; i < LOOPREPEAT; i++)
497 {
498 re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
499 if (re != NULL) free(re);
500 }
501 time_taken = clock() - start_time;
502 fprintf(outfile, "Compile time %.3f milliseconds\n",
503 ((double)time_taken * 1000.0) /
504 ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
505 }
506
507 re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
508
509 /* Compilation failed; go back for another re, skipping to blank line
510 if non-interactive. */
511
512 if (re == NULL)
513 {
514 fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset);
515 SKIP_DATA:
516 if (infile != stdin)
517 {
518 for (;;)
519 {
520 if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)
521 {
522 done = 1;
523 goto CONTINUE;
524 }
525 len = (int)strlen((char *)buffer);
526 while (len > 0 && isspace(buffer[len-1])) len--;
527 if (len == 0) break;
528 }
529 fprintf(outfile, "\n");
530 }
531 goto CONTINUE;
532 }
533
534 /* Compilation succeeded; print data if required */
535
536 if (do_showinfo)
537 {
538 int first_char, count;
539
540 if (do_debug) print_internals(re, outfile);
541
542 count = pcre_info(re, &options, &first_char);
543 if (count < 0) fprintf(outfile,
544 "Error %d while reading info\n", count);
545 else
546 {
547 fprintf(outfile, "Identifying subpattern count = %d\n", count);
548 if (options == 0) fprintf(outfile, "No options\n");
549 else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s\n",
550 ((options & PCRE_ANCHORED) != 0)? " anchored" : "",
551 ((options & PCRE_CASELESS) != 0)? " caseless" : "",
552 ((options & PCRE_EXTENDED) != 0)? " extended" : "",
553 ((options & PCRE_MULTILINE) != 0)? " multiline" : "",
554 ((options & PCRE_DOTALL) != 0)? " dotall" : "",
555 ((options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
556 ((options & PCRE_EXTRA) != 0)? " extra" : "",
557 ((options & PCRE_UNGREEDY) != 0)? " ungreedy" : "");
558 if (first_char == -1)
559 {
560 fprintf(outfile, "First char at start or follows \\n\n");
561 }
562 else if (first_char < 0)
563 {
564 fprintf(outfile, "No first char\n");
565 }
566 else
567 {
568 if (isprint(first_char))
569 fprintf(outfile, "First char = \'%c\'\n", first_char);
570 else
571 fprintf(outfile, "First char = %d\n", first_char);
572 }
573 }
574 }
575
576 /* If /S was present, study the regexp to generate additional info to
577 help with the matching. */
578
579 if (do_study)
580 {
581 if (timeit)
582 {
583 register int i;
584 clock_t time_taken;
585 clock_t start_time = clock();
586 for (i = 0; i < LOOPREPEAT; i++)
587 extra = pcre_study(re, study_options, &error);
588 time_taken = clock() - start_time;
589 if (extra != NULL) free(extra);
590 fprintf(outfile, " Study time %.3f milliseconds\n",
591 ((double)time_taken * 1000.0)/
592 ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
593 }
594
595 extra = pcre_study(re, study_options, &error);
596 if (error != NULL)
597 fprintf(outfile, "Failed to study: %s\n", error);
598 else if (extra == NULL)
599 fprintf(outfile, "Study returned NULL\n");
600
601 /* This looks at internal information. A bit kludgy to do it this
602 way, but it is useful for testing. */
603
604 else if (do_showinfo)
605 {
606 real_pcre_extra *xx = (real_pcre_extra *)extra;
607 if ((xx->options & PCRE_STUDY_MAPPED) == 0)
608 fprintf(outfile, "No starting character set\n");
609 else
610 {
611 int i;
612 int c = 24;
613 fprintf(outfile, "Starting character set: ");
614 for (i = 0; i < 256; i++)
615 {
616 if ((xx->start_bits[i/8] & (1<<(i%8))) != 0)
617 {
618 if (c > 75)
619 {
620 fprintf(outfile, "\n ");
621 c = 2;
622 }
623 if (isprint(i) && i != ' ')
624 {
625 fprintf(outfile, "%c ", i);
626 c += 2;
627 }
628 else
629 {
630 fprintf(outfile, "\\x%02x ", i);
631 c += 5;
632 }
633 }
634 }
635 fprintf(outfile, "\n");
636 }
637 }
638 }
639 }
640
641 /* Read data lines and test them */
642
643 for (;;)
644 {
645 unsigned char *q;
646 int count, c;
647 int offsets[45];
648 int size_offsets = sizeof(offsets)/sizeof(int);
649
650 options = 0;
651
652 if (infile == stdin) printf(" data> ");
653 if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)
654 {
655 done = 1;
656 goto CONTINUE;
657 }
658 if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
659
660 len = (int)strlen((char *)buffer);
661 while (len > 0 && isspace(buffer[len-1])) len--;
662 buffer[len] = 0;
663 if (len == 0) break;
664
665 p = buffer;
666 while (isspace(*p)) p++;
667
668 q = dbuffer;
669 while ((c = *p++) != 0)
670 {
671 int i = 0;
672 int n = 0;
673 if (c == '\\') switch ((c = *p++))
674 {
675 case 'a': c = 7; break;
676 case 'b': c = '\b'; break;
677 case 'e': c = 27; break;
678 case 'f': c = '\f'; break;
679 case 'n': c = '\n'; break;
680 case 'r': c = '\r'; break;
681 case 't': c = '\t'; break;
682 case 'v': c = '\v'; break;
683
684 case '0': case '1': case '2': case '3':
685 case '4': case '5': case '6': case '7':
686 c -= '0';
687 while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
688 c = c * 8 + *p++ - '0';
689 break;
690
691 case 'x':
692 c = 0;
693 while (i++ < 2 && isxdigit(*p))
694 {
695 c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W');
696 p++;
697 }
698 break;
699
700 case 0: /* Allows for an empty line */
701 p--;
702 continue;
703
704 case 'A': /* Option setting */
705 options |= PCRE_ANCHORED;
706 continue;
707
708 case 'B':
709 options |= PCRE_NOTBOL;
710 continue;
711
712 case 'O':
713 while(isdigit(*p)) n = n * 10 + *p++ - '0';
714 if (n <= (int)(sizeof(offsets)/sizeof(int))) size_offsets = n;
715 continue;
716
717 case 'Z':
718 options |= PCRE_NOTEOL;
719 continue;
720 }
721 *q++ = c;
722 }
723 *q = 0;
724 len = q - dbuffer;
725
726 /* Handle matching via the POSIX interface, which does not
727 support timing. */
728
729 if (posix || do_posix)
730 {
731 int rc;
732 int eflags = 0;
733 regmatch_t pmatch[30];
734 if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;
735 if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;
736
737 rc = regexec(&preg, (char *)dbuffer, sizeof(pmatch)/sizeof(regmatch_t),
738 pmatch, eflags);
739
740 if (rc != 0)
741 {
742 (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer));
743 fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer);
744 }
745 else
746 {
747 size_t i;
748 for (i = 0; i < sizeof(pmatch)/sizeof(regmatch_t); i++)
749 {
750 if (pmatch[i].rm_so >= 0)
751 {
752 fprintf(outfile, "%2d: ", (int)i);
753 pchars(dbuffer + pmatch[i].rm_so,
754 pmatch[i].rm_eo - pmatch[i].rm_so);
755 fprintf(outfile, "\n");
756 }
757 }
758 }
759 }
760
761 /* Handle matching via the native interface */
762
763 else
764 {
765 if (timeit)
766 {
767 register int i;
768 clock_t time_taken;
769 clock_t start_time = clock();
770 for (i = 0; i < LOOPREPEAT; i++)
771 count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets,
772 size_offsets);
773 time_taken = clock() - start_time;
774 fprintf(outfile, "Execute time %.3f milliseconds\n",
775 ((double)time_taken * 1000.0)/
776 ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
777 }
778
779 count = pcre_exec(re, extra, (char *)dbuffer, len, options, offsets,
780 size_offsets);
781
782 if (count == 0)
783 {
784 fprintf(outfile, "Matched, but too many substrings\n");
785 count = size_offsets/3;
786 }
787
788 if (count >= 0)
789 {
790 int i;
791 count *= 2;
792 for (i = 0; i < count; i += 2)
793 {
794 if (offsets[i] < 0)
795 fprintf(outfile, "%2d: <unset>\n", i/2);
796 else
797 {
798 fprintf(outfile, "%2d: ", i/2);
799 pchars(dbuffer + offsets[i], offsets[i+1] - offsets[i]);
800 fprintf(outfile, "\n");
801 }
802 }
803 }
804 else
805 {
806 if (count == -1) fprintf(outfile, "No match\n");
807 else fprintf(outfile, "Error %d\n", count);
808 }
809 }
810 }
811
812 CONTINUE:
813 if (posix || do_posix) regfree(&preg);
814 if (re != NULL) free(re);
815 if (extra != NULL) free(extra);
816 if (tables != NULL)
817 {
818 free((void *)tables);
819 setlocale(LC_CTYPE, "C");
820 }
821 }
822
823 fprintf(outfile, "\n");
824 return 0;
825 }
826
827 /* End */

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12