/[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 345 by ph10, Mon Apr 28 15:10:02 2008 UTC revision 389 by ph10, Sun Mar 15 18:24:05 2009 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2009 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 455  static const char * Line 455  static const char *
455  find_error_text(int n)  find_error_text(int n)
456  {  {
457  const char *s = error_texts;  const char *s = error_texts;
458  for (; n > 0; n--) while (*s++ != 0);  for (; n > 0; n--) while (*s++ != 0) {};
459  return s;  return s;
460  }  }
461    
# Line 1002  for (; *ptr != 0; ptr++) Line 1002  for (; *ptr != 0; ptr++)
1002      if (*(++ptr) == 0) return -1;      if (*(++ptr) == 0) return -1;
1003      if (*ptr == 'Q') for (;;)      if (*ptr == 'Q') for (;;)
1004        {        {
1005        while (*(++ptr) != 0 && *ptr != '\\');        while (*(++ptr) != 0 && *ptr != '\\') {};
1006        if (*ptr == 0) return -1;        if (*ptr == 0) return -1;
1007        if (*(++ptr) == 'E') break;        if (*(++ptr) == 'E') break;
1008        }        }
# Line 1045  for (; *ptr != 0; ptr++) Line 1045  for (; *ptr != 0; ptr++)
1045          if (*(++ptr) == 0) return -1;          if (*(++ptr) == 0) return -1;
1046          if (*ptr == 'Q') for (;;)          if (*ptr == 'Q') for (;;)
1047            {            {
1048            while (*(++ptr) != 0 && *ptr != '\\');            while (*(++ptr) != 0 && *ptr != '\\') {};
1049            if (*ptr == 0) return -1;            if (*ptr == 0) return -1;
1050            if (*(++ptr) == 'E') break;            if (*(++ptr) == 'E') break;
1051            }            }
# Line 1059  for (; *ptr != 0; ptr++) Line 1059  for (; *ptr != 0; ptr++)
1059    
1060    if (xmode && *ptr == '#')    if (xmode && *ptr == '#')
1061      {      {
1062      while (*(++ptr) != 0 && *ptr != '\n');      while (*(++ptr) != 0 && *ptr != '\n') {};
1063      if (*ptr == 0) return -1;      if (*ptr == 0) return -1;
1064      continue;      continue;
1065      }      }
# Line 1450  for (;;) Line 1450  for (;;)
1450        if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];        if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
1451        break;        break;
1452        }        }
1453    #else
1454        (void)(utf8);  /* Keep compiler happy by referencing function argument */
1455  #endif  #endif
1456      }      }
1457    }    }
# Line 1543  for (;;) Line 1545  for (;;)
1545        if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];        if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
1546        break;        break;
1547        }        }
1548    #else
1549        (void)(utf8);  /* Keep compiler happy by referencing function argument */
1550  #endif  #endif
1551      }      }
1552    }    }
# Line 2015  get_othercase_range(unsigned int *cptr, Line 2019  get_othercase_range(unsigned int *cptr,
2019  unsigned int c, othercase, next;  unsigned int c, othercase, next;
2020    
2021  for (c = *cptr; c <= d; c++)  for (c = *cptr; c <= d; c++)
2022    { if ((othercase = _pcre_ucp_othercase(c)) != NOTACHAR) break; }    { if ((othercase = UCD_OTHERCASE(c)) != c) break; }
2023    
2024  if (c > d) return FALSE;  if (c > d) return FALSE;
2025    
# Line 2024  next = othercase + 1; Line 2028  next = othercase + 1;
2028    
2029  for (++c; c <= d; c++)  for (++c; c <= d; c++)
2030    {    {
2031    if (_pcre_ucp_othercase(c) != next) break;    if (UCD_OTHERCASE(c) != next) break;
2032    next++;    next++;
2033    }    }
2034    
# Line 2134  if (next >= 0) switch(op_code) Line 2138  if (next >= 0) switch(op_code)
2138    case OP_CHAR:    case OP_CHAR:
2139  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2140    if (utf8 && item > 127) { GETCHAR(item, utf8_char); }    if (utf8 && item > 127) { GETCHAR(item, utf8_char); }
2141    #else
2142      (void)(utf8_char);  /* Keep compiler happy by referencing function argument */
2143  #endif  #endif
2144    return item != next;    return item != next;
2145    
# Line 2152  if (next >= 0) switch(op_code) Line 2158  if (next >= 0) switch(op_code)
2158      unsigned int othercase;      unsigned int othercase;
2159      if (next < 128) othercase = cd->fcc[next]; else      if (next < 128) othercase = cd->fcc[next]; else
2160  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2161      othercase = _pcre_ucp_othercase((unsigned int)next);      othercase = UCD_OTHERCASE((unsigned int)next);
2162  #else  #else
2163      othercase = NOTACHAR;      othercase = NOTACHAR;
2164  #endif  #endif
# Line 2173  if (next >= 0) switch(op_code) Line 2179  if (next >= 0) switch(op_code)
2179      unsigned int othercase;      unsigned int othercase;
2180      if (next < 128) othercase = cd->fcc[next]; else      if (next < 128) othercase = cd->fcc[next]; else
2181  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2182      othercase = _pcre_ucp_othercase(next);      othercase = UCD_OTHERCASE(next);
2183  #else  #else
2184      othercase = NOTACHAR;      othercase = NOTACHAR;
2185  #endif  #endif
# Line 3339  for (;; ptr++) Line 3345  for (;; ptr++)
3345          if ((options & PCRE_CASELESS) != 0)          if ((options & PCRE_CASELESS) != 0)
3346            {            {
3347            unsigned int othercase;            unsigned int othercase;
3348            if ((othercase = _pcre_ucp_othercase(c)) != NOTACHAR)            if ((othercase = UCD_OTHERCASE(c)) != c)
3349              {              {
3350              *class_utf8data++ = XCL_SINGLE;              *class_utf8data++ = XCL_SINGLE;
3351              class_utf8data += _pcre_ord2utf8(othercase, class_utf8data);              class_utf8data += _pcre_ord2utf8(othercase, class_utf8data);
# Line 4216  we set the flag only if there is a liter Line 4222  we set the flag only if there is a liter
4222        const char *vn = verbnames;        const char *vn = verbnames;
4223        const uschar *name = ++ptr;        const uschar *name = ++ptr;
4224        previous = NULL;        previous = NULL;
4225        while ((cd->ctypes[*++ptr] & ctype_letter) != 0);        while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {};
4226        if (*ptr == ':')        if (*ptr == ':')
4227          {          {
4228          *errorcodeptr = ERR59;   /* Not supported */          *errorcodeptr = ERR59;   /* Not supported */
# Line 4920  we set the flag only if there is a liter Line 4926  we set the flag only if there is a liter
4926          both phases.          both phases.
4927    
4928          If we are not at the pattern start, compile code to change the ims          If we are not at the pattern start, compile code to change the ims
4929          options if this setting actually changes any of them. We also pass the          options if this setting actually changes any of them, and reset the
4930          new setting back so that it can be put at the start of any following          greedy defaults and the case value for firstbyte and reqbyte. */
         branches, and when this group ends (if we are in a group), a resetting  
         item can be compiled. */  
4931    
4932          if (*ptr == ')')          if (*ptr == ')')
4933            {            {
# Line 4931  we set the flag only if there is a liter Line 4935  we set the flag only if there is a liter
4935                 (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE))                 (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE))
4936              {              {
4937              cd->external_options = newoptions;              cd->external_options = newoptions;
             options = newoptions;  
4938              }              }
4939           else           else
4940              {              {
# Line 4940  we set the flag only if there is a liter Line 4943  we set the flag only if there is a liter
4943                *code++ = OP_OPT;                *code++ = OP_OPT;
4944                *code++ = newoptions & PCRE_IMS;                *code++ = newoptions & PCRE_IMS;
4945                }                }
   
             /* Change options at this level, and pass them back for use  
             in subsequent branches. Reset the greedy defaults and the case  
             value for firstbyte and reqbyte. */  
   
             *optionsptr = options = newoptions;  
4946              greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);              greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);
4947              greedy_non_default = greedy_default ^ 1;              greedy_non_default = greedy_default ^ 1;
4948              req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;              req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
4949              }              }
4950    
4951              /* Change options at this level, and pass them back for use
4952              in subsequent branches. When not at the start of the pattern, this
4953              information is also necessary so that a resetting item can be
4954              compiled at the end of a group (if we are in a group). */
4955    
4956              *optionsptr = options = newoptions;
4957            previous = NULL;       /* This item can't be repeated */            previous = NULL;       /* This item can't be repeated */
4958            continue;              /* It is complete */            continue;              /* It is complete */
4959            }            }
# Line 5807  do { Line 5810  do {
5810     const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],     const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],
5811       NULL, 0, FALSE);       NULL, 0, FALSE);
5812     register int op = *scode;     register int op = *scode;
5813    
5814       /* If we are at the start of a conditional assertion group, *both* the
5815       conditional assertion *and* what follows the condition must satisfy the test
5816       for start of line. Other kinds of condition fail. Note that there may be an
5817       auto-callout at the start of a condition. */
5818    
5819       if (op == OP_COND)
5820         {
5821         scode += 1 + LINK_SIZE;
5822         if (*scode == OP_CALLOUT) scode += _pcre_OP_lengths[OP_CALLOUT];
5823         switch (*scode)
5824           {
5825           case OP_CREF:
5826           case OP_RREF:
5827           case OP_DEF:
5828           return FALSE;
5829    
5830           default:     /* Assertion */
5831           if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
5832           do scode += GET(scode, 1); while (*scode == OP_ALT);
5833           scode += 1 + LINK_SIZE;
5834           break;
5835           }
5836         scode = first_significant_code(scode, NULL, 0, FALSE);
5837         op = *scode;
5838         }
5839    
5840     /* Non-capturing brackets */     /* Non-capturing brackets */
5841    
# Line 5826  do { Line 5855  do {
5855    
5856     /* Other brackets */     /* Other brackets */
5857    
5858     else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND)     else if (op == OP_ASSERT || op == OP_ONCE)
5859       { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; }       {
5860         if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
5861         }
5862    
5863     /* .* means "start at start or after \n" if it isn't in brackets that     /* .* means "start at start or after \n" if it isn't in brackets that
5864     may be referenced. */     may be referenced. */
# Line 5944  Returns:        pointer to compiled data Line 5975  Returns:        pointer to compiled data
5975                  with errorptr and erroroffset set                  with errorptr and erroroffset set
5976  */  */
5977    
5978  PCRE_EXP_DEFN pcre *  PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
5979  pcre_compile(const char *pattern, int options, const char **errorptr,  pcre_compile(const char *pattern, int options, const char **errorptr,
5980    int *erroroffset, const unsigned char *tables)    int *erroroffset, const unsigned char *tables)
5981  {  {
# Line 5952  return pcre_compile2(pattern, options, N Line 5983  return pcre_compile2(pattern, options, N
5983  }  }
5984    
5985    
5986  PCRE_EXP_DEFN pcre *  PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
5987  pcre_compile2(const char *pattern, int options, int *errorcodeptr,  pcre_compile2(const char *pattern, int options, int *errorcodeptr,
5988    const char **errorptr, int *erroroffset, const unsigned char *tables)    const char **errorptr, int *erroroffset, const unsigned char *tables)
5989  {  {
# Line 6024  if ((options & PCRE_UTF8) != 0) Line 6055  if ((options & PCRE_UTF8) != 0)
6055    }    }
6056  #endif  #endif
6057    
6058  if ((options & ~PUBLIC_OPTIONS) != 0)  if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
6059    {    {
6060    errorcode = ERR17;    errorcode = ERR17;
6061    goto PCRE_EARLY_ERROR_RETURN;    goto PCRE_EARLY_ERROR_RETURN;

Legend:
Removed from v.345  
changed lines
  Added in v.389

  ViewVC Help
Powered by ViewVC 1.1.5