/[pcre]/code/trunk/pcre_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_compile.c

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

revision 172 by ph10, Tue Jun 5 10:40:13 2007 UTC revision 178 by ph10, Wed Jun 13 08:44:34 2007 UTC
# Line 58  used by pcretest. DEBUG is not defined w Line 58  used by pcretest. DEBUG is not defined w
58  #endif  #endif
59    
60    
61    /* Macro for setting individual bits in class bitmaps. */
62    
63    #define SETBIT(a,b) a[b/8] |= (1 << (b%8))
64    
65    
66  /*************************************************  /*************************************************
67  *      Code parameters and static tables         *  *      Code parameters and static tables         *
68  *************************************************/  *************************************************/
# Line 87  static const short int escapes[] = { Line 92  static const short int escapes[] = {
92       0,      0,      0,      0,      0,      0,      0,      0,   /* 0 - 7 */       0,      0,      0,      0,      0,      0,      0,      0,   /* 0 - 7 */
93       0,      0,    ':',    ';',    '<',    '=',    '>',    '?',   /* 8 - ? */       0,      0,    ':',    ';',    '<',    '=',    '>',    '?',   /* 8 - ? */
94     '@', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E,      0, -ESC_G,   /* @ - G */     '@', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E,      0, -ESC_G,   /* @ - G */
95       0,      0,      0, -ESC_K,      0,      0,      0,      0,   /* H - O */  -ESC_H,      0,      0, -ESC_K,      0,      0,      0,      0,   /* H - O */
96  -ESC_P, -ESC_Q, -ESC_R, -ESC_S,      0,      0,      0, -ESC_W,   /* P - W */  -ESC_P, -ESC_Q, -ESC_R, -ESC_S,      0,      0, -ESC_V, -ESC_W,   /* P - W */
97  -ESC_X,      0, -ESC_Z,    '[',   '\\',    ']',    '^',    '_',   /* X - _ */  -ESC_X,      0, -ESC_Z,    '[',   '\\',    ']',    '^',    '_',   /* X - _ */
98     '`',      7, -ESC_b,      0, -ESC_d,  ESC_e,  ESC_f,      0,   /* ` - g */     '`',      7, -ESC_b,      0, -ESC_d,  ESC_e,  ESC_f,      0,   /* ` - g */
99       0,      0,      0, -ESC_k,      0,      0,  ESC_n,      0,   /* h - o */  -ESC_h,      0,      0, -ESC_k,      0,      0,  ESC_n,      0,   /* h - o */
100  -ESC_p,      0,  ESC_r, -ESC_s,  ESC_tee,    0,      0, -ESC_w,   /* p - w */  -ESC_p,      0,  ESC_r, -ESC_s,  ESC_tee,    0, -ESC_v, -ESC_w,   /* p - w */
101       0,      0, -ESC_z                                            /* x - z */       0,      0, -ESC_z                                            /* x - z */
102  };  };
103    
# Line 106  static const short int escapes[] = { Line 111  static const short int escapes[] = {
111  /*  70 */     0,     0,      0,       0,      0,     0,      0,      0,  /*  70 */     0,     0,      0,       0,      0,     0,      0,      0,
112  /*  78 */     0,   '`',    ':',     '#',    '@',  '\'',    '=',    '"',  /*  78 */     0,   '`',    ':',     '#',    '@',  '\'',    '=',    '"',
113  /*  80 */     0,     7, -ESC_b,       0, -ESC_d, ESC_e,  ESC_f,      0,  /*  80 */     0,     7, -ESC_b,       0, -ESC_d, ESC_e,  ESC_f,      0,
114  /*  88 */     0,     0,      0,     '{',      0,     0,      0,      0,  /*  88 */-ESC_h,     0,      0,     '{',      0,     0,      0,      0,
115  /*  90 */     0,     0, -ESC_k,     'l',      0, ESC_n,      0, -ESC_p,  /*  90 */     0,     0, -ESC_k,     'l',      0, ESC_n,      0, -ESC_p,
116  /*  98 */     0, ESC_r,      0,     '}',      0,     0,      0,      0,  /*  98 */     0, ESC_r,      0,     '}',      0,     0,      0,      0,
117  /*  A0 */     0,   '~', -ESC_s, ESC_tee,      0,     0, -ESC_w,      0,  /*  A0 */     0,   '~', -ESC_s, ESC_tee,      0,-ESC_v, -ESC_w,      0,
118  /*  A8 */     0,-ESC_z,      0,       0,      0,   '[',      0,      0,  /*  A8 */     0,-ESC_z,      0,       0,      0,   '[',      0,      0,
119  /*  B0 */     0,     0,      0,       0,      0,     0,      0,      0,  /*  B0 */     0,     0,      0,       0,      0,     0,      0,      0,
120  /*  B8 */     0,     0,      0,       0,      0,   ']',    '=',    '-',  /*  B8 */     0,     0,      0,       0,      0,   ']',    '=',    '-',
121  /*  C0 */   '{',-ESC_A, -ESC_B,  -ESC_C, -ESC_D,-ESC_E,      0, -ESC_G,  /*  C0 */   '{',-ESC_A, -ESC_B,  -ESC_C, -ESC_D,-ESC_E,      0, -ESC_G,
122  /*  C8 */     0,     0,      0,       0,      0,     0,      0,      0,  /*  C8 */-ESC_H,     0,      0,       0,      0,     0,      0,      0,
123  /*  D0 */   '}',     0,      0,       0,      0,     0,      0, -ESC_P,  /*  D0 */   '}',     0,      0,       0,      0,     0,      0, -ESC_P,
124  /*  D8 */-ESC_Q,-ESC_R,      0,       0,      0,     0,      0,      0,  /*  D8 */-ESC_Q,-ESC_R,      0,       0,      0,     0,      0,      0,
125  /*  E0 */  '\\',     0, -ESC_S,       0,      0,     0, -ESC_W, -ESC_X,  /*  E0 */  '\\',     0, -ESC_S,       0,      0,-ESC_V, -ESC_W, -ESC_X,
126  /*  E8 */     0,-ESC_Z,      0,       0,      0,     0,      0,      0,  /*  E8 */     0,-ESC_Z,      0,       0,      0,     0,      0,      0,
127  /*  F0 */     0,     0,      0,       0,      0,     0,      0,      0,  /*  F0 */     0,     0,      0,       0,      0,     0,      0,      0,
128  /*  F8 */     0,     0,      0,       0,      0,     0,      0,      0  /*  F8 */     0,     0,      0,       0,      0,     0,      0,      0
# Line 374  static const unsigned char ebcdic_charta Line 379  static const unsigned char ebcdic_charta
379  /* Definition to allow mutual recursion */  /* Definition to allow mutual recursion */
380    
381  static BOOL  static BOOL
382    compile_regex(int, int, uschar **, const uschar **, int *, BOOL, int, int *,    compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int,
383      int *, branch_chain *, compile_data *, int *);      int *, int *, branch_chain *, compile_data *, int *);
384    
385    
386    
# Line 2110  for (;; ptr++) Line 2115  for (;; ptr++)
2115    BOOL possessive_quantifier;    BOOL possessive_quantifier;
2116    BOOL is_quantifier;    BOOL is_quantifier;
2117    BOOL is_recurse;    BOOL is_recurse;
2118      BOOL reset_bracount;
2119    int class_charcount;    int class_charcount;
2120    int class_lastchar;    int class_lastchar;
2121    int newoptions;    int newoptions;
# Line 2529  for (;; ptr++) Line 2535  for (;; ptr++)
2535    
2536              case ESC_E: /* Perl ignores an orphan \E */              case ESC_E: /* Perl ignores an orphan \E */
2537              continue;              continue;
2538    
2539              default:    /* Not recognized; fall through */              default:    /* Not recognized; fall through */
2540              break;      /* Need "default" setting to stop compiler warning. */              break;      /* Need "default" setting to stop compiler warning. */
2541              }              }
# Line 2538  for (;; ptr++) Line 2544  for (;; ptr++)
2544    
2545            else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||            else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||
2546                     c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;                     c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;
2547    
2548              /* We need to deal with \H, \h, \V, and \v in both phases because
2549              they use extra memory. */
2550    
2551              if (-c == ESC_h)
2552                {
2553                SETBIT(classbits, 0x09); /* VT */
2554                SETBIT(classbits, 0x20); /* SPACE */
2555                SETBIT(classbits, 0xa0); /* NSBP */
2556    #ifdef SUPPORT_UTF8
2557                if (utf8)
2558                  {
2559                  class_utf8 = TRUE;
2560                  *class_utf8data++ = XCL_SINGLE;
2561                  class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data);
2562                  *class_utf8data++ = XCL_SINGLE;
2563                  class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data);
2564                  *class_utf8data++ = XCL_RANGE;
2565                  class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data);
2566                  class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data);
2567                  *class_utf8data++ = XCL_SINGLE;
2568                  class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data);
2569                  *class_utf8data++ = XCL_SINGLE;
2570                  class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data);
2571                  *class_utf8data++ = XCL_SINGLE;
2572                  class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data);
2573                  }
2574    #endif
2575                continue;
2576                }
2577    
2578              if (-c == ESC_H)
2579                {
2580                for (c = 0; c < 32; c++)
2581                  {
2582                  int x = 0xff;
2583                  switch (c)
2584                    {
2585                    case 0x09/8: x ^= 1 << (0x09%8); break;
2586                    case 0x20/8: x ^= 1 << (0x20%8); break;
2587                    case 0xa0/8: x ^= 1 << (0xa0%8); break;
2588                    default: break;
2589                    }
2590                  classbits[c] |= x;
2591                  }
2592    
2593    #ifdef SUPPORT_UTF8
2594                if (utf8)
2595                  {
2596                  class_utf8 = TRUE;
2597                  *class_utf8data++ = XCL_RANGE;
2598                  class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2599                  class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data);
2600                  *class_utf8data++ = XCL_RANGE;
2601                  class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data);
2602                  class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data);
2603                  *class_utf8data++ = XCL_RANGE;
2604                  class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data);
2605                  class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data);
2606                  *class_utf8data++ = XCL_RANGE;
2607                  class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data);
2608                  class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data);
2609                  *class_utf8data++ = XCL_RANGE;
2610                  class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data);
2611                  class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data);
2612                  *class_utf8data++ = XCL_RANGE;
2613                  class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data);
2614                  class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data);
2615                  *class_utf8data++ = XCL_RANGE;
2616                  class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data);
2617                  class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2618                  }
2619    #endif
2620                continue;
2621                }
2622    
2623              if (-c == ESC_v)
2624                {
2625                SETBIT(classbits, 0x0a); /* LF */
2626                SETBIT(classbits, 0x0b); /* VT */
2627                SETBIT(classbits, 0x0c); /* FF */
2628                SETBIT(classbits, 0x0d); /* CR */
2629                SETBIT(classbits, 0x85); /* NEL */
2630    #ifdef SUPPORT_UTF8
2631                if (utf8)
2632                  {
2633                  class_utf8 = TRUE;
2634                  *class_utf8data++ = XCL_RANGE;
2635                  class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data);
2636                  class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2637                  }
2638    #endif
2639                continue;
2640                }
2641    
2642              if (-c == ESC_V)
2643                {
2644                for (c = 0; c < 32; c++)
2645                  {
2646                  int x = 0xff;
2647                  switch (c)
2648                    {
2649                    case 0x0a/8: x ^= 1 << (0x0a%8);
2650                                 x ^= 1 << (0x0b%8);
2651                                 x ^= 1 << (0x0c%8);
2652                                 x ^= 1 << (0x0d%8);
2653                                 break;
2654                    case 0x85/8: x ^= 1 << (0x85%8); break;
2655                    default: break;
2656                    }
2657                  classbits[c] |= x;
2658                  }
2659    
2660    #ifdef SUPPORT_UTF8
2661                if (utf8)
2662                  {
2663                  class_utf8 = TRUE;
2664                  *class_utf8data++ = XCL_RANGE;
2665                  class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2666                  class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data);
2667                  *class_utf8data++ = XCL_RANGE;
2668                  class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2669                  class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2670                  }
2671    #endif
2672                continue;
2673                }
2674    
2675            /* We need to deal with \P and \p in both phases. */            /* We need to deal with \P and \p in both phases. */
2676    
# Line 2679  for (;; ptr++) Line 2812  for (;; ptr++)
2812              unsigned int origd = d;              unsigned int origd = d;
2813              while (get_othercase_range(&cc, origd, &occ, &ocd))              while (get_othercase_range(&cc, origd, &occ, &ocd))
2814                {                {
2815                if (occ >= c && ocd <= d) continue;  /* Skip embedded ranges */                if (occ >= (unsigned int)c &&
2816                      ocd <= (unsigned int)d)
2817                    continue;                          /* Skip embedded ranges */
2818    
2819                if (occ < c  && ocd >= c - 1)        /* Extend the basic range */                if (occ < (unsigned int)c  &&
2820                      ocd >= (unsigned int)c - 1)      /* Extend the basic range */
2821                  {                                  /* if there is overlap,   */                  {                                  /* if there is overlap,   */
2822                  c = occ;                           /* noting that if occ < c */                  c = occ;                           /* noting that if occ < c */
2823                  continue;                          /* we can't have ocd > d  */                  continue;                          /* we can't have ocd > d  */
2824                  }                                  /* because a subrange is  */                  }                                  /* because a subrange is  */
2825                if (ocd > d && occ <= d + 1)         /* always shorter than    */                if (ocd > (unsigned int)d &&
2826                      occ <= (unsigned int)d + 1)      /* always shorter than    */
2827                  {                                  /* the basic range.       */                  {                                  /* the basic range.       */
2828                  d = ocd;                  d = ocd;
2829                  continue;                  continue;
# Line 3584  for (;; ptr++) Line 3721  for (;; ptr++)
3721      skipbytes = 0;      skipbytes = 0;
3722      bravalue = OP_CBRA;      bravalue = OP_CBRA;
3723      save_hwm = cd->hwm;      save_hwm = cd->hwm;
3724        reset_bracount = FALSE;
3725    
3726      if (*(++ptr) == '?')      if (*(++ptr) == '?')
3727        {        {
# Line 3606  for (;; ptr++) Line 3744  for (;; ptr++)
3744    
3745    
3746          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
3747            case '|':                 /* Reset capture count for each branch */
3748            reset_bracount = TRUE;
3749            /* Fall through */
3750    
3751            /* ------------------------------------------------------------ */
3752          case ':':                 /* Non-capturing bracket */          case ':':                 /* Non-capturing bracket */
3753          bravalue = OP_BRA;          bravalue = OP_BRA;
3754          ptr++;          ptr++;
# Line 4304  for (;; ptr++) Line 4447  for (;; ptr++)
4447           errorcodeptr,                 /* Where to put an error message */           errorcodeptr,                 /* Where to put an error message */
4448           (bravalue == OP_ASSERTBACK ||           (bravalue == OP_ASSERTBACK ||
4449            bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */            bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
4450             reset_bracount,               /* True if (?| group */
4451           skipbytes,                    /* Skip over bracket number */           skipbytes,                    /* Skip over bracket number */
4452           &subfirstbyte,                /* For possible first char */           &subfirstbyte,                /* For possible first char */
4453           &subreqbyte,                  /* For possible last char */           &subreqbyte,                  /* For possible last char */
# Line 4663  Arguments: Line 4807  Arguments:
4807    ptrptr         -> the address of the current pattern pointer    ptrptr         -> the address of the current pattern pointer
4808    errorcodeptr   -> pointer to error code variable    errorcodeptr   -> pointer to error code variable
4809    lookbehind     TRUE if this is a lookbehind assertion    lookbehind     TRUE if this is a lookbehind assertion
4810      reset_bracount TRUE to reset the count for each branch
4811    skipbytes      skip this many bytes at start (for brackets and OP_COND)    skipbytes      skip this many bytes at start (for brackets and OP_COND)
4812    firstbyteptr   place to put the first required character, or a negative number    firstbyteptr   place to put the first required character, or a negative number
4813    reqbyteptr     place to put the last required character, or a negative number    reqbyteptr     place to put the last required character, or a negative number
# Line 4676  Returns:         TRUE on success Line 4821  Returns:         TRUE on success
4821    
4822  static BOOL  static BOOL
4823  compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,  compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,
4824    int *errorcodeptr, BOOL lookbehind, int skipbytes, int *firstbyteptr,    int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
4825    int *reqbyteptr, branch_chain *bcptr, compile_data *cd, int *lengthptr)    int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd,
4826      int *lengthptr)
4827  {  {
4828  const uschar *ptr = *ptrptr;  const uschar *ptr = *ptrptr;
4829  uschar *code = *codeptr;  uschar *code = *codeptr;
# Line 4687  uschar *reverse_count = NULL; Line 4833  uschar *reverse_count = NULL;
4833  int firstbyte, reqbyte;  int firstbyte, reqbyte;
4834  int branchfirstbyte, branchreqbyte;  int branchfirstbyte, branchreqbyte;
4835  int length;  int length;
4836    int orig_bracount;
4837    int max_bracount;
4838  branch_chain bc;  branch_chain bc;
4839    
4840  bc.outer = bcptr;  bc.outer = bcptr;
# Line 4715  code += 1 + LINK_SIZE + skipbytes; Line 4863  code += 1 + LINK_SIZE + skipbytes;
4863    
4864  /* Loop for each alternative branch */  /* Loop for each alternative branch */
4865    
4866    orig_bracount = max_bracount = cd->bracount;
4867  for (;;)  for (;;)
4868    {    {
4869      /* For a (?| group, reset the capturing bracket count so that each branch
4870      uses the same numbers. */
4871    
4872      if (reset_bracount) cd->bracount = orig_bracount;
4873    
4874    /* Handle a change of ims options at the start of the branch */    /* Handle a change of ims options at the start of the branch */
4875    
4876    if ((options & PCRE_IMS) != oldims)    if ((options & PCRE_IMS) != oldims)
# Line 4745  for (;;) Line 4899  for (;;)
4899      *ptrptr = ptr;      *ptrptr = ptr;
4900      return FALSE;      return FALSE;
4901      }      }
4902    
4903      /* Keep the highest bracket count in case (?| was used and some branch
4904      has fewer than the rest. */
4905    
4906      if (cd->bracount > max_bracount) max_bracount = cd->bracount;
4907    
4908    /* In the real compile phase, there is some post-processing to be done. */    /* In the real compile phase, there is some post-processing to be done. */
4909    
# Line 4847  for (;;) Line 5006  for (;;)
5006        *code++ = oldims;        *code++ = oldims;
5007        length += 2;        length += 2;
5008        }        }
5009    
5010        /* Retain the highest bracket number, in case resetting was used. */
5011    
5012        cd->bracount = max_bracount;
5013    
5014      /* Set values to pass back */      /* Set values to pass back */
5015    
# Line 5322  outside can help speed up starting point Line 5485  outside can help speed up starting point
5485  code = cworkspace;  code = cworkspace;
5486  *code = OP_BRA;  *code = OP_BRA;
5487  (void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,  (void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,
5488    &code, &ptr, &errorcode, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, &length);    &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,
5489      &length);
5490  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
5491    
5492  DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,  DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
# Line 5390  ptr = (const uschar *)pattern; Line 5554  ptr = (const uschar *)pattern;
5554  code = (uschar *)codestart;  code = (uschar *)codestart;
5555  *code = OP_BRA;  *code = OP_BRA;
5556  (void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,  (void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,
5557    &errorcode, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);    &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);
5558  re->top_bracket = cd->bracount;  re->top_bracket = cd->bracount;
5559  re->top_backref = cd->top_backref;  re->top_backref = cd->top_backref;
5560    

Legend:
Removed from v.172  
changed lines
  Added in v.178

  ViewVC Help
Powered by ViewVC 1.1.5