root/ext/pcre/pcrelib/pcre_printint.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. print_char
  2. print_puchar
  3. get_ucpname
  4. print_prop
  5. pcre_printint

   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 #include "config.h"
  55 
  56 /* For pcretest program. */
  57 #define PRIV(name) name
  58 
  59 /* We have to include pcre_internal.h because we need the internal info for
  60 displaying the results of pcre_study() and we also need to know about the
  61 internal macros, structures, and other internal data values; pcretest has
  62 "inside information" compared to a program that strictly follows the PCRE API.
  63 
  64 Although pcre_internal.h does itself include pcre.h, we explicitly include it
  65 here before pcre_internal.h so that the PCRE_EXP_xxx macros get set
  66 appropriately for an application, not for building PCRE. */
  67 
  68 #include "pcre.h"
  69 #include "pcre_internal.h"
  70 
  71 /* These are the funtions that are contained within. It doesn't seem worth
  72 having a separate .h file just for this. */
  73 
  74 #endif /* PCRE_INCLUDED */
  75 
  76 #ifdef PCRE_INCLUDED
  77 static /* Keep the following function as private. */
  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 /* Macro that decides whether a character should be output as a literal or in
  89 hexadecimal. We don't use isprint() because that can vary from system to system
  90 (even without the use of locales) and we want the output always to be the same,
  91 for testing purposes. */
  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 /* The table of operator names. */
 100 
 101 static const char *priv_OP_names[] = { OP_NAME_LIST };
 102 
 103 /* This table of operator lengths is not actually used by the working code,
 104 but its size is needed for a check that ensures it is the correct size for the
 105 number of opcodes (thus catching update omissions). */
 106 
 107 static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS };
 108 
 109 
 110 
 111 /*************************************************
 112 *       Print single- or multi-byte character    *
 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;  /* Avoid compiler warning */
 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];  /* Number of additional bytes */
 143   int s = 6*a;
 144   c = (c & PRIV(utf8_table3)[a]) << s;
 145   for (i = 1; i <= a; i++)
 146     {
 147     /* This is a check for malformed UTF-8; it should only occur if the sanity
 148     check has been turned off. Rather than swallow random bytes, just stop if
 149     we hit a bad one. Print it with \X instead of \x as an indication. */
 150 
 151     if ((ptr[i] & 0xc0) != 0x80)
 152       {
 153       fprintf(f, "\\X{%x}", c);
 154       return i - 1;
 155       }
 156 
 157     /* The byte is OK */
 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   /* This is a check for malformed UTF-16; it should only occur if the sanity
 178   check has been turned off. Rather than swallow a low surrogate, just stop if
 179   we hit a bad one. Print it with \X instead of \x as an indication. */
 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   /* This is a check for malformed UTF-32; it should only occur if the sanity
 204   check has been turned off. Rather than swallow a surrogate, just stop if
 205   we hit one. Print it with \X instead of \x as an indication. */
 206   fprintf(f, "\\X{%x}", c);
 207   return 0;
 208   }
 209 
 210 #endif /* COMPILE_PCRE[8|16|32] */
 211 
 212 #endif /* SUPPORT_UTF */
 213 }
 214 
 215 /*************************************************
 216 *  Print uchar string (regardless of utf)        *
 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 *          Find Unicode property name            *
 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 /* It gets harder and harder to shut off unwanted compiler warnings. */
 245 ptype = ptype * pvalue;
 246 return (ptype == pvalue)? "??" : "??";
 247 #endif
 248 }
 249 
 250 
 251 /*************************************************
 252 *       Print Unicode property value             *
 253 *************************************************/
 254 
 255 /* "Normal" properties can be printed from tables. The PT_CLIST property is a
 256 pseudo-property that contains a pointer to a list of case-equivalent
 257 characters. This is used only when UCP support is available and UTF mode is
 258 selected. It should never occur otherwise, but just in case it does, have
 259 something ready to print. */
 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 *         Print compiled regex                   *
 288 *************************************************/
 289 
 290 /* Make this function work for a regex with integers either byte order.
 291 However, we assume that what we are passed is a compiled regex. The
 292 print_lengths flag controls whether offsets and lengths of items are printed.
 293 They can be turned off from pcretest so that automatic tests on bytecode can be
 294 written that do not depend on the value of LINK_SIZE. */
 295 
 296 #ifdef PCRE_INCLUDED
 297 static /* Keep the following function as private. */
 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 /* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
 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       /* These cases are never obeyed. This is a fudge that causes a compile-
 350       time error if the vectors OP_names or OP_lengths, which are indexed
 351       by opcode, are not the correct length. It seems to be the only way to do
 352       such a check at compile time, as the sizeof() operator does not work in
 353       the C preprocessor. */
 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     /* Fall through */
 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     /* Fall through */
 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     /* Fall through */
 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     /* Fall through */
 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     /* Fall through */
 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     /* Fall through */
 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     /* Fall through */
 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     /* OP_XCLASS cannot occur in 8-bit, non-UTF mode. However, there's no harm
 635     in having this code always here, and it makes it less messy without all
 636     those #ifdefs. */
 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       /* Print a bit map */
 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       /* For an XCLASS there is always some additional data */
 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             /* Fall through */
 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       /* Indicate a non-UTF class which was created by negation */
 760 
 761       fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
 762 
 763       /* Handle repeats after a class or a back reference */
 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         /* Do nothing if it's not a repeat; this code stops picky compilers
 794         warning about the lack of a default code path. */
 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     /* Fall through */
 819 
 820     /* Anything else is just an item with no data, but possibly a flag. */
 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 /* End of pcre_printint.src */

/* [<][>][^][v][top][bottom][index][help] */