"Fossies" - the Fresh Open Source Software Archive

Member "pcre-8.43/pcre_printint.c" (31 Jan 2014, 23408 Bytes) of package /linux/misc/pcre-8.43.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pcre_printint.c" see the Fossies "Dox" file reference documentation.

    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
  222 print_puchar(FILE *f, PCRE_PUCHAR ptr)
  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 */