/[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 336 by ph10, Sat Apr 12 15:59:03 2008 UTC revision 342 by ph10, Sun Apr 20 17:10:13 2008 UTC
# Line 976  be terminated by '>' because that is che Line 976  be terminated by '>' because that is che
976    
977  Arguments:  Arguments:
978    ptr          current position in the pattern    ptr          current position in the pattern
979    count        current count of capturing parens so far encountered    cd           compile background data
980    name         name to seek, or NULL if seeking a numbered subpattern    name         name to seek, or NULL if seeking a numbered subpattern
981    lorn         name length, or subpattern number if name is NULL    lorn         name length, or subpattern number if name is NULL
982    xmode        TRUE if we are in /x mode    xmode        TRUE if we are in /x mode
# Line 985  Returns:       the number of the named s Line 985  Returns:       the number of the named s
985  */  */
986    
987  static int  static int
988  find_parens(const uschar *ptr, int count, const uschar *name, int lorn,  find_parens(const uschar *ptr, compile_data *cd, const uschar *name, int lorn,
989    BOOL xmode)    BOOL xmode)
990  {  {
991  const uschar *thisname;  const uschar *thisname;
992    int count = cd->bracount;
993    
994  for (; *ptr != 0; ptr++)  for (; *ptr != 0; ptr++)
995    {    {
# Line 1008  for (; *ptr != 0; ptr++) Line 1009  for (; *ptr != 0; ptr++)
1009      continue;      continue;
1010      }      }
1011    
1012    /* Skip over character classes */    /* Skip over character classes; this logic must be similar to the way they
1013      are handled for real. If the first character is '^', skip it. Also, if the
1014      first few characters (either before or after ^) are \Q\E or \E we skip them
1015      too. This makes for compatibility with Perl. */
1016    
1017    if (*ptr == '[')    if (*ptr == '[')
1018      {      {
1019        BOOL negate_class = FALSE;
1020        for (;;)
1021          {
1022          int c = *(++ptr);
1023          if (c == '\\')
1024            {
1025            if (ptr[1] == 'E') ptr++;
1026              else if (strncmp((const char *)ptr+1, "Q\\E", 3) == 0) ptr += 3;
1027                else break;
1028            }
1029          else if (!negate_class && c == '^')
1030            negate_class = TRUE;
1031          else break;
1032          }
1033    
1034        /* If the next character is ']', it is a data character that must be
1035        skipped, except in JavaScript compatibility mode. */
1036    
1037        if (ptr[1] == ']' && (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)
1038          ptr++;
1039    
1040      while (*(++ptr) != ']')      while (*(++ptr) != ']')
1041        {        {
1042        if (*ptr == 0) return -1;        if (*ptr == 0) return -1;
# Line 1276  for (;;) Line 1301  for (;;)
1301      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
1302      case OP_WORDCHAR:      case OP_WORDCHAR:
1303      case OP_ANY:      case OP_ANY:
1304        case OP_ALLANY:
1305      branchlength++;      branchlength++;
1306      cc++;      cc++;
1307      break;      break;
# Line 1654  for (code = first_significant_code(code Line 1680  for (code = first_significant_code(code
1680      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
1681      case OP_WORDCHAR:      case OP_WORDCHAR:
1682      case OP_ANY:      case OP_ANY:
1683        case OP_ALLANY:
1684      case OP_ANYBYTE:      case OP_ANYBYTE:
1685      case OP_CHAR:      case OP_CHAR:
1686      case OP_CHARNC:      case OP_CHARNC:
# Line 2640  for (;; ptr++) Line 2667  for (;; ptr++)
2667      zerofirstbyte = firstbyte;      zerofirstbyte = firstbyte;
2668      zeroreqbyte = reqbyte;      zeroreqbyte = reqbyte;
2669      previous = code;      previous = code;
2670      *code++ = OP_ANY;      *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
2671      break;      break;
2672    
2673    
# Line 2698  for (;; ptr++) Line 2725  for (;; ptr++)
2725          negate_class = TRUE;          negate_class = TRUE;
2726        else break;        else break;
2727        }        }
2728    
2729        /* Empty classes are allowed in JavaScript compatibility mode. Otherwise,
2730        an initial ']' is taken as a data character -- the code below handles
2731        that. In JS mode, [] must always fail, so generate OP_FAIL, whereas
2732        [^] must match any character, so generate OP_ALLANY. */
2733    
2734        if (c ==']' && (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
2735          {
2736          *code++ = negate_class? OP_ALLANY : OP_FAIL;
2737          if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
2738          zerofirstbyte = firstbyte;
2739          break;
2740          }
2741    
2742      /* If a class contains a negative special such as \S, we need to flip the      /* If a class contains a negative special such as \S, we need to flip the
2743      negation flag at the end, so that support for characters > 255 works      negation flag at the end, so that support for characters > 255 works
# Line 4079  we set the flag only if there is a liter Line 4119  we set the flag only if there is a liter
4119            }            }
4120          }          }
4121        }        }
4122    
4123        /* If previous is OP_FAIL, it was generated by an empty class [] in
4124        JavaScript mode. The other ways in which OP_FAIL can be generated, that is
4125        by (*FAIL) or (?!) set previous to NULL, which gives a "nothing to repeat"
4126        error above. We can just ignore the repeat in JS case. */
4127    
4128        else if (*previous == OP_FAIL) goto END_REPEAT;
4129    
4130      /* Else there's some kind of shambles */      /* Else there's some kind of shambles */
4131    
# Line 4366  we set the flag only if there is a liter Line 4413  we set the flag only if there is a liter
4413    
4414          /* Search the pattern for a forward reference */          /* Search the pattern for a forward reference */
4415    
4416          else if ((i = find_parens(ptr, cd->bracount, name, namelen,          else if ((i = find_parens(ptr, cd, name, namelen,
4417                          (options & PCRE_EXTENDED) != 0)) > 0)                          (options & PCRE_EXTENDED) != 0)) > 0)
4418            {            {
4419            PUT2(code, 2+LINK_SIZE, i);            PUT2(code, 2+LINK_SIZE, i);
# Line 4663  we set the flag only if there is a liter Line 4710  we set the flag only if there is a liter
4710              recno = GET2(slot, 0);              recno = GET2(slot, 0);
4711              }              }
4712            else if ((recno =                /* Forward back reference */            else if ((recno =                /* Forward back reference */
4713                      find_parens(ptr, cd->bracount, name, namelen,                      find_parens(ptr, cd, name, namelen,
4714                        (options & PCRE_EXTENDED) != 0)) <= 0)                        (options & PCRE_EXTENDED) != 0)) <= 0)
4715              {              {
4716              *errorcodeptr = ERR15;              *errorcodeptr = ERR15;
# Line 4773  we set the flag only if there is a liter Line 4820  we set the flag only if there is a liter
4820    
4821              if (called == NULL)              if (called == NULL)
4822                {                {
4823                if (find_parens(ptr, cd->bracount, NULL, recno,                if (find_parens(ptr, cd, NULL, recno,
4824                     (options & PCRE_EXTENDED) != 0) < 0)                      (options & PCRE_EXTENDED) != 0) < 0)
4825                  {                  {
4826                  *errorcodeptr = ERR15;                  *errorcodeptr = ERR15;
4827                  goto FAILED;                  goto FAILED;
# Line 5708  do { Line 5755  do {
5755       if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE;       if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE;
5756       }       }
5757    
5758     /* .* is not anchored unless DOTALL is set and it isn't in brackets that     /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
5759     are or may be referenced. */     it isn't in brackets that are or may be referenced. */
5760    
5761     else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||     else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
5762               op == OP_TYPEPOSSTAR) &&               op == OP_TYPEPOSSTAR))
             (*options & PCRE_DOTALL) != 0)  
5763       {       {
5764       if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE;       if (scode[1] != OP_ALLANY || (bracket_map & backref_map) != 0)
5765           return FALSE;
5766       }       }
5767    
5768     /* Check for explicit anchoring */     /* Check for explicit anchoring */

Legend:
Removed from v.336  
changed lines
  Added in v.342

  ViewVC Help
Powered by ViewVC 1.1.5