/[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 507 by ph10, Wed Mar 10 16:08:01 2010 UTC revision 514 by ph10, Mon May 3 12:54:22 2010 UTC
# Line 124  static const short int escapes[] = { Line 124  static const short int escapes[] = {
124       -ESC_H,                  0,       -ESC_H,                  0,
125       0,                       -ESC_K,       0,                       -ESC_K,
126       0,                       0,       0,                       0,
127       0,                       0,       -ESC_N,                  0,
128       -ESC_P,                  -ESC_Q,       -ESC_P,                  -ESC_Q,
129       -ESC_R,                  -ESC_S,       -ESC_R,                  -ESC_S,
130       0,                       0,       0,                       0,
# Line 171  static const short int escapes[] = { Line 171  static const short int escapes[] = {
171  /*  B8 */     0,     0,      0,       0,      0,   ']',    '=',    '-',  /*  B8 */     0,     0,      0,       0,      0,   ']',    '=',    '-',
172  /*  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,
173  /*  C8 */-ESC_H,     0,      0,       0,      0,     0,      0,      0,  /*  C8 */-ESC_H,     0,      0,       0,      0,     0,      0,      0,
174  /*  D0 */   '}',     0, -ESC_K,       0,      0,     0,      0, -ESC_P,  /*  D0 */   '}',     0, -ESC_K,       0,      0,-ESC_N,      0, -ESC_P,
175  /*  D8 */-ESC_Q,-ESC_R,      0,       0,      0,     0,      0,      0,  /*  D8 */-ESC_Q,-ESC_R,      0,       0,      0,     0,      0,      0,
176  /*  E0 */  '\\',     0, -ESC_S,       0,      0,-ESC_V, -ESC_W, -ESC_X,  /*  E0 */  '\\',     0, -ESC_S,       0,      0,-ESC_V, -ESC_W, -ESC_X,
177  /*  E8 */     0,-ESC_Z,      0,       0,      0,     0,      0,      0,  /*  E8 */     0,-ESC_Z,      0,       0,      0,     0,      0,      0,
# Line 188  string is built from string macros so th Line 188  string is built from string macros so th
188  platforms. */  platforms. */
189    
190  typedef struct verbitem {  typedef struct verbitem {
191    int   len;    int   len;                 /* Length of verb name */
192    int   op;    int   op;                  /* Op when no arg, or -1 if arg mandatory */
193      int   op_arg;              /* Op when arg present, or -1 if not allowed */
194  } verbitem;  } verbitem;
195    
196  static const char verbnames[] =  static const char verbnames[] =
197      "\0"                       /* Empty name is a shorthand for MARK */
198      STRING_MARK0
199    STRING_ACCEPT0    STRING_ACCEPT0
200    STRING_COMMIT0    STRING_COMMIT0
201    STRING_F0    STRING_F0
# Line 202  static const char verbnames[] = Line 205  static const char verbnames[] =
205    STRING_THEN;    STRING_THEN;
206    
207  static const verbitem verbs[] = {  static const verbitem verbs[] = {
208    { 6, OP_ACCEPT },    { 0, -1,        OP_MARK },
209    { 6, OP_COMMIT },    { 4, -1,        OP_MARK },
210    { 1, OP_FAIL },    { 6, OP_ACCEPT, -1 },
211    { 4, OP_FAIL },    { 6, OP_COMMIT, -1 },
212    { 5, OP_PRUNE },    { 1, OP_FAIL,   -1 },
213    { 4, OP_SKIP  },    { 4, OP_FAIL,   -1 },
214    { 4, OP_THEN  }    { 5, OP_PRUNE,  OP_PRUNE_ARG },
215      { 4, OP_SKIP,   OP_SKIP_ARG  },
216      { 4, OP_THEN,   OP_THEN_ARG  }
217  };  };
218    
219  static const int verbcount = sizeof(verbs)/sizeof(verbitem);  static const int verbcount = sizeof(verbs)/sizeof(verbitem);
# Line 319  static const char error_texts[] = Line 324  static const char error_texts[] =
324    /* 35 */    /* 35 */
325    "invalid condition (?(0)\0"    "invalid condition (?(0)\0"
326    "\\C not allowed in lookbehind assertion\0"    "\\C not allowed in lookbehind assertion\0"
327    "PCRE does not support \\L, \\l, \\N, \\U, or \\u\0"    "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0"
328    "number after (?C is > 255\0"    "number after (?C is > 255\0"
329    "closing ) for (?C expected\0"    "closing ) for (?C expected\0"
330    /* 40 */    /* 40 */
# Line 345  static const char error_texts[] = Line 350  static const char error_texts[] =
350    "inconsistent NEWLINE options\0"    "inconsistent NEWLINE options\0"
351    "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"    "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
352    "a numbered reference must not be zero\0"    "a numbered reference must not be zero\0"
353    "(*VERB) with an argument is not supported\0"    "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0"
354    /* 60 */    /* 60 */
355    "(*VERB) not recognized\0"    "(*VERB) not recognized\0"
356    "number is too big\0"    "number is too big\0"
# Line 353  static const char error_texts[] = Line 358  static const char error_texts[] =
358    "digit expected after (?+\0"    "digit expected after (?+\0"
359    "] is an invalid data character in JavaScript compatibility mode\0"    "] is an invalid data character in JavaScript compatibility mode\0"
360    /* 65 */    /* 65 */
361    "different names for subpatterns of the same number are not allowed\0";    "different names for subpatterns of the same number are not allowed\0"
362      "(*MARK) must have an argument\0"
363      ;
364    
365  /* Table to identify digits and hex digits. This is used when compiling  /* Table to identify digits and hex digits. This is used when compiling
366  patterns. Note that the tables in chartables are dependent on the locale, and  patterns. Note that the tables in chartables are dependent on the locale, and
# Line 586  else Line 593  else
593    
594      case CHAR_l:      case CHAR_l:
595      case CHAR_L:      case CHAR_L:
     case CHAR_N:  
596      case CHAR_u:      case CHAR_u:
597      case CHAR_U:      case CHAR_U:
598      *errorcodeptr = ERR37;      *errorcodeptr = ERR37;
# Line 823  else Line 829  else
829      break;      break;
830      }      }
831    }    }
832    
833    /* Perl supports \N{name} for character names, as well as plain \N for "not
834    newline". PCRE does not support \N{name}. */
835    
836    if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET)
837      *errorcodeptr = ERR37;
838    
839  *ptrptr = ptr;  *ptrptr = ptr;
840  return c;  return c;
# Line 1615  for (;;) Line 1627  for (;;)
1627    
1628    /* Otherwise, we can get the item's length from the table, except that for    /* Otherwise, we can get the item's length from the table, except that for
1629    repeated character types, we have to test for \p and \P, which have an extra    repeated character types, we have to test for \p and \P, which have an extra
1630    two bytes of parameters. */    two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
1631      must add in its length. */
1632    
1633    else    else
1634      {      {
# Line 1639  for (;;) Line 1652  for (;;)
1652        case OP_TYPEPOSUPTO:        case OP_TYPEPOSUPTO:
1653        if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;        if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
1654        break;        break;
1655    
1656          case OP_MARK:
1657          case OP_PRUNE_ARG:
1658          case OP_SKIP_ARG:
1659          case OP_THEN_ARG:
1660          code += code[1];
1661          break;
1662        }        }
1663    
1664      /* Add in the fixed length from the table */      /* Add in the fixed length from the table */
# Line 1710  for (;;) Line 1730  for (;;)
1730    
1731    /* Otherwise, we can get the item's length from the table, except that for    /* Otherwise, we can get the item's length from the table, except that for
1732    repeated character types, we have to test for \p and \P, which have an extra    repeated character types, we have to test for \p and \P, which have an extra
1733    two bytes of parameters. */    two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
1734      must add in its length. */
1735    
1736    else    else
1737      {      {
# Line 1734  for (;;) Line 1755  for (;;)
1755        case OP_TYPEEXACT:        case OP_TYPEEXACT:
1756        if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;        if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
1757        break;        break;
1758    
1759          case OP_MARK:
1760          case OP_PRUNE_ARG:
1761          case OP_SKIP_ARG:
1762          case OP_THEN_ARG:
1763          code += code[1];
1764          break;
1765        }        }
1766    
1767      /* Add in the fixed length from the table */      /* Add in the fixed length from the table */
# Line 2003  for (code = first_significant_code(code Line 2031  for (code = first_significant_code(code
2031      break;      break;
2032  #endif  #endif
2033    
2034        /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument
2035        string. */
2036    
2037        case OP_MARK:
2038        case OP_PRUNE_ARG:
2039        case OP_SKIP_ARG:
2040        case OP_THEN_ARG:
2041        code += code[1];
2042        break;
2043    
2044      /* None of the remaining opcodes are required to match a character. */      /* None of the remaining opcodes are required to match a character. */
2045    
2046      default:      default:
# Line 3171  for (;; ptr++) Line 3209  for (;; ptr++)
3209    
3210        /* Backslash may introduce a single character, or it may introduce one        /* Backslash may introduce a single character, or it may introduce one
3211        of the specials, which just set a flag. The sequence \b is a special        of the specials, which just set a flag. The sequence \b is a special
3212        case. Inside a class (and only there) it is treated as backspace.        case. Inside a class (and only there) it is treated as backspace. We
3213        Elsewhere it marks a word boundary. Other escapes have preset maps ready        assume that other escapes have more than one character in them, so set
3214        to 'or' into the one we are building. We assume they have more than one        class_charcount bigger than one. Unrecognized escapes fall through and
3215        character in them, so set class_charcount bigger than one. */        are either treated as literal characters (by default), or are faulted if
3216          PCRE_EXTRA is set. */
3217    
3218        if (c == CHAR_BACKSLASH)        if (c == CHAR_BACKSLASH)
3219          {          {
3220          c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);          c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
3221          if (*errorcodeptr != 0) goto FAILED;          if (*errorcodeptr != 0) goto FAILED;
3222    
3223          if (-c == ESC_b) c = CHAR_BS;       /* \b is backspace in a class */          if (-c == ESC_b) c = CHAR_BS;    /* \b is backspace in a class */
         else if (-c == ESC_X) c = CHAR_X;   /* \X is literal X in a class */  
         else if (-c == ESC_R) c = CHAR_R;   /* \R is literal R in a class */  
3224          else if (-c == ESC_Q)            /* Handle start of quoted string */          else if (-c == ESC_Q)            /* Handle start of quoted string */
3225            {            {
3226            if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)            if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
# Line 3468  for (;; ptr++) Line 3505  for (;; ptr++)
3505            d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);            d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
3506            if (*errorcodeptr != 0) goto FAILED;            if (*errorcodeptr != 0) goto FAILED;
3507    
3508            /* \b is backspace; \X is literal X; \R is literal R; any other            /* \b is backspace; any other special means the '-' was literal */
           special means the '-' was literal */  
3509    
3510            if (d < 0)            if (d < 0)
3511              {              {
3512              if (d == -ESC_b) d = CHAR_BS;              if (d == -ESC_b) d = CHAR_BS; else
             else if (d == -ESC_X) d = CHAR_X;  
             else if (d == -ESC_R) d = CHAR_R; else  
3513                {                {
3514                ptr = oldptr;                ptr = oldptr;
3515                goto LONE_SINGLE_CHARACTER;  /* A few lines below */                goto LONE_SINGLE_CHARACTER;  /* A few lines below */
# Line 4514  we set the flag only if there is a liter Line 4548  we set the flag only if there is a liter
4548    
4549      /* First deal with various "verbs" that can be introduced by '*'. */      /* First deal with various "verbs" that can be introduced by '*'. */
4550    
4551      if (*(++ptr) == CHAR_ASTERISK && (cd->ctypes[ptr[1]] & ctype_letter) != 0)      if (*(++ptr) == CHAR_ASTERISK &&
4552             ((cd->ctypes[ptr[1]] & ctype_letter) != 0 || ptr[1] == ':'))
4553        {        {
4554        int i, namelen;        int i, namelen;
4555          int arglen = 0;
4556        const char *vn = verbnames;        const char *vn = verbnames;
4557        const uschar *name = ++ptr;        const uschar *name = ptr + 1;
4558          const uschar *arg = NULL;
4559        previous = NULL;        previous = NULL;
4560        while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {};        while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {};
4561          namelen = ptr - name;
4562    
4563        if (*ptr == CHAR_COLON)        if (*ptr == CHAR_COLON)
4564          {          {
4565          *errorcodeptr = ERR59;   /* Not supported */          arg = ++ptr;
4566          goto FAILED;          while ((cd->ctypes[*ptr] & (ctype_letter|ctype_digit)) != 0
4567              || *ptr == '_') ptr++;
4568            arglen = ptr - arg;
4569          }          }
4570    
4571        if (*ptr != CHAR_RIGHT_PARENTHESIS)        if (*ptr != CHAR_RIGHT_PARENTHESIS)
4572          {          {
4573          *errorcodeptr = ERR60;          *errorcodeptr = ERR60;
4574          goto FAILED;          goto FAILED;
4575          }          }
4576        namelen = ptr - name;  
4577          /* Scan the table of verb names */
4578    
4579        for (i = 0; i < verbcount; i++)        for (i = 0; i < verbcount; i++)
4580          {          {
4581          if (namelen == verbs[i].len &&          if (namelen == verbs[i].len &&
# Line 4549  we set the flag only if there is a liter Line 4593  we set the flag only if there is a liter
4593                PUT2INC(code, 0, oc->number);                PUT2INC(code, 0, oc->number);
4594                }                }
4595              }              }
4596            *code++ = verbs[i].op;  
4597            break;            /* Handle the cases with/without an argument */
4598    
4599              if (arglen == 0)
4600                {
4601                if (verbs[i].op < 0)   /* Argument is mandatory */
4602                  {
4603                  *errorcodeptr = ERR66;
4604                  goto FAILED;
4605                  }
4606                *code++ = verbs[i].op;
4607                }
4608    
4609              else
4610                {
4611                if (verbs[i].op_arg < 0)   /* Argument is forbidden */
4612                  {
4613                  *errorcodeptr = ERR59;
4614                  goto FAILED;
4615                  }
4616                *code++ = verbs[i].op_arg;
4617                *code++ = arglen;
4618                memcpy(code, arg, arglen);
4619                code += arglen;
4620                *code++ = 0;
4621                }
4622    
4623              break;  /* Found verb, exit loop */
4624            }            }
4625    
4626          vn += verbs[i].len + 1;          vn += verbs[i].len + 1;
4627          }          }
4628        if (i < verbcount) continue;  
4629        *errorcodeptr = ERR60;        if (i < verbcount) continue;    /* Successfully handled a verb */
4630          *errorcodeptr = ERR60;          /* Verb not recognized */
4631        goto FAILED;        goto FAILED;
4632        }        }
4633    
# Line 5338  we set the flag only if there is a liter Line 5410  we set the flag only if there is a liter
5410          }     /* End of switch for character following (? */          }     /* End of switch for character following (? */
5411        }       /* End of (? handling */        }       /* End of (? handling */
5412    
5413      /* Opening parenthesis not followed by '?'. If PCRE_NO_AUTO_CAPTURE is set,      /* Opening parenthesis not followed by '*' or '?'. If PCRE_NO_AUTO_CAPTURE
5414      all unadorned brackets become non-capturing and behave like (?:...)      is set, all unadorned brackets become non-capturing and behave like (?:...)
5415      brackets. */      brackets. */
5416    
5417      else if ((options & PCRE_NO_AUTO_CAPTURE) != 0)      else if ((options & PCRE_NO_AUTO_CAPTURE) != 0)

Legend:
Removed from v.507  
changed lines
  Added in v.514

  ViewVC Help
Powered by ViewVC 1.1.5