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