/[pcre]/code/tags/pcre-8.10/pcre_printint.src
ViewVC logotype

Diff of /code/tags/pcre-8.10/pcre_printint.src

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

code/trunk/pcre_printint.src revision 91 by nigel, Sat Feb 24 21:41:34 2007 UTC code/tags/pcre-8.10/pcre_printint.src revision 549 by ph10, Fri Jun 25 14:43:53 2010 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2005 University of Cambridge             Copyright (c) 1997-2010 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 43  internal form of a compiled regular expr Line 43  internal form of a compiled regular expr
43  local functions. This source file is used in two places:  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  (1) It is #included by pcre_compile.c when it is compiled in debugging mode
46  (DEBUG defined in pcre_internal.h). It is not included in production compiles.  (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  (2) It is always #included by pcretest.c, which can be asked to print out a
50  compiled regex for debugging purposes. */  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 };  static const char *OP_names[] = { OP_NAME_LIST };
67    
68    
69    
70  /*************************************************  /*************************************************
71  *       Print single- or multi-byte character    *  *       Print single- or multi-byte character    *
72  *************************************************/  *************************************************/
# Line 61  print_char(FILE *f, uschar *ptr, BOOL ut Line 76  print_char(FILE *f, uschar *ptr, BOOL ut
76  {  {
77  int c = *ptr;  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)  if (!utf8 || (c & 0xc0) != 0xc0)
86    {    {
87    if (isprint(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);    if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
88    return 0;    return 0;
89    }    }
90  else  else
# Line 92  else Line 113  else
113    if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c);    if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c);
114    return a;    return a;
115    }    }
116    #endif
117  }  }
118    
119    
# Line 105  get_ucpname(int ptype, int pvalue) Line 127  get_ucpname(int ptype, int pvalue)
127  {  {
128  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
129  int i;  int i;
130  for (i = _pcre_utt_size; i >= 0; i--)  for (i = _pcre_utt_size - 1; i >= 0; i--)
131    {    {
132    if (ptype == _pcre_utt[i].type && pvalue == _pcre_utt[i].value) break;    if (ptype == _pcre_utt[i].type && pvalue == _pcre_utt[i].value) break;
133    }    }
134  return (i >= 0)? _pcre_utt[i].name : "??";  return (i >= 0)? _pcre_utt_names + _pcre_utt[i].name_offset : "??";
135  #else  #else
136  /* It gets harder and harder to shut off unwanted compiler warnings. */  /* It gets harder and harder to shut off unwanted compiler warnings. */
137  ptype = ptype * pvalue;  ptype = ptype * pvalue;
# Line 124  return (ptype == pvalue)? "??" : "??"; Line 146  return (ptype == pvalue)? "??" : "??";
146  *************************************************/  *************************************************/
147    
148  /* Make this function work for a regex with integers either byte order.  /* 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. */  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  static void
155  pcre_printint(pcre *external_re, FILE *f)  pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
156  {  {
157  real_pcre *re = (real_pcre *)external_re;  real_pcre *re = (real_pcre *)external_re;
158  uschar *codestart, *code;  uschar *codestart, *code;
# Line 158  for(;;) Line 183  for(;;)
183    int c;    int c;
184    int extra = 0;    int extra = 0;
185    
186    fprintf(f, "%3d ", (int)(code - codestart));    if (print_lengths)
187        fprintf(f, "%3d ", (int)(code - codestart));
188    if (*code >= OP_BRA)    else
189      {      fprintf(f, "    ");
     if (*code - OP_BRA > EXTRACT_BASIC_MAX)  
       fprintf(f, "%3d Bra extra\n", GET(code, 1));  
     else  
       fprintf(f, "%3d Bra %d\n", GET(code, 1), *code - OP_BRA);  
     code += _pcre_OP_lengths[OP_BRA];  
     continue;  
     }  
190    
191    switch(*code)    switch(*code)
192      {      {
193    /* ========================================================================== */
194          /* These cases are never obeyed. This is a fudge that causes a compile-
195          time error if the vectors OP_names or _pcre_OP_lengths, which are indexed
196          by opcode, are not the correct length. It seems to be the only way to do
197          such a check at compile time, as the sizeof() operator does not work in
198          the C preprocessor. We do this while compiling pcretest, because that
199          #includes pcre_tables.c, which holds _pcre_OP_lengths. We can't do this
200          when building pcre_compile.c with PCRE_DEBUG set, because it doesn't then
201          know the size of _pcre_OP_lengths. */
202    
203    #ifdef COMPILING_PCRETEST
204          case OP_TABLE_LENGTH:
205          case OP_TABLE_LENGTH +
206            ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&
207            (sizeof(_pcre_OP_lengths) == OP_TABLE_LENGTH)):
208          break;
209    #endif
210    /* ========================================================================== */
211    
212      case OP_END:      case OP_END:
213      fprintf(f, "    %s\n", OP_names[*code]);      fprintf(f, "    %s\n", OP_names[*code]);
214      fprintf(f, "------------------------------------------------------------------\n");      fprintf(f, "------------------------------------------------------------------\n");
# Line 203  for(;;) Line 240  for(;;)
240      fprintf(f, "\n");      fprintf(f, "\n");
241      continue;      continue;
242    
243        case OP_CBRA:
244        case OP_SCBRA:
245        if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
246          else fprintf(f, "    ");
247        fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));
248        break;
249    
250        case OP_BRA:
251        case OP_SBRA:
252      case OP_KETRMAX:      case OP_KETRMAX:
253      case OP_KETRMIN:      case OP_KETRMIN:
254      case OP_ALT:      case OP_ALT:
# Line 213  for(;;) Line 259  for(;;)
259      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
260      case OP_ONCE:      case OP_ONCE:
261      case OP_COND:      case OP_COND:
262        case OP_SCOND:
263      case OP_REVERSE:      case OP_REVERSE:
264      fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]);      if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
265          else fprintf(f, "    ");
266        fprintf(f, "%s", OP_names[*code]);
267      break;      break;
268    
269      case OP_BRANUMBER:      case OP_CLOSE:
270      printf("%3d %s", GET2(code, 1), OP_names[*code]);      fprintf(f, "    %s %d", OP_names[*code], GET2(code, 1));
271      break;      break;
272    
273      case OP_CREF:      case OP_CREF:
274      if (GET2(code, 1) == CREF_RECURSE)      case OP_NCREF:
275        fprintf(f, "    Cond recurse");      fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
276        break;
277    
278        case OP_RREF:
279        c = GET2(code, 1);
280        if (c == RREF_ANY)
281          fprintf(f, "    Cond recurse any");
282      else      else
283        fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);        fprintf(f, "    Cond recurse %d", c);
284        break;
285    
286        case OP_NRREF:
287        c = GET2(code, 1);
288        if (c == RREF_ANY)
289          fprintf(f, "    Cond nrecurse any");
290        else
291          fprintf(f, "    Cond nrecurse %d", c);
292        break;
293    
294        case OP_DEF:
295        fprintf(f, "    Cond def");
296      break;      break;
297    
298      case OP_STAR:      case OP_STAR:
299      case OP_MINSTAR:      case OP_MINSTAR:
300        case OP_POSSTAR:
301      case OP_PLUS:      case OP_PLUS:
302      case OP_MINPLUS:      case OP_MINPLUS:
303        case OP_POSPLUS:
304      case OP_QUERY:      case OP_QUERY:
305      case OP_MINQUERY:      case OP_MINQUERY:
306        case OP_POSQUERY:
307      case OP_TYPESTAR:      case OP_TYPESTAR:
308      case OP_TYPEMINSTAR:      case OP_TYPEMINSTAR:
309        case OP_TYPEPOSSTAR:
310      case OP_TYPEPLUS:      case OP_TYPEPLUS:
311      case OP_TYPEMINPLUS:      case OP_TYPEMINPLUS:
312        case OP_TYPEPOSPLUS:
313      case OP_TYPEQUERY:      case OP_TYPEQUERY:
314      case OP_TYPEMINQUERY:      case OP_TYPEMINQUERY:
315        case OP_TYPEPOSQUERY:
316      fprintf(f, "    ");      fprintf(f, "    ");
317      if (*code >= OP_TYPESTAR)      if (*code >= OP_TYPESTAR)
318        {        {
# Line 257  for(;;) Line 330  for(;;)
330      case OP_EXACT:      case OP_EXACT:
331      case OP_UPTO:      case OP_UPTO:
332      case OP_MINUPTO:      case OP_MINUPTO:
333        case OP_POSUPTO:
334      fprintf(f, "    ");      fprintf(f, "    ");
335      extra = print_char(f, code+3, utf8);      extra = print_char(f, code+3, utf8);
336      fprintf(f, "{");      fprintf(f, "{");
337      if (*code != OP_EXACT) fprintf(f, ",");      if (*code != OP_EXACT) fprintf(f, "0,");
338      fprintf(f, "%d}", GET2(code,1));      fprintf(f, "%d}", GET2(code,1));
339      if (*code == OP_MINUPTO) fprintf(f, "?");      if (*code == OP_MINUPTO) fprintf(f, "?");
340          else if (*code == OP_POSUPTO) fprintf(f, "+");
341      break;      break;
342    
343      case OP_TYPEEXACT:      case OP_TYPEEXACT:
344      case OP_TYPEUPTO:      case OP_TYPEUPTO:
345      case OP_TYPEMINUPTO:      case OP_TYPEMINUPTO:
346        case OP_TYPEPOSUPTO:
347      fprintf(f, "    %s", OP_names[code[3]]);      fprintf(f, "    %s", OP_names[code[3]]);
348      if (code[3] == OP_PROP || code[3] == OP_NOTPROP)      if (code[3] == OP_PROP || code[3] == OP_NOTPROP)
349        {        {
# Line 278  for(;;) Line 354  for(;;)
354      if (*code != OP_TYPEEXACT) fprintf(f, "0,");      if (*code != OP_TYPEEXACT) fprintf(f, "0,");
355      fprintf(f, "%d}", GET2(code,1));      fprintf(f, "%d}", GET2(code,1));
356      if (*code == OP_TYPEMINUPTO) fprintf(f, "?");      if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
357          else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
358      break;      break;
359    
360      case OP_NOT:      case OP_NOT:
361      if (isprint(c = code[1])) fprintf(f, "    [^%c]", c);      c = code[1];
362        if (PRINTABLE(c)) fprintf(f, "    [^%c]", c);
363        else fprintf(f, "    [^\\x%02x]", c);        else fprintf(f, "    [^\\x%02x]", c);
364      break;      break;
365    
366      case OP_NOTSTAR:      case OP_NOTSTAR:
367      case OP_NOTMINSTAR:      case OP_NOTMINSTAR:
368        case OP_NOTPOSSTAR:
369      case OP_NOTPLUS:      case OP_NOTPLUS:
370      case OP_NOTMINPLUS:      case OP_NOTMINPLUS:
371        case OP_NOTPOSPLUS:
372      case OP_NOTQUERY:      case OP_NOTQUERY:
373      case OP_NOTMINQUERY:      case OP_NOTMINQUERY:
374      if (isprint(c = code[1])) fprintf(f, "    [^%c]", c);      case OP_NOTPOSQUERY:
375        c = code[1];
376        if (PRINTABLE(c)) fprintf(f, "    [^%c]", c);
377        else fprintf(f, "    [^\\x%02x]", c);        else fprintf(f, "    [^\\x%02x]", c);
378      fprintf(f, "%s", OP_names[*code]);      fprintf(f, "%s", OP_names[*code]);
379      break;      break;
# Line 299  for(;;) Line 381  for(;;)
381      case OP_NOTEXACT:      case OP_NOTEXACT:
382      case OP_NOTUPTO:      case OP_NOTUPTO:
383      case OP_NOTMINUPTO:      case OP_NOTMINUPTO:
384      if (isprint(c = code[3])) fprintf(f, "    [^%c]{", c);      case OP_NOTPOSUPTO:
385        c = code[3];
386        if (PRINTABLE(c)) fprintf(f, "    [^%c]{", c);
387        else fprintf(f, "    [^\\x%02x]{", c);        else fprintf(f, "    [^\\x%02x]{", c);
388      if (*code != OP_NOTEXACT) fprintf(f, "0,");      if (*code != OP_NOTEXACT) fprintf(f, "0,");
389      fprintf(f, "%d}", GET2(code,1));      fprintf(f, "%d}", GET2(code,1));
390      if (*code == OP_NOTMINUPTO) fprintf(f, "?");      if (*code == OP_NOTMINUPTO) fprintf(f, "?");
391          else if (*code == OP_NOTPOSUPTO) fprintf(f, "+");
392      break;      break;
393    
394      case OP_RECURSE:      case OP_RECURSE:
395      fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]);      if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
396          else fprintf(f, "    ");
397        fprintf(f, "%s", OP_names[*code]);
398      break;      break;
399    
400      case OP_REF:      case OP_REF:
# Line 363  for(;;) Line 450  for(;;)
450              for (j = i+1; j < 256; j++)              for (j = i+1; j < 256; j++)
451                if ((ccode[j/8] & (1 << (j&7))) == 0) break;                if ((ccode[j/8] & (1 << (j&7))) == 0) break;
452              if (i == '-' || i == ']') fprintf(f, "\\");              if (i == '-' || i == ']') fprintf(f, "\\");
453              if (isprint(i)) fprintf(f, "%c", i); else fprintf(f, "\\x%02x", i);              if (PRINTABLE(i)) fprintf(f, "%c", i);
454                  else fprintf(f, "\\x%02x", i);
455              if (--j > i)              if (--j > i)
456                {                {
457                if (j != i + 1) fprintf(f, "-");                if (j != i + 1) fprintf(f, "-");
458                if (j == '-' || j == ']') fprintf(f, "\\");                if (j == '-' || j == ']') fprintf(f, "\\");
459                if (isprint(j)) fprintf(f, "%c", j); else fprintf(f, "\\x%02x", j);                if (PRINTABLE(j)) fprintf(f, "%c", j);
460                    else fprintf(f, "\\x%02x", j);
461                }                }
462              i = j;              i = j;
463              }              }
# Line 445  for(;;) Line 534  for(;;)
534        }        }
535      break;      break;
536    
537        case OP_MARK:
538        case OP_PRUNE_ARG:
539        case OP_SKIP_ARG:
540        case OP_THEN_ARG:
541        fprintf(f, "    %s %s", OP_names[*code], code + 2);
542        extra += code[1];
543        break;
544    
545      /* Anything else is just an item with no data*/      /* Anything else is just an item with no data*/
546    
547      default:      default:

Legend:
Removed from v.91  
changed lines
  Added in v.549

  ViewVC Help
Powered by ViewVC 1.1.5