/[pcre]/code/branches/pcre16/pcre_printint.src
ViewVC logotype

Diff of /code/branches/pcre16/pcre_printint.src

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

code/trunk/pcre_printint.src revision 117 by ph10, Fri Mar 9 15:59:06 2007 UTC code/branches/pcre16/pcre_printint.src revision 756 by ph10, Mon Nov 21 10:48:42 2011 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-2007 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. */
# Line 54  hexadecimal. We don't use isprint() beca Line 55  hexadecimal. We don't use isprint() beca
55  (even without the use of locales) and we want the output always to be the same,  (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. */  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)  #define PRINTABLE(c) ((c) >= 32 && (c) < 127)
62    #endif
63    
64  /* The table of operator names. */  /* The table of operator names. */
65    
# Line 67  static const char *OP_names[] = { OP_NAM Line 72  static const char *OP_names[] = { OP_NAM
72  *************************************************/  *************************************************/
73    
74  static int  static int
75  print_char(FILE *f, uschar *ptr, BOOL utf8)  print_char(FILE *f, pcre_uchar *ptr, BOOL utf8)
76  {  {
77  int c = *ptr;  int c = *ptr;
78    
# Line 122  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 142  return (ptype == pvalue)? "??" : "??"; Line 147  return (ptype == pvalue)? "??" : "??";
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. The  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.  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  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. */  written that do not depend on the value of LINK_SIZE. */
153    
# Line 150  static void Line 155  static void
155  pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)  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;  pcre_uchar *codestart, *code;
159  BOOL utf8;  BOOL utf8;
160    
161  unsigned int options = re->options;  unsigned int options = re->options;
# Line 169  if (re->magic_number != MAGIC_NUMBER) Line 174  if (re->magic_number != MAGIC_NUMBER)
174              ((options >> 24) & 0x000000ff);              ((options >> 24) & 0x000000ff);
175    }    }
176    
177  code = codestart = (uschar *)re + offset + count * size;  code = codestart = (pcre_uchar *)re + offset + count * size;
178  utf8 = (options & PCRE_UTF8) != 0;  utf8 = (options & PCRE_UTF8) != 0;
179    
180  for(;;)  for(;;)
181    {    {
182    uschar *ccode;    pcre_uchar *ccode;
183      const char *flag = "  ";
184    int c;    int c;
185    int extra = 0;    int extra = 0;
186    
187    if (print_lengths)    if (print_lengths)
188      fprintf(f, "%3d ", (int)(code - codestart));      fprintf(f, "%3d ", (int)(code - codestart));
189    else    else
190      fprintf(f, "    ");      fprintf(f, "    ");
191    
192    switch(*code)    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:      case OP_END:
214      fprintf(f, "    %s\n", OP_names[*code]);      fprintf(f, "    %s\n", OP_names[*code]);
215      fprintf(f, "------------------------------------------------------------------\n");      fprintf(f, "------------------------------------------------------------------\n");
216      return;      return;
217    
     case OP_OPT:  
     fprintf(f, " %.2x %s", code[1], OP_names[*code]);  
     break;  
   
218      case OP_CHAR:      case OP_CHAR:
219      fprintf(f, "    ");      fprintf(f, "    ");
220      do      do
# Line 205  for(;;) Line 226  for(;;)
226      fprintf(f, "\n");      fprintf(f, "\n");
227      continue;      continue;
228    
229      case OP_CHARNC:      case OP_CHARI:
230      fprintf(f, " NC ");      fprintf(f, " /i ");
231      do      do
232        {        {
233        code++;        code++;
234        code += 1 + print_char(f, code, utf8);        code += 1 + print_char(f, code, utf8);
235        }        }
236      while (*code == OP_CHARNC);      while (*code == OP_CHARI);
237      fprintf(f, "\n");      fprintf(f, "\n");
238      continue;      continue;
239    
240      case OP_CBRA:      case OP_CBRA:
241        case OP_CBRAPOS:
242      case OP_SCBRA:      case OP_SCBRA:
243        case OP_SCBRAPOS:
244      if (print_lengths) fprintf(f, "%3d ", GET(code, 1));      if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
245        else fprintf(f, "    ");        else fprintf(f, "    ");
246      fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));      fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));
247      break;      break;
248    
249      case OP_BRA:      case OP_BRA:
250        case OP_BRAPOS:
251      case OP_SBRA:      case OP_SBRA:
252        case OP_SBRAPOS:
253      case OP_KETRMAX:      case OP_KETRMAX:
254      case OP_KETRMIN:      case OP_KETRMIN:
255        case OP_KETRPOS:
256      case OP_ALT:      case OP_ALT:
257      case OP_KET:      case OP_KET:
258      case OP_ASSERT:      case OP_ASSERT:
# Line 234  for(;;) Line 260  for(;;)
260      case OP_ASSERTBACK:      case OP_ASSERTBACK:
261      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
262      case OP_ONCE:      case OP_ONCE:
263        case OP_ONCE_NC:
264      case OP_COND:      case OP_COND:
265      case OP_SCOND:      case OP_SCOND:
266      case OP_REVERSE:      case OP_REVERSE:
267      if (print_lengths) fprintf(f, "%3d ", GET(code, 1));      if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
268        else fprintf(f, "    ");        else fprintf(f, "    ");
269      fprintf(f, "%s", OP_names[*code]);      fprintf(f, "%s", OP_names[*code]);
270      break;      break;
271    
272        case OP_CLOSE:
273        fprintf(f, "    %s %d", OP_names[*code], GET2(code, 1));
274        break;
275    
276      case OP_CREF:      case OP_CREF:
277        case OP_NCREF:
278      fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);      fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
279      break;      break;
280    
# Line 254  for(;;) Line 286  for(;;)
286        fprintf(f, "    Cond recurse %d", c);        fprintf(f, "    Cond recurse %d", c);
287      break;      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:      case OP_DEF:
298      fprintf(f, "    Cond def");      fprintf(f, "    Cond def");
299      break;      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:      case OP_STAR:
313      case OP_MINSTAR:      case OP_MINSTAR:
314      case OP_POSSTAR:      case OP_POSSTAR:
# Line 276  for(;;) Line 327  for(;;)
327      case OP_TYPEQUERY:      case OP_TYPEQUERY:
328      case OP_TYPEMINQUERY:      case OP_TYPEMINQUERY:
329      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
330      fprintf(f, "    ");      fprintf(f, " %s ", flag);
331      if (*code >= OP_TYPESTAR)      if (*code >= OP_TYPESTAR)
332        {        {
333        fprintf(f, "%s", OP_names[code[1]]);        fprintf(f, "%s", OP_names[code[1]]);
# Line 290  for(;;) Line 341  for(;;)
341      fprintf(f, "%s", OP_names[*code]);      fprintf(f, "%s", OP_names[*code]);
342      break;      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:      case OP_EXACT:
351      case OP_UPTO:      case OP_UPTO:
352      case OP_MINUPTO:      case OP_MINUPTO:
353      case OP_POSUPTO:      case OP_POSUPTO:
354      fprintf(f, "    ");      fprintf(f, " %s ", flag);
355      extra = print_char(f, code+3, utf8);      extra = print_char(f, code+3, utf8);
356      fprintf(f, "{");      fprintf(f, "{");
357      if (*code != OP_EXACT) fprintf(f, "0,");      if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,");
358      fprintf(f, "%d}", GET2(code,1));      fprintf(f, "%d}", GET2(code,1));
359      if (*code == OP_MINUPTO) fprintf(f, "?");      if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?");
360        else if (*code == OP_POSUPTO) fprintf(f, "+");        else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+");
361      break;      break;
362    
363      case OP_TYPEEXACT:      case OP_TYPEEXACT:
# Line 320  for(;;) Line 377  for(;;)
377        else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");        else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
378      break;      break;
379    
380        case OP_NOTI:
381        flag = "/i";
382        /* Fall through */
383      case OP_NOT:      case OP_NOT:
384      c = code[1];      c = code[1];
385      if (PRINTABLE(c)) fprintf(f, "    [^%c]", c);      if (PRINTABLE(c)) fprintf(f, " %s [^%c]", flag, c);
386        else fprintf(f, "    [^\\x%02x]", c);        else fprintf(f, " %s [^\\x%02x]", flag, c);
387      break;      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:      case OP_NOTSTAR:
402      case OP_NOTMINSTAR:      case OP_NOTMINSTAR:
403      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 336  for(;;) Line 408  for(;;)
408      case OP_NOTMINQUERY:      case OP_NOTMINQUERY:
409      case OP_NOTPOSQUERY:      case OP_NOTPOSQUERY:
410      c = code[1];      c = code[1];
411      if (PRINTABLE(c)) fprintf(f, "    [^%c]", c);      if (PRINTABLE(c)) fprintf(f, " %s [^%c]", flag, c);
412        else fprintf(f, "    [^\\x%02x]", c);        else fprintf(f, " %s [^\\x%02x]", flag, c);
413      fprintf(f, "%s", OP_names[*code]);      fprintf(f, "%s", OP_names[*code]);
414      break;      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:      case OP_NOTEXACT:
424      case OP_NOTUPTO:      case OP_NOTUPTO:
425      case OP_NOTMINUPTO:      case OP_NOTMINUPTO:
426      case OP_NOTPOSUPTO:      case OP_NOTPOSUPTO:
427      c = code[3];      c = code[3];
428      if (PRINTABLE(c)) fprintf(f, "    [^%c]{", c);      if (PRINTABLE(c)) fprintf(f, " %s [^%c]{", flag, c);
429        else fprintf(f, "    [^\\x%02x]{", c);        else fprintf(f, " %s [^\\x%02x]{", flag, c);
430      if (*code != OP_NOTEXACT) fprintf(f, "0,");      if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,");
431      fprintf(f, "%d}", GET2(code,1));      fprintf(f, "%d}", GET2(code,1));
432      if (*code == OP_NOTMINUPTO) fprintf(f, "?");      if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?");
433        else if (*code == OP_NOTPOSUPTO) fprintf(f, "+");        else
434        if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+");
435      break;      break;
436    
437      case OP_RECURSE:      case OP_RECURSE:
438      if (print_lengths) fprintf(f, "%3d ", GET(code, 1));      if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
439        else fprintf(f, "    ");        else fprintf(f, "    ");
440      fprintf(f, "%s", OP_names[*code]);      fprintf(f, "%s", OP_names[*code]);
441      break;      break;
442    
443        case OP_REFI:
444        flag = "/i";
445        /* Fall through */
446      case OP_REF:      case OP_REF:
447      fprintf(f, "    \\%d", GET2(code,1));      fprintf(f, " %s \\%d", flag, GET2(code,1));
448      ccode = code + _pcre_OP_lengths[*code];      ccode = code + _pcre_OP_lengths[*code];
449      goto CLASS_REF_REPEAT;      goto CLASS_REF_REPEAT;
450    
# Line 497  for(;;) Line 580  for(;;)
580        }        }
581      break;      break;
582    
583      /* Anything else is just an item with no data*/      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      default:      case OP_THEN:
591      fprintf(f, "    %s", OP_names[*code]);      fprintf(f, "    %s", OP_names[*code]);
592      break;      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;    code += _pcre_OP_lengths[*code] + extra;

Legend:
Removed from v.117  
changed lines
  Added in v.756

  ViewVC Help
Powered by ViewVC 1.1.5