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