/[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 210 by ph10, Wed Aug 8 14:24:50 2007 UTC revision 226 by ph10, Tue Aug 21 11:46:08 2007 UTC
# Line 146  typedef struct verbitem { Line 146  typedef struct verbitem {
146    const char *name;    const char *name;
147    int   len;    int   len;
148    int   op;    int   op;
149  } verbitem;  } verbitem;
150    
151  static verbitem verbs[] = {  static verbitem verbs[] = {
152    { "ACCEPT", 6, OP_ACCEPT },    { "ACCEPT", 6, OP_ACCEPT },
153    { "COMMIT", 6, OP_COMMIT },    { "COMMIT", 6, OP_COMMIT },
154    { "F",      1, OP_FAIL },    { "F",      1, OP_FAIL },
155    { "FAIL",   4, OP_FAIL },    { "FAIL",   4, OP_FAIL },
156    { "PRUNE",  5, OP_PRUNE },    { "PRUNE",  5, OP_PRUNE },
157    { "SKIP",   4, OP_SKIP  },    { "SKIP",   4, OP_SKIP  },
158    { "THEN",   4, OP_THEN  }    { "THEN",   4, OP_THEN  }
# Line 281  static const char *error_texts[] = { Line 281  static const char *error_texts[] = {
281    "\\g is not followed by a braced name or an optionally braced non-zero number",    "\\g is not followed by a braced name or an optionally braced non-zero number",
282    "(?+ or (?- or (?(+ or (?(- must be followed by a non-zero number",    "(?+ or (?- or (?(+ or (?(- must be followed by a non-zero number",
283    "(*VERB) with an argument is not supported",    "(*VERB) with an argument is not supported",
284    /* 60 */    /* 60 */
285    "(*VERB) not recognized"    "(*VERB) not recognized",
286      "number is too big"
287  };  };
288    
289    
# Line 439  Arguments: Line 440  Arguments:
440    
441  Returns:         zero or positive => a data character  Returns:         zero or positive => a data character
442                   negative => a special escape sequence                   negative => a special escape sequence
443                   on error, errorptr is set                   on error, errorcodeptr is set
444  */  */
445    
446  static int  static int
# Line 524  else Line 525  else
525      while ((digitab[ptr[1]] & ctype_digit) != 0)      while ((digitab[ptr[1]] & ctype_digit) != 0)
526        c = c * 10 + *(++ptr) - '0';        c = c * 10 + *(++ptr) - '0';
527    
528        if (c < 0)
529          {
530          *errorcodeptr = ERR61;
531          break;
532          }
533    
534      if (c == 0 || (braced && *(++ptr) != '}'))      if (c == 0 || (braced && *(++ptr) != '}'))
535        {        {
536        *errorcodeptr = ERR57;        *errorcodeptr = ERR57;
537        return 0;        break;
538        }        }
539    
540      if (negated)      if (negated)
# Line 535  else Line 542  else
542        if (c > bracount)        if (c > bracount)
543          {          {
544          *errorcodeptr = ERR15;          *errorcodeptr = ERR15;
545          return 0;          break;
546          }          }
547        c = bracount - (c - 1);        c = bracount - (c - 1);
548        }        }
# Line 564  else Line 571  else
571        c -= '0';        c -= '0';
572        while ((digitab[ptr[1]] & ctype_digit) != 0)        while ((digitab[ptr[1]] & ctype_digit) != 0)
573          c = c * 10 + *(++ptr) - '0';          c = c * 10 + *(++ptr) - '0';
574          if (c < 0)
575            {
576            *errorcodeptr = ERR61;
577            break;
578            }
579        if (c < 10 || c <= bracount)        if (c < 10 || c <= bracount)
580          {          {
581          c = -(ESC_REF + c);          c = -(ESC_REF + c);
# Line 659  else Line 671  else
671      if (c == 0)      if (c == 0)
672        {        {
673        *errorcodeptr = ERR2;        *errorcodeptr = ERR2;
674        return 0;        break;
675        }        }
676    
677  #ifndef EBCDIC  /* ASCII coding */  #ifndef EBCDIC  /* ASCII coding */
# Line 938  for (; *ptr != 0; ptr++) Line 950  for (; *ptr != 0; ptr++)
950      {      {
951      while (*(++ptr) != ']')      while (*(++ptr) != ']')
952        {        {
953          if (*ptr == 0) return -1;
954        if (*ptr == '\\')        if (*ptr == '\\')
955          {          {
956          if (*(++ptr) == 0) return -1;          if (*(++ptr) == 0) return -1;
# Line 1093  for (;;) Line 1106  for (;;)
1106    {    {
1107    int d;    int d;
1108    register int op = *cc;    register int op = *cc;
   
1109    switch (op)    switch (op)
1110      {      {
1111      case OP_CBRA:      case OP_CBRA:
# Line 1182  for (;;) Line 1194  for (;;)
1194    
1195      case OP_TYPEEXACT:      case OP_TYPEEXACT:
1196      branchlength += GET2(cc,1);      branchlength += GET2(cc,1);
1197        if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2;
1198      cc += 4;      cc += 4;
1199      break;      break;
1200    
# Line 1290  for (;;) Line 1303  for (;;)
1303      code += _pcre_OP_lengths[c];      code += _pcre_OP_lengths[c];
1304      }      }
1305    
1306    /* In UTF-8 mode, opcodes that are followed by a character may be followed by    /* Otherwise, we can get the item's length from the table, except that for
1307    a multi-byte character. The length in the table is a minimum, so we have to    repeated character types, we have to test for \p and \P, which have an extra
1308    arrange to skip the extra bytes. */    two bytes of parameters. */
1309    
1310    else    else
1311      {      {
1312        switch(c)
1313          {
1314          case OP_TYPESTAR:
1315          case OP_TYPEMINSTAR:
1316          case OP_TYPEPLUS:
1317          case OP_TYPEMINPLUS:
1318          case OP_TYPEQUERY:
1319          case OP_TYPEMINQUERY:
1320          case OP_TYPEPOSSTAR:
1321          case OP_TYPEPOSPLUS:
1322          case OP_TYPEPOSQUERY:
1323          if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
1324          break;
1325    
1326          case OP_TYPEUPTO:
1327          case OP_TYPEMINUPTO:
1328          case OP_TYPEEXACT:
1329          case OP_TYPEPOSUPTO:
1330          if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
1331          break;
1332          }
1333    
1334        /* Add in the fixed length from the table */
1335    
1336      code += _pcre_OP_lengths[c];      code += _pcre_OP_lengths[c];
1337    
1338      /* In UTF-8 mode, opcodes that are followed by a character may be followed by
1339      a multi-byte character. The length in the table is a minimum, so we have to
1340      arrange to skip the extra bytes. */
1341    
1342  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1343      if (utf8) switch(c)      if (utf8) switch(c)
1344        {        {
# Line 1354  for (;;) Line 1396  for (;;)
1396    
1397    if (c == OP_XCLASS) code += GET(code, 1);    if (c == OP_XCLASS) code += GET(code, 1);
1398    
1399    /* Otherwise, we get the item's length from the table. In UTF-8 mode, opcodes    /* Otherwise, we can get the item's length from the table, except that for
1400    that are followed by a character may be followed by a multi-byte character.    repeated character types, we have to test for \p and \P, which have an extra
1401    The length in the table is a minimum, so we have to arrange to skip the extra    two bytes of parameters. */
   bytes. */  
1402    
1403    else    else
1404      {      {
1405        switch(c)
1406          {
1407          case OP_TYPESTAR:
1408          case OP_TYPEMINSTAR:
1409          case OP_TYPEPLUS:
1410          case OP_TYPEMINPLUS:
1411          case OP_TYPEQUERY:
1412          case OP_TYPEMINQUERY:
1413          case OP_TYPEPOSSTAR:
1414          case OP_TYPEPOSPLUS:
1415          case OP_TYPEPOSQUERY:
1416          if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
1417          break;
1418    
1419          case OP_TYPEPOSUPTO:
1420          case OP_TYPEUPTO:
1421          case OP_TYPEMINUPTO:
1422          case OP_TYPEEXACT:
1423          if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
1424          break;
1425          }
1426    
1427        /* Add in the fixed length from the table */
1428    
1429      code += _pcre_OP_lengths[c];      code += _pcre_OP_lengths[c];
1430    
1431        /* In UTF-8 mode, opcodes that are followed by a character may be followed
1432        by a multi-byte character. The length in the table is a minimum, so we have
1433        to arrange to skip the extra bytes. */
1434    
1435  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1436      if (utf8) switch(c)      if (utf8) switch(c)
1437        {        {
# Line 1457  for (code = first_significant_code(code Line 1527  for (code = first_significant_code(code
1527    
1528    switch (c)    switch (c)
1529      {      {
1530      /* Check for quantifiers after a class */      /* Check for quantifiers after a class. XCLASS is used for classes that
1531        cannot be represented just by a bit map. This includes negated single
1532        high-valued characters. The length in _pcre_OP_lengths[] is zero; the
1533        actual length is stored in the compiled code, so we must update "code"
1534        here. */
1535    
1536  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1537      case OP_XCLASS:      case OP_XCLASS:
1538      ccode = code + GET(code, 1);      ccode = code += GET(code, 1);
1539      goto CHECK_CLASS_REPEAT;      goto CHECK_CLASS_REPEAT;
1540  #endif  #endif
1541    
# Line 1522  for (code = first_significant_code(code Line 1596  for (code = first_significant_code(code
1596      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
1597      case OP_TYPEEXACT:      case OP_TYPEEXACT:
1598      return FALSE;      return FALSE;
1599    
1600        /* These are going to continue, as they may be empty, but we have to
1601        fudge the length for the \p and \P cases. */
1602    
1603        case OP_TYPESTAR:
1604        case OP_TYPEMINSTAR:
1605        case OP_TYPEPOSSTAR:
1606        case OP_TYPEQUERY:
1607        case OP_TYPEMINQUERY:
1608        case OP_TYPEPOSQUERY:
1609        if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
1610        break;
1611    
1612        /* Same for these */
1613    
1614        case OP_TYPEUPTO:
1615        case OP_TYPEMINUPTO:
1616        case OP_TYPEPOSUPTO:
1617        if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
1618        break;
1619    
1620      /* End of branch */      /* End of branch */
1621    
# Line 1685  adjust_recurse(uschar *group, int adjust Line 1779  adjust_recurse(uschar *group, int adjust
1779    uschar *save_hwm)    uschar *save_hwm)
1780  {  {
1781  uschar *ptr = group;  uschar *ptr = group;
1782    
1783  while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL)  while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL)
1784    {    {
1785    int offset;    int offset;
# Line 2654  for (;; ptr++) Line 2749  for (;; ptr++)
2749            else inescq = TRUE;            else inescq = TRUE;
2750            continue;            continue;
2751            }            }
2752            else if (-c == ESC_E) continue;  /* Ignore orphan \E */
2753    
2754          if (c < 0)          if (c < 0)
2755            {            {
# Line 3099  for (;; ptr++) Line 3195  for (;; ptr++)
3195        *errorcodeptr = ERR6;        *errorcodeptr = ERR6;
3196        goto FAILED;        goto FAILED;
3197        }        }
3198    
3199        /* Remember whether \r or \n are in this class */
3200    
3201        if (negate_class)
3202          {
3203          if ((classbits[1] & 0x24) != 0x24) cd->external_options |= PCRE_HASCRORLF;
3204          }
3205        else
3206          {
3207          if ((classbits[1] & 0x24) != 0) cd->external_options |= PCRE_HASCRORLF;
3208          }
3209    
3210      /* If class_charcount is 1, we saw precisely one character whose value is      /* If class_charcount is 1, we saw precisely one character whose value is
3211      less than 256. In non-UTF-8 mode we can always optimize. In UTF-8 mode, we      less than 256. As long as there were no characters >= 128 and there was no
3212      can optimize the negative case only if there were no characters >= 128      use of \p or \P, in other words, no use of any XCLASS features, we can
3213      because OP_NOT and the related opcodes like OP_NOTSTAR operate on      optimize.
3214      single-bytes only. This is an historical hangover. Maybe one day we can  
3215      tidy these opcodes to handle multi-byte characters.      In UTF-8 mode, we can optimize the negative case only if there were no
3216        characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR
3217        operate on single-bytes only. This is an historical hangover. Maybe one day
3218        we can tidy these opcodes to handle multi-byte characters.
3219    
3220      The optimization throws away the bit map. We turn the item into a      The optimization throws away the bit map. We turn the item into a
3221      1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note      1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note
# Line 3115  for (;; ptr++) Line 3225  for (;; ptr++)
3225      reqbyte, save the previous value for reinstating. */      reqbyte, save the previous value for reinstating. */
3226    
3227  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
3228      if (class_charcount == 1 &&      if (class_charcount == 1 && !class_utf8 &&
3229            (!utf8 ||        (!utf8 || !negate_class || class_lastchar < 128))
           (!class_utf8 && (!negate_class || class_lastchar < 128))))  
   
3230  #else  #else
3231      if (class_charcount == 1)      if (class_charcount == 1)
3232  #endif  #endif
# Line 3892  for (;; ptr++) Line 4000  for (;; ptr++)
4000      bravalue = OP_CBRA;      bravalue = OP_CBRA;
4001      save_hwm = cd->hwm;      save_hwm = cd->hwm;
4002      reset_bracount = FALSE;      reset_bracount = FALSE;
4003    
4004      /* First deal with various "verbs" that can be introduced by '*'. */      /* First deal with various "verbs" that can be introduced by '*'. */
4005    
4006      if (*(++ptr) == '*' && (cd->ctypes[ptr[1]] & ctype_letter) != 0)      if (*(++ptr) == '*' && (cd->ctypes[ptr[1]] & ctype_letter) != 0)
4007        {        {
4008        int i, namelen;        int i, namelen;
4009        const uschar *name = ++ptr;        const uschar *name = ++ptr;
4010        previous = NULL;        previous = NULL;
4011        while ((cd->ctypes[*++ptr] & ctype_letter) != 0);        while ((cd->ctypes[*++ptr] & ctype_letter) != 0);
4012        if (*ptr == ':')        if (*ptr == ':')
4013          {          {
4014          *errorcodeptr = ERR59;   /* Not supported */          *errorcodeptr = ERR59;   /* Not supported */
4015          goto FAILED;          goto FAILED;
4016          }          }
4017        if (*ptr != ')')        if (*ptr != ')')
4018          {          {
4019          *errorcodeptr = ERR60;          *errorcodeptr = ERR60;
4020          goto FAILED;          goto FAILED;
4021          }          }
4022        namelen = ptr - name;        namelen = ptr - name;
4023        for (i = 0; i < verbcount; i++)        for (i = 0; i < verbcount; i++)
4024          {          {
4025          if (namelen == verbs[i].len &&          if (namelen == verbs[i].len &&
4026              strncmp((char *)name, verbs[i].name, namelen) == 0)              strncmp((char *)name, verbs[i].name, namelen) == 0)
4027            {            {
4028            *code = verbs[i].op;            *code = verbs[i].op;
4029            if (*code++ == OP_ACCEPT) cd->had_accept = TRUE;            if (*code++ == OP_ACCEPT) cd->had_accept = TRUE;
4030            break;            break;
4031            }            }
4032          }          }
4033        if (i < verbcount) continue;        if (i < verbcount) continue;
4034        *errorcodeptr = ERR60;        *errorcodeptr = ERR60;
4035        goto FAILED;        goto FAILED;
4036        }        }
4037    
4038      /* Deal with the extended parentheses; all are introduced by '?', and the      /* Deal with the extended parentheses; all are introduced by '?', and the
4039      appearance of any of them means that this is not a capturing group. */      appearance of any of them means that this is not a capturing group. */
4040    
# Line 4176  for (;; ptr++) Line 4284  for (;; ptr++)
4284          if (*ptr == ')')          /* Optimize (?!) */          if (*ptr == ')')          /* Optimize (?!) */
4285            {            {
4286            *code++ = OP_FAIL;            *code++ = OP_FAIL;
4287            previous = NULL;            previous = NULL;
4288            continue;            continue;
4289            }            }
4290          bravalue = OP_ASSERT_NOT;          bravalue = OP_ASSERT_NOT;
4291          break;          break;
4292    
# Line 4728  for (;; ptr++) Line 4836  for (;; ptr++)
4836        goto FAILED;        goto FAILED;
4837        }        }
4838    
4839      /* In the pre-compile phase, update the length by the length of the nested      /* In the pre-compile phase, update the length by the length of the group,
4840      group, less the brackets at either end. Then reduce the compiled code to      less the brackets at either end. Then reduce the compiled code to just a
4841      just the brackets so that it doesn't use much memory if it is duplicated by      set of non-capturing brackets so that it doesn't use much memory if it is
4842      a quantifier. */      duplicated by a quantifier.*/
4843    
4844      if (lengthptr != NULL)      if (lengthptr != NULL)
4845        {        {
# Line 4741  for (;; ptr++) Line 4849  for (;; ptr++)
4849          goto FAILED;          goto FAILED;
4850          }          }
4851        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
4852        code++;        *code++ = OP_BRA;
4853        PUTINC(code, 0, 1 + LINK_SIZE);        PUTINC(code, 0, 1 + LINK_SIZE);
4854        *code++ = OP_KET;        *code++ = OP_KET;
4855        PUTINC(code, 0, 1 + LINK_SIZE);        PUTINC(code, 0, 1 + LINK_SIZE);
4856          break;    /* No need to waste time with special character handling */
4857        }        }
4858    
4859      /* Otherwise update the main code pointer to the end of the group. */      /* Otherwise update the main code pointer to the end of the group. */
4860    
4861      else code = tempcode;      code = tempcode;
4862    
4863      /* For a DEFINE group, required and first character settings are not      /* For a DEFINE group, required and first character settings are not
4864      relevant. */      relevant. */
# Line 4952  for (;; ptr++) Line 5061  for (;; ptr++)
5061      previous = code;      previous = code;
5062      *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR;      *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR;
5063      for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];      for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];
5064    
5065        /* Remember if \r or \n were seen */
5066    
5067        if (mcbuffer[0] == '\r' || mcbuffer[0] == '\n')
5068          cd->external_options |= PCRE_HASCRORLF;
5069    
5070      /* Set the first and required bytes appropriately. If no previous first      /* Set the first and required bytes appropriately. If no previous first
5071      byte, set it from this character, but revert to none on a zero repeat.      byte, set it from this character, but revert to none on a zero repeat.
# Line 5884  case when building a production library. Line 5998  case when building a production library.
5998    
5999  printf("Length = %d top_bracket = %d top_backref = %d\n",  printf("Length = %d top_bracket = %d top_backref = %d\n",
6000    length, re->top_bracket, re->top_backref);    length, re->top_bracket, re->top_backref);
6001    
6002  if (re->options != 0)  printf("Options=%08x\n", re->options);
   {  
   printf("%s%s%s%s%s%s%s%s%s\n",  
     ((re->options & PCRE_NOPARTIAL) != 0)? "nopartial " : "",  
     ((re->options & PCRE_ANCHORED) != 0)? "anchored " : "",  
     ((re->options & PCRE_CASELESS) != 0)? "caseless " : "",  
     ((re->options & PCRE_EXTENDED) != 0)? "extended " : "",  
     ((re->options & PCRE_MULTILINE) != 0)? "multiline " : "",  
     ((re->options & PCRE_DOTALL) != 0)? "dotall " : "",  
     ((re->options & PCRE_DOLLAR_ENDONLY) != 0)? "endonly " : "",  
     ((re->options & PCRE_EXTRA) != 0)? "extra " : "",  
     ((re->options & PCRE_UNGREEDY) != 0)? "ungreedy " : "");  
   }  
6003    
6004  if ((re->options & PCRE_FIRSTSET) != 0)  if ((re->options & PCRE_FIRSTSET) != 0)
6005    {    {

Legend:
Removed from v.210  
changed lines
  Added in v.226

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12