/[pcre]/code/branches/pcre16/pcre_compile.c
ViewVC logotype

Diff of /code/branches/pcre16/pcre_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 406 by ph10, Mon Mar 23 12:05:43 2009 UTC revision 447 by ph10, Tue Sep 15 18:17:54 2009 UTC
# Line 1009  return p; Line 1009  return p;
1009    
1010    
1011  /*************************************************  /*************************************************
1012  *       Find forward referenced subpattern       *  *  Subroutine for finding forward reference      *
1013  *************************************************/  *************************************************/
1014    
1015  /* This function scans along a pattern's text looking for capturing  /* This recursive function is called only from find_parens() below. The
1016    top-level call starts at the beginning of the pattern. All other calls must
1017    start at a parenthesis. It scans along a pattern's text looking for capturing
1018  subpatterns, and counting them. If it finds a named pattern that matches the  subpatterns, and counting them. If it finds a named pattern that matches the
1019  name it is given, it returns its number. Alternatively, if the name is NULL, it  name it is given, it returns its number. Alternatively, if the name is NULL, it
1020  returns when it reaches a given numbered subpattern. This is used for forward  returns when it reaches a given numbered subpattern. We know that if (?P< is
1021  references to subpatterns. We know that if (?P< is encountered, the name will  encountered, the name will be terminated by '>' because that is checked in the
1022  be terminated by '>' because that is checked in the first pass.  first pass. Recursion is used to keep track of subpatterns that reset the
1023    capturing group numbers - the (?| feature.
1024    
1025  Arguments:  Arguments:
1026    ptr          current position in the pattern    ptrptr       address of the current character pointer (updated)
1027    cd           compile background data    cd           compile background data
1028    name         name to seek, or NULL if seeking a numbered subpattern    name         name to seek, or NULL if seeking a numbered subpattern
1029    lorn         name length, or subpattern number if name is NULL    lorn         name length, or subpattern number if name is NULL
1030    xmode        TRUE if we are in /x mode    xmode        TRUE if we are in /x mode
1031      count        pointer to the current capturing subpattern number (updated)
1032    
1033  Returns:       the number of the named subpattern, or -1 if not found  Returns:       the number of the named subpattern, or -1 if not found
1034  */  */
1035    
1036  static int  static int
1037  find_parens(const uschar *ptr, compile_data *cd, const uschar *name, int lorn,  find_parens_sub(uschar **ptrptr, compile_data *cd, const uschar *name, int lorn,
1038    BOOL xmode)    BOOL xmode, int *count)
1039  {  {
1040  const uschar *thisname;  uschar *ptr = *ptrptr;
1041  int count = cd->bracount;  int start_count = *count;
1042    int hwm_count = start_count;
1043    BOOL dup_parens = FALSE;
1044    
1045  for (; *ptr != 0; ptr++)  /* If the first character is a parenthesis, check on the type of group we are
1046    dealing with. The very first call may not start with a parenthesis. */
1047    
1048    if (ptr[0] == CHAR_LEFT_PARENTHESIS)
1049    {    {
1050    int term;    if (ptr[1] == CHAR_QUESTION_MARK &&
1051          ptr[2] == CHAR_VERTICAL_LINE)
1052        {
1053        ptr += 3;
1054        dup_parens = TRUE;
1055        }
1056    
1057      /* Handle a normal, unnamed capturing parenthesis */
1058    
1059      else if (ptr[1] != CHAR_QUESTION_MARK && ptr[1] != CHAR_ASTERISK)
1060        {
1061        *count += 1;
1062        if (name == NULL && *count == lorn) return *count;
1063        ptr++;
1064        }
1065    
1066      /* Handle a condition. If it is an assertion, just carry on so that it
1067      is processed as normal. If not, skip to the closing parenthesis of the
1068      condition (there can't be any nested parens. */
1069    
1070      else if (ptr[2] == CHAR_LEFT_PARENTHESIS)
1071        {
1072        ptr += 2;
1073        if (ptr[1] != CHAR_QUESTION_MARK)
1074          {
1075          while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
1076          if (*ptr != 0) ptr++;
1077          }
1078        }
1079    
1080      /* We have either (? or (* and not a condition */
1081    
1082      else
1083        {
1084        ptr += 2;
1085        if (*ptr == CHAR_P) ptr++;                      /* Allow optional P */
1086    
1087        /* We have to disambiguate (?<! and (?<= from (?<name> for named groups */
1088    
1089        if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK &&
1090            ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE)
1091          {
1092          int term;
1093          const uschar *thisname;
1094          *count += 1;
1095          if (name == NULL && *count == lorn) return *count;
1096          term = *ptr++;
1097          if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;
1098          thisname = ptr;
1099          while (*ptr != term) ptr++;
1100          if (name != NULL && lorn == ptr - thisname &&
1101              strncmp((const char *)name, (const char *)thisname, lorn) == 0)
1102            return *count;
1103          term++;
1104          }
1105        }
1106      }
1107    
1108    /* Past any initial parenthesis handling, scan for parentheses or vertical
1109    bars. */
1110    
1111    for (; *ptr != 0; ptr++)
1112      {
1113    /* Skip over backslashed characters and also entire \Q...\E */    /* Skip over backslashed characters and also entire \Q...\E */
1114    
1115    if (*ptr == CHAR_BACKSLASH)    if (*ptr == CHAR_BACKSLASH)
1116      {      {
1117      if (*(++ptr) == 0) return -1;      if (*(++ptr) == 0) goto FAIL_EXIT;
1118      if (*ptr == CHAR_Q) for (;;)      if (*ptr == CHAR_Q) for (;;)
1119        {        {
1120        while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};        while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
1121        if (*ptr == 0) return -1;        if (*ptr == 0) goto FAIL_EXIT;
1122        if (*(++ptr) == CHAR_E) break;        if (*(++ptr) == CHAR_E) break;
1123        }        }
1124      continue;      continue;
# Line 1065  for (; *ptr != 0; ptr++) Line 1135  for (; *ptr != 0; ptr++)
1135      BOOL negate_class = FALSE;      BOOL negate_class = FALSE;
1136      for (;;)      for (;;)
1137        {        {
1138        int c = *(++ptr);        if (ptr[1] == CHAR_BACKSLASH)
       if (c == CHAR_BACKSLASH)  
1139          {          {
1140          if (ptr[1] == CHAR_E)          if (ptr[2] == CHAR_E)
1141            ptr++;            ptr+= 2;
1142          else if (strncmp((const char *)ptr+1,          else if (strncmp((const char *)ptr+2,
1143                   STR_Q STR_BACKSLASH STR_E, 3) == 0)                   STR_Q STR_BACKSLASH STR_E, 3) == 0)
1144            ptr += 3;            ptr += 4;
1145          else          else
1146            break;            break;
1147          }          }
1148        else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)        else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
1149            {
1150          negate_class = TRUE;          negate_class = TRUE;
1151            ptr++;
1152            }
1153        else break;        else break;
1154        }        }
1155    
# Line 1093  for (; *ptr != 0; ptr++) Line 1165  for (; *ptr != 0; ptr++)
1165        if (*ptr == 0) return -1;        if (*ptr == 0) return -1;
1166        if (*ptr == CHAR_BACKSLASH)        if (*ptr == CHAR_BACKSLASH)
1167          {          {
1168          if (*(++ptr) == 0) return -1;          if (*(++ptr) == 0) goto FAIL_EXIT;
1169          if (*ptr == CHAR_Q) for (;;)          if (*ptr == CHAR_Q) for (;;)
1170            {            {
1171            while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};            while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
1172            if (*ptr == 0) return -1;            if (*ptr == 0) goto FAIL_EXIT;
1173            if (*(++ptr) == CHAR_E) break;            if (*(++ptr) == CHAR_E) break;
1174            }            }
1175          continue;          continue;
# Line 1111  for (; *ptr != 0; ptr++) Line 1183  for (; *ptr != 0; ptr++)
1183    if (xmode && *ptr == CHAR_NUMBER_SIGN)    if (xmode && *ptr == CHAR_NUMBER_SIGN)
1184      {      {
1185      while (*(++ptr) != 0 && *ptr != CHAR_NL) {};      while (*(++ptr) != 0 && *ptr != CHAR_NL) {};
1186      if (*ptr == 0) return -1;      if (*ptr == 0) goto FAIL_EXIT;
1187      continue;      continue;
1188      }      }
1189    
1190    /* An opening parens must now be a real metacharacter */    /* Check for the special metacharacters */
1191    
1192    if (*ptr != CHAR_LEFT_PARENTHESIS) continue;    if (*ptr == CHAR_LEFT_PARENTHESIS)
   if (ptr[1] != CHAR_QUESTION_MARK && ptr[1] != CHAR_ASTERISK)  
1193      {      {
1194      count++;      int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, count);
1195      if (name == NULL && count == lorn) return count;      if (rc > 0) return rc;
1196      continue;      if (*ptr == 0) goto FAIL_EXIT;
1197        }
1198    
1199      else if (*ptr == CHAR_RIGHT_PARENTHESIS)
1200        {
1201        if (dup_parens && *count < hwm_count) *count = hwm_count;
1202        *ptrptr = ptr;
1203        return -1;
1204      }      }
1205    
1206    ptr += 2;    else if (*ptr == CHAR_VERTICAL_LINE && dup_parens)
1207    if (*ptr == CHAR_P) ptr++;                      /* Allow optional P */      {
1208        if (*count > hwm_count) hwm_count = *count;
1209        *count = start_count;
1210        }
1211      }
1212    
1213    /* We have to disambiguate (?<! and (?<= from (?<name> */  FAIL_EXIT:
1214    *ptrptr = ptr;
1215    return -1;
1216    }
1217    
   if ((*ptr != CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_EXCLAMATION_MARK ||  
       ptr[1] == CHAR_EQUALS_SIGN) && *ptr != CHAR_APOSTROPHE)  
     continue;  
1218    
   count++;  
1219    
1220    if (name == NULL && count == lorn) return count;  
1221    term = *ptr++;  /*************************************************
1222    if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;  *       Find forward referenced subpattern       *
1223    thisname = ptr;  *************************************************/
1224    while (*ptr != term) ptr++;  
1225    if (name != NULL && lorn == ptr - thisname &&  /* This function scans along a pattern's text looking for capturing
1226        strncmp((const char *)name, (const char *)thisname, lorn) == 0)  subpatterns, and counting them. If it finds a named pattern that matches the
1227      return count;  name it is given, it returns its number. Alternatively, if the name is NULL, it
1228    returns when it reaches a given numbered subpattern. This is used for forward
1229    references to subpatterns. We used to be able to start this scan from the
1230    current compiling point, using the current count value from cd->bracount, and
1231    do it all in a single loop, but the addition of the possibility of duplicate
1232    subpattern numbers means that we have to scan from the very start, in order to
1233    take account of such duplicates, and to use a recursive function to keep track
1234    of the different types of group.
1235    
1236    Arguments:
1237      cd           compile background data
1238      name         name to seek, or NULL if seeking a numbered subpattern
1239      lorn         name length, or subpattern number if name is NULL
1240      xmode        TRUE if we are in /x mode
1241    
1242    Returns:       the number of the found subpattern, or -1 if not found
1243    */
1244    
1245    static int
1246    find_parens(compile_data *cd, const uschar *name, int lorn, BOOL xmode)
1247    {
1248    uschar *ptr = (uschar *)cd->start_pattern;
1249    int count = 0;
1250    int rc;
1251    
1252    /* If the pattern does not start with an opening parenthesis, the first call
1253    to find_parens_sub() will scan right to the end (if necessary). However, if it
1254    does start with a parenthesis, find_parens_sub() will return when it hits the
1255    matching closing parens. That is why we have to have a loop. */
1256    
1257    for (;;)
1258      {
1259      rc = find_parens_sub(&ptr, cd, name, lorn, xmode, &count);
1260      if (rc > 0 || *ptr++ == 0) break;
1261    }    }
1262    
1263  return -1;  return rc;
1264  }  }
1265    
1266    
1267    
1268    
1269  /*************************************************  /*************************************************
1270  *      Find first significant op code            *  *      Find first significant op code            *
1271  *************************************************/  *************************************************/
# Line 1311  for (;;) Line 1426  for (;;)
1426      branchlength++;      branchlength++;
1427      cc += 2;      cc += 2;
1428  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1429      if ((options & PCRE_UTF8) != 0)      if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0)
1430        {        cc += _pcre_utf8_table4[cc[-1] & 0x3f];
       while ((*cc & 0xc0) == 0x80) cc++;  
       }  
1431  #endif  #endif
1432      break;      break;
1433    
# Line 1325  for (;;) Line 1438  for (;;)
1438      branchlength += GET2(cc,1);      branchlength += GET2(cc,1);
1439      cc += 4;      cc += 4;
1440  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1441      if ((options & PCRE_UTF8) != 0)      if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0)
1442        {        cc += _pcre_utf8_table4[cc[-1] & 0x3f];
       while((*cc & 0x80) == 0x80) cc++;  
       }  
1443  #endif  #endif
1444      break;      break;
1445    
# Line 1800  for (code = first_significant_code(code Line 1911  for (code = first_significant_code(code
1911      case OP_QUERY:      case OP_QUERY:
1912      case OP_MINQUERY:      case OP_MINQUERY:
1913      case OP_POSQUERY:      case OP_POSQUERY:
1914        if (utf8 && code[1] >= 0xc0) code += _pcre_utf8_table4[code[1] & 0x3f];
1915        break;
1916    
1917      case OP_UPTO:      case OP_UPTO:
1918      case OP_MINUPTO:      case OP_MINUPTO:
1919      case OP_POSUPTO:      case OP_POSUPTO:
1920      if (utf8) while ((code[2] & 0xc0) == 0x80) code++;      if (utf8 && code[3] >= 0xc0) code += _pcre_utf8_table4[code[3] & 0x3f];
1921      break;      break;
1922  #endif  #endif
1923      }      }
# Line 3757  we set the flag only if there is a liter Line 3871  we set the flag only if there is a liter
3871    
3872        if (repeat_max == 0) goto END_REPEAT;        if (repeat_max == 0) goto END_REPEAT;
3873    
3874          /*--------------------------------------------------------------------*/
3875          /* This code is obsolete from release 8.00; the restriction was finally
3876          removed: */
3877    
3878        /* All real repeats make it impossible to handle partial matching (maybe        /* All real repeats make it impossible to handle partial matching (maybe
3879        one day we will be able to remove this restriction). */        one day we will be able to remove this restriction). */
3880    
3881        if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL;        /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
3882          /*--------------------------------------------------------------------*/
3883    
3884        /* Combine the op_type with the repeat_type */        /* Combine the op_type with the repeat_type */
3885    
# Line 3907  we set the flag only if there is a liter Line 4026  we set the flag only if there is a liter
4026          goto END_REPEAT;          goto END_REPEAT;
4027          }          }
4028    
4029          /*--------------------------------------------------------------------*/
4030          /* This code is obsolete from release 8.00; the restriction was finally
4031          removed: */
4032    
4033        /* All real repeats make it impossible to handle partial matching (maybe        /* All real repeats make it impossible to handle partial matching (maybe
4034        one day we will be able to remove this restriction). */        one day we will be able to remove this restriction). */
4035    
4036        if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL;        /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
4037          /*--------------------------------------------------------------------*/
4038    
4039        if (repeat_min == 0 && repeat_max == -1)        if (repeat_min == 0 && repeat_max == -1)
4040          *code++ = OP_CRSTAR + repeat_type;          *code++ = OP_CRSTAR + repeat_type;
# Line 4225  we set the flag only if there is a liter Line 4349  we set the flag only if there is a liter
4349      if (possessive_quantifier)      if (possessive_quantifier)
4350        {        {
4351        int len;        int len;
4352        if (*tempcode == OP_EXACT || *tempcode == OP_TYPEEXACT ||  
4353            *tempcode == OP_NOTEXACT)        if (*tempcode == OP_TYPEEXACT)
4354          tempcode += _pcre_OP_lengths[*tempcode] +          tempcode += _pcre_OP_lengths[*tempcode] +
4355            ((*tempcode == OP_TYPEEXACT &&            ((tempcode[3] == OP_PROP || tempcode[3] == OP_NOTPROP)? 2 : 0);
4356               (tempcode[3] == OP_PROP || tempcode[3] == OP_NOTPROP))? 2:0);  
4357          else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
4358            {
4359            tempcode += _pcre_OP_lengths[*tempcode];
4360    #ifdef SUPPORT_UTF8
4361            if (utf8 && tempcode[-1] >= 0xc0)
4362              tempcode += _pcre_utf8_table4[tempcode[-1] & 0x3f];
4363    #endif
4364            }
4365    
4366        len = code - tempcode;        len = code - tempcode;
4367        if (len > 0) switch (*tempcode)        if (len > 0) switch (*tempcode)
4368          {          {
# Line 4307  we set the flag only if there is a liter Line 4440  we set the flag only if there is a liter
4440          if (namelen == verbs[i].len &&          if (namelen == verbs[i].len &&
4441              strncmp((char *)name, vn, namelen) == 0)              strncmp((char *)name, vn, namelen) == 0)
4442            {            {
4443            *code = verbs[i].op;            /* Check for open captures before ACCEPT */
4444            if (*code++ == OP_ACCEPT) cd->had_accept = TRUE;  
4445              if (verbs[i].op == OP_ACCEPT)
4446                {
4447                open_capitem *oc;
4448                cd->had_accept = TRUE;
4449                for (oc = cd->open_caps; oc != NULL; oc = oc->next)
4450                  {
4451                  *code++ = OP_CLOSE;
4452                  PUT2INC(code, 0, oc->number);
4453                  }
4454                }
4455              *code++ = verbs[i].op;
4456            break;            break;
4457            }            }
4458          vn += verbs[i].len + 1;          vn += verbs[i].len + 1;
# Line 4489  we set the flag only if there is a liter Line 4633  we set the flag only if there is a liter
4633    
4634          /* Search the pattern for a forward reference */          /* Search the pattern for a forward reference */
4635    
4636          else if ((i = find_parens(ptr, cd, name, namelen,          else if ((i = find_parens(cd, name, namelen,
4637                          (options & PCRE_EXTENDED) != 0)) > 0)                          (options & PCRE_EXTENDED) != 0)) > 0)
4638            {            {
4639            PUT2(code, 2+LINK_SIZE, i);            PUT2(code, 2+LINK_SIZE, i);
# Line 4788  we set the flag only if there is a liter Line 4932  we set the flag only if there is a liter
4932              recno = GET2(slot, 0);              recno = GET2(slot, 0);
4933              }              }
4934            else if ((recno =                /* Forward back reference */            else if ((recno =                /* Forward back reference */
4935                      find_parens(ptr, cd, name, namelen,                      find_parens(cd, name, namelen,
4936                        (options & PCRE_EXTENDED) != 0)) <= 0)                        (options & PCRE_EXTENDED) != 0)) <= 0)
4937              {              {
4938              *errorcodeptr = ERR15;              *errorcodeptr = ERR15;
# Line 4898  we set the flag only if there is a liter Line 5042  we set the flag only if there is a liter
5042    
5043              if (called == NULL)              if (called == NULL)
5044                {                {
5045                if (find_parens(ptr, cd, NULL, recno,                if (find_parens(cd, NULL, recno,
5046                      (options & PCRE_EXTENDED) != 0) < 0)                      (options & PCRE_EXTENDED) != 0) < 0)
5047                  {                  {
5048                  *errorcodeptr = ERR15;                  *errorcodeptr = ERR15;
# Line 5536  uschar *code = *codeptr; Line 5680  uschar *code = *codeptr;
5680  uschar *last_branch = code;  uschar *last_branch = code;
5681  uschar *start_bracket = code;  uschar *start_bracket = code;
5682  uschar *reverse_count = NULL;  uschar *reverse_count = NULL;
5683    open_capitem capitem;
5684    int capnumber = 0;
5685  int firstbyte, reqbyte;  int firstbyte, reqbyte;
5686  int branchfirstbyte, branchreqbyte;  int branchfirstbyte, branchreqbyte;
5687  int length;  int length;
# Line 5562  the code that abstracts option settings Line 5708  the code that abstracts option settings
5708  them global. It tests the value of length for (2 + 2*LINK_SIZE) in the  them global. It tests the value of length for (2 + 2*LINK_SIZE) in the
5709  pre-compile phase to find out whether anything has yet been compiled or not. */  pre-compile phase to find out whether anything has yet been compiled or not. */
5710    
5711    /* If this is a capturing subpattern, add to the chain of open capturing items
5712    so that we can detect them if (*ACCEPT) is encountered. */
5713    
5714    if (*code == OP_CBRA)
5715      {
5716      capnumber = GET2(code, 1 + LINK_SIZE);
5717      capitem.number = capnumber;
5718      capitem.next = cd->open_caps;
5719      cd->open_caps = &capitem;
5720      }
5721    
5722  /* Offset is set zero to mark that this bracket is still open */  /* Offset is set zero to mark that this bracket is still open */
5723    
5724  PUT(code, 1, 0);  PUT(code, 1, 0);
# Line 5697  for (;;) Line 5854  for (;;)
5854          }          }
5855        while (branch_length > 0);        while (branch_length > 0);
5856        }        }
5857    
5858        /* If it was a capturing subpattern, remove it from the chain. */
5859    
5860        if (capnumber > 0) cd->open_caps = cd->open_caps->next;
5861    
5862      /* Fill in the ket */      /* Fill in the ket */
5863    
# Line 6114  if (erroroffset == NULL) Line 6275  if (erroroffset == NULL)
6275    
6276  *erroroffset = 0;  *erroroffset = 0;
6277    
 /* Can't support UTF8 unless PCRE has been compiled to include the code. */  
   
 #ifdef SUPPORT_UTF8  
 utf8 = (options & PCRE_UTF8) != 0;  
 if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&  
      (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0)  
   {  
   errorcode = ERR44;  
   goto PCRE_EARLY_ERROR_RETURN2;  
   }  
 #else  
 if ((options & PCRE_UTF8) != 0)  
   {  
   errorcode = ERR32;  
   goto PCRE_EARLY_ERROR_RETURN;  
   }  
 #endif  
   
 if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)  
   {  
   errorcode = ERR17;  
   goto PCRE_EARLY_ERROR_RETURN;  
   }  
   
6278  /* Set up pointers to the individual character tables */  /* Set up pointers to the individual character tables */
6279    
6280  if (tables == NULL) tables = _pcre_default_tables;  if (tables == NULL) tables = _pcre_default_tables;
# Line 6146  cd->fcc = tables + fcc_offset; Line 6283  cd->fcc = tables + fcc_offset;
6283  cd->cbits = tables + cbits_offset;  cd->cbits = tables + cbits_offset;
6284  cd->ctypes = tables + ctypes_offset;  cd->ctypes = tables + ctypes_offset;
6285    
6286    /* Check that all undefined public option bits are zero */
6287    
6288    if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
6289      {
6290      errorcode = ERR17;
6291      goto PCRE_EARLY_ERROR_RETURN;
6292      }
6293    
6294  /* Check for global one-time settings at the start of the pattern, and remember  /* Check for global one-time settings at the start of the pattern, and remember
6295  the offset for later. */  the offset for later. */
6296    
# Line 6155  while (ptr[skipatstart] == CHAR_LEFT_PAR Line 6300  while (ptr[skipatstart] == CHAR_LEFT_PAR
6300    int newnl = 0;    int newnl = 0;
6301    int newbsr = 0;    int newbsr = 0;
6302    
6303      if (strncmp((char *)(ptr+skipatstart+2), STRING_UTF8_RIGHTPAR, 5) == 0)
6304        { skipatstart += 7; options |= PCRE_UTF8; continue; }
6305    
6306    if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0)    if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0)
6307      { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }      { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
6308    else if (strncmp((char *)(ptr+skipatstart+2), STRING_LF_RIGHTPAR, 3)  == 0)    else if (strncmp((char *)(ptr+skipatstart+2), STRING_LF_RIGHTPAR, 3)  == 0)
# Line 6178  while (ptr[skipatstart] == CHAR_LEFT_PAR Line 6326  while (ptr[skipatstart] == CHAR_LEFT_PAR
6326    else break;    else break;
6327    }    }
6328    
6329    /* Can't support UTF8 unless PCRE has been compiled to include the code. */
6330    
6331    #ifdef SUPPORT_UTF8
6332    utf8 = (options & PCRE_UTF8) != 0;
6333    if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&
6334         (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0)
6335      {
6336      errorcode = ERR44;
6337      goto PCRE_EARLY_ERROR_RETURN2;
6338      }
6339    #else
6340    if ((options & PCRE_UTF8) != 0)
6341      {
6342      errorcode = ERR32;
6343      goto PCRE_EARLY_ERROR_RETURN;
6344      }
6345    #endif
6346    
6347  /* Check validity of \R options. */  /* Check validity of \R options. */
6348    
6349  switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))  switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
# Line 6260  cd->end_pattern = (const uschar *)(patte Line 6426  cd->end_pattern = (const uschar *)(patte
6426  cd->req_varyopt = 0;  cd->req_varyopt = 0;
6427  cd->external_options = options;  cd->external_options = options;
6428  cd->external_flags = 0;  cd->external_flags = 0;
6429    cd->open_caps = NULL;
6430    
6431  /* Now do the pre-compile. On error, errorcode will be set non-zero, so we  /* Now do the pre-compile. On error, errorcode will be set non-zero, so we
6432  don't need to look at the result of the function here. The initial options have  don't need to look at the result of the function here. The initial options have
# Line 6334  cd->start_code = codestart; Line 6501  cd->start_code = codestart;
6501  cd->hwm = cworkspace;  cd->hwm = cworkspace;
6502  cd->req_varyopt = 0;  cd->req_varyopt = 0;
6503  cd->had_accept = FALSE;  cd->had_accept = FALSE;
6504    cd->open_caps = NULL;
6505    
6506  /* Set up a starting, non-extracting bracket, then compile the expression. On  /* Set up a starting, non-extracting bracket, then compile the expression. On
6507  error, errorcode will be set non-zero, so we don't need to look at the result  error, errorcode will be set non-zero, so we don't need to look at the result

Legend:
Removed from v.406  
changed lines
  Added in v.447

  ViewVC Help
Powered by ViewVC 1.1.5