NCBI C++ ToolKit
pcre_printint.c
Go to the documentation of this file.

Go to the SVN repository for this file.

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 print_char(FILE *f, pcre_uchar *ptr, BOOL utf)
119 {
120 pcre_uint32 c = *ptr;
121 
122 #ifndef SUPPORT_UTF
123 
124 (void)utf; /* Avoid compiler warning */
125 if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
126 else if (c <= 0x80) fprintf(f, "\\x%02x", c);
127 else fprintf(f, "\\x{%x}", c);
128 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
223 {
224 while (*ptr != '\0')
225  {
226  register pcre_uint32 c = *ptr++;
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 *
236 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 ptype = ptype * pvalue;
248 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 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 
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 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 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;
333 /* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
334 utf = (options & PCRE_UTF8) != 0;
335 
336 for(;;)
337  {
338  pcre_uchar *ccode;
339  const char *flag = " ";
340  pcre_uint32 c;
341  unsigned int extra = 0;
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 
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 
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 
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  }
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  {
497  print_prop(f, code + 1, "", " ");
498  extra = 2;
499  }
500  else fprintf(f, "%s", priv_OP_names[code[1]]);
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  {
531  print_prop(f, code + IMM2_SIZE + 1, " ", " ");
532  extra = 2;
533  }
534  else fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]);
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:
546  fprintf(f, " %s [^", flag);
547  extra = print_char(f, code + 1, utf);
548  fprintf(f, "]");
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:
572  fprintf(f, " %s [^", flag);
573  extra = print_char(f, code + 1, utf);
574  fprintf(f, "]%s", priv_OP_names[*code]);
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:
588  fprintf(f, " %s [^", flag);
589  extra = print_char(f, code + 1 + IMM2_SIZE, utf);
590  fprintf(f, "]{");
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 
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 
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:
633  print_prop(f, code, " ", "");
634  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  BOOL invertmap = FALSE;
648  pcre_uint8 *map;
649  pcre_uint8 inverted_map[32];
650 
651  fprintf(f, " [");
652 
653  if (*code == OP_XCLASS)
654  {
655  extra = GET(code, 1);
656  ccode = code + LINK_SIZE + 1;
657  printmap = (*ccode & XCL_MAP) != 0;
658  if ((*ccode & XCL_NOT) != 0)
659  {
660  invertmap = (*ccode & XCL_HASPROP) == 0;
661  fprintf(f, "^");
662  }
663  ccode++;
664  }
665  else
666  {
667  printmap = TRUE;
668  ccode = code + 1;
669  }
670 
671  /* Print a bit map */
672 
673  if (printmap)
674  {
675  map = (pcre_uint8 *)ccode;
676  if (invertmap)
677  {
678  for (i = 0; i < 32; i++) inverted_map[i] = ~map[i];
679  map = inverted_map;
680  }
681 
682  for (i = 0; i < 256; i++)
683  {
684  if ((map[i/8] & (1 << (i&7))) != 0)
685  {
686  int j;
687  for (j = i+1; j < 256; j++)
688  if ((map[j/8] & (1 << (j&7))) == 0) break;
689  if (i == '-' || i == ']') fprintf(f, "\\");
690  if (PRINTABLE(i)) fprintf(f, "%c", i);
691  else fprintf(f, "\\x%02x", i);
692  if (--j > i)
693  {
694  if (j != i + 1) fprintf(f, "-");
695  if (j == '-' || j == ']') fprintf(f, "\\");
696  if (PRINTABLE(j)) fprintf(f, "%c", j);
697  else fprintf(f, "\\x%02x", j);
698  }
699  i = j;
700  }
701  }
702  ccode += 32 / sizeof(pcre_uchar);
703  }
704 
705  /* For an XCLASS there is always some additional data */
706 
707  if (*code == OP_XCLASS)
708  {
709  pcre_uchar ch;
710  while ((ch = *ccode++) != XCL_END)
711  {
712  BOOL not = FALSE;
713  const char *notch = "";
714 
715  switch(ch)
716  {
717  case XCL_NOTPROP:
718  not = TRUE;
719  notch = "^";
720  /* Fall through */
721 
722  case XCL_PROP:
723  {
724  unsigned int ptype = *ccode++;
725  unsigned int pvalue = *ccode++;
726 
727  switch(ptype)
728  {
729  case PT_PXGRAPH:
730  fprintf(f, "[:%sgraph:]", notch);
731  break;
732 
733  case PT_PXPRINT:
734  fprintf(f, "[:%sprint:]", notch);
735  break;
736 
737  case PT_PXPUNCT:
738  fprintf(f, "[:%spunct:]", notch);
739  break;
740 
741  default:
742  fprintf(f, "\\%c{%s}", (not? 'P':'p'),
743  get_ucpname(ptype, pvalue));
744  break;
745  }
746  }
747  break;
748 
749  default:
750  ccode += 1 + print_char(f, ccode, utf);
751  if (ch == XCL_RANGE)
752  {
753  fprintf(f, "-");
754  ccode += 1 + print_char(f, ccode, utf);
755  }
756  break;
757  }
758  }
759  }
760 
761  /* Indicate a non-UTF class which was created by negation */
762 
763  fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
764 
765  /* Handle repeats after a class or a back reference */
766 
767  CLASS_REF_REPEAT:
768  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  fprintf(f, "%s", priv_OP_names[*ccode]);
780  extra += priv_OP_lengths[*ccode];
781  break;
782 
783  case OP_CRRANGE:
784  case OP_CRMINRANGE:
785  case OP_CRPOSRANGE:
786  min = GET2(ccode,1);
787  max = GET2(ccode,1 + IMM2_SIZE);
788  if (max == 0) fprintf(f, "{%u,}", min);
789  else fprintf(f, "{%u,%u}", min, max);
790  if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
791  else if (*ccode == OP_CRPOSRANGE) fprintf(f, "+");
792  extra += priv_OP_lengths[*ccode];
793  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  break;
800  }
801  }
802  break;
803 
804  case OP_MARK:
805  case OP_PRUNE_ARG:
806  case OP_SKIP_ARG:
807  case OP_THEN_ARG:
808  fprintf(f, " %s ", priv_OP_names[*code]);
809  print_puchar(f, code + 2);
810  extra += code[1];
811  break;
812 
813  case OP_THEN:
814  fprintf(f, " %s", priv_OP_names[*code]);
815  break;
816 
817  case OP_CIRCM:
818  case OP_DOLLM:
819  flag = "/m";
820  /* Fall through */
821 
822  /* Anything else is just an item with no data, but possibly a flag. */
823 
824  default:
825  fprintf(f, " %s %s", flag, priv_OP_names[*code]);
826  break;
827  }
828 
829  code += priv_OP_lengths[*code] + extra;
830  fprintf(f, "\n");
831  }
832 }
833 
834 /* End of pcre_printint.src */
Definition: map.hpp:338
int offset
Definition: replacements.h:160
int BOOL
Definition: sybdb.h:150
int i
const struct ncbi::grid::netcache::search::fields::SIZE size
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
unsigned int a
Definition: ncbi_localip.c:102
#define TRUE
bool replacment for C indicating true.
Definition: ncbi_std.h:97
#define FALSE
bool replacment for C indicating false.
Definition: ncbi_std.h:101
T max(T x_, T y_)
T min(T x_, T y_)
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
#define PCRE_UTF8
Definition: pcre.h:144
#define XCL_END
#define OP_NAME_LIST
#define PCRE_PUCHAR
#define XCL_HASPROP
#define PT_PXPUNCT
#define REAL_PCRE
@ OP_STARI
@ OP_END
@ OP_NOTMINSTARI
@ OP_CHAR
@ OP_CRMINQUERY
@ OP_NOTPOSUPTOI
@ OP_SBRA
@ OP_ONCE
@ OP_NOTPROP
@ OP_NOTPLUS
@ OP_TYPEMINPLUS
@ OP_TYPEQUERY
@ OP_SBRAPOS
@ OP_SCOND
@ OP_ASSERTBACK
@ OP_CIRCM
@ OP_CLASS
@ OP_TYPEPLUS
@ OP_SKIP_ARG
@ OP_MINSTARI
@ OP_CRMINPLUS
@ OP_CRRANGE
@ OP_ONCE_NC
@ OP_BRAPOS
@ OP_ASSERT_NOT
@ OP_NOTSTARI
@ OP_NOT
@ OP_DNCREF
@ OP_ASSERT
@ OP_NOTMINPLUSI
@ OP_TYPEPOSSTAR
@ OP_TYPEMINUPTO
@ OP_TYPEPOSPLUS
@ OP_POSSTAR
@ OP_NOTUPTO
@ OP_TYPESTAR
@ OP_EXACTI
@ OP_PRUNE_ARG
@ OP_NOTPLUSI
@ OP_NOTQUERYI
@ OP_THEN_ARG
@ OP_CRQUERY
@ OP_ASSERTBACK_NOT
@ OP_RREF
@ OP_DNRREF
@ OP_KETRPOS
@ OP_EXACT
@ OP_TYPEEXACT
@ OP_PLUS
@ OP_CRMINSTAR
@ OP_NOTPOSPLUSI
@ OP_KET
@ OP_CALLOUT
@ OP_CRMINRANGE
@ OP_RECURSE
@ OP_BRA
@ OP_CREF
@ OP_TABLE_LENGTH
@ OP_POSUPTO
@ OP_MINUPTOI
@ OP_NOTPOSUPTO
@ OP_REVERSE
@ OP_NCLASS
@ OP_KETRMIN
@ OP_COND
@ OP_MINPLUS
@ OP_TYPEPOSUPTO
@ OP_MINQUERY
@ OP_UPTOI
@ OP_CRPOSRANGE
@ OP_THEN
@ OP_ALT
@ OP_UPTO
@ OP_QUERY
@ OP_POSQUERYI
@ OP_NOTPOSSTARI
@ OP_PROP
@ OP_NOTPOSSTAR
@ OP_PLUSI
@ OP_KETRMAX
@ OP_NOTMINPLUS
@ OP_CBRAPOS
@ OP_QUERYI
@ OP_POSPLUSI
@ OP_CLOSE
@ OP_SCBRAPOS
@ OP_CHARI
@ OP_NOTMINQUERYI
@ OP_MARK
@ OP_TYPEMINQUERY
@ OP_NOTMINSTAR
@ OP_NOTSTAR
@ OP_SCBRA
@ OP_CRPOSSTAR
@ OP_MINUPTO
@ OP_NOTPOSQUERYI
@ OP_CRSTAR
@ OP_POSQUERY
@ OP_MINSTAR
@ OP_STAR
@ OP_DEF
@ OP_DOLLM
@ OP_CRPOSQUERY
@ OP_DNREFI
@ OP_TYPEMINSTAR
@ OP_NOTMINUPTO
@ OP_NOTMINQUERY
@ OP_CRPLUS
@ OP_TYPEPOSQUERY
@ OP_POSPLUS
@ OP_REF
@ OP_NOTPOSQUERY
@ OP_TYPEUPTO
@ OP_XCLASS
@ OP_POSSTARI
@ OP_MINQUERYI
@ OP_MINPLUSI
@ OP_NOTMINUPTOI
@ OP_NOTI
@ OP_NOTQUERY
@ OP_POSUPTOI
@ OP_CBRA
@ OP_REFI
@ OP_NOTUPTOI
@ OP_CRPOSPLUS
@ OP_DNREF
@ OP_NOTEXACTI
@ OP_NOTEXACT
@ OP_NOTPOSPLUS
#define XCL_NOTPROP
#define PT_CLIST
#define PT_PXGRAPH
#define MAGIC_NUMBER
#define XCL_NOT
#define NOTACHAR
unsigned char pcre_uint8
#define RREF_ANY
#define XCL_RANGE
#define PT_PXPRINT
unsigned char pcre_uchar
#define XCL_PROP
#define OP_LENGTHS
#define IMM2_SIZE
#define XCL_MAP
#define GET2(a, n)
static unsigned int print_char(FILE *f, pcre_uchar *ptr, BOOL utf)
void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
static const pcre_uint8 priv_OP_lengths[]
static void print_puchar(FILE *f, const pcre_uchar *ptr)
#define PRINTABLE(c)
Definition: pcre_printint.c:98
static void print_prop(FILE *f, pcre_uchar *code, const char *before, const char *after)
static const char * get_ucpname(unsigned int ptype, unsigned int pvalue)
#define PRIV(name)
Definition: pcre_printint.c:59
static const char * priv_OP_names[]
const char utf8_table4[]
Definition: pcregrep.c:415
const int utf8_table3[]
Definition: pcregrep.c:413
#define LINK_SIZE
Definition: config.h:188
Definition: inftrees.h:24
Definition: type.c:6
Modified on Mon Apr 22 04:00:07 2024 by modify_doxy.py rev. 669887