File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pcre / pcre_printint.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:50:25 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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: #ifdef COMPILE_PCRE8
   82: void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
   83: #else
   84: void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths);
   85: #endif
   86: 
   87: /* Macro that decides whether a character should be output as a literal or in
   88: hexadecimal. We don't use isprint() because that can vary from system to system
   89: (even without the use of locales) and we want the output always to be the same,
   90: for testing purposes. */
   91: 
   92: #ifdef EBCDIC
   93: #define PRINTABLE(c) ((c) >= 64 && (c) < 255)
   94: #else
   95: #define PRINTABLE(c) ((c) >= 32 && (c) < 127)
   96: #endif
   97: 
   98: /* The table of operator names. */
   99: 
  100: static const char *priv_OP_names[] = { OP_NAME_LIST };
  101: 
  102: /* This table of operator lengths is not actually used by the working code,
  103: but its size is needed for a check that ensures it is the correct size for the
  104: number of opcodes (thus catching update omissions). */
  105: 
  106: static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS };
  107: 
  108: 
  109: 
  110: /*************************************************
  111: *       Print single- or multi-byte character    *
  112: *************************************************/
  113: 
  114: static int
  115: print_char(FILE *f, pcre_uchar *ptr, BOOL utf)
  116: {
  117: int c = *ptr;
  118: 
  119: #ifndef SUPPORT_UTF
  120: 
  121: (void)utf;  /* Avoid compiler warning */
  122: if (PRINTABLE(c)) fprintf(f, "%c", c);
  123: else if (c <= 0xff) fprintf(f, "\\x%02x", c);
  124: else fprintf(f, "\\x{%x}", c);
  125: return 0;
  126: 
  127: #else
  128: 
  129: #ifdef COMPILE_PCRE8
  130: 
  131: if (!utf || (c & 0xc0) != 0xc0)
  132:   {
  133:   if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
  134:   return 0;
  135:   }
  136: else
  137:   {
  138:   int i;
  139:   int a = PRIV(utf8_table4)[c & 0x3f];  /* Number of additional bytes */
  140:   int s = 6*a;
  141:   c = (c & PRIV(utf8_table3)[a]) << s;
  142:   for (i = 1; i <= a; i++)
  143:     {
  144:     /* This is a check for malformed UTF-8; it should only occur if the sanity
  145:     check has been turned off. Rather than swallow random bytes, just stop if
  146:     we hit a bad one. Print it with \X instead of \x as an indication. */
  147: 
  148:     if ((ptr[i] & 0xc0) != 0x80)
  149:       {
  150:       fprintf(f, "\\X{%x}", c);
  151:       return i - 1;
  152:       }
  153: 
  154:     /* The byte is OK */
  155: 
  156:     s -= 6;
  157:     c |= (ptr[i] & 0x3f) << s;
  158:     }
  159:   fprintf(f, "\\x{%x}", c);
  160:   return a;
  161:   }
  162: 
  163: #else
  164: 
  165: #ifdef COMPILE_PCRE16
  166: 
  167: if (!utf || (c & 0xfc00) != 0xd800)
  168:   {
  169:   if (PRINTABLE(c)) fprintf(f, "%c", c);
  170:   else if (c <= 0xff) fprintf(f, "\\x%02x", c);
  171:   else fprintf(f, "\\x{%x}", c);
  172:   return 0;
  173:   }
  174: else
  175:   {
  176:   /* This is a check for malformed UTF-16; it should only occur if the sanity
  177:   check has been turned off. Rather than swallow a low surrogate, just stop if
  178:   we hit a bad one. Print it with \X instead of \x as an indication. */
  179: 
  180:   if ((ptr[1] & 0xfc00) != 0xdc00)
  181:     {
  182:     fprintf(f, "\\X{%x}", c);
  183:     return 0;
  184:     }
  185: 
  186:   c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000;
  187:   fprintf(f, "\\x{%x}", c);
  188:   return 1;
  189:   }
  190: 
  191: #endif /* COMPILE_PCRE16 */
  192: 
  193: #endif /* COMPILE_PCRE8 */
  194: 
  195: #endif /* SUPPORT_UTF */
  196: }
  197: 
  198: /*************************************************
  199: *  Print uchar string (regardless of utf)        *
  200: *************************************************/
  201: 
  202: static void
  203: print_puchar(FILE *f, PCRE_PUCHAR ptr)
  204: {
  205: while (*ptr != '\0')
  206:   {
  207:   register int c = *ptr++;
  208:   if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
  209:   }
  210: }
  211: 
  212: /*************************************************
  213: *          Find Unicode property name            *
  214: *************************************************/
  215: 
  216: static const char *
  217: get_ucpname(int ptype, int pvalue)
  218: {
  219: #ifdef SUPPORT_UCP
  220: int i;
  221: for (i = PRIV(utt_size) - 1; i >= 0; i--)
  222:   {
  223:   if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break;
  224:   }
  225: return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??";
  226: #else
  227: /* It gets harder and harder to shut off unwanted compiler warnings. */
  228: ptype = ptype * pvalue;
  229: return (ptype == pvalue)? "??" : "??";
  230: #endif
  231: }
  232: 
  233: 
  234: 
  235: /*************************************************
  236: *         Print compiled regex                   *
  237: *************************************************/
  238: 
  239: /* Make this function work for a regex with integers either byte order.
  240: However, we assume that what we are passed is a compiled regex. The
  241: print_lengths flag controls whether offsets and lengths of items are printed.
  242: They can be turned off from pcretest so that automatic tests on bytecode can be
  243: written that do not depend on the value of LINK_SIZE. */
  244: 
  245: #ifdef PCRE_INCLUDED
  246: static /* Keep the following function as private. */
  247: #endif
  248: #ifdef COMPILE_PCRE8
  249: void
  250: pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
  251: #else
  252: void
  253: pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths)
  254: #endif
  255: {
  256: REAL_PCRE *re = (REAL_PCRE *)external_re;
  257: pcre_uchar *codestart, *code;
  258: BOOL utf;
  259: 
  260: unsigned int options = re->options;
  261: int offset = re->name_table_offset;
  262: int count = re->name_count;
  263: int size = re->name_entry_size;
  264: 
  265: if (re->magic_number != MAGIC_NUMBER)
  266:   {
  267:   offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
  268:   count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
  269:   size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
  270:   options = ((options << 24) & 0xff000000) |
  271:             ((options <<  8) & 0x00ff0000) |
  272:             ((options >>  8) & 0x0000ff00) |
  273:             ((options >> 24) & 0x000000ff);
  274:   }
  275: 
  276: code = codestart = (pcre_uchar *)re + offset + count * size;
  277: /* PCRE_UTF16 has the same value as PCRE_UTF8. */
  278: utf = (options & PCRE_UTF8) != 0;
  279: 
  280: for(;;)
  281:   {
  282:   pcre_uchar *ccode;
  283:   const char *flag = "  ";
  284:   int c;
  285:   int extra = 0;
  286: 
  287:   if (print_lengths)
  288:     fprintf(f, "%3d ", (int)(code - codestart));
  289:   else
  290:     fprintf(f, "    ");
  291: 
  292:   switch(*code)
  293:     {
  294: /* ========================================================================== */
  295:       /* These cases are never obeyed. This is a fudge that causes a compile-
  296:       time error if the vectors OP_names or OP_lengths, which are indexed
  297:       by opcode, are not the correct length. It seems to be the only way to do
  298:       such a check at compile time, as the sizeof() operator does not work in
  299:       the C preprocessor. */
  300: 
  301:       case OP_TABLE_LENGTH:
  302:       case OP_TABLE_LENGTH +
  303:         ((sizeof(priv_OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&
  304:         (sizeof(priv_OP_lengths) == OP_TABLE_LENGTH)):
  305:       break;
  306: /* ========================================================================== */
  307: 
  308:     case OP_END:
  309:     fprintf(f, "    %s\n", priv_OP_names[*code]);
  310:     fprintf(f, "------------------------------------------------------------------\n");
  311:     return;
  312: 
  313:     case OP_CHAR:
  314:     fprintf(f, "    ");
  315:     do
  316:       {
  317:       code++;
  318:       code += 1 + print_char(f, code, utf);
  319:       }
  320:     while (*code == OP_CHAR);
  321:     fprintf(f, "\n");
  322:     continue;
  323: 
  324:     case OP_CHARI:
  325:     fprintf(f, " /i ");
  326:     do
  327:       {
  328:       code++;
  329:       code += 1 + print_char(f, code, utf);
  330:       }
  331:     while (*code == OP_CHARI);
  332:     fprintf(f, "\n");
  333:     continue;
  334: 
  335:     case OP_CBRA:
  336:     case OP_CBRAPOS:
  337:     case OP_SCBRA:
  338:     case OP_SCBRAPOS:
  339:     if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
  340:       else fprintf(f, "    ");
  341:     fprintf(f, "%s %d", priv_OP_names[*code], GET2(code, 1+LINK_SIZE));
  342:     break;
  343: 
  344:     case OP_BRA:
  345:     case OP_BRAPOS:
  346:     case OP_SBRA:
  347:     case OP_SBRAPOS:
  348:     case OP_KETRMAX:
  349:     case OP_KETRMIN:
  350:     case OP_KETRPOS:
  351:     case OP_ALT:
  352:     case OP_KET:
  353:     case OP_ASSERT:
  354:     case OP_ASSERT_NOT:
  355:     case OP_ASSERTBACK:
  356:     case OP_ASSERTBACK_NOT:
  357:     case OP_ONCE:
  358:     case OP_ONCE_NC:
  359:     case OP_COND:
  360:     case OP_SCOND:
  361:     case OP_REVERSE:
  362:     if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
  363:       else fprintf(f, "    ");
  364:     fprintf(f, "%s", priv_OP_names[*code]);
  365:     break;
  366: 
  367:     case OP_CLOSE:
  368:     fprintf(f, "    %s %d", priv_OP_names[*code], GET2(code, 1));
  369:     break;
  370: 
  371:     case OP_CREF:
  372:     case OP_NCREF:
  373:     fprintf(f, "%3d %s", GET2(code,1), priv_OP_names[*code]);
  374:     break;
  375: 
  376:     case OP_RREF:
  377:     c = GET2(code, 1);
  378:     if (c == RREF_ANY)
  379:       fprintf(f, "    Cond recurse any");
  380:     else
  381:       fprintf(f, "    Cond recurse %d", c);
  382:     break;
  383: 
  384:     case OP_NRREF:
  385:     c = GET2(code, 1);
  386:     if (c == RREF_ANY)
  387:       fprintf(f, "    Cond nrecurse any");
  388:     else
  389:       fprintf(f, "    Cond nrecurse %d", c);
  390:     break;
  391: 
  392:     case OP_DEF:
  393:     fprintf(f, "    Cond def");
  394:     break;
  395: 
  396:     case OP_STARI:
  397:     case OP_MINSTARI:
  398:     case OP_POSSTARI:
  399:     case OP_PLUSI:
  400:     case OP_MINPLUSI:
  401:     case OP_POSPLUSI:
  402:     case OP_QUERYI:
  403:     case OP_MINQUERYI:
  404:     case OP_POSQUERYI:
  405:     flag = "/i";
  406:     /* Fall through */
  407:     case OP_STAR:
  408:     case OP_MINSTAR:
  409:     case OP_POSSTAR:
  410:     case OP_PLUS:
  411:     case OP_MINPLUS:
  412:     case OP_POSPLUS:
  413:     case OP_QUERY:
  414:     case OP_MINQUERY:
  415:     case OP_POSQUERY:
  416:     case OP_TYPESTAR:
  417:     case OP_TYPEMINSTAR:
  418:     case OP_TYPEPOSSTAR:
  419:     case OP_TYPEPLUS:
  420:     case OP_TYPEMINPLUS:
  421:     case OP_TYPEPOSPLUS:
  422:     case OP_TYPEQUERY:
  423:     case OP_TYPEMINQUERY:
  424:     case OP_TYPEPOSQUERY:
  425:     fprintf(f, " %s ", flag);
  426:     if (*code >= OP_TYPESTAR)
  427:       {
  428:       fprintf(f, "%s", priv_OP_names[code[1]]);
  429:       if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
  430:         {
  431:         fprintf(f, " %s ", get_ucpname(code[2], code[3]));
  432:         extra = 2;
  433:         }
  434:       }
  435:     else extra = print_char(f, code+1, utf);
  436:     fprintf(f, "%s", priv_OP_names[*code]);
  437:     break;
  438: 
  439:     case OP_EXACTI:
  440:     case OP_UPTOI:
  441:     case OP_MINUPTOI:
  442:     case OP_POSUPTOI:
  443:     flag = "/i";
  444:     /* Fall through */
  445:     case OP_EXACT:
  446:     case OP_UPTO:
  447:     case OP_MINUPTO:
  448:     case OP_POSUPTO:
  449:     fprintf(f, " %s ", flag);
  450:     extra = print_char(f, code + 1 + IMM2_SIZE, utf);
  451:     fprintf(f, "{");
  452:     if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,");
  453:     fprintf(f, "%d}", GET2(code,1));
  454:     if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?");
  455:       else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+");
  456:     break;
  457: 
  458:     case OP_TYPEEXACT:
  459:     case OP_TYPEUPTO:
  460:     case OP_TYPEMINUPTO:
  461:     case OP_TYPEPOSUPTO:
  462:     fprintf(f, "    %s", priv_OP_names[code[1 + IMM2_SIZE]]);
  463:     if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
  464:       {
  465:       fprintf(f, " %s ", get_ucpname(code[1 + IMM2_SIZE + 1],
  466:         code[1 + IMM2_SIZE + 2]));
  467:       extra = 2;
  468:       }
  469:     fprintf(f, "{");
  470:     if (*code != OP_TYPEEXACT) fprintf(f, "0,");
  471:     fprintf(f, "%d}", GET2(code,1));
  472:     if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
  473:       else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
  474:     break;
  475: 
  476:     case OP_NOTI:
  477:     flag = "/i";
  478:     /* Fall through */
  479:     case OP_NOT:
  480:     c = code[1];
  481:     if (PRINTABLE(c)) fprintf(f, " %s [^%c]", flag, c);
  482:     else if (utf || c > 0xff)
  483:       fprintf(f, " %s [^\\x{%02x}]", flag, c);
  484:     else
  485:       fprintf(f, " %s [^\\x%02x]", flag, c);
  486:     break;
  487: 
  488:     case OP_NOTSTARI:
  489:     case OP_NOTMINSTARI:
  490:     case OP_NOTPOSSTARI:
  491:     case OP_NOTPLUSI:
  492:     case OP_NOTMINPLUSI:
  493:     case OP_NOTPOSPLUSI:
  494:     case OP_NOTQUERYI:
  495:     case OP_NOTMINQUERYI:
  496:     case OP_NOTPOSQUERYI:
  497:     flag = "/i";
  498:     /* Fall through */
  499: 
  500:     case OP_NOTSTAR:
  501:     case OP_NOTMINSTAR:
  502:     case OP_NOTPOSSTAR:
  503:     case OP_NOTPLUS:
  504:     case OP_NOTMINPLUS:
  505:     case OP_NOTPOSPLUS:
  506:     case OP_NOTQUERY:
  507:     case OP_NOTMINQUERY:
  508:     case OP_NOTPOSQUERY:
  509:     c = code[1];
  510:     if (PRINTABLE(c)) fprintf(f, " %s [^%c]", flag, c);
  511:       else fprintf(f, " %s [^\\x%02x]", flag, c);
  512:     fprintf(f, "%s", priv_OP_names[*code]);
  513:     break;
  514: 
  515:     case OP_NOTEXACTI:
  516:     case OP_NOTUPTOI:
  517:     case OP_NOTMINUPTOI:
  518:     case OP_NOTPOSUPTOI:
  519:     flag = "/i";
  520:     /* Fall through */
  521: 
  522:     case OP_NOTEXACT:
  523:     case OP_NOTUPTO:
  524:     case OP_NOTMINUPTO:
  525:     case OP_NOTPOSUPTO:
  526:     c = code[1 + IMM2_SIZE];
  527:     if (PRINTABLE(c)) fprintf(f, " %s [^%c]{", flag, c);
  528:       else fprintf(f, " %s [^\\x%02x]{", flag, c);
  529:     if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,");
  530:     fprintf(f, "%d}", GET2(code,1));
  531:     if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?");
  532:       else
  533:     if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+");
  534:     break;
  535: 
  536:     case OP_RECURSE:
  537:     if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
  538:       else fprintf(f, "    ");
  539:     fprintf(f, "%s", priv_OP_names[*code]);
  540:     break;
  541: 
  542:     case OP_REFI:
  543:     flag = "/i";
  544:     /* Fall through */
  545:     case OP_REF:
  546:     fprintf(f, " %s \\%d", flag, GET2(code,1));
  547:     ccode = code + priv_OP_lengths[*code];
  548:     goto CLASS_REF_REPEAT;
  549: 
  550:     case OP_CALLOUT:
  551:     fprintf(f, "    %s %d %d %d", priv_OP_names[*code], code[1], GET(code,2),
  552:       GET(code, 2 + LINK_SIZE));
  553:     break;
  554: 
  555:     case OP_PROP:
  556:     case OP_NOTPROP:
  557:     fprintf(f, "    %s %s", priv_OP_names[*code], get_ucpname(code[1], code[2]));
  558:     break;
  559: 
  560:     /* OP_XCLASS can only occur in UTF or PCRE16 modes. However, there's no
  561:     harm in having this code always here, and it makes it less messy without
  562:     all those #ifdefs. */
  563: 
  564:     case OP_CLASS:
  565:     case OP_NCLASS:
  566:     case OP_XCLASS:
  567:       {
  568:       int i, min, max;
  569:       BOOL printmap;
  570:       pcre_uint8 *map;
  571: 
  572:       fprintf(f, "    [");
  573: 
  574:       if (*code == OP_XCLASS)
  575:         {
  576:         extra = GET(code, 1);
  577:         ccode = code + LINK_SIZE + 1;
  578:         printmap = (*ccode & XCL_MAP) != 0;
  579:         if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
  580:         }
  581:       else
  582:         {
  583:         printmap = TRUE;
  584:         ccode = code + 1;
  585:         }
  586: 
  587:       /* Print a bit map */
  588: 
  589:       if (printmap)
  590:         {
  591:         map = (pcre_uint8 *)ccode;
  592:         for (i = 0; i < 256; i++)
  593:           {
  594:           if ((map[i/8] & (1 << (i&7))) != 0)
  595:             {
  596:             int j;
  597:             for (j = i+1; j < 256; j++)
  598:               if ((map[j/8] & (1 << (j&7))) == 0) break;
  599:             if (i == '-' || i == ']') fprintf(f, "\\");
  600:             if (PRINTABLE(i)) fprintf(f, "%c", i);
  601:               else fprintf(f, "\\x%02x", i);
  602:             if (--j > i)
  603:               {
  604:               if (j != i + 1) fprintf(f, "-");
  605:               if (j == '-' || j == ']') fprintf(f, "\\");
  606:               if (PRINTABLE(j)) fprintf(f, "%c", j);
  607:                 else fprintf(f, "\\x%02x", j);
  608:               }
  609:             i = j;
  610:             }
  611:           }
  612:         ccode += 32 / sizeof(pcre_uchar);
  613:         }
  614: 
  615:       /* For an XCLASS there is always some additional data */
  616: 
  617:       if (*code == OP_XCLASS)
  618:         {
  619:         int ch;
  620:         while ((ch = *ccode++) != XCL_END)
  621:           {
  622:           if (ch == XCL_PROP)
  623:             {
  624:             int ptype = *ccode++;
  625:             int pvalue = *ccode++;
  626:             fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
  627:             }
  628:           else if (ch == XCL_NOTPROP)
  629:             {
  630:             int ptype = *ccode++;
  631:             int pvalue = *ccode++;
  632:             fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
  633:             }
  634:           else
  635:             {
  636:             ccode += 1 + print_char(f, ccode, utf);
  637:             if (ch == XCL_RANGE)
  638:               {
  639:               fprintf(f, "-");
  640:               ccode += 1 + print_char(f, ccode, utf);
  641:               }
  642:             }
  643:           }
  644:         }
  645: 
  646:       /* Indicate a non-UTF class which was created by negation */
  647: 
  648:       fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
  649: 
  650:       /* Handle repeats after a class or a back reference */
  651: 
  652:       CLASS_REF_REPEAT:
  653:       switch(*ccode)
  654:         {
  655:         case OP_CRSTAR:
  656:         case OP_CRMINSTAR:
  657:         case OP_CRPLUS:
  658:         case OP_CRMINPLUS:
  659:         case OP_CRQUERY:
  660:         case OP_CRMINQUERY:
  661:         fprintf(f, "%s", priv_OP_names[*ccode]);
  662:         extra += priv_OP_lengths[*ccode];
  663:         break;
  664: 
  665:         case OP_CRRANGE:
  666:         case OP_CRMINRANGE:
  667:         min = GET2(ccode,1);
  668:         max = GET2(ccode,1 + IMM2_SIZE);
  669:         if (max == 0) fprintf(f, "{%d,}", min);
  670:         else fprintf(f, "{%d,%d}", min, max);
  671:         if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
  672:         extra += priv_OP_lengths[*ccode];
  673:         break;
  674: 
  675:         /* Do nothing if it's not a repeat; this code stops picky compilers
  676:         warning about the lack of a default code path. */
  677: 
  678:         default:
  679:         break;
  680:         }
  681:       }
  682:     break;
  683: 
  684:     case OP_MARK:
  685:     case OP_PRUNE_ARG:
  686:     case OP_SKIP_ARG:
  687:     case OP_THEN_ARG:
  688:     fprintf(f, "    %s ", priv_OP_names[*code]);
  689:     print_puchar(f, code + 2);
  690:     extra += code[1];
  691:     break;
  692: 
  693:     case OP_THEN:
  694:     fprintf(f, "    %s", priv_OP_names[*code]);
  695:     break;
  696: 
  697:     case OP_CIRCM:
  698:     case OP_DOLLM:
  699:     flag = "/m";
  700:     /* Fall through */
  701: 
  702:     /* Anything else is just an item with no data, but possibly a flag. */
  703: 
  704:     default:
  705:     fprintf(f, " %s %s", flag, priv_OP_names[*code]);
  706:     break;
  707:     }
  708: 
  709:   code += priv_OP_lengths[*code] + extra;
  710:   fprintf(f, "\n");
  711:   }
  712: }
  713: 
  714: /* End of pcre_printint.src */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>