File Coverage

deps/libgit2/deps/pcre/pcre_printint.c
Criterion Covered Total %
statement 0 238 0.0
branch 0 126 0.0
condition n/a
subroutine n/a
pod n/a
total 0 364 0.0


line stmt bran cond sub pod time code
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              
82             #if defined COMPILE_PCRE8
83             void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
84             #elif defined COMPILE_PCRE16
85             void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths);
86             #elif defined COMPILE_PCRE32
87             void pcre32_printint(pcre *external_re, FILE *f, BOOL print_lengths);
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              
117             static unsigned int
118 0           print_char(FILE *f, pcre_uchar *ptr, BOOL utf)
119             {
120 0           pcre_uint32 c = *ptr;
121              
122             #ifndef SUPPORT_UTF
123              
124             (void)utf; /* Avoid compiler warning */
125 0 0         if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
    0          
126 0 0         else if (c <= 0x80) fprintf(f, "\\x%02x", c);
127 0           else fprintf(f, "\\x{%x}", c);
128 0           return 0;
129              
130             #else
131              
132             #if defined COMPILE_PCRE8
133              
134             if (!utf || (c & 0xc0) != 0xc0)
135             {
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);
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              
168             #elif defined COMPILE_PCRE16
169              
170             if (!utf || (c & 0xfc00) != 0xd800)
171             {
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);
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              
194             #elif defined COMPILE_PCRE32
195              
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] */
213              
214             #endif /* SUPPORT_UTF */
215             }
216              
217             /*************************************************
218             * Print uchar string (regardless of utf) *
219             *************************************************/
220              
221             static void
222 0           print_puchar(FILE *f, PCRE_PUCHAR ptr)
223             {
224 0 0         while (*ptr != '\0')
225             {
226 0           register pcre_uint32 c = *ptr++;
227 0 0         if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
    0          
228             }
229 0           }
230              
231             /*************************************************
232             * Find Unicode property name *
233             *************************************************/
234              
235             static const char *
236 0           get_ucpname(unsigned int ptype, unsigned int pvalue)
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 0           ptype = ptype * pvalue;
248 0           return (ptype == pvalue)? "??" : "??";
249             #endif
250             }
251              
252              
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 0           print_prop(FILE *f, pcre_uchar *code, const char *before, const char *after)
265             {
266 0 0         if (code[1] != PT_CLIST)
267             {
268 0           fprintf(f, "%s%s %s%s", before, priv_OP_names[*code], get_ucpname(code[1],
269 0           code[2]), after);
270             }
271             else
272             {
273 0 0         const char *not = (*code == OP_PROP)? "" : "not ";
274             #ifndef SUPPORT_UCP
275 0           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 0           }
284              
285              
286              
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
301             #if defined COMPILE_PCRE8
302             void
303 0           pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
304             #elif defined COMPILE_PCRE16
305             void
306             pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths)
307             #elif defined COMPILE_PCRE32
308             void
309             pcre32_printint(pcre *external_re, FILE *f, BOOL print_lengths)
310             #endif
311             {
312 0           REAL_PCRE *re = (REAL_PCRE *)external_re;
313             pcre_uchar *codestart, *code;
314             BOOL utf;
315              
316 0           unsigned int options = re->options;
317 0           int offset = re->name_table_offset;
318 0           int count = re->name_count;
319 0           int size = re->name_entry_size;
320              
321 0 0         if (re->magic_number != MAGIC_NUMBER)
322             {
323 0           offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
324 0           count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
325 0           size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
326 0           options = ((options << 24) & 0xff000000) |
327 0           ((options << 8) & 0x00ff0000) |
328 0           ((options >> 8) & 0x0000ff00) |
329 0           ((options >> 24) & 0x000000ff);
330             }
331              
332 0           code = codestart = (pcre_uchar *)re + offset + count * size;
333             /* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
334 0           utf = (options & PCRE_UTF8) != 0;
335              
336             for(;;)
337             {
338             pcre_uchar *ccode;
339 0           const char *flag = " ";
340             pcre_uint32 c;
341 0           unsigned int extra = 0;
342              
343 0 0         if (print_lengths)
344 0           fprintf(f, "%3d ", (int)(code - codestart));
345             else
346 0           fprintf(f, " ");
347              
348 0           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 0           break;
362             /* ========================================================================== */
363              
364             case OP_END:
365 0           fprintf(f, " %s\n", priv_OP_names[*code]);
366 0           fprintf(f, "------------------------------------------------------------------\n");
367 0           return;
368              
369             case OP_CHAR:
370 0           fprintf(f, " ");
371             do
372             {
373 0           code++;
374 0           code += 1 + print_char(f, code, utf);
375             }
376 0 0         while (*code == OP_CHAR);
377 0           fprintf(f, "\n");
378 0           continue;
379              
380             case OP_CHARI:
381 0           fprintf(f, " /i ");
382             do
383             {
384 0           code++;
385 0           code += 1 + print_char(f, code, utf);
386             }
387 0 0         while (*code == OP_CHARI);
388 0           fprintf(f, "\n");
389 0           continue;
390              
391             case OP_CBRA:
392             case OP_CBRAPOS:
393             case OP_SCBRA:
394             case OP_SCBRAPOS:
395 0 0         if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
396 0           else fprintf(f, " ");
397 0           fprintf(f, "%s %d", priv_OP_names[*code], GET2(code, 1+LINK_SIZE));
398 0           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 0 0         if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
419 0           else fprintf(f, " ");
420 0           fprintf(f, "%s", priv_OP_names[*code]);
421 0           break;
422              
423             case OP_CLOSE:
424 0           fprintf(f, " %s %d", priv_OP_names[*code], GET2(code, 1));
425 0           break;
426              
427             case OP_CREF:
428 0           fprintf(f, "%3d %s", GET2(code,1), priv_OP_names[*code]);
429 0           break;
430              
431             case OP_DNCREF:
432             {
433 0           pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) +
434             IMM2_SIZE;
435 0           fprintf(f, " %s Cond ref <", flag);
436 0           print_puchar(f, entry);
437 0           fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
438             }
439 0           break;
440              
441             case OP_RREF:
442 0           c = GET2(code, 1);
443 0 0         if (c == RREF_ANY)
444 0           fprintf(f, " Cond recurse any");
445             else
446 0           fprintf(f, " Cond recurse %d", c);
447 0           break;
448              
449             case OP_DNRREF:
450             {
451 0           pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) +
452             IMM2_SIZE;
453 0           fprintf(f, " %s Cond recurse <", flag);
454 0           print_puchar(f, entry);
455 0           fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
456             }
457 0           break;
458              
459             case OP_DEF:
460 0           fprintf(f, " Cond def");
461 0           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 0           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 0           fprintf(f, " %s ", flag);
493 0 0         if (*code >= OP_TYPESTAR)
494             {
495 0 0         if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
    0          
496             {
497 0           print_prop(f, code + 1, "", " ");
498 0           extra = 2;
499             }
500 0           else fprintf(f, "%s", priv_OP_names[code[1]]);
501             }
502 0           else extra = print_char(f, code+1, utf);
503 0           fprintf(f, "%s", priv_OP_names[*code]);
504 0           break;
505              
506             case OP_EXACTI:
507             case OP_UPTOI:
508             case OP_MINUPTOI:
509             case OP_POSUPTOI:
510 0           flag = "/i";
511             /* Fall through */
512             case OP_EXACT:
513             case OP_UPTO:
514             case OP_MINUPTO:
515             case OP_POSUPTO:
516 0           fprintf(f, " %s ", flag);
517 0           extra = print_char(f, code + 1 + IMM2_SIZE, utf);
518 0           fprintf(f, "{");
519 0 0         if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,");
    0          
520 0           fprintf(f, "%d}", GET2(code,1));
521 0 0         if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?");
    0          
522 0 0         else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+");
    0          
523 0           break;
524              
525             case OP_TYPEEXACT:
526             case OP_TYPEUPTO:
527             case OP_TYPEMINUPTO:
528             case OP_TYPEPOSUPTO:
529 0 0         if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
    0          
530             {
531 0           print_prop(f, code + IMM2_SIZE + 1, " ", " ");
532 0           extra = 2;
533             }
534 0           else fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]);
535 0           fprintf(f, "{");
536 0 0         if (*code != OP_TYPEEXACT) fprintf(f, "0,");
537 0           fprintf(f, "%d}", GET2(code,1));
538 0 0         if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
539 0 0         else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
540 0           break;
541              
542             case OP_NOTI:
543 0           flag = "/i";
544             /* Fall through */
545             case OP_NOT:
546 0           fprintf(f, " %s [^", flag);
547 0           extra = print_char(f, code + 1, utf);
548 0           fprintf(f, "]");
549 0           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 0           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:
572 0           fprintf(f, " %s [^", flag);
573 0           extra = print_char(f, code + 1, utf);
574 0           fprintf(f, "]%s", priv_OP_names[*code]);
575 0           break;
576              
577             case OP_NOTEXACTI:
578             case OP_NOTUPTOI:
579             case OP_NOTMINUPTOI:
580             case OP_NOTPOSUPTOI:
581 0           flag = "/i";
582             /* Fall through */
583              
584             case OP_NOTEXACT:
585             case OP_NOTUPTO:
586             case OP_NOTMINUPTO:
587             case OP_NOTPOSUPTO:
588 0           fprintf(f, " %s [^", flag);
589 0           extra = print_char(f, code + 1 + IMM2_SIZE, utf);
590 0           fprintf(f, "]{");
591 0 0         if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,");
    0          
592 0           fprintf(f, "%d}", GET2(code,1));
593 0 0         if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?");
    0          
594             else
595 0 0         if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+");
    0          
596 0           break;
597              
598             case OP_RECURSE:
599 0 0         if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
600 0           else fprintf(f, " ");
601 0           fprintf(f, "%s", priv_OP_names[*code]);
602 0           break;
603              
604             case OP_REFI:
605 0           flag = "/i";
606             /* Fall through */
607             case OP_REF:
608 0           fprintf(f, " %s \\%d", flag, GET2(code,1));
609 0           ccode = code + priv_OP_lengths[*code];
610 0           goto CLASS_REF_REPEAT;
611              
612             case OP_DNREFI:
613 0           flag = "/i";
614             /* Fall through */
615             case OP_DNREF:
616             {
617 0           pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) +
618             IMM2_SIZE;
619 0           fprintf(f, " %s \\k<", flag);
620 0           print_puchar(f, entry);
621 0           fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
622             }
623 0           ccode = code + priv_OP_lengths[*code];
624 0           goto CLASS_REF_REPEAT;
625              
626             case OP_CALLOUT:
627 0           fprintf(f, " %s %d %d %d", priv_OP_names[*code], code[1], GET(code,2),
628 0           GET(code, 2 + LINK_SIZE));
629 0           break;
630              
631             case OP_PROP:
632             case OP_NOTPROP:
633 0           print_prop(f, code, " ", "");
634 0           break;
635              
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. */
639              
640             case OP_CLASS:
641             case OP_NCLASS:
642             case OP_XCLASS:
643             {
644             int i;
645             unsigned int min, max;
646             BOOL printmap;
647 0           BOOL invertmap = FALSE;
648             pcre_uint8 *map;
649             pcre_uint8 inverted_map[32];
650              
651 0           fprintf(f, " [");
652              
653 0 0         if (*code == OP_XCLASS)
654             {
655 0           extra = GET(code, 1);
656 0           ccode = code + LINK_SIZE + 1;
657 0           printmap = (*ccode & XCL_MAP) != 0;
658 0 0         if ((*ccode & XCL_NOT) != 0)
659             {
660 0           invertmap = (*ccode & XCL_HASPROP) == 0;
661 0           fprintf(f, "^");
662             }
663 0           ccode++;
664             }
665             else
666             {
667 0           printmap = TRUE;
668 0           ccode = code + 1;
669             }
670              
671             /* Print a bit map */
672              
673 0 0         if (printmap)
674             {
675 0           map = (pcre_uint8 *)ccode;
676 0 0         if (invertmap)
677             {
678 0 0         for (i = 0; i < 32; i++) inverted_map[i] = ~map[i];
679 0           map = inverted_map;
680             }
681              
682 0 0         for (i = 0; i < 256; i++)
683             {
684 0 0         if ((map[i/8] & (1 << (i&7))) != 0)
685             {
686             int j;
687 0 0         for (j = i+1; j < 256; j++)
688 0 0         if ((map[j/8] & (1 << (j&7))) == 0) break;
689 0 0         if (i == '-' || i == ']') fprintf(f, "\\");
    0          
690 0 0         if (PRINTABLE(i)) fprintf(f, "%c", i);
    0          
691 0           else fprintf(f, "\\x%02x", i);
692 0 0         if (--j > i)
693             {
694 0 0         if (j != i + 1) fprintf(f, "-");
695 0 0         if (j == '-' || j == ']') fprintf(f, "\\");
    0          
696 0 0         if (PRINTABLE(j)) fprintf(f, "%c", j);
    0          
697 0           else fprintf(f, "\\x%02x", j);
698             }
699 0           i = j;
700             }
701             }
702 0           ccode += 32 / sizeof(pcre_uchar);
703             }
704              
705             /* For an XCLASS there is always some additional data */
706              
707 0 0         if (*code == OP_XCLASS)
708             {
709             pcre_uchar ch;
710 0 0         while ((ch = *ccode++) != XCL_END)
711             {
712 0           BOOL not = FALSE;
713 0           const char *notch = "";
714              
715 0           switch(ch)
716             {
717             case XCL_NOTPROP:
718 0           not = TRUE;
719 0           notch = "^";
720             /* Fall through */
721              
722             case XCL_PROP:
723             {
724 0           unsigned int ptype = *ccode++;
725 0           unsigned int pvalue = *ccode++;
726              
727 0           switch(ptype)
728             {
729             case PT_PXGRAPH:
730 0           fprintf(f, "[:%sgraph:]", notch);
731 0           break;
732              
733             case PT_PXPRINT:
734 0           fprintf(f, "[:%sprint:]", notch);
735 0           break;
736              
737             case PT_PXPUNCT:
738 0           fprintf(f, "[:%spunct:]", notch);
739 0           break;
740              
741             default:
742 0 0         fprintf(f, "\\%c{%s}", (not? 'P':'p'),
743             get_ucpname(ptype, pvalue));
744 0           break;
745             }
746             }
747 0           break;
748              
749             default:
750 0           ccode += 1 + print_char(f, ccode, utf);
751 0 0         if (ch == XCL_RANGE)
752             {
753 0           fprintf(f, "-");
754 0           ccode += 1 + print_char(f, ccode, utf);
755             }
756 0           break;
757             }
758             }
759             }
760              
761             /* Indicate a non-UTF class which was created by negation */
762              
763 0 0         fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
764              
765             /* Handle repeats after a class or a back reference */
766              
767             CLASS_REF_REPEAT:
768 0           switch(*ccode)
769             {
770             case OP_CRSTAR:
771             case OP_CRMINSTAR:
772             case OP_CRPLUS:
773             case OP_CRMINPLUS:
774             case OP_CRQUERY:
775             case OP_CRMINQUERY:
776             case OP_CRPOSSTAR:
777             case OP_CRPOSPLUS:
778             case OP_CRPOSQUERY:
779 0           fprintf(f, "%s", priv_OP_names[*ccode]);
780 0           extra += priv_OP_lengths[*ccode];
781 0           break;
782              
783             case OP_CRRANGE:
784             case OP_CRMINRANGE:
785             case OP_CRPOSRANGE:
786 0           min = GET2(ccode,1);
787 0           max = GET2(ccode,1 + IMM2_SIZE);
788 0 0         if (max == 0) fprintf(f, "{%u,}", min);
789 0           else fprintf(f, "{%u,%u}", min, max);
790 0 0         if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
791 0 0         else if (*ccode == OP_CRPOSRANGE) fprintf(f, "+");
792 0           extra += priv_OP_lengths[*ccode];
793 0           break;
794              
795             /* Do nothing if it's not a repeat; this code stops picky compilers
796             warning about the lack of a default code path. */
797              
798             default:
799 0           break;
800             }
801             }
802 0           break;
803              
804             case OP_MARK:
805             case OP_PRUNE_ARG:
806             case OP_SKIP_ARG:
807             case OP_THEN_ARG:
808 0           fprintf(f, " %s ", priv_OP_names[*code]);
809 0           print_puchar(f, code + 2);
810 0           extra += code[1];
811 0           break;
812              
813             case OP_THEN:
814 0           fprintf(f, " %s", priv_OP_names[*code]);
815 0           break;
816              
817             case OP_CIRCM:
818             case OP_DOLLM:
819 0           flag = "/m";
820             /* Fall through */
821              
822             /* Anything else is just an item with no data, but possibly a flag. */
823              
824             default:
825 0           fprintf(f, " %s %s", flag, priv_OP_names[*code]);
826 0           break;
827             }
828              
829 0           code += priv_OP_lengths[*code] + extra;
830 0           fprintf(f, "\n");
831 0           }
832             }
833              
834             /* End of pcre_printint.src */