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