tools/pcre/pcre_printint.src
author Nicholas Hastings <skamonkey@gmail.com>
Sun Jul 15 12:31:06 2012 -0400 (2012-07-15)
changeset 3579 6d730190a3e4
parent 2762 d2d467bf1b5a
permissions -rw-r--r--
Added missing files to each core and logic makefiles (NPOTB).
dvander@2762
     1
/*************************************************
dvander@2762
     2
*      Perl-Compatible Regular Expressions       *
dvander@2762
     3
*************************************************/
dvander@2762
     4
dvander@2762
     5
/* PCRE is a library of functions to support regular expressions whose syntax
dvander@2762
     6
and semantics are as close as possible to those of the Perl 5 language.
dvander@2762
     7
dvander@2762
     8
                       Written by Philip Hazel
dvander@2762
     9
           Copyright (c) 1997-2009 University of Cambridge
dvander@2762
    10
dvander@2762
    11
-----------------------------------------------------------------------------
dvander@2762
    12
Redistribution and use in source and binary forms, with or without
dvander@2762
    13
modification, are permitted provided that the following conditions are met:
dvander@2762
    14
dvander@2762
    15
    * Redistributions of source code must retain the above copyright notice,
dvander@2762
    16
      this list of conditions and the following disclaimer.
dvander@2762
    17
dvander@2762
    18
    * Redistributions in binary form must reproduce the above copyright
dvander@2762
    19
      notice, this list of conditions and the following disclaimer in the
dvander@2762
    20
      documentation and/or other materials provided with the distribution.
dvander@2762
    21
dvander@2762
    22
    * Neither the name of the University of Cambridge nor the names of its
dvander@2762
    23
      contributors may be used to endorse or promote products derived from
dvander@2762
    24
      this software without specific prior written permission.
dvander@2762
    25
dvander@2762
    26
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
dvander@2762
    27
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
dvander@2762
    28
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
dvander@2762
    29
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
dvander@2762
    30
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
dvander@2762
    31
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
dvander@2762
    32
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
dvander@2762
    33
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
dvander@2762
    34
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
dvander@2762
    35
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
dvander@2762
    36
POSSIBILITY OF SUCH DAMAGE.
dvander@2762
    37
-----------------------------------------------------------------------------
dvander@2762
    38
*/
dvander@2762
    39
dvander@2762
    40
dvander@2762
    41
/* This module contains a PCRE private debugging function for printing out the
dvander@2762
    42
internal form of a compiled regular expression, along with some supporting
dvander@2762
    43
local functions. This source file is used in two places:
dvander@2762
    44
dvander@2762
    45
(1) It is #included by pcre_compile.c when it is compiled in debugging mode
dvander@2762
    46
(DEBUG defined in pcre_internal.h). It is not included in production compiles.
dvander@2762
    47
dvander@2762
    48
(2) It is always #included by pcretest.c, which can be asked to print out a
dvander@2762
    49
compiled regex for debugging purposes. */
dvander@2762
    50
dvander@2762
    51
dvander@2762
    52
/* Macro that decides whether a character should be output as a literal or in
dvander@2762
    53
hexadecimal. We don't use isprint() because that can vary from system to system
dvander@2762
    54
(even without the use of locales) and we want the output always to be the same,
dvander@2762
    55
for testing purposes. This macro is used in pcretest as well as in this file. */
dvander@2762
    56
dvander@2762
    57
#ifdef EBCDIC
dvander@2762
    58
#define PRINTABLE(c) ((c) >= 64 && (c) < 255)
dvander@2762
    59
#else
dvander@2762
    60
#define PRINTABLE(c) ((c) >= 32 && (c) < 127)
dvander@2762
    61
#endif
dvander@2762
    62
dvander@2762
    63
/* The table of operator names. */
dvander@2762
    64
dvander@2762
    65
static const char *OP_names[] = { OP_NAME_LIST };
dvander@2762
    66
dvander@2762
    67
dvander@2762
    68
dvander@2762
    69
/*************************************************
dvander@2762
    70
*       Print single- or multi-byte character    *
dvander@2762
    71
*************************************************/
dvander@2762
    72
dvander@2762
    73
static int
dvander@2762
    74
print_char(FILE *f, uschar *ptr, BOOL utf8)
dvander@2762
    75
{
dvander@2762
    76
int c = *ptr;
dvander@2762
    77
dvander@2762
    78
#ifndef SUPPORT_UTF8
dvander@2762
    79
utf8 = utf8;  /* Avoid compiler warning */
dvander@2762
    80
if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
dvander@2762
    81
return 0;
dvander@2762
    82
dvander@2762
    83
#else
dvander@2762
    84
if (!utf8 || (c & 0xc0) != 0xc0)
dvander@2762
    85
  {
dvander@2762
    86
  if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
dvander@2762
    87
  return 0;
dvander@2762
    88
  }
dvander@2762
    89
else
dvander@2762
    90
  {
dvander@2762
    91
  int i;
dvander@2762
    92
  int a = _pcre_utf8_table4[c & 0x3f];  /* Number of additional bytes */
dvander@2762
    93
  int s = 6*a;
dvander@2762
    94
  c = (c & _pcre_utf8_table3[a]) << s;
dvander@2762
    95
  for (i = 1; i <= a; i++)
dvander@2762
    96
    {
dvander@2762
    97
    /* This is a check for malformed UTF-8; it should only occur if the sanity
dvander@2762
    98
    check has been turned off. Rather than swallow random bytes, just stop if
dvander@2762
    99
    we hit a bad one. Print it with \X instead of \x as an indication. */
dvander@2762
   100
dvander@2762
   101
    if ((ptr[i] & 0xc0) != 0x80)
dvander@2762
   102
      {
dvander@2762
   103
      fprintf(f, "\\X{%x}", c);
dvander@2762
   104
      return i - 1;
dvander@2762
   105
      }
dvander@2762
   106
dvander@2762
   107
    /* The byte is OK */
dvander@2762
   108
dvander@2762
   109
    s -= 6;
dvander@2762
   110
    c |= (ptr[i] & 0x3f) << s;
dvander@2762
   111
    }
dvander@2762
   112
  if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c);
dvander@2762
   113
  return a;
dvander@2762
   114
  }
dvander@2762
   115
#endif
dvander@2762
   116
}
dvander@2762
   117
dvander@2762
   118
dvander@2762
   119
dvander@2762
   120
/*************************************************
dvander@2762
   121
*          Find Unicode property name            *
dvander@2762
   122
*************************************************/
dvander@2762
   123
dvander@2762
   124
static const char *
dvander@2762
   125
get_ucpname(int ptype, int pvalue)
dvander@2762
   126
{
dvander@2762
   127
#ifdef SUPPORT_UCP
dvander@2762
   128
int i;
dvander@2762
   129
for (i = _pcre_utt_size - 1; i >= 0; i--)
dvander@2762
   130
  {
dvander@2762
   131
  if (ptype == _pcre_utt[i].type && pvalue == _pcre_utt[i].value) break;
dvander@2762
   132
  }
dvander@2762
   133
return (i >= 0)? _pcre_utt_names + _pcre_utt[i].name_offset : "??";
dvander@2762
   134
#else
dvander@2762
   135
/* It gets harder and harder to shut off unwanted compiler warnings. */
dvander@2762
   136
ptype = ptype * pvalue;
dvander@2762
   137
return (ptype == pvalue)? "??" : "??";
dvander@2762
   138
#endif
dvander@2762
   139
}
dvander@2762
   140
dvander@2762
   141
dvander@2762
   142
dvander@2762
   143
/*************************************************
dvander@2762
   144
*         Print compiled regex                   *
dvander@2762
   145
*************************************************/
dvander@2762
   146
dvander@2762
   147
/* Make this function work for a regex with integers either byte order.
dvander@2762
   148
However, we assume that what we are passed is a compiled regex. The
dvander@2762
   149
print_lengths flag controls whether offsets and lengths of items are printed.
dvander@2762
   150
They can be turned off from pcretest so that automatic tests on bytecode can be
dvander@2762
   151
written that do not depend on the value of LINK_SIZE. */
dvander@2762
   152
dvander@2762
   153
static void
dvander@2762
   154
pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
dvander@2762
   155
{
dvander@2762
   156
real_pcre *re = (real_pcre *)external_re;
dvander@2762
   157
uschar *codestart, *code;
dvander@2762
   158
BOOL utf8;
dvander@2762
   159
dvander@2762
   160
unsigned int options = re->options;
dvander@2762
   161
int offset = re->name_table_offset;
dvander@2762
   162
int count = re->name_count;
dvander@2762
   163
int size = re->name_entry_size;
dvander@2762
   164
dvander@2762
   165
if (re->magic_number != MAGIC_NUMBER)
dvander@2762
   166
  {
dvander@2762
   167
  offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
dvander@2762
   168
  count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
dvander@2762
   169
  size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
dvander@2762
   170
  options = ((options << 24) & 0xff000000) |
dvander@2762
   171
            ((options <<  8) & 0x00ff0000) |
dvander@2762
   172
            ((options >>  8) & 0x0000ff00) |
dvander@2762
   173
            ((options >> 24) & 0x000000ff);
dvander@2762
   174
  }
dvander@2762
   175
dvander@2762
   176
code = codestart = (uschar *)re + offset + count * size;
dvander@2762
   177
utf8 = (options & PCRE_UTF8) != 0;
dvander@2762
   178
dvander@2762
   179
for(;;)
dvander@2762
   180
  {
dvander@2762
   181
  uschar *ccode;
dvander@2762
   182
  int c;
dvander@2762
   183
  int extra = 0;
dvander@2762
   184
dvander@2762
   185
  if (print_lengths)
dvander@2762
   186
    fprintf(f, "%3d ", (int)(code - codestart));
dvander@2762
   187
  else
dvander@2762
   188
    fprintf(f, "    ");
dvander@2762
   189
dvander@2762
   190
  switch(*code)
dvander@2762
   191
    {
dvander@2762
   192
    case OP_END:
dvander@2762
   193
    fprintf(f, "    %s\n", OP_names[*code]);
dvander@2762
   194
    fprintf(f, "------------------------------------------------------------------\n");
dvander@2762
   195
    return;
dvander@2762
   196
dvander@2762
   197
    case OP_OPT:
dvander@2762
   198
    fprintf(f, " %.2x %s", code[1], OP_names[*code]);
dvander@2762
   199
    break;
dvander@2762
   200
dvander@2762
   201
    case OP_CHAR:
dvander@2762
   202
    fprintf(f, "    ");
dvander@2762
   203
    do
dvander@2762
   204
      {
dvander@2762
   205
      code++;
dvander@2762
   206
      code += 1 + print_char(f, code, utf8);
dvander@2762
   207
      }
dvander@2762
   208
    while (*code == OP_CHAR);
dvander@2762
   209
    fprintf(f, "\n");
dvander@2762
   210
    continue;
dvander@2762
   211
dvander@2762
   212
    case OP_CHARNC:
dvander@2762
   213
    fprintf(f, " NC ");
dvander@2762
   214
    do
dvander@2762
   215
      {
dvander@2762
   216
      code++;
dvander@2762
   217
      code += 1 + print_char(f, code, utf8);
dvander@2762
   218
      }
dvander@2762
   219
    while (*code == OP_CHARNC);
dvander@2762
   220
    fprintf(f, "\n");
dvander@2762
   221
    continue;
dvander@2762
   222
dvander@2762
   223
    case OP_CBRA:
dvander@2762
   224
    case OP_SCBRA:
dvander@2762
   225
    if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
dvander@2762
   226
      else fprintf(f, "    ");
dvander@2762
   227
    fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));
dvander@2762
   228
    break;
dvander@2762
   229
dvander@2762
   230
    case OP_BRA:
dvander@2762
   231
    case OP_SBRA:
dvander@2762
   232
    case OP_KETRMAX:
dvander@2762
   233
    case OP_KETRMIN:
dvander@2762
   234
    case OP_ALT:
dvander@2762
   235
    case OP_KET:
dvander@2762
   236
    case OP_ASSERT:
dvander@2762
   237
    case OP_ASSERT_NOT:
dvander@2762
   238
    case OP_ASSERTBACK:
dvander@2762
   239
    case OP_ASSERTBACK_NOT:
dvander@2762
   240
    case OP_ONCE:
dvander@2762
   241
    case OP_COND:
dvander@2762
   242
    case OP_SCOND:
dvander@2762
   243
    case OP_REVERSE:
dvander@2762
   244
    if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
dvander@2762
   245
      else fprintf(f, "    ");
dvander@2762
   246
    fprintf(f, "%s", OP_names[*code]);
dvander@2762
   247
    break;
dvander@2762
   248
dvander@2762
   249
    case OP_CREF:
dvander@2762
   250
    fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
dvander@2762
   251
    break;
dvander@2762
   252
dvander@2762
   253
    case OP_RREF:
dvander@2762
   254
    c = GET2(code, 1);
dvander@2762
   255
    if (c == RREF_ANY)
dvander@2762
   256
      fprintf(f, "    Cond recurse any");
dvander@2762
   257
    else
dvander@2762
   258
      fprintf(f, "    Cond recurse %d", c);
dvander@2762
   259
    break;
dvander@2762
   260
dvander@2762
   261
    case OP_DEF:
dvander@2762
   262
    fprintf(f, "    Cond def");
dvander@2762
   263
    break;
dvander@2762
   264
dvander@2762
   265
    case OP_STAR:
dvander@2762
   266
    case OP_MINSTAR:
dvander@2762
   267
    case OP_POSSTAR:
dvander@2762
   268
    case OP_PLUS:
dvander@2762
   269
    case OP_MINPLUS:
dvander@2762
   270
    case OP_POSPLUS:
dvander@2762
   271
    case OP_QUERY:
dvander@2762
   272
    case OP_MINQUERY:
dvander@2762
   273
    case OP_POSQUERY:
dvander@2762
   274
    case OP_TYPESTAR:
dvander@2762
   275
    case OP_TYPEMINSTAR:
dvander@2762
   276
    case OP_TYPEPOSSTAR:
dvander@2762
   277
    case OP_TYPEPLUS:
dvander@2762
   278
    case OP_TYPEMINPLUS:
dvander@2762
   279
    case OP_TYPEPOSPLUS:
dvander@2762
   280
    case OP_TYPEQUERY:
dvander@2762
   281
    case OP_TYPEMINQUERY:
dvander@2762
   282
    case OP_TYPEPOSQUERY:
dvander@2762
   283
    fprintf(f, "    ");
dvander@2762
   284
    if (*code >= OP_TYPESTAR)
dvander@2762
   285
      {
dvander@2762
   286
      fprintf(f, "%s", OP_names[code[1]]);
dvander@2762
   287
      if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
dvander@2762
   288
        {
dvander@2762
   289
        fprintf(f, " %s ", get_ucpname(code[2], code[3]));
dvander@2762
   290
        extra = 2;
dvander@2762
   291
        }
dvander@2762
   292
      }
dvander@2762
   293
    else extra = print_char(f, code+1, utf8);
dvander@2762
   294
    fprintf(f, "%s", OP_names[*code]);
dvander@2762
   295
    break;
dvander@2762
   296
dvander@2762
   297
    case OP_EXACT:
dvander@2762
   298
    case OP_UPTO:
dvander@2762
   299
    case OP_MINUPTO:
dvander@2762
   300
    case OP_POSUPTO:
dvander@2762
   301
    fprintf(f, "    ");
dvander@2762
   302
    extra = print_char(f, code+3, utf8);
dvander@2762
   303
    fprintf(f, "{");
dvander@2762
   304
    if (*code != OP_EXACT) fprintf(f, "0,");
dvander@2762
   305
    fprintf(f, "%d}", GET2(code,1));
dvander@2762
   306
    if (*code == OP_MINUPTO) fprintf(f, "?");
dvander@2762
   307
      else if (*code == OP_POSUPTO) fprintf(f, "+");
dvander@2762
   308
    break;
dvander@2762
   309
dvander@2762
   310
    case OP_TYPEEXACT:
dvander@2762
   311
    case OP_TYPEUPTO:
dvander@2762
   312
    case OP_TYPEMINUPTO:
dvander@2762
   313
    case OP_TYPEPOSUPTO:
dvander@2762
   314
    fprintf(f, "    %s", OP_names[code[3]]);
dvander@2762
   315
    if (code[3] == OP_PROP || code[3] == OP_NOTPROP)
dvander@2762
   316
      {
dvander@2762
   317
      fprintf(f, " %s ", get_ucpname(code[4], code[5]));
dvander@2762
   318
      extra = 2;
dvander@2762
   319
      }
dvander@2762
   320
    fprintf(f, "{");
dvander@2762
   321
    if (*code != OP_TYPEEXACT) fprintf(f, "0,");
dvander@2762
   322
    fprintf(f, "%d}", GET2(code,1));
dvander@2762
   323
    if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
dvander@2762
   324
      else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
dvander@2762
   325
    break;
dvander@2762
   326
dvander@2762
   327
    case OP_NOT:
dvander@2762
   328
    c = code[1];
dvander@2762
   329
    if (PRINTABLE(c)) fprintf(f, "    [^%c]", c);
dvander@2762
   330
      else fprintf(f, "    [^\\x%02x]", c);
dvander@2762
   331
    break;
dvander@2762
   332
dvander@2762
   333
    case OP_NOTSTAR:
dvander@2762
   334
    case OP_NOTMINSTAR:
dvander@2762
   335
    case OP_NOTPOSSTAR:
dvander@2762
   336
    case OP_NOTPLUS:
dvander@2762
   337
    case OP_NOTMINPLUS:
dvander@2762
   338
    case OP_NOTPOSPLUS:
dvander@2762
   339
    case OP_NOTQUERY:
dvander@2762
   340
    case OP_NOTMINQUERY:
dvander@2762
   341
    case OP_NOTPOSQUERY:
dvander@2762
   342
    c = code[1];
dvander@2762
   343
    if (PRINTABLE(c)) fprintf(f, "    [^%c]", c);
dvander@2762
   344
      else fprintf(f, "    [^\\x%02x]", c);
dvander@2762
   345
    fprintf(f, "%s", OP_names[*code]);
dvander@2762
   346
    break;
dvander@2762
   347
dvander@2762
   348
    case OP_NOTEXACT:
dvander@2762
   349
    case OP_NOTUPTO:
dvander@2762
   350
    case OP_NOTMINUPTO:
dvander@2762
   351
    case OP_NOTPOSUPTO:
dvander@2762
   352
    c = code[3];
dvander@2762
   353
    if (PRINTABLE(c)) fprintf(f, "    [^%c]{", c);
dvander@2762
   354
      else fprintf(f, "    [^\\x%02x]{", c);
dvander@2762
   355
    if (*code != OP_NOTEXACT) fprintf(f, "0,");
dvander@2762
   356
    fprintf(f, "%d}", GET2(code,1));
dvander@2762
   357
    if (*code == OP_NOTMINUPTO) fprintf(f, "?");
dvander@2762
   358
      else if (*code == OP_NOTPOSUPTO) fprintf(f, "+");
dvander@2762
   359
    break;
dvander@2762
   360
dvander@2762
   361
    case OP_RECURSE:
dvander@2762
   362
    if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
dvander@2762
   363
      else fprintf(f, "    ");
dvander@2762
   364
    fprintf(f, "%s", OP_names[*code]);
dvander@2762
   365
    break;
dvander@2762
   366
dvander@2762
   367
    case OP_REF:
dvander@2762
   368
    fprintf(f, "    \\%d", GET2(code,1));
dvander@2762
   369
    ccode = code + _pcre_OP_lengths[*code];
dvander@2762
   370
    goto CLASS_REF_REPEAT;
dvander@2762
   371
dvander@2762
   372
    case OP_CALLOUT:
dvander@2762
   373
    fprintf(f, "    %s %d %d %d", OP_names[*code], code[1], GET(code,2),
dvander@2762
   374
      GET(code, 2 + LINK_SIZE));
dvander@2762
   375
    break;
dvander@2762
   376
dvander@2762
   377
    case OP_PROP:
dvander@2762
   378
    case OP_NOTPROP:
dvander@2762
   379
    fprintf(f, "    %s %s", OP_names[*code], get_ucpname(code[1], code[2]));
dvander@2762
   380
    break;
dvander@2762
   381
dvander@2762
   382
    /* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in
dvander@2762
   383
    having this code always here, and it makes it less messy without all those
dvander@2762
   384
    #ifdefs. */
dvander@2762
   385
dvander@2762
   386
    case OP_CLASS:
dvander@2762
   387
    case OP_NCLASS:
dvander@2762
   388
    case OP_XCLASS:
dvander@2762
   389
      {
dvander@2762
   390
      int i, min, max;
dvander@2762
   391
      BOOL printmap;
dvander@2762
   392
dvander@2762
   393
      fprintf(f, "    [");
dvander@2762
   394
dvander@2762
   395
      if (*code == OP_XCLASS)
dvander@2762
   396
        {
dvander@2762
   397
        extra = GET(code, 1);
dvander@2762
   398
        ccode = code + LINK_SIZE + 1;
dvander@2762
   399
        printmap = (*ccode & XCL_MAP) != 0;
dvander@2762
   400
        if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
dvander@2762
   401
        }
dvander@2762
   402
      else
dvander@2762
   403
        {
dvander@2762
   404
        printmap = TRUE;
dvander@2762
   405
        ccode = code + 1;
dvander@2762
   406
        }
dvander@2762
   407
dvander@2762
   408
      /* Print a bit map */
dvander@2762
   409
dvander@2762
   410
      if (printmap)
dvander@2762
   411
        {
dvander@2762
   412
        for (i = 0; i < 256; i++)
dvander@2762
   413
          {
dvander@2762
   414
          if ((ccode[i/8] & (1 << (i&7))) != 0)
dvander@2762
   415
            {
dvander@2762
   416
            int j;
dvander@2762
   417
            for (j = i+1; j < 256; j++)
dvander@2762
   418
              if ((ccode[j/8] & (1 << (j&7))) == 0) break;
dvander@2762
   419
            if (i == '-' || i == ']') fprintf(f, "\\");
dvander@2762
   420
            if (PRINTABLE(i)) fprintf(f, "%c", i);
dvander@2762
   421
              else fprintf(f, "\\x%02x", i);
dvander@2762
   422
            if (--j > i)
dvander@2762
   423
              {
dvander@2762
   424
              if (j != i + 1) fprintf(f, "-");
dvander@2762
   425
              if (j == '-' || j == ']') fprintf(f, "\\");
dvander@2762
   426
              if (PRINTABLE(j)) fprintf(f, "%c", j);
dvander@2762
   427
                else fprintf(f, "\\x%02x", j);
dvander@2762
   428
              }
dvander@2762
   429
            i = j;
dvander@2762
   430
            }
dvander@2762
   431
          }
dvander@2762
   432
        ccode += 32;
dvander@2762
   433
        }
dvander@2762
   434
dvander@2762
   435
      /* For an XCLASS there is always some additional data */
dvander@2762
   436
dvander@2762
   437
      if (*code == OP_XCLASS)
dvander@2762
   438
        {
dvander@2762
   439
        int ch;
dvander@2762
   440
        while ((ch = *ccode++) != XCL_END)
dvander@2762
   441
          {
dvander@2762
   442
          if (ch == XCL_PROP)
dvander@2762
   443
            {
dvander@2762
   444
            int ptype = *ccode++;
dvander@2762
   445
            int pvalue = *ccode++;
dvander@2762
   446
            fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
dvander@2762
   447
            }
dvander@2762
   448
          else if (ch == XCL_NOTPROP)
dvander@2762
   449
            {
dvander@2762
   450
            int ptype = *ccode++;
dvander@2762
   451
            int pvalue = *ccode++;
dvander@2762
   452
            fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
dvander@2762
   453
            }
dvander@2762
   454
          else
dvander@2762
   455
            {
dvander@2762
   456
            ccode += 1 + print_char(f, ccode, TRUE);
dvander@2762
   457
            if (ch == XCL_RANGE)
dvander@2762
   458
              {
dvander@2762
   459
              fprintf(f, "-");
dvander@2762
   460
              ccode += 1 + print_char(f, ccode, TRUE);
dvander@2762
   461
              }
dvander@2762
   462
            }
dvander@2762
   463
          }
dvander@2762
   464
        }
dvander@2762
   465
dvander@2762
   466
      /* Indicate a non-UTF8 class which was created by negation */
dvander@2762
   467
dvander@2762
   468
      fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
dvander@2762
   469
dvander@2762
   470
      /* Handle repeats after a class or a back reference */
dvander@2762
   471
dvander@2762
   472
      CLASS_REF_REPEAT:
dvander@2762
   473
      switch(*ccode)
dvander@2762
   474
        {
dvander@2762
   475
        case OP_CRSTAR:
dvander@2762
   476
        case OP_CRMINSTAR:
dvander@2762
   477
        case OP_CRPLUS:
dvander@2762
   478
        case OP_CRMINPLUS:
dvander@2762
   479
        case OP_CRQUERY:
dvander@2762
   480
        case OP_CRMINQUERY:
dvander@2762
   481
        fprintf(f, "%s", OP_names[*ccode]);
dvander@2762
   482
        extra += _pcre_OP_lengths[*ccode];
dvander@2762
   483
        break;
dvander@2762
   484
dvander@2762
   485
        case OP_CRRANGE:
dvander@2762
   486
        case OP_CRMINRANGE:
dvander@2762
   487
        min = GET2(ccode,1);
dvander@2762
   488
        max = GET2(ccode,3);
dvander@2762
   489
        if (max == 0) fprintf(f, "{%d,}", min);
dvander@2762
   490
        else fprintf(f, "{%d,%d}", min, max);
dvander@2762
   491
        if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
dvander@2762
   492
        extra += _pcre_OP_lengths[*ccode];
dvander@2762
   493
        break;
dvander@2762
   494
dvander@2762
   495
        /* Do nothing if it's not a repeat; this code stops picky compilers
dvander@2762
   496
        warning about the lack of a default code path. */
dvander@2762
   497
dvander@2762
   498
        default:
dvander@2762
   499
        break;
dvander@2762
   500
        }
dvander@2762
   501
      }
dvander@2762
   502
    break;
dvander@2762
   503
dvander@2762
   504
    /* Anything else is just an item with no data*/
dvander@2762
   505
dvander@2762
   506
    default:
dvander@2762
   507
    fprintf(f, "    %s", OP_names[*code]);
dvander@2762
   508
    break;
dvander@2762
   509
    }
dvander@2762
   510
dvander@2762
   511
  code += _pcre_OP_lengths[*code] + extra;
dvander@2762
   512
  fprintf(f, "\n");
dvander@2762
   513
  }
dvander@2762
   514
}
dvander@2762
   515
dvander@2762
   516
/* End of pcre_printint.src */