This source file includes following definitions.
- print_char
- print_puchar
- get_ucpname
- print_prop
- pcre_printint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 #ifndef PCRE_INCLUDED
53
54 #include "config.h"
55
56
57 #define PRIV(name) name
58
59
60
61
62
63
64
65
66
67
68 #include "pcre.h"
69 #include "pcre_internal.h"
70
71
72
73
74 #endif
75
76 #ifdef PCRE_INCLUDED
77 static
78 #endif
79
80 #if defined COMPILE_PCRE8
81 void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
82 #elif defined COMPILE_PCRE16
83 void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths);
84 #elif defined COMPILE_PCRE32
85 void pcre32_printint(pcre *external_re, FILE *f, BOOL print_lengths);
86 #endif
87
88
89
90
91
92
93 #ifdef EBCDIC
94 #define PRINTABLE(c) ((c) >= 64 && (c) < 255)
95 #else
96 #define PRINTABLE(c) ((c) >= 32 && (c) < 127)
97 #endif
98
99
100
101 static const char *priv_OP_names[] = { OP_NAME_LIST };
102
103
104
105
106
107 static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS };
108
109
110
111
112
113
114
115 static unsigned int
116 print_char(FILE *f, pcre_uchar *ptr, BOOL utf)
117 {
118 pcre_uint32 c = *ptr;
119
120 #ifndef SUPPORT_UTF
121
122 (void)utf;
123 if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
124 else if (c <= 0x80) fprintf(f, "\\x%02x", c);
125 else fprintf(f, "\\x{%x}", c);
126 return 0;
127
128 #else
129
130 #if defined COMPILE_PCRE8
131
132 if (!utf || (c & 0xc0) != 0xc0)
133 {
134 if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
135 else if (c < 0x80) fprintf(f, "\\x%02x", c);
136 else fprintf(f, "\\x{%02x}", c);
137 return 0;
138 }
139 else
140 {
141 int i;
142 int a = PRIV(utf8_table4)[c & 0x3f];
143 int s = 6*a;
144 c = (c & PRIV(utf8_table3)[a]) << s;
145 for (i = 1; i <= a; i++)
146 {
147
148
149
150
151 if ((ptr[i] & 0xc0) != 0x80)
152 {
153 fprintf(f, "\\X{%x}", c);
154 return i - 1;
155 }
156
157
158
159 s -= 6;
160 c |= (ptr[i] & 0x3f) << s;
161 }
162 fprintf(f, "\\x{%x}", c);
163 return a;
164 }
165
166 #elif defined COMPILE_PCRE16
167
168 if (!utf || (c & 0xfc00) != 0xd800)
169 {
170 if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
171 else if (c <= 0x80) fprintf(f, "\\x%02x", c);
172 else fprintf(f, "\\x{%02x}", c);
173 return 0;
174 }
175 else
176 {
177
178
179
180
181 if ((ptr[1] & 0xfc00) != 0xdc00)
182 {
183 fprintf(f, "\\X{%x}", c);
184 return 0;
185 }
186
187 c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000;
188 fprintf(f, "\\x{%x}", c);
189 return 1;
190 }
191
192 #elif defined COMPILE_PCRE32
193
194 if (!utf || (c & 0xfffff800u) != 0xd800u)
195 {
196 if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
197 else if (c <= 0x80) fprintf(f, "\\x%02x", c);
198 else fprintf(f, "\\x{%x}", c);
199 return 0;
200 }
201 else
202 {
203
204
205
206 fprintf(f, "\\X{%x}", c);
207 return 0;
208 }
209
210 #endif
211
212 #endif
213 }
214
215
216
217
218
219 static void
220 print_puchar(FILE *f, PCRE_PUCHAR ptr)
221 {
222 while (*ptr != '\0')
223 {
224 register pcre_uint32 c = *ptr++;
225 if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
226 }
227 }
228
229
230
231
232
233 static const char *
234 get_ucpname(unsigned int ptype, unsigned int pvalue)
235 {
236 #ifdef SUPPORT_UCP
237 int i;
238 for (i = PRIV(utt_size) - 1; i >= 0; i--)
239 {
240 if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break;
241 }
242 return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??";
243 #else
244
245 ptype = ptype * pvalue;
246 return (ptype == pvalue)? "??" : "??";
247 #endif
248 }
249
250
251
252
253
254
255
256
257
258
259
260
261 static void
262 print_prop(FILE *f, pcre_uchar *code, const char *before, const char *after)
263 {
264 if (code[1] != PT_CLIST)
265 {
266 fprintf(f, "%s%s %s%s", before, priv_OP_names[*code], get_ucpname(code[1],
267 code[2]), after);
268 }
269 else
270 {
271 const char *not = (*code == OP_PROP)? "" : "not ";
272 #ifndef SUPPORT_UCP
273 fprintf(f, "%s%sclist %d%s", before, not, code[2], after);
274 #else
275 const pcre_uint32 *p = PRIV(ucd_caseless_sets) + code[2];
276 fprintf (f, "%s%sclist", before, not);
277 while (*p < NOTACHAR) fprintf(f, " %04x", *p++);
278 fprintf(f, "%s", after);
279 #endif
280 }
281 }
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296 #ifdef PCRE_INCLUDED
297 static
298 #endif
299 #if defined COMPILE_PCRE8
300 void
301 pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
302 #elif defined COMPILE_PCRE16
303 void
304 pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths)
305 #elif defined COMPILE_PCRE32
306 void
307 pcre32_printint(pcre *external_re, FILE *f, BOOL print_lengths)
308 #endif
309 {
310 REAL_PCRE *re = (REAL_PCRE *)external_re;
311 pcre_uchar *codestart, *code;
312 BOOL utf;
313
314 unsigned int options = re->options;
315 int offset = re->name_table_offset;
316 int count = re->name_count;
317 int size = re->name_entry_size;
318
319 if (re->magic_number != MAGIC_NUMBER)
320 {
321 offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
322 count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
323 size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
324 options = ((options << 24) & 0xff000000) |
325 ((options << 8) & 0x00ff0000) |
326 ((options >> 8) & 0x0000ff00) |
327 ((options >> 24) & 0x000000ff);
328 }
329
330 code = codestart = (pcre_uchar *)re + offset + count * size;
331
332 utf = (options & PCRE_UTF8) != 0;
333
334 for(;;)
335 {
336 pcre_uchar *ccode;
337 const char *flag = " ";
338 pcre_uint32 c;
339 unsigned int extra = 0;
340
341 if (print_lengths)
342 fprintf(f, "%3d ", (int)(code - codestart));
343 else
344 fprintf(f, " ");
345
346 switch(*code)
347 {
348
349
350
351
352
353
354
355 case OP_TABLE_LENGTH:
356 case OP_TABLE_LENGTH +
357 ((sizeof(priv_OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&
358 (sizeof(priv_OP_lengths) == OP_TABLE_LENGTH)):
359 break;
360
361
362 case OP_END:
363 fprintf(f, " %s\n", priv_OP_names[*code]);
364 fprintf(f, "------------------------------------------------------------------\n");
365 return;
366
367 case OP_CHAR:
368 fprintf(f, " ");
369 do
370 {
371 code++;
372 code += 1 + print_char(f, code, utf);
373 }
374 while (*code == OP_CHAR);
375 fprintf(f, "\n");
376 continue;
377
378 case OP_CHARI:
379 fprintf(f, " /i ");
380 do
381 {
382 code++;
383 code += 1 + print_char(f, code, utf);
384 }
385 while (*code == OP_CHARI);
386 fprintf(f, "\n");
387 continue;
388
389 case OP_CBRA:
390 case OP_CBRAPOS:
391 case OP_SCBRA:
392 case OP_SCBRAPOS:
393 if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
394 else fprintf(f, " ");
395 fprintf(f, "%s %d", priv_OP_names[*code], GET2(code, 1+LINK_SIZE));
396 break;
397
398 case OP_BRA:
399 case OP_BRAPOS:
400 case OP_SBRA:
401 case OP_SBRAPOS:
402 case OP_KETRMAX:
403 case OP_KETRMIN:
404 case OP_KETRPOS:
405 case OP_ALT:
406 case OP_KET:
407 case OP_ASSERT:
408 case OP_ASSERT_NOT:
409 case OP_ASSERTBACK:
410 case OP_ASSERTBACK_NOT:
411 case OP_ONCE:
412 case OP_ONCE_NC:
413 case OP_COND:
414 case OP_SCOND:
415 case OP_REVERSE:
416 if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
417 else fprintf(f, " ");
418 fprintf(f, "%s", priv_OP_names[*code]);
419 break;
420
421 case OP_CLOSE:
422 fprintf(f, " %s %d", priv_OP_names[*code], GET2(code, 1));
423 break;
424
425 case OP_CREF:
426 fprintf(f, "%3d %s", GET2(code,1), priv_OP_names[*code]);
427 break;
428
429 case OP_DNCREF:
430 {
431 pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) +
432 IMM2_SIZE;
433 fprintf(f, " %s Cond ref <", flag);
434 print_puchar(f, entry);
435 fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
436 }
437 break;
438
439 case OP_RREF:
440 c = GET2(code, 1);
441 if (c == RREF_ANY)
442 fprintf(f, " Cond recurse any");
443 else
444 fprintf(f, " Cond recurse %d", c);
445 break;
446
447 case OP_DNRREF:
448 {
449 pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) +
450 IMM2_SIZE;
451 fprintf(f, " %s Cond recurse <", flag);
452 print_puchar(f, entry);
453 fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
454 }
455 break;
456
457 case OP_DEF:
458 fprintf(f, " Cond def");
459 break;
460
461 case OP_STARI:
462 case OP_MINSTARI:
463 case OP_POSSTARI:
464 case OP_PLUSI:
465 case OP_MINPLUSI:
466 case OP_POSPLUSI:
467 case OP_QUERYI:
468 case OP_MINQUERYI:
469 case OP_POSQUERYI:
470 flag = "/i";
471
472 case OP_STAR:
473 case OP_MINSTAR:
474 case OP_POSSTAR:
475 case OP_PLUS:
476 case OP_MINPLUS:
477 case OP_POSPLUS:
478 case OP_QUERY:
479 case OP_MINQUERY:
480 case OP_POSQUERY:
481 case OP_TYPESTAR:
482 case OP_TYPEMINSTAR:
483 case OP_TYPEPOSSTAR:
484 case OP_TYPEPLUS:
485 case OP_TYPEMINPLUS:
486 case OP_TYPEPOSPLUS:
487 case OP_TYPEQUERY:
488 case OP_TYPEMINQUERY:
489 case OP_TYPEPOSQUERY:
490 fprintf(f, " %s ", flag);
491 if (*code >= OP_TYPESTAR)
492 {
493 if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
494 {
495 print_prop(f, code + 1, "", " ");
496 extra = 2;
497 }
498 else fprintf(f, "%s", priv_OP_names[code[1]]);
499 }
500 else extra = print_char(f, code+1, utf);
501 fprintf(f, "%s", priv_OP_names[*code]);
502 break;
503
504 case OP_EXACTI:
505 case OP_UPTOI:
506 case OP_MINUPTOI:
507 case OP_POSUPTOI:
508 flag = "/i";
509
510 case OP_EXACT:
511 case OP_UPTO:
512 case OP_MINUPTO:
513 case OP_POSUPTO:
514 fprintf(f, " %s ", flag);
515 extra = print_char(f, code + 1 + IMM2_SIZE, utf);
516 fprintf(f, "{");
517 if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,");
518 fprintf(f, "%d}", GET2(code,1));
519 if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?");
520 else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+");
521 break;
522
523 case OP_TYPEEXACT:
524 case OP_TYPEUPTO:
525 case OP_TYPEMINUPTO:
526 case OP_TYPEPOSUPTO:
527 if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
528 {
529 print_prop(f, code + IMM2_SIZE + 1, " ", " ");
530 extra = 2;
531 }
532 else fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]);
533 fprintf(f, "{");
534 if (*code != OP_TYPEEXACT) fprintf(f, "0,");
535 fprintf(f, "%d}", GET2(code,1));
536 if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
537 else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
538 break;
539
540 case OP_NOTI:
541 flag = "/i";
542
543 case OP_NOT:
544 fprintf(f, " %s [^", flag);
545 extra = print_char(f, code + 1, utf);
546 fprintf(f, "]");
547 break;
548
549 case OP_NOTSTARI:
550 case OP_NOTMINSTARI:
551 case OP_NOTPOSSTARI:
552 case OP_NOTPLUSI:
553 case OP_NOTMINPLUSI:
554 case OP_NOTPOSPLUSI:
555 case OP_NOTQUERYI:
556 case OP_NOTMINQUERYI:
557 case OP_NOTPOSQUERYI:
558 flag = "/i";
559
560
561 case OP_NOTSTAR:
562 case OP_NOTMINSTAR:
563 case OP_NOTPOSSTAR:
564 case OP_NOTPLUS:
565 case OP_NOTMINPLUS:
566 case OP_NOTPOSPLUS:
567 case OP_NOTQUERY:
568 case OP_NOTMINQUERY:
569 case OP_NOTPOSQUERY:
570 fprintf(f, " %s [^", flag);
571 extra = print_char(f, code + 1, utf);
572 fprintf(f, "]%s", priv_OP_names[*code]);
573 break;
574
575 case OP_NOTEXACTI:
576 case OP_NOTUPTOI:
577 case OP_NOTMINUPTOI:
578 case OP_NOTPOSUPTOI:
579 flag = "/i";
580
581
582 case OP_NOTEXACT:
583 case OP_NOTUPTO:
584 case OP_NOTMINUPTO:
585 case OP_NOTPOSUPTO:
586 fprintf(f, " %s [^", flag);
587 extra = print_char(f, code + 1 + IMM2_SIZE, utf);
588 fprintf(f, "]{");
589 if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,");
590 fprintf(f, "%d}", GET2(code,1));
591 if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?");
592 else
593 if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+");
594 break;
595
596 case OP_RECURSE:
597 if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
598 else fprintf(f, " ");
599 fprintf(f, "%s", priv_OP_names[*code]);
600 break;
601
602 case OP_REFI:
603 flag = "/i";
604
605 case OP_REF:
606 fprintf(f, " %s \\%d", flag, GET2(code,1));
607 ccode = code + priv_OP_lengths[*code];
608 goto CLASS_REF_REPEAT;
609
610 case OP_DNREFI:
611 flag = "/i";
612
613 case OP_DNREF:
614 {
615 pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) +
616 IMM2_SIZE;
617 fprintf(f, " %s \\k<", flag);
618 print_puchar(f, entry);
619 fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
620 }
621 ccode = code + priv_OP_lengths[*code];
622 goto CLASS_REF_REPEAT;
623
624 case OP_CALLOUT:
625 fprintf(f, " %s %d %d %d", priv_OP_names[*code], code[1], GET(code,2),
626 GET(code, 2 + LINK_SIZE));
627 break;
628
629 case OP_PROP:
630 case OP_NOTPROP:
631 print_prop(f, code, " ", "");
632 break;
633
634
635
636
637
638 case OP_CLASS:
639 case OP_NCLASS:
640 case OP_XCLASS:
641 {
642 int i;
643 unsigned int min, max;
644 BOOL printmap;
645 BOOL invertmap = FALSE;
646 pcre_uint8 *map;
647 pcre_uint8 inverted_map[32];
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)
657 {
658 invertmap = (*ccode & XCL_HASPROP) == 0;
659 fprintf(f, "^");
660 }
661 ccode++;
662 }
663 else
664 {
665 printmap = TRUE;
666 ccode = code + 1;
667 }
668
669
670
671 if (printmap)
672 {
673 map = (pcre_uint8 *)ccode;
674 if (invertmap)
675 {
676 for (i = 0; i < 32; i++) inverted_map[i] = ~map[i];
677 map = inverted_map;
678 }
679
680 for (i = 0; i < 256; i++)
681 {
682 if ((map[i/8] & (1 << (i&7))) != 0)
683 {
684 int j;
685 for (j = i+1; j < 256; j++)
686 if ((map[j/8] & (1 << (j&7))) == 0) break;
687 if (i == '-' || i == ']') fprintf(f, "\\");
688 if (PRINTABLE(i)) fprintf(f, "%c", i);
689 else fprintf(f, "\\x%02x", i);
690 if (--j > i)
691 {
692 if (j != i + 1) fprintf(f, "-");
693 if (j == '-' || j == ']') fprintf(f, "\\");
694 if (PRINTABLE(j)) fprintf(f, "%c", j);
695 else fprintf(f, "\\x%02x", j);
696 }
697 i = j;
698 }
699 }
700 ccode += 32 / sizeof(pcre_uchar);
701 }
702
703
704
705 if (*code == OP_XCLASS)
706 {
707 pcre_uchar ch;
708 while ((ch = *ccode++) != XCL_END)
709 {
710 BOOL not = FALSE;
711 const char *notch = "";
712
713 switch(ch)
714 {
715 case XCL_NOTPROP:
716 not = TRUE;
717 notch = "^";
718
719
720 case XCL_PROP:
721 {
722 unsigned int ptype = *ccode++;
723 unsigned int pvalue = *ccode++;
724
725 switch(ptype)
726 {
727 case PT_PXGRAPH:
728 fprintf(f, "[:%sgraph:]", notch);
729 break;
730
731 case PT_PXPRINT:
732 fprintf(f, "[:%sprint:]", notch);
733 break;
734
735 case PT_PXPUNCT:
736 fprintf(f, "[:%spunct:]", notch);
737 break;
738
739 default:
740 fprintf(f, "\\%c{%s}", (not? 'P':'p'),
741 get_ucpname(ptype, pvalue));
742 break;
743 }
744 }
745 break;
746
747 default:
748 ccode += 1 + print_char(f, ccode, utf);
749 if (ch == XCL_RANGE)
750 {
751 fprintf(f, "-");
752 ccode += 1 + print_char(f, ccode, utf);
753 }
754 break;
755 }
756 }
757 }
758
759
760
761 fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
762
763
764
765 CLASS_REF_REPEAT:
766 switch(*ccode)
767 {
768 case OP_CRSTAR:
769 case OP_CRMINSTAR:
770 case OP_CRPLUS:
771 case OP_CRMINPLUS:
772 case OP_CRQUERY:
773 case OP_CRMINQUERY:
774 case OP_CRPOSSTAR:
775 case OP_CRPOSPLUS:
776 case OP_CRPOSQUERY:
777 fprintf(f, "%s", priv_OP_names[*ccode]);
778 extra += priv_OP_lengths[*ccode];
779 break;
780
781 case OP_CRRANGE:
782 case OP_CRMINRANGE:
783 case OP_CRPOSRANGE:
784 min = GET2(ccode,1);
785 max = GET2(ccode,1 + IMM2_SIZE);
786 if (max == 0) fprintf(f, "{%u,}", min);
787 else fprintf(f, "{%u,%u}", min, max);
788 if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
789 else if (*ccode == OP_CRPOSRANGE) fprintf(f, "+");
790 extra += priv_OP_lengths[*ccode];
791 break;
792
793
794
795
796 default:
797 break;
798 }
799 }
800 break;
801
802 case OP_MARK:
803 case OP_PRUNE_ARG:
804 case OP_SKIP_ARG:
805 case OP_THEN_ARG:
806 fprintf(f, " %s ", priv_OP_names[*code]);
807 print_puchar(f, code + 2);
808 extra += code[1];
809 break;
810
811 case OP_THEN:
812 fprintf(f, " %s", priv_OP_names[*code]);
813 break;
814
815 case OP_CIRCM:
816 case OP_DOLLM:
817 flag = "/m";
818
819
820
821
822 default:
823 fprintf(f, " %s %s", flag, priv_OP_names[*code]);
824 break;
825 }
826
827 code += priv_OP_lengths[*code] + extra;
828 fprintf(f, "\n");
829 }
830 }
831
832