/[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 333 by ph10, Thu Apr 10 19:55:57 2008 UTC revision 340 by ph10, Fri Apr 18 20:00:21 2008 UTC
# Line 302  static const char error_texts[] = Line 302  static const char error_texts[] =
302    "(*VERB) not recognized\0"    "(*VERB) not recognized\0"
303    "number is too big\0"    "number is too big\0"
304    "subpattern name expected\0"    "subpattern name expected\0"
305    "digit expected after (?+";    "digit expected after (?+\0"
306      "] is an invalid data character in JavaScript compatibility mode";
307    
308    
309  /* Table to identify digits and hex digits. This is used when compiling  /* Table to identify digits and hex digits. This is used when compiling
# Line 1007  for (; *ptr != 0; ptr++) Line 1008  for (; *ptr != 0; ptr++)
1008      continue;      continue;
1009      }      }
1010    
1011    /* Skip over character classes */    /* Skip over character classes; this logic must be similar to the way they
1012      are handled for real. If the first character is '^', skip it. Also, if the
1013      first few characters (either before or after ^) are \Q\E or \E we skip them
1014      too. This makes for compatibility with Perl. */
1015    
1016    if (*ptr == '[')    if (*ptr == '[')
1017      {      {
1018        BOOL negate_class = FALSE;
1019        for (;;)
1020          {
1021          int c = *(++ptr);
1022          if (c == '\\')
1023            {
1024            if (ptr[1] == 'E') ptr++;
1025              else if (strncmp((const char *)ptr+1, "Q\\E", 3) == 0) ptr += 3;
1026                else break;
1027            }
1028          else if (!negate_class && c == '^')
1029            negate_class = TRUE;
1030          else break;
1031          }
1032    
1033        /* If the next character is ']', it is a data character that must be
1034        skipped. */
1035    
1036        if (ptr[1] == ']') ptr++;
1037    
1038      while (*(++ptr) != ']')      while (*(++ptr) != ']')
1039        {        {
1040        if (*ptr == 0) return -1;        if (*ptr == 0) return -1;
# Line 1567  for (code = first_significant_code(code Line 1591  for (code = first_significant_code(code
1591    
1592    /* Groups with zero repeats can of course be empty; skip them. */    /* Groups with zero repeats can of course be empty; skip them. */
1593    
1594    if (c == OP_BRAZERO || c == OP_BRAMINZERO)    if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO)
1595      {      {
1596      code += _pcre_OP_lengths[c];      code += _pcre_OP_lengths[c];
1597      do code += GET(code, 1); while (*code == OP_ALT);      do code += GET(code, 1); while (*code == OP_ALT);
# Line 1847  return -1; Line 1871  return -1;
1871  that is referenced. This means that groups can be replicated for fixed  that is referenced. This means that groups can be replicated for fixed
1872  repetition simply by copying (because the recursion is allowed to refer to  repetition simply by copying (because the recursion is allowed to refer to
1873  earlier groups that are outside the current group). However, when a group is  earlier groups that are outside the current group). However, when a group is
1874  optional (i.e. the minimum quantifier is zero), OP_BRAZERO is inserted before  optional (i.e. the minimum quantifier is zero), OP_BRAZERO or OP_SKIPZERO is
1875  it, after it has been compiled. This means that any OP_RECURSE items within it  inserted before it, after it has been compiled. This means that any OP_RECURSE
1876  that refer to the group itself or any contained groups have to have their  items within it that refer to the group itself or any contained groups have to
1877  offsets adjusted. That one of the jobs of this function. Before it is called,  have their offsets adjusted. That one of the jobs of this function. Before it
1878  the partially compiled regex must be temporarily terminated with OP_END.  is called, the partially compiled regex must be temporarily terminated with
1879    OP_END.
1880    
1881  This function has been extended with the possibility of forward references for  This function has been extended with the possibility of forward references for
1882  recursions and subroutine calls. It must also check the list of such references  recursions and subroutine calls. It must also check the list of such references
# Line 1882  while ((ptr = (uschar *)find_recurse(ptr Line 1907  while ((ptr = (uschar *)find_recurse(ptr
1907    
1908    /* See if this recursion is on the forward reference list. If so, adjust the    /* See if this recursion is on the forward reference list. If so, adjust the
1909    reference. */    reference. */
1910    
1911    for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)    for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
1912      {      {
1913      offset = GET(hc, 0);      offset = GET(hc, 0);
# Line 2458  for (;; ptr++) Line 2483  for (;; ptr++)
2483    /* Get next byte in the pattern */    /* Get next byte in the pattern */
2484    
2485    c = *ptr;    c = *ptr;
2486    
2487    /* If we are in the pre-compile phase, accumulate the length used for the    /* If we are in the pre-compile phase, accumulate the length used for the
2488    previous cycle of this loop. */    previous cycle of this loop. */
2489    
# Line 2653  for (;; ptr++) Line 2678  for (;; ptr++)
2678      opcode is compiled. It may optionally have a bit map for characters < 256,      opcode is compiled. It may optionally have a bit map for characters < 256,
2679      but those above are are explicitly listed afterwards. A flag byte tells      but those above are are explicitly listed afterwards. A flag byte tells
2680      whether the bitmap is present, and whether this is a negated class or not.      whether the bitmap is present, and whether this is a negated class or not.
2681      */  
2682        In JavaScript compatibility mode, an isolated ']' causes an error. In
2683        default (Perl) mode, it is treated as a data character. */
2684    
2685        case ']':
2686        if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
2687          {
2688          *errorcodeptr = ERR64;
2689          goto FAILED;
2690          }
2691        goto NORMAL_CHAR;
2692    
2693      case '[':      case '[':
2694      previous = code;      previous = code;
# Line 3842  we set the flag only if there is a liter Line 3877  we set the flag only if there is a liter
3877    
3878        if (repeat_min == 0)        if (repeat_min == 0)
3879          {          {
3880          /* If the maximum is also zero, we just omit the group from the output          /* If the maximum is also zero, we used to just omit the group from the
3881          altogether. */          output altogether, like this:
3882    
3883          if (repeat_max == 0)          ** if (repeat_max == 0)
3884            {          **   {
3885            code = previous;          **   code = previous;
3886            goto END_REPEAT;          **   goto END_REPEAT;
3887            }          **   }
3888    
3889          /* If the maximum is 1 or unlimited, we just have to stick in the          However, that fails when a group is referenced as a subroutine from
3890          BRAZERO and do no more at this point. However, we do need to adjust          elsewhere in the pattern, so now we stick in OP_SKIPZERO in front of it
3891          any OP_RECURSE calls inside the group that refer to the group itself or          so that it is skipped on execution. As we don't have a list of which
3892          any internal or forward referenced group, because the offset is from          groups are referenced, we cannot do this selectively.
3893          the start of the whole regex. Temporarily terminate the pattern while  
3894          doing this. */          If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
3895            and do no more at this point. However, we do need to adjust any
3896            OP_RECURSE calls inside the group that refer to the group itself or any
3897            internal or forward referenced group, because the offset is from the
3898            start of the whole regex. Temporarily terminate the pattern while doing
3899            this. */
3900    
3901          if (repeat_max <= 1)          if (repeat_max <= 1)    /* Covers 0, 1, and unlimited */
3902            {            {
3903            *code = OP_END;            *code = OP_END;
3904            adjust_recurse(previous, 1, utf8, cd, save_hwm);            adjust_recurse(previous, 1, utf8, cd, save_hwm);
3905            memmove(previous+1, previous, len);            memmove(previous+1, previous, len);
3906            code++;            code++;
3907              if (repeat_max == 0)
3908                {
3909                *previous++ = OP_SKIPZERO;
3910                goto END_REPEAT;
3911                }
3912            *previous++ = OP_BRAZERO + repeat_type;            *previous++ = OP_BRAZERO + repeat_type;
3913            }            }
3914    
# Line 4138  we set the flag only if there is a liter Line 4183  we set the flag only if there is a liter
4183      bravalue = OP_CBRA;      bravalue = OP_CBRA;
4184      save_hwm = cd->hwm;      save_hwm = cd->hwm;
4185      reset_bracount = FALSE;      reset_bracount = FALSE;
4186    
4187      /* First deal with various "verbs" that can be introduced by '*'. */      /* First deal with various "verbs" that can be introduced by '*'. */
4188    
4189      if (*(++ptr) == '*' && (cd->ctypes[ptr[1]] & ctype_letter) != 0)      if (*(++ptr) == '*' && (cd->ctypes[ptr[1]] & ctype_letter) != 0)
# Line 5127  we set the flag only if there is a liter Line 5172  we set the flag only if there is a liter
5172        -ESC_g is returned only for these cases. So we don't need to check for <        -ESC_g is returned only for these cases. So we don't need to check for <
5173        or ' if the value is -ESC_g. For the Perl syntax \g{n} the value is        or ' if the value is -ESC_g. For the Perl syntax \g{n} the value is
5174        -ESC_REF+n, and for the Perl syntax \g{name} the result is -ESC_k (as        -ESC_REF+n, and for the Perl syntax \g{name} the result is -ESC_k (as
5175        that is a synonym). */        that is a synonym for a named back reference). */
5176    
5177        if (-c == ESC_g)        if (-c == ESC_g)
5178          {          {
5179          const uschar *p;          const uschar *p;
5180            save_hwm = cd->hwm;   /* Normally this is set when '(' is read */
5181          terminator = (*(++ptr) == '<')? '>' : '\'';          terminator = (*(++ptr) == '<')? '>' : '\'';
5182    
5183          /* These two statements stop the compiler for warning about possibly          /* These two statements stop the compiler for warning about possibly
# Line 6197  while (errorcode == 0 && cd->hwm > cwork Line 6243  while (errorcode == 0 && cd->hwm > cwork
6243    if (groupptr == NULL) errorcode = ERR53;    if (groupptr == NULL) errorcode = ERR53;
6244      else PUT(((uschar *)codestart), offset, groupptr - codestart);      else PUT(((uschar *)codestart), offset, groupptr - codestart);
6245    }    }
6246    
6247  /* Give an error if there's back reference to a non-existent capturing  /* Give an error if there's back reference to a non-existent capturing
6248  subpattern. */  subpattern. */
6249    

Legend:
Removed from v.333  
changed lines
  Added in v.340

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12