/[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 - (hide annotations) (download)
Mon Dec 19 13:34:10 2011 UTC (2 years, 4 months ago) by ph10
File MIME type: text/plain
File size: 19811 byte(s)
A lot more work on pcretest; now runs many (but not all) tests.

1 ph10 805 /*************************************************
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 zherczeg 806 compiles. In this case PCRE_INCLUDED is defined.
48 ph10 805
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 zherczeg 806 #ifndef PCRE_INCLUDED
53    
54 ph10 805 #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 zherczeg 806 #endif /* PCRE_INCLUDED */
74    
75     #ifdef PCRE_INCLUDED
76     static /* Keep the following function as private. */
77     #endif
78 ph10 805 #ifdef COMPILE_PCRE8
79     void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
80 zherczeg 806 #else
81 ph10 805 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 zherczeg 806 #ifdef PCRE_INCLUDED
240     static /* Keep the following function as private. */
241     #endif
242 ph10 805 #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 ph10 810 else if (utf || c > 0xff)
477     fprintf(f, " %s [^\\x{%02x}]", flag, c);
478     else
479     fprintf(f, " %s [^\\x%02x]", flag, c);
480 ph10 805 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 */

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12