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