1/************************************************* 2* Perl-Compatible Regular Expressions * 3*************************************************/ 4 5/* PCRE is a library of functions to support regular expressions whose syntax 6and 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----------------------------------------------------------------------------- 12Redistribution and use in source and binary forms, with or without 13modification, 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 26THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 27AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 30LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36POSSIBILITY OF SUCH DAMAGE. 37----------------------------------------------------------------------------- 38*/ 39 40 41/* This module contains a PCRE private debugging function for printing out the 42internal form of a compiled regular expression, along with some supporting 43local 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 47compiles. In this case PCRE_INCLUDED is defined. 48 49(2) It is also compiled separately and linked with pcretest.c, which can be 50asked 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 62displaying the results of pcre_study() and we also need to know about the 63internal macros, structures, and other internal data values; pcretest has 64"inside information" compared to a program that strictly follows the PCRE API. 65 66Although pcre_internal.h does itself include pcre.h, we explicitly include it 67here before pcre_internal.h so that the PCRE_EXP_xxx macros get set 68appropriately 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 74having a separate .h file just for this. */ 75 76#endif /* PCRE_INCLUDED */ 77 78#ifdef PCRE_INCLUDED 79static /* Keep the following function as private. */ 80#endif 81#ifdef COMPILE_PCRE8 82void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths); 83#else 84void 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 88hexadecimal. 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, 90for 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 100static const char *priv_OP_names[] = { OP_NAME_LIST }; 101 102/* This table of operator lengths is not actually used by the working code, 103but its size is needed for a check that ensures it is the correct size for the 104number of opcodes (thus catching update omissions). */ 105 106static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS }; 107 108 109 110/************************************************* 111* Print single- or multi-byte character * 112*************************************************/ 113 114static int 115print_char(FILE *f, pcre_uchar *ptr, BOOL utf) 116{ 117int c = *ptr; 118 119#ifndef SUPPORT_UTF 120 121(void)utf; /* Avoid compiler warning */ 122if (PRINTABLE(c)) fprintf(f, "%c", c); 123else if (c <= 0xff) fprintf(f, "\\x%02x", c); 124else fprintf(f, "\\x{%x}", c); 125return 0; 126 127#else 128 129#ifdef COMPILE_PCRE8 130 131if (!utf || (c & 0xc0) != 0xc0) 132 { 133 if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); 134 return 0; 135 } 136else 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 167if (!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 } 174else 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 202static void 203print_puchar(FILE *f, PCRE_PUCHAR ptr) 204{ 205while (*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 216static const char * 217get_ucpname(int ptype, int pvalue) 218{ 219#ifdef SUPPORT_UCP 220int i; 221for (i = PRIV(utt_size) - 1; i >= 0; i--) 222 { 223 if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break; 224 } 225return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??"; 226#else 227/* It gets harder and harder to shut off unwanted compiler warnings. */ 228ptype = ptype * pvalue; 229return (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. 240However, we assume that what we are passed is a compiled regex. The 241print_lengths flag controls whether offsets and lengths of items are printed. 242They can be turned off from pcretest so that automatic tests on bytecode can be 243written that do not depend on the value of LINK_SIZE. */ 244 245#ifdef PCRE_INCLUDED 246static /* Keep the following function as private. */ 247#endif 248#ifdef COMPILE_PCRE8 249void 250pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths) 251#else 252void 253pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths) 254#endif 255{ 256REAL_PCRE *re = (REAL_PCRE *)external_re; 257pcre_uchar *codestart, *code; 258BOOL utf; 259 260unsigned int options = re->options; 261int offset = re->name_table_offset; 262int count = re->name_count; 263int size = re->name_entry_size; 264 265if (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 276code = codestart = (pcre_uchar *)re + offset + count * size; 277/* PCRE_UTF16 has the same value as PCRE_UTF8. */ 278utf = (options & PCRE_UTF8) != 0; 279 280for(;;) 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 fprintf(f, " %s [^", flag); 481 extra = print_char(f, code + 1, utf); 482 fprintf(f, "]"); 483 break; 484 485 case OP_NOTSTARI: 486 case OP_NOTMINSTARI: 487 case OP_NOTPOSSTARI: 488 case OP_NOTPLUSI: 489 case OP_NOTMINPLUSI: 490 case OP_NOTPOSPLUSI: 491 case OP_NOTQUERYI: 492 case OP_NOTMINQUERYI: 493 case OP_NOTPOSQUERYI: 494 flag = "/i"; 495 /* Fall through */ 496 497 case OP_NOTSTAR: 498 case OP_NOTMINSTAR: 499 case OP_NOTPOSSTAR: 500 case OP_NOTPLUS: 501 case OP_NOTMINPLUS: 502 case OP_NOTPOSPLUS: 503 case OP_NOTQUERY: 504 case OP_NOTMINQUERY: 505 case OP_NOTPOSQUERY: 506 fprintf(f, " %s [^", flag); 507 extra = print_char(f, code + 1, utf); 508 fprintf(f, "]%s", priv_OP_names[*code]); 509 break; 510 511 case OP_NOTEXACTI: 512 case OP_NOTUPTOI: 513 case OP_NOTMINUPTOI: 514 case OP_NOTPOSUPTOI: 515 flag = "/i"; 516 /* Fall through */ 517 518 case OP_NOTEXACT: 519 case OP_NOTUPTO: 520 case OP_NOTMINUPTO: 521 case OP_NOTPOSUPTO: 522 fprintf(f, " %s [^", flag); 523 extra = print_char(f, code + 1 + IMM2_SIZE, utf); 524 fprintf(f, "]{"); 525 if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,"); 526 fprintf(f, "%d}", GET2(code,1)); 527 if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?"); 528 else 529 if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+"); 530 break; 531 532 case OP_RECURSE: 533 if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); 534 else fprintf(f, " "); 535 fprintf(f, "%s", priv_OP_names[*code]); 536 break; 537 538 case OP_REFI: 539 flag = "/i"; 540 /* Fall through */ 541 case OP_REF: 542 fprintf(f, " %s \\%d", flag, GET2(code,1)); 543 ccode = code + priv_OP_lengths[*code]; 544 goto CLASS_REF_REPEAT; 545 546 case OP_CALLOUT: 547 fprintf(f, " %s %d %d %d", priv_OP_names[*code], code[1], GET(code,2), 548 GET(code, 2 + LINK_SIZE)); 549 break; 550 551 case OP_PROP: 552 case OP_NOTPROP: 553 fprintf(f, " %s %s", priv_OP_names[*code], get_ucpname(code[1], code[2])); 554 break; 555 556 /* OP_XCLASS can only occur in UTF or PCRE16 modes. However, there's no 557 harm in having this code always here, and it makes it less messy without 558 all those #ifdefs. */ 559 560 case OP_CLASS: 561 case OP_NCLASS: 562 case OP_XCLASS: 563 { 564 int i, min, max; 565 BOOL printmap; 566 pcre_uint8 *map; 567 568 fprintf(f, " ["); 569 570 if (*code == OP_XCLASS) 571 { 572 extra = GET(code, 1); 573 ccode = code + LINK_SIZE + 1; 574 printmap = (*ccode & XCL_MAP) != 0; 575 if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^"); 576 } 577 else 578 { 579 printmap = TRUE; 580 ccode = code + 1; 581 } 582 583 /* Print a bit map */ 584 585 if (printmap) 586 { 587 map = (pcre_uint8 *)ccode; 588 for (i = 0; i < 256; i++) 589 { 590 if ((map[i/8] & (1 << (i&7))) != 0) 591 { 592 int j; 593 for (j = i+1; j < 256; j++) 594 if ((map[j/8] & (1 << (j&7))) == 0) break; 595 if (i == '-' || i == ']') fprintf(f, "\\"); 596 if (PRINTABLE(i)) fprintf(f, "%c", i); 597 else fprintf(f, "\\x%02x", i); 598 if (--j > i) 599 { 600 if (j != i + 1) fprintf(f, "-"); 601 if (j == '-' || j == ']') fprintf(f, "\\"); 602 if (PRINTABLE(j)) fprintf(f, "%c", j); 603 else fprintf(f, "\\x%02x", j); 604 } 605 i = j; 606 } 607 } 608 ccode += 32 / sizeof(pcre_uchar); 609 } 610 611 /* For an XCLASS there is always some additional data */ 612 613 if (*code == OP_XCLASS) 614 { 615 int ch; 616 while ((ch = *ccode++) != XCL_END) 617 { 618 if (ch == XCL_PROP) 619 { 620 int ptype = *ccode++; 621 int pvalue = *ccode++; 622 fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue)); 623 } 624 else if (ch == XCL_NOTPROP) 625 { 626 int ptype = *ccode++; 627 int pvalue = *ccode++; 628 fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue)); 629 } 630 else 631 { 632 ccode += 1 + print_char(f, ccode, utf); 633 if (ch == XCL_RANGE) 634 { 635 fprintf(f, "-"); 636 ccode += 1 + print_char(f, ccode, utf); 637 } 638 } 639 } 640 } 641 642 /* Indicate a non-UTF class which was created by negation */ 643 644 fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); 645 646 /* Handle repeats after a class or a back reference */ 647 648 CLASS_REF_REPEAT: 649 switch(*ccode) 650 { 651 case OP_CRSTAR: 652 case OP_CRMINSTAR: 653 case OP_CRPLUS: 654 case OP_CRMINPLUS: 655 case OP_CRQUERY: 656 case OP_CRMINQUERY: 657 fprintf(f, "%s", priv_OP_names[*ccode]); 658 extra += priv_OP_lengths[*ccode]; 659 break; 660 661 case OP_CRRANGE: 662 case OP_CRMINRANGE: 663 min = GET2(ccode,1); 664 max = GET2(ccode,1 + IMM2_SIZE); 665 if (max == 0) fprintf(f, "{%d,}", min); 666 else fprintf(f, "{%d,%d}", min, max); 667 if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); 668 extra += priv_OP_lengths[*ccode]; 669 break; 670 671 /* Do nothing if it's not a repeat; this code stops picky compilers 672 warning about the lack of a default code path. */ 673 674 default: 675 break; 676 } 677 } 678 break; 679 680 case OP_MARK: 681 case OP_PRUNE_ARG: 682 case OP_SKIP_ARG: 683 case OP_THEN_ARG: 684 fprintf(f, " %s ", priv_OP_names[*code]); 685 print_puchar(f, code + 2); 686 extra += code[1]; 687 break; 688 689 case OP_THEN: 690 fprintf(f, " %s", priv_OP_names[*code]); 691 break; 692 693 case OP_CIRCM: 694 case OP_DOLLM: 695 flag = "/m"; 696 /* Fall through */ 697 698 /* Anything else is just an item with no data, but possibly a flag. */ 699 700 default: 701 fprintf(f, " %s %s", flag, priv_OP_names[*code]); 702 break; 703 } 704 705 code += priv_OP_lengths[*code] + extra; 706 fprintf(f, "\n"); 707 } 708} 709 710/* End of pcre_printint.src */ 711