/[pcre]/code/branches/pcre16/pcre_printint.c
ViewVC logotype

Contents of /code/branches/pcre16/pcre_printint.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 810 - (show annotations)
Mon Dec 19 13:34:10 2011 UTC (3 years, 5 months ago) by ph10
File MIME type: text/plain
File size: 19811 byte(s)
Error occurred while calculating annotation data.
A lot more work on pcretest; now runs many (but not all) tests.
1 /*************************************************
2 * Perl-Compatible Regular Expressions *
3 *************************************************/
4
5 /* PCRE is a library of functions to support regular expressions whose syntax
6 and semantics are as close as possible to those of the Perl 5 language.
7
8 Written by Philip Hazel
9 Copyright (c) 1997-2010 University of Cambridge
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
40
41 /* This module contains a PCRE private debugging function for printing out the
42 internal form of a compiled regular expression, along with some supporting
43 local functions. This source file is used in two places:
44
45 (1) It is #included by pcre_compile.c when it is compiled in debugging mode
46 (PCRE_DEBUG defined in pcre_internal.h). It is not included in production
47 compiles. In this case PCRE_INCLUDED is defined.
48
49 (2) It is also compiled separately and linked with pcretest.c, which can be
50 asked to print out a compiled regex for debugging purposes. */
51
52 #ifndef PCRE_INCLUDED
53
54 #ifdef HAVE_CONFIG_H
55 #include "config.h"
56 #endif
57
58 /* We have to include pcre_internal.h because we need the internal info for
59 displaying the results of pcre_study() and we also need to know about the
60 internal macros, structures, and other internal data values; pcretest has
61 "inside information" compared to a program that strictly follows the PCRE API.
62
63 Although pcre_internal.h does itself include pcre.h, we explicitly include it
64 here before pcre_internal.h so that the PCRE_EXP_xxx macros get set
65 appropriately for an application, not for building PCRE. */
66
67 #include "pcre.h"
68 #include "pcre_internal.h"
69
70 /* These are the funtions that are contained within. It doesn't seem worth
71 having a separate .h file just for this. */
72
73 #endif /* PCRE_INCLUDED */
74
75 #ifdef PCRE_INCLUDED
76 static /* Keep the following function as private. */
77 #endif
78 #ifdef COMPILE_PCRE8
79 void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
80 #else
81 void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths);
82 #endif
83
84 /* Macro that decides whether a character should be output as a literal or in
85 hexadecimal. We don't use isprint() because that can vary from system to system
86 (even without the use of locales) and we want the output always to be the same,
87 for testing purposes. */
88
89 #ifdef EBCDIC
90 #define PRINTABLE(c) ((c) >= 64 && (c) < 255)
91 #else
92 #define PRINTABLE(c) ((c) >= 32 && (c) < 127)
93 #endif
94
95 /* The table of operator names. */
96
97 static const char *OP_names[] = { OP_NAME_LIST };
98
99 /* This table of operator lengths is not actually used by the working code,
100 but its size is needed for a check that ensures it is the correct size for the
101 number of opcodes (thus catching update omissions). */
102
103 static const pcre_uint8 OP_lengths[] = { OP_LENGTHS };
104
105
106
107 /*************************************************
108 * Print single- or multi-byte character *
109 *************************************************/
110
111 static int
112 print_char(FILE *f, pcre_uchar *ptr, BOOL utf)
113 {
114 int c = *ptr;
115
116 #ifndef SUPPORT_UTF
117 (void)utf; /* Avoid compiler warning */
118 if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
119 return 0;
120
121 #else
122
123 #ifdef COMPILE_PCRE8
124
125 if (!utf || (c & 0xc0) != 0xc0)
126 {
127 if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
128 return 0;
129 }
130 else
131 {
132 int i;
133 int a = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */
134 int s = 6*a;
135 c = (c & PRIV(utf8_table3)[a]) << s;
136 for (i = 1; i <= a; i++)
137 {
138 /* This is a check for malformed UTF-8; it should only occur if the sanity
139 check has been turned off. Rather than swallow random bytes, just stop if
140 we hit a bad one. Print it with \X instead of \x as an indication. */
141
142 if ((ptr[i] & 0xc0) != 0x80)
143 {
144 fprintf(f, "\\X{%x}", c);
145 return i - 1;
146 }
147
148 /* The byte is OK */
149
150 s -= 6;
151 c |= (ptr[i] & 0x3f) << s;
152 }
153 fprintf(f, "\\x{%x}", c);
154 return a;
155 }
156
157 #else
158
159 #ifdef COMPILE_PCRE16
160
161 if (!utf || (c & 0xfc00) != 0xd800)
162 {
163 if (PRINTABLE(c)) fprintf(f, "%c", c);
164 else if (c <= 0xff) fprintf(f, "\\x%02x", c);
165 else fprintf(f, "\\x{%x}", c);
166 return 0;
167 }
168 else
169 {
170 /* This is a check for malformed UTF-16; it should only occur if the sanity
171 check has been turned off. Rather than swallow a low surrogate, just stop if
172 we hit a bad one. Print it with \X instead of \x as an indication. */
173
174 if ((ptr[1] & 0xfc00) != 0xdc00)
175 {
176 fprintf(f, "\\X{%x}", c);
177 return 0;
178 }
179
180 c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000;
181 fprintf(f, "\\x{%x}", c);
182 return 1;
183 }
184
185 #endif /* COMPILE_PCRE16 */
186
187 #endif /* COMPILE_PCRE8 */
188
189 #endif /* SUPPORT_UTF */
190 }
191
192 /*************************************************
193 * Print uchar string (regardless of utf) *
194 *************************************************/
195
196 static void
197 print_puchar(FILE *f, PCRE_PUCHAR ptr)
198 {
199 while (*ptr != '\0')
200 {
201 register int c = *ptr++;
202 if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
203 }
204 }
205
206 /*************************************************
207 * Find Unicode property name *
208 *************************************************/
209
210 static const char *
211 get_ucpname(int ptype, int pvalue)
212 {
213 #ifdef SUPPORT_UCP
214 int i;
215 for (i = PRIV(utt_size) - 1; i >= 0; i--)
216 {
217 if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break;
218 }
219 return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??";
220 #else
221 /* It gets harder and harder to shut off unwanted compiler warnings. */
222 ptype = ptype * pvalue;
223 return (ptype == pvalue)? "??" : "??";
224 #endif
225 }
226
227
228
229 /*************************************************
230 * Print compiled regex *
231 *************************************************/
232
233 /* Make this function work for a regex with integers either byte order.
234 However, we assume that what we are passed is a compiled regex. The
235 print_lengths flag controls whether offsets and lengths of items are printed.
236 They can be turned off from pcretest so that automatic tests on bytecode can be
237 written that do not depend on the value of LINK_SIZE. */
238
239 #ifdef PCRE_INCLUDED
240 static /* Keep the following function as private. */
241 #endif
242 #ifdef COMPILE_PCRE8
243 void
244 pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
245 #else
246 void
247 pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths)
248 #endif
249 {
250 real_pcre *re = (real_pcre *)external_re;
251 pcre_uchar *codestart, *code;
252 BOOL utf;
253
254 unsigned int options = re->options;
255 int offset = re->name_table_offset;
256 int count = re->name_count;
257 int size = re->name_entry_size;
258
259 if (re->magic_number != MAGIC_NUMBER)
260 {
261 offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
262 count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
263 size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
264 options = ((options << 24) & 0xff000000) |
265 ((options << 8) & 0x00ff0000) |
266 ((options >> 8) & 0x0000ff00) |
267 ((options >> 24) & 0x000000ff);
268 }
269
270 code = codestart = (pcre_uchar *)re + offset + count * size;
271 /* PCRE_UTF16 has the same value as PCRE_UTF8. */
272 utf = (options & PCRE_UTF8) != 0;
273
274 for(;;)
275 {
276 pcre_uchar *ccode;
277 const char *flag = " ";
278 int c;
279 int extra = 0;
280
281 if (print_lengths)
282 fprintf(f, "%3d ", (int)(code - codestart));
283 else
284 fprintf(f, " ");
285
286 switch(*code)
287 {
288 /* ========================================================================== */
289 /* These cases are never obeyed. This is a fudge that causes a compile-
290 time error if the vectors OP_names or OP_lengths, which are indexed
291 by opcode, are not the correct length. It seems to be the only way to do
292 such a check at compile time, as the sizeof() operator does not work in
293 the C preprocessor. */
294
295 case OP_TABLE_LENGTH:
296 case OP_TABLE_LENGTH +
297 ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&
298 (sizeof(OP_lengths) == OP_TABLE_LENGTH)):
299 break;
300 /* ========================================================================== */
301
302 case OP_END:
303 fprintf(f, " %s\n", OP_names[*code]);
304 fprintf(f, "------------------------------------------------------------------\n");
305 return;
306
307 case OP_CHAR:
308 fprintf(f, " ");
309 do
310 {
311 code++;
312 code += 1 + print_char(f, code, utf);
313 }
314 while (*code == OP_CHAR);
315 fprintf(f, "\n");
316 continue;
317
318 case OP_CHARI:
319 fprintf(f, " /i ");
320 do
321 {
322 code++;
323 code += 1 + print_char(f, code, utf);
324 }
325 while (*code == OP_CHARI);
326 fprintf(f, "\n");
327 continue;
328
329 case OP_CBRA:
330 case OP_CBRAPOS:
331 case OP_SCBRA:
332 case OP_SCBRAPOS:
333 if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
334 else fprintf(f, " ");
335 fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));
336 break;
337
338 case OP_BRA:
339 case OP_BRAPOS:
340 case OP_SBRA:
341 case OP_SBRAPOS:
342 case OP_KETRMAX:
343 case OP_KETRMIN:
344 case OP_KETRPOS:
345 case OP_ALT:
346 case OP_KET:
347 case OP_ASSERT:
348 case OP_ASSERT_NOT:
349 case OP_ASSERTBACK:
350 case OP_ASSERTBACK_NOT:
351 case OP_ONCE:
352 case OP_ONCE_NC:
353 case OP_COND:
354 case OP_SCOND:
355 case OP_REVERSE:
356 if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
357 else fprintf(f, " ");
358 fprintf(f, "%s", OP_names[*code]);
359 break;
360
361 case OP_CLOSE:
362 fprintf(f, " %s %d", OP_names[*code], GET2(code, 1));
363 break;
364
365 case OP_CREF:
366 case OP_NCREF:
367 fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
368 break;
369
370 case OP_RREF:
371 c = GET2(code, 1);
372 if (c == RREF_ANY)
373 fprintf(f, " Cond recurse any");
374 else
375 fprintf(f, " Cond recurse %d", c);
376 break;
377
378 case OP_NRREF:
379 c = GET2(code, 1);
380 if (c == RREF_ANY)
381 fprintf(f, " Cond nrecurse any");
382 else
383 fprintf(f, " Cond nrecurse %d", c);
384 break;
385
386 case OP_DEF:
387 fprintf(f, " Cond def");
388 break;
389
390 case OP_STARI:
391 case OP_MINSTARI:
392 case OP_POSSTARI:
393 case OP_PLUSI:
394 case OP_MINPLUSI:
395 case OP_POSPLUSI:
396 case OP_QUERYI:
397 case OP_MINQUERYI:
398 case OP_POSQUERYI:
399 flag = "/i";
400 /* Fall through */
401 case OP_STAR:
402 case OP_MINSTAR:
403 case OP_POSSTAR:
404 case OP_PLUS:
405 case OP_MINPLUS:
406 case OP_POSPLUS:
407 case OP_QUERY:
408 case OP_MINQUERY:
409 case OP_POSQUERY:
410 case OP_TYPESTAR:
411 case OP_TYPEMINSTAR:
412 case OP_TYPEPOSSTAR:
413 case OP_TYPEPLUS:
414 case OP_TYPEMINPLUS:
415 case OP_TYPEPOSPLUS:
416 case OP_TYPEQUERY:
417 case OP_TYPEMINQUERY:
418 case OP_TYPEPOSQUERY:
419 fprintf(f, " %s ", flag);
420 if (*code >= OP_TYPESTAR)
421 {
422 fprintf(f, "%s", OP_names[code[1]]);
423 if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
424 {
425 fprintf(f, " %s ", get_ucpname(code[2], code[3]));
426 extra = 2;
427 }
428 }
429 else extra = print_char(f, code+1, utf);
430 fprintf(f, "%s", OP_names[*code]);
431 break;
432
433 case OP_EXACTI:
434 case OP_UPTOI:
435 case OP_MINUPTOI:
436 case OP_POSUPTOI:
437 flag = "/i";
438 /* Fall through */
439 case OP_EXACT:
440 case OP_UPTO:
441 case OP_MINUPTO:
442 case OP_POSUPTO:
443 fprintf(f, " %s ", flag);
444 extra = print_char(f, code + 1 + IMM2_SIZE, utf);
445 fprintf(f, "{");
446 if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,");
447 fprintf(f, "%d}", GET2(code,1));
448 if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?");
449 else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+");
450 break;
451
452 case OP_TYPEEXACT:
453 case OP_TYPEUPTO:
454 case OP_TYPEMINUPTO:
455 case OP_TYPEPOSUPTO:
456 fprintf(f, " %s", OP_names[code[1 + IMM2_SIZE]]);
457 if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
458 {
459 fprintf(f, " %s ", get_ucpname(code[1 + IMM2_SIZE + 1],
460 code[1 + IMM2_SIZE + 2]));
461 extra = 2;
462 }
463 fprintf(f, "{");
464 if (*code != OP_TYPEEXACT) fprintf(f, "0,");
465 fprintf(f, "%d}", GET2(code,1));
466 if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
467 else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
468 break;
469
470 case OP_NOTI:
471 flag = "/i";
472 /* Fall through */
473 case OP_NOT:
474 c = code[1];
475 if (PRINTABLE(c)) fprintf(f, " %s [^%c]", flag, c);
476 else if (utf || c > 0xff)
477 fprintf(f, " %s [^\\x{%02x}]", flag, c);
478 else
479 fprintf(f, " %s [^\\x%02x]", flag, c);
480 break;
481
482 case OP_NOTSTARI:
483 case OP_NOTMINSTARI:
484 case OP_NOTPOSSTARI:
485 case OP_NOTPLUSI:
486 case OP_NOTMINPLUSI:
487 case OP_NOTPOSPLUSI:
488 case OP_NOTQUERYI:
489 case OP_NOTMINQUERYI:
490 case OP_NOTPOSQUERYI:
491 flag = "/i";
492 /* Fall through */
493
494 case OP_NOTSTAR:
495 case OP_NOTMINSTAR:
496 case OP_NOTPOSSTAR:
497 case OP_NOTPLUS:
498 case OP_NOTMINPLUS:
499 case OP_NOTPOSPLUS:
500 case OP_NOTQUERY:
501 case OP_NOTMINQUERY:
502 case OP_NOTPOSQUERY:
503 c = code[1];
504 if (PRINTABLE(c)) fprintf(f, " %s [^%c]", flag, c);
505 else fprintf(f, " %s [^\\x%02x]", flag, c);
506 fprintf(f, "%s", OP_names[*code]);
507 break;
508
509 case OP_NOTEXACTI:
510 case OP_NOTUPTOI:
511 case OP_NOTMINUPTOI:
512 case OP_NOTPOSUPTOI:
513 flag = "/i";
514 /* Fall through */
515
516 case OP_NOTEXACT:
517 case OP_NOTUPTO:
518 case OP_NOTMINUPTO:
519 case OP_NOTPOSUPTO:
520 c = code[1 + IMM2_SIZE];
521 if (PRINTABLE(c)) fprintf(f, " %s [^%c]{", flag, c);
522 else fprintf(f, " %s [^\\x%02x]{", flag, c);
523 if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,");
524 fprintf(f, "%d}", GET2(code,1));
525 if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?");
526 else
527 if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+");
528 break;
529
530 case OP_RECURSE:
531 if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
532 else fprintf(f, " ");
533 fprintf(f, "%s", OP_names[*code]);
534 break;
535
536 case OP_REFI:
537 flag = "/i";
538 /* Fall through */
539 case OP_REF:
540 fprintf(f, " %s \\%d", flag, GET2(code,1));
541 ccode = code + PRIV(OP_lengths)[*code];
542 goto CLASS_REF_REPEAT;
543
544 case OP_CALLOUT:
545 fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2),
546 GET(code, 2 + LINK_SIZE));
547 break;
548
549 case OP_PROP:
550 case OP_NOTPROP:
551 fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1], code[2]));
552 break;
553
554 /* OP_XCLASS can only occur in UTF or PCRE16 modes. However, there's no
555 harm in having this code always here, and it makes it less messy without
556 all those #ifdefs. */
557
558 case OP_CLASS:
559 case OP_NCLASS:
560 case OP_XCLASS:
561 {
562 int i, min, max;
563 BOOL printmap;
564 pcre_uint8 *map;
565
566 fprintf(f, " [");
567
568 if (*code == OP_XCLASS)
569 {
570 extra = GET(code, 1);
571 ccode = code + LINK_SIZE + 1;
572 printmap = (*ccode & XCL_MAP) != 0;
573 if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
574 }
575 else
576 {
577 printmap = TRUE;
578 ccode = code + 1;
579 }
580
581 /* Print a bit map */
582
583 if (printmap)
584 {
585 map = (pcre_uint8 *)ccode;
586 for (i = 0; i < 256; i++)
587 {
588 if ((map[i/8] & (1 << (i&7))) != 0)
589 {
590 int j;
591 for (j = i+1; j < 256; j++)
592 if ((map[j/8] & (1 << (j&7))) == 0) break;
593 if (i == '-' || i == ']') fprintf(f, "\\");
594 if (PRINTABLE(i)) fprintf(f, "%c", i);
595 else fprintf(f, "\\x%02x", i);
596 if (--j > i)
597 {
598 if (j != i + 1) fprintf(f, "-");
599 if (j == '-' || j == ']') fprintf(f, "\\");
600 if (PRINTABLE(j)) fprintf(f, "%c", j);
601 else fprintf(f, "\\x%02x", j);
602 }
603 i = j;
604 }
605 }
606 ccode += 32 / sizeof(pcre_uchar);
607 }
608
609 /* For an XCLASS there is always some additional data */
610
611 if (*code == OP_XCLASS)
612 {
613 int ch;
614 while ((ch = *ccode++) != XCL_END)
615 {
616 if (ch == XCL_PROP)
617 {
618 int ptype = *ccode++;
619 int pvalue = *ccode++;
620 fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
621 }
622 else if (ch == XCL_NOTPROP)
623 {
624 int ptype = *ccode++;
625 int pvalue = *ccode++;
626 fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
627 }
628 else
629 {
630 ccode += 1 + print_char(f, ccode, TRUE);
631 if (ch == XCL_RANGE)
632 {
633 fprintf(f, "-");
634 ccode += 1 + print_char(f, ccode, TRUE);
635 }
636 }
637 }
638 }
639
640 /* Indicate a non-UTF class which was created by negation */
641
642 fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
643
644 /* Handle repeats after a class or a back reference */
645
646 CLASS_REF_REPEAT:
647 switch(*ccode)
648 {
649 case OP_CRSTAR:
650 case OP_CRMINSTAR:
651 case OP_CRPLUS:
652 case OP_CRMINPLUS:
653 case OP_CRQUERY:
654 case OP_CRMINQUERY:
655 fprintf(f, "%s", OP_names[*ccode]);
656 extra += PRIV(OP_lengths)[*ccode];
657 break;
658
659 case OP_CRRANGE:
660 case OP_CRMINRANGE:
661 min = GET2(ccode,1);
662 max = GET2(ccode,1 + IMM2_SIZE);
663 if (max == 0) fprintf(f, "{%d,}", min);
664 else fprintf(f, "{%d,%d}", min, max);
665 if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
666 extra += PRIV(OP_lengths)[*ccode];
667 break;
668
669 /* Do nothing if it's not a repeat; this code stops picky compilers
670 warning about the lack of a default code path. */
671
672 default:
673 break;
674 }
675 }
676 break;
677
678 case OP_MARK:
679 case OP_PRUNE_ARG:
680 case OP_SKIP_ARG:
681 case OP_THEN_ARG:
682 fprintf(f, " %s ", OP_names[*code]);
683 print_puchar(f, code + 2);
684 extra += code[1];
685 break;
686
687 case OP_THEN:
688 fprintf(f, " %s", OP_names[*code]);
689 break;
690
691 case OP_CIRCM:
692 case OP_DOLLM:
693 flag = "/m";
694 /* Fall through */
695
696 /* Anything else is just an item with no data, but possibly a flag. */
697
698 default:
699 fprintf(f, " %s %s", flag, OP_names[*code]);
700 break;
701 }
702
703 code += PRIV(OP_lengths)[*code] + extra;
704 fprintf(f, "\n");
705 }
706 }
707
708 /* End of pcre_printint.src */

  ViewVC Help
Powered by ViewVC 1.1.5