This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate:
[perl5.git] / regcomp.c
index bd900fb..b0be233 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -5,6 +5,16 @@
  * "A fair jaw-cracker dwarf-language must be."  --Samwise Gamgee
  */
 
+/* This file contains functions for compiling a regular expression.  See
+ * also regexec.c which funnily enough, contains functions for executing
+ * a regular expression.
+ *
+ * This file is also copied at build time to ext/re/re_comp.c, where
+ * it's built with -DPERL_EXT_RE_BUILD -DPERL_EXT_RE_DEBUG -DPERL_EXT.
+ * This causes the main functions to be compiled under new names and with
+ * debugging support added, which makes "use re 'debug'" work.
+ */
+
 /* NOTE: this is derived from Henry Spencer's regexp code, and should not
  * confused with the original package (see point 3 below).  Thanks, Henry!
  */
@@ -70,7 +80,7 @@
  ****    Alterations to Henry's code are...
  ****
  ****    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- ****    2000, 2001, 2002, 2003, by Larry Wall and others
+ ****    2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
  ****
  ****    You may distribute under the terms of either the GNU General Public
  ****    License or the Artistic License, as specified in the README file.
@@ -1188,7 +1198,9 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                if (  OP(oscan) == CURLYX && data
                      && !(data->flags & SF_HAS_PAR)
                      && !(data->flags & SF_HAS_EVAL)
-                     && !deltanext  ) {
+                     && !deltanext     /* atom is fixed width */
+                     && minnext != 0   /* CURLYM can't handle zero width */
+               ) {
                    /* XXXX How to optimize if data == 0? */
                    /* Optimize to a simpler form.  */
                    regnode *nxt = NEXTOPER(oscan) + EXTRA_STEP_2ARGS; /* OPEN */
@@ -1297,7 +1309,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap, reg
                                SvGROW(last_str, (mincount * l) + 1);
                                repeatcpy(SvPVX(last_str) + l,
                                          SvPVX(last_str), l, mincount - 1);
-                               SvCUR(last_str) *= mincount;
+                               SvCUR_set(last_str, SvCUR(last_str) * mincount);
                                /* Add additional parts. */
                                SvCUR_set(data->last_found,
                                          SvCUR(data->last_found) - l);
@@ -2506,8 +2518,8 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
            if (paren == '>')
                node = SUSPEND, flag = 0;
            reginsert(pRExC_state, node,ret);
-           Set_Node_Offset(ret, oregcomp_parse);
-           Set_Node_Length(ret,  RExC_parse - oregcomp_parse + 2);
+           Set_Node_Cur_Length(ret);
+           Set_Node_Offset(ret, parse_start + 1);
            ret->flags = flag;
            regtail(pRExC_state, ret, reg_node(pRExC_state, TAIL));
        }
@@ -2788,7 +2800,7 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp)
 {
     register regnode *ret = 0;
     I32 flags;
-    char *parse_start = 0;
+    char *parse_start = RExC_parse;
 
     *flagp = WORST;            /* Tentatively. */
 
@@ -3051,6 +3063,7 @@ tryagain:
        default:
            /* Do not generate `unrecognized' warnings here, we fall
               back into the quick-grab loop below */
+           parse_start--;
            goto defchar;
        }
        break;
@@ -3070,7 +3083,7 @@ tryagain:
            char *oldp, *s;
            STRLEN numlen;
            STRLEN foldlen;
-           U8 tmpbuf[UTF8_MAXLEN_FOLD+1], *foldbuf;
+           U8 tmpbuf[UTF8_MAXBYTES_CASE+1], *foldbuf;
 
             parse_start = RExC_parse - 1;
 
@@ -3388,90 +3401,125 @@ S_regpposixcc(pTHX_ RExC_state_t *pRExC_state, I32 value)
        else {
            char* t = RExC_parse++; /* skip over the c */
 
+           assert(*t == c);
+
            if (UCHARAT(RExC_parse) == ']') {
                RExC_parse++; /* skip over the ending ] */
                posixcc = s + 1;
                if (*s == ':') {
                    I32 complement = *posixcc == '^' ? *posixcc++ : 0;
-                   I32 skip = 5; /* the most common skip */
-
-                   switch (*posixcc) {
-                   case 'a':
-                       if (strnEQ(posixcc, "alnum", 5))
-                           namedclass =
-                               complement ? ANYOF_NALNUMC : ANYOF_ALNUMC;
-                       else if (strnEQ(posixcc, "alpha", 5))
-                           namedclass =
-                               complement ? ANYOF_NALPHA : ANYOF_ALPHA;
-                       else if (strnEQ(posixcc, "ascii", 5))
-                           namedclass =
-                               complement ? ANYOF_NASCII : ANYOF_ASCII;
-                       break;
-                   case 'b':
-                       if (strnEQ(posixcc, "blank", 5))
-                           namedclass =
-                               complement ? ANYOF_NBLANK : ANYOF_BLANK;
-                       break;
-                   case 'c':
-                       if (strnEQ(posixcc, "cntrl", 5))
-                           namedclass =
-                               complement ? ANYOF_NCNTRL : ANYOF_CNTRL;
-                       break;
-                   case 'd':
-                       if (strnEQ(posixcc, "digit", 5))
-                           namedclass =
-                               complement ? ANYOF_NDIGIT : ANYOF_DIGIT;
-                       break;
-                   case 'g':
-                       if (strnEQ(posixcc, "graph", 5))
-                           namedclass =
-                               complement ? ANYOF_NGRAPH : ANYOF_GRAPH;
-                       break;
-                   case 'l':
-                       if (strnEQ(posixcc, "lower", 5))
-                           namedclass =
-                               complement ? ANYOF_NLOWER : ANYOF_LOWER;
-                       break;
-                   case 'p':
-                       if (strnEQ(posixcc, "print", 5))
-                           namedclass =
-                               complement ? ANYOF_NPRINT : ANYOF_PRINT;
-                       else if (strnEQ(posixcc, "punct", 5))
-                           namedclass =
-                               complement ? ANYOF_NPUNCT : ANYOF_PUNCT;
-                       break;
-                   case 's':
-                       if (strnEQ(posixcc, "space", 5))
-                           namedclass =
-                               complement ? ANYOF_NPSXSPC : ANYOF_PSXSPC;
+                   I32 skip = t - posixcc;
+
+                   /* Initially switch on the length of the name.  */
+                   switch (skip) {
+                   case 4:
+                       if (memEQ(posixcc, "word", 4)) {
+                           /* this is not POSIX, this is the Perl \w */;
+                           namedclass
+                               = complement ? ANYOF_NALNUM : ANYOF_ALNUM;
+                       }
                        break;
-                   case 'u':
-                       if (strnEQ(posixcc, "upper", 5))
-                           namedclass =
-                               complement ? ANYOF_NUPPER : ANYOF_UPPER;
-                       break;
-                   case 'w': /* this is not POSIX, this is the Perl \w */
-                       if (strnEQ(posixcc, "word", 4)) {
-                           namedclass =
-                               complement ? ANYOF_NALNUM : ANYOF_ALNUM;
-                           skip = 4;
+                   case 5:
+                       /* Names all of length 5.  */
+                       /* alnum alpha ascii blank cntrl digit graph lower
+                          print punct space upper  */
+                       /* Offset 4 gives the best switch position.  */
+                       switch (posixcc[4]) {
+                       case 'a':
+                           if (memEQ(posixcc, "alph", 4)) {
+                               /*                  a     */
+                               namedclass
+                                   = complement ? ANYOF_NALPHA : ANYOF_ALPHA;
+                           }
+                           break;
+                       case 'e':
+                           if (memEQ(posixcc, "spac", 4)) {
+                               /*                  e     */
+                               namedclass
+                                   = complement ? ANYOF_NPSXSPC : ANYOF_PSXSPC;
+                           }
+                           break;
+                       case 'h':
+                           if (memEQ(posixcc, "grap", 4)) {
+                               /*                  h     */
+                               namedclass
+                                   = complement ? ANYOF_NGRAPH : ANYOF_GRAPH;
+                           }
+                           break;
+                       case 'i':
+                           if (memEQ(posixcc, "asci", 4)) {
+                               /*                  i     */
+                               namedclass
+                                   = complement ? ANYOF_NASCII : ANYOF_ASCII;
+                           }
+                           break;
+                       case 'k':
+                           if (memEQ(posixcc, "blan", 4)) {
+                               /*                  k     */
+                               namedclass
+                                   = complement ? ANYOF_NBLANK : ANYOF_BLANK;
+                           }
+                           break;
+                       case 'l':
+                           if (memEQ(posixcc, "cntr", 4)) {
+                               /*                  l     */
+                               namedclass
+                                   = complement ? ANYOF_NCNTRL : ANYOF_CNTRL;
+                           }
+                           break;
+                       case 'm':
+                           if (memEQ(posixcc, "alnu", 4)) {
+                               /*                  m     */
+                               namedclass
+                                   = complement ? ANYOF_NALNUMC : ANYOF_ALNUMC;
+                           }
+                           break;
+                       case 'r':
+                           if (memEQ(posixcc, "lowe", 4)) {
+                               /*                  r     */
+                               namedclass
+                                   = complement ? ANYOF_NLOWER : ANYOF_LOWER;
+                           }
+                           if (memEQ(posixcc, "uppe", 4)) {
+                               /*                  r     */
+                               namedclass
+                                   = complement ? ANYOF_NUPPER : ANYOF_UPPER;
+                           }
+                           break;
+                       case 't':
+                           if (memEQ(posixcc, "digi", 4)) {
+                               /*                  t     */
+                               namedclass
+                                   = complement ? ANYOF_NDIGIT : ANYOF_DIGIT;
+                           }
+                           if (memEQ(posixcc, "prin", 4)) {
+                               /*                  t     */
+                               namedclass
+                                   = complement ? ANYOF_NPRINT : ANYOF_PRINT;
+                           }
+                           if (memEQ(posixcc, "punc", 4)) {
+                               /*                  t     */
+                               namedclass
+                                   = complement ? ANYOF_NPUNCT : ANYOF_PUNCT;
+                           }
+                           break;
                        }
                        break;
-                   case 'x':
-                       if (strnEQ(posixcc, "xdigit", 6)) {
-                           namedclass =
-                               complement ? ANYOF_NXDIGIT : ANYOF_XDIGIT;
-                           skip = 6;
+                   case 6:
+                       if (memEQ(posixcc, "xdigit", 6)) {
+                           namedclass
+                               = complement ? ANYOF_NXDIGIT : ANYOF_XDIGIT;
                        }
                        break;
                    }
-                   if (namedclass == OOB_NAMEDCLASS ||
-                       posixcc[skip] != ':' ||
-                       posixcc[skip+1] != ']')
+
+                   if (namedclass == OOB_NAMEDCLASS)
                    {
                        Simple_vFAIL3("POSIX class [:%.*s:] unknown",
                                      t - s - 1, s + 1);
                    }
+                   assert (posixcc[skip] == ':');
+                   assert (posixcc[skip+1] == ']');
                } else if (!SIZE_ONLY) {
                    /* [[=foo=]] and [[.foo.]] are still future. */
 
@@ -3653,7 +3701,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                }
                RExC_parse = e + 1;
                ANYOF_FLAGS(ret) |= ANYOF_UNICODE;
-               continue;
+               namedclass = ANYOF_MAX;  /* no official name, but it's named */
+               break;
            case 'n':   value = '\n';                   break;
            case 'r':   value = '\r';                   break;
            case 't':   value = '\t';                   break;
@@ -3737,6 +3786,9 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
            }
 
            if (!SIZE_ONLY) {
+               const char *what = NULL;
+               char yesno = 0;
+
                if (namedclass > OOB_NAMEDCLASS)
                    optimize_invert = FALSE;
                /* Possible truncation here but in some 64-bit environments
@@ -3752,7 +3804,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isALNUM(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsWord\n");    
+                   yesno = '+';
+                   what = "Word";      
                    break;
                case ANYOF_NALNUM:
                    if (LOC)
@@ -3762,7 +3815,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isALNUM(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsWord\n");
+                   yesno = '!';
+                   what = "Word";
                    break;
                case ANYOF_ALNUMC:
                    if (LOC)
@@ -3772,7 +3826,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isALNUMC(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsAlnum\n");
+                   yesno = '+';
+                   what = "Alnum";
                    break;
                case ANYOF_NALNUMC:
                    if (LOC)
@@ -3782,7 +3837,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isALNUMC(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsAlnum\n");
+                   yesno = '!';
+                   what = "Alnum";
                    break;
                case ANYOF_ALPHA:
                    if (LOC)
@@ -3792,7 +3848,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isALPHA(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsAlpha\n");
+                   yesno = '+';
+                   what = "Alpha";
                    break;
                case ANYOF_NALPHA:
                    if (LOC)
@@ -3802,7 +3859,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isALPHA(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsAlpha\n");
+                   yesno = '!';
+                   what = "Alpha";
                    break;
                case ANYOF_ASCII:
                    if (LOC)
@@ -3818,7 +3876,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                        }
 #endif /* EBCDIC */
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsASCII\n");
+                   yesno = '+';
+                   what = "ASCII";
                    break;
                case ANYOF_NASCII:
                    if (LOC)
@@ -3834,7 +3893,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                        }
 #endif /* EBCDIC */
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsASCII\n");
+                   yesno = '!';
+                   what = "ASCII";
                    break;
                case ANYOF_BLANK:
                    if (LOC)
@@ -3844,7 +3904,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isBLANK(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsBlank\n");
+                   yesno = '+';
+                   what = "Blank";
                    break;
                case ANYOF_NBLANK:
                    if (LOC)
@@ -3854,7 +3915,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isBLANK(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsBlank\n");
+                   yesno = '!';
+                   what = "Blank";
                    break;
                case ANYOF_CNTRL:
                    if (LOC)
@@ -3864,7 +3926,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isCNTRL(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsCntrl\n");
+                   yesno = '+';
+                   what = "Cntrl";
                    break;
                case ANYOF_NCNTRL:
                    if (LOC)
@@ -3874,7 +3937,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isCNTRL(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsCntrl\n");
+                   yesno = '!';
+                   what = "Cntrl";
                    break;
                case ANYOF_DIGIT:
                    if (LOC)
@@ -3884,7 +3948,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                        for (value = '0'; value <= '9'; value++)
                            ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsDigit\n");
+                   yesno = '+';
+                   what = "Digit";
                    break;
                case ANYOF_NDIGIT:
                    if (LOC)
@@ -3896,7 +3961,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                        for (value = '9' + 1; value < 256; value++)
                            ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsDigit\n");
+                   yesno = '!';
+                   what = "Digit";
                    break;
                case ANYOF_GRAPH:
                    if (LOC)
@@ -3906,7 +3972,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isGRAPH(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsGraph\n");
+                   yesno = '+';
+                   what = "Graph";
                    break;
                case ANYOF_NGRAPH:
                    if (LOC)
@@ -3916,7 +3983,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isGRAPH(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsGraph\n");
+                   yesno = '!';
+                   what = "Graph";
                    break;
                case ANYOF_LOWER:
                    if (LOC)
@@ -3926,7 +3994,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isLOWER(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsLower\n");
+                   yesno = '+';
+                   what = "Lower";
                    break;
                case ANYOF_NLOWER:
                    if (LOC)
@@ -3936,7 +4005,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isLOWER(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsLower\n");
+                   yesno = '!';
+                   what = "Lower";
                    break;
                case ANYOF_PRINT:
                    if (LOC)
@@ -3946,7 +4016,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isPRINT(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsPrint\n");
+                   yesno = '+';
+                   what = "Print";
                    break;
                case ANYOF_NPRINT:
                    if (LOC)
@@ -3956,7 +4027,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isPRINT(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsPrint\n");
+                   yesno = '!';
+                   what = "Print";
                    break;
                case ANYOF_PSXSPC:
                    if (LOC)
@@ -3966,7 +4038,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isPSXSPC(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsSpace\n");
+                   yesno = '+';
+                   what = "Space";
                    break;
                case ANYOF_NPSXSPC:
                    if (LOC)
@@ -3976,7 +4049,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isPSXSPC(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsSpace\n");
+                   yesno = '!';
+                   what = "Space";
                    break;
                case ANYOF_PUNCT:
                    if (LOC)
@@ -3986,7 +4060,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isPUNCT(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsPunct\n");
+                   yesno = '+';
+                   what = "Punct";
                    break;
                case ANYOF_NPUNCT:
                    if (LOC)
@@ -3996,7 +4071,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isPUNCT(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsPunct\n");
+                   yesno = '!';
+                   what = "Punct";
                    break;
                case ANYOF_SPACE:
                    if (LOC)
@@ -4006,7 +4082,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isSPACE(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsSpacePerl\n");
+                   yesno = '+';
+                   what = "SpacePerl";
                    break;
                case ANYOF_NSPACE:
                    if (LOC)
@@ -4016,7 +4093,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isSPACE(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsSpacePerl\n");
+                   yesno = '!';
+                   what = "SpacePerl";
                    break;
                case ANYOF_UPPER:
                    if (LOC)
@@ -4026,7 +4104,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isUPPER(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsUpper\n");
+                   yesno = '+';
+                   what = "Upper";
                    break;
                case ANYOF_NUPPER:
                    if (LOC)
@@ -4036,7 +4115,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isUPPER(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsUpper\n");
+                   yesno = '!';
+                   what = "Upper";
                    break;
                case ANYOF_XDIGIT:
                    if (LOC)
@@ -4046,7 +4126,8 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (isXDIGIT(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsXDigit\n");
+                   yesno = '+';
+                   what = "XDigit";
                    break;
                case ANYOF_NXDIGIT:
                    if (LOC)
@@ -4056,12 +4137,20 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                            if (!isXDIGIT(value))
                                ANYOF_BITMAP_SET(ret, value);
                    }
-                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsXDigit\n");
+                   yesno = '!';
+                   what = "XDigit";
+                   break;
+               case ANYOF_MAX:
+                   /* this is to handle \p and \P */
                    break;
                default:
                    vFAIL("Invalid [::] class");
                    break;
                }
+               if (what) {
+                   /* Strings such as "+utf8::isWord\n" */
+                   Perl_sv_catpvf(aTHX_ listsv, "%cutf8::Is%s\n", yesno, what);
+               }
                if (LOC)
                    ANYOF_FLAGS(ret) |= ANYOF_CLASS;
                continue;
@@ -4140,7 +4229,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
                else if (prevnatvalue == natvalue) {
                    Perl_sv_catpvf(aTHX_ listsv, "%04"UVxf"\n", natvalue);
                    if (FOLD) {
-                        U8 foldbuf[UTF8_MAXLEN_FOLD+1];
+                        U8 foldbuf[UTF8_MAXBYTES_CASE+1];
                         STRLEN foldlen;
                         UV f = to_uni_fold(natvalue, foldbuf, &foldlen);
 
@@ -4420,6 +4509,7 @@ S_reginsert(pTHX_ RExC_state_t *pRExC_state, U8 op, regnode *opnd)
               RExC_parse - RExC_start,
               RExC_offsets[0])); 
        Set_Node_Offset(place, RExC_parse);
+       Set_Node_Length(place, 1);
     }
     src = NEXTOPER(place);
     FILL_ADVANCE_NODE(place, op);
@@ -4809,7 +4899,7 @@ Perl_regprop(pTHX_ SV *sv, regnode *o)
        
            if (lv) {
                if (sw) {
-                   U8 s[UTF8_MAXLEN+1];
+                   U8 s[UTF8_MAXBYTES_CASE+1];
                
                    for (i = 0; i <= 256; i++) { /* just the first 256 */
                        U8 *e = uvchr_to_utf8(s, i);
@@ -4840,7 +4930,7 @@ Perl_regprop(pTHX_ SV *sv, regnode *o)
                }
 
                {
-                   char *s = savepv(SvPVX(lv));
+                   char *s = savesvpv(lv);
                    char *origs = s;
                
                    while(*s && *s != '\n') s++;
@@ -4941,6 +5031,7 @@ Perl_pregfree(pTHX_ struct regexp *r)
        int n = r->data->count;
        PAD* new_comppad = NULL;
        PAD* old_comppad;
+       PADOFFSET refcnt;
 
        while (--n >= 0) {
           /* If you add a ->what type here, update the comment in regcomp.h */
@@ -4962,9 +5053,11 @@ Perl_pregfree(pTHX_ struct regexp *r)
                    (SvTYPE(new_comppad) == SVt_PVAV) ?
                                new_comppad : Null(PAD *)
                );
-               if (!OpREFCNT_dec((OP_4tree*)r->data->data[n])) {
+               OP_REFCNT_LOCK;
+               refcnt = OpREFCNT_dec((OP_4tree*)r->data->data[n]);
+               OP_REFCNT_UNLOCK;
+               if (!refcnt)
                     op_free((OP_4tree*)r->data->data[n]);
-               }
 
                PAD_RESTORE_LOCAL(old_comppad);
                SvREFCNT_dec((SV*)new_comppad);
@@ -5035,7 +5128,7 @@ S_re_croak2(pTHX_ const char* pat1,const char* pat2,...)
     if (l1 > 512)
        l1 = 512;
     Copy(message, buf, l1 , char);
-    buf[l1] = '\0';                    /* Overwrite \n */
+    buf[l1-1] = '\0';                  /* Overwrite \n */
     Perl_croak(aTHX_ "%s", buf);
 }
 
@@ -5095,7 +5188,7 @@ Perl_save_re_context(pTHX)
        U32 i;
        GV *mgv;
        REGEXP *rx;
-       char digits[16];
+       char digits[TYPE_CHARS(long)];
 
        if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
            for (i = 1; i <= rx->nparens; i++) {
@@ -5117,3 +5210,12 @@ clear_re(pTHX_ void *r)
     ReREFCNT_dec((regexp *)r);
 }
 
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vim: shiftwidth=4:
+*/