tweaks for building with -DUSE_ITHREADS on !WIN32 platforms;
[p5sagit/p5-mst-13.2.git] / regcomp.c
index ceab482..0d6b581 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -702,11 +702,7 @@ S_study_chunk(pTHX_ regnode **scanp, I32 *deltap, regnode *last, scan_data_t *da
                    FAIL("variable length lookbehind not implemented");
                }
                else if (minnext > U8_MAX) {
-#ifdef UV_IS_QUAD
-                   FAIL2("lookbehind longer than %" PERL_PRIu64 " not implemented", (UV)U8_MAX);
-#else
-                   FAIL2("lookbehind longer than %d not implemented", U8_MAX);
-#endif
+                   FAIL2("lookbehind longer than %"UVuf" not implemented", (UV)U8_MAX);
                }
                scan->flags = minnext;
            }
@@ -848,7 +844,7 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
     DEBUG_r(if (!PL_colorset) reginitcolors());
     DEBUG_r(PerlIO_printf(Perl_debug_log, "%sCompiling REx%s `%s%*s%s'\n",
                      PL_colors[4],PL_colors[5],PL_colors[0],
-                     xend - exp, PL_regprecomp, PL_colors[1]));
+                     (int)(xend - exp), PL_regprecomp, PL_colors[1]));
     PL_regflags = pm->op_pmflags;
     PL_regsawback = 0;
 
@@ -871,7 +867,7 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
        PL_regprecomp = Nullch;
        return(NULL);
     }
-    DEBUG_r(PerlIO_printf(Perl_debug_log, "size %d ", PL_regsize));
+    DEBUG_r(PerlIO_printf(Perl_debug_log, "size %"IVdf" ", (IV)PL_regsize));
 
     /* Small enough for pointer-storage convention?
        If extralen==0, this means that we will not need long jumps. */
@@ -948,7 +944,12 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
 
        /* Starting-point info. */
       again:
-       if (OP(first) == EXACT);        /* Empty, get anchored substr later. */
+       if (PL_regkind[(U8)OP(first) == EXACT]) {
+           if (OP(first) == EXACT);    /* Empty, get anchored substr later. */
+           else if ((OP(first) == EXACTF || OP(first) == EXACTFL)
+                    && !UTF)
+               r->regstclass = first;
+       }
        else if (strchr((char*)PL_simple+4,OP(first)))
            r->regstclass = first;
        else if (PL_regkind[(U8)OP(first)] == BOUND ||
@@ -990,8 +991,8 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
            r->reganch |= ROPT_SKIP;
 
        /* Scan is after the zeroth branch, first is atomic matcher. */
-       DEBUG_r(PerlIO_printf(Perl_debug_log, "first at %d\n", 
-                             first - scan + 1));
+       DEBUG_r(PerlIO_printf(Perl_debug_log, "first at %"IVdf"\n", 
+                             (IV)(first - scan + 1)));
        /*
        * If there's something expensive in the r.e., find the
        * longest literal string that must appear and make it the
@@ -1080,7 +1081,9 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
            r->check_offset_min = data.offset_float_min;
            r->check_offset_max = data.offset_float_max;
        }
-       if (r->check_substr) {
+       /* XXXX Currently intuiting is not compatible with ANCH_GPOS.
+          This should be changed ASAP!  */
+       if (r->check_substr && !(r->reganch & ROPT_ANCH_GPOS)) {
            r->reganch |= RE_USE_INTUIT;
            if (SvTAIL(r->check_substr))
                r->reganch |= RE_INTUIT_TAIL;
@@ -2024,7 +2027,7 @@ tryagain:
                            if (!e)
                                FAIL("Missing right brace on \\x{}");
                            else if (UTF) {
-                               ender = scan_hex(p + 1, e - p, &numlen);
+                               ender = (UV)scan_hex(p + 1, e - p, &numlen);
                                if (numlen + len >= 127) {      /* numlen is generous */
                                    p--;
                                    goto loopdone;
@@ -2035,7 +2038,7 @@ tryagain:
                                FAIL("Can't use \\x{} without 'use utf8' declaration");
                        }
                        else {
-                           ender = scan_hex(p, 2, &numlen);
+                           ender = (UV)scan_hex(p, 2, &numlen);
                            p += numlen;
                        }
                        break;
@@ -2048,7 +2051,7 @@ tryagain:
                    case '5': case '6': case '7': case '8':case '9':
                        if (*p == '0' ||
                          (isDIGIT(p[1]) && atoi(p) >= PL_regnpar) ) {
-                           ender = scan_oct(p, 3, &numlen);
+                           ender = (UV)scan_oct(p, 3, &numlen);
                            p += numlen;
                        }
                        else {
@@ -2063,9 +2066,9 @@ tryagain:
                    default:
                        if (!SIZE_ONLY && ckWARN(WARN_UNSAFE) && isALPHA(*p))
                            Perl_warner(aTHX_ WARN_UNSAFE, 
-                                  "/%.127s/: Unrecognized escape \\%c passed through",
-                                  PL_regprecomp,
-                                  *p);
+                                       "/%.127s/: Unrecognized escape \\%c passed through",
+                                       PL_regprecomp,
+                                       *p);
                        goto normal_default;
                    }
                    break;
@@ -2158,7 +2161,7 @@ S_regpposixcc(pTHX_ I32 value)
 {
     dTHR;
     char *posixcc = 0;
-    I32 namedclass = -1;
+    I32 namedclass = OOB_NAMEDCLASS;
 
     if (value == '[' && PL_regcomp_parse + 1 < PL_regxend &&
        /* I smell either [: or [= or [. -- POSIX has been here, right? */
@@ -2271,7 +2274,7 @@ S_regpposixcc(pTHX_ I32 value)
 STATIC void
 S_checkposixcc(pTHX)
 {
-    if (ckWARN(WARN_UNSAFE) && !SIZE_ONLY &&
+    if (!SIZE_ONLY && ckWARN(WARN_UNSAFE) &&
        (*PL_regcomp_parse == ':' ||
         *PL_regcomp_parse == '=' ||
         *PL_regcomp_parse == '.')) {
@@ -2294,43 +2297,45 @@ STATIC regnode *
 S_regclass(pTHX)
 {
     dTHR;
-    register char *opnd, *s;
-    register I32 value;
+    register UV value;
     register I32 lastvalue = OOB_CHAR8;
     register I32 range = 0;
     register regnode *ret;
     register I32 def;
     I32 numlen;
     I32 namedclass;
+    char *rangebegin;
+    bool need_class = 0;
 
-    s = opnd = MASK(PL_regcode);
     ret = reg_node(ANYOF);
-    for (value = 0; value < ANYOF_SIZE; value++)
-       REGC(0, s++);
+    if (SIZE_ONLY)
+       PL_regsize += ANYOF_SKIP;
+    else {
+       ret->flags = 0;
+       ANYOF_BITMAP_ZERO(ret);
+       PL_regcode += ANYOF_SKIP;
+       if (FOLD)
+           ANYOF_FLAGS(ret) |= ANYOF_FOLD;
+       if (LOC)
+           ANYOF_FLAGS(ret) |= ANYOF_LOCALE;
+    }
     if (*PL_regcomp_parse == '^') {    /* Complement of range. */
        PL_regnaughty++;
        PL_regcomp_parse++;
        if (!SIZE_ONLY)
-           ANYOF_FLAGS(opnd) |= ANYOF_INVERT;
-    }
-    if (!SIZE_ONLY) {
-       PL_regcode += ANY_SKIP;
-       if (FOLD)
-           ANYOF_FLAGS(opnd) |= ANYOF_FOLD;
-       if (LOC)
-           ANYOF_FLAGS(opnd) |= ANYOF_LOCALE;
-    }
-    else {
-       PL_regsize += ANY_SKIP;
+           ANYOF_FLAGS(ret) |= ANYOF_INVERT;
     }
 
-    checkposixcc();
+    if (!SIZE_ONLY && ckWARN(WARN_UNSAFE))
+       checkposixcc();
 
     if (*PL_regcomp_parse == ']' || *PL_regcomp_parse == '-')
        goto skipcond;          /* allow 1st char to be ] or - */
     while (PL_regcomp_parse < PL_regxend && *PL_regcomp_parse != ']') {
        skipcond:
        namedclass = OOB_NAMEDCLASS;
+       if (!range)
+           rangebegin = PL_regcomp_parse;
        value = UCHARAT(PL_regcomp_parse++);
        if (value == '[')
            namedclass = regpposixcc(value);
@@ -2351,7 +2356,7 @@ S_regclass(pTHX)
            case 'e':   value = '\033';                 break;
            case 'a':   value = '\007';                 break;
            case 'x':
-               value = scan_hex(PL_regcomp_parse, 2, &numlen);
+               value = (UV)scan_hex(PL_regcomp_parse, 2, &numlen);
                PL_regcomp_parse += numlen;
                break;
            case 'c':
@@ -2360,269 +2365,320 @@ S_regclass(pTHX)
                break;
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
-               value = scan_oct(--PL_regcomp_parse, 3, &numlen);
+               value = (UV)scan_oct(--PL_regcomp_parse, 3, &numlen);
                PL_regcomp_parse += numlen;
                break;
+           default:
+               if (!SIZE_ONLY && ckWARN(WARN_UNSAFE) && isALPHA(value))
+                   Perl_warner(aTHX_ WARN_UNSAFE, 
+                               "/%.127s/: Unrecognized escape \\%c in character class passed through",
+                               PL_regprecomp,
+                               value);
+               break;
            }
        }
-       if (!SIZE_ONLY && namedclass > OOB_NAMEDCLASS) {
-           if (range)
-               FAIL("invalid [] range in regexp"); /* [a-\w], [a-[:word:]] */
-           switch (namedclass) {
-           case ANYOF_ALNUM:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_ALNUM);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isALNUM(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NALNUM:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NALNUM);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isALNUM(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_SPACE:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_SPACE);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isSPACE(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NSPACE:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NSPACE);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isSPACE(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_DIGIT:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_DIGIT);
-               else {
-                   for (value = '0'; value <= '9'; value++)
-                       ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NDIGIT:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NDIGIT);
-               else {
-                   for (value = 0; value < '0'; value++)
-                       ANYOF_BITMAP_SET(opnd, value);
-                   for (value = '9' + 1; value < 256; value++)
-                       ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NALNUMC:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NALNUMC);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isALNUMC(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_ALNUMC:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_ALNUMC);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isALNUMC(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_ALPHA:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_ALPHA);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isALPHA(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NALPHA:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NALPHA);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isALPHA(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_ASCII:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_ASCII);
-               else {
-                   for (value = 0; value < 128; value++)
-                       ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NASCII:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NASCII);
-               else {
-                   for (value = 128; value < 256; value++)
-                       ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_CNTRL:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_CNTRL);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isCNTRL(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               lastvalue = OOB_CHAR8;
-               break;
-           case ANYOF_NCNTRL:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NCNTRL);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isCNTRL(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_GRAPH:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_GRAPH);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isGRAPH(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NGRAPH:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NGRAPH);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isGRAPH(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_LOWER:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_LOWER);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isLOWER(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NLOWER:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NLOWER);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isLOWER(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_PRINT:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_PRINT);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isPRINT(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NPRINT:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NPRINT);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isPRINT(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_PUNCT:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_PUNCT);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isPUNCT(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NPUNCT:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NPUNCT);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isPUNCT(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_UPPER:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_UPPER);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isUPPER(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_NUPPER:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NUPPER);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isUPPER(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           case ANYOF_XDIGIT:
-               if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_XDIGIT);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (isXDIGIT(value))
-                           ANYOF_BITMAP_SET(opnd, value);
+       if (namedclass > OOB_NAMEDCLASS) {
+           if (!need_class && !SIZE_ONLY)
+               ANYOF_CLASS_ZERO(ret);
+           need_class = 1;
+           if (range) { /* a-\d, a-[:digit:] */
+               if (!SIZE_ONLY) {
+                   if (ckWARN(WARN_UNSAFE))
+                       Perl_warner(aTHX_ WARN_UNSAFE,
+                                   "/%.127s/: false [] range \"%*.*s\" in regexp",
+                                   PL_regprecomp,
+                                   PL_regcomp_parse - rangebegin,
+                                   PL_regcomp_parse - rangebegin,
+                                   rangebegin);
+                   ANYOF_BITMAP_SET(ret, lastvalue);
+                   ANYOF_BITMAP_SET(ret, '-');
+               }
+               range = 0; /* this is not a true range */
+           }
+           if (!SIZE_ONLY) {
+               switch (namedclass) {
+               case ANYOF_ALNUM:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_ALNUM);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isALNUM(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NALNUM:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NALNUM);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isALNUM(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_SPACE:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_SPACE);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isSPACE(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NSPACE:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NSPACE);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isSPACE(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_DIGIT:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_DIGIT);
+                   else {
+                       for (value = '0'; value <= '9'; value++)
+                           ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NDIGIT:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NDIGIT);
+                   else {
+                       for (value = 0; value < '0'; value++)
+                           ANYOF_BITMAP_SET(ret, value);
+                       for (value = '9' + 1; value < 256; value++)
+                           ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NALNUMC:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NALNUMC);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isALNUMC(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_ALNUMC:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_ALNUMC);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isALNUMC(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_ALPHA:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_ALPHA);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isALPHA(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NALPHA:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NALPHA);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isALPHA(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_ASCII:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_ASCII);
+                   else {
+#ifdef ASCIIish
+                       for (value = 0; value < 128; value++)
+                           ANYOF_BITMAP_SET(ret, value);
+#else  /* EBCDIC */
+                       for (value = 0; value < 256; value++)
+                           if (isASCII(value))
+                               ANYOF_BITMAP_SET(ret, value);
+#endif /* EBCDIC */
+                   }
+                   break;
+               case ANYOF_NASCII:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NASCII);
+                   else {
+#ifdef ASCIIish
+                       for (value = 128; value < 256; value++)
+                           ANYOF_BITMAP_SET(ret, value);
+#else  /* EBCDIC */
+                       for (value = 0; value < 256; value++)
+                           if (!isASCII(value))
+                               ANYOF_BITMAP_SET(ret, value);
+#endif /* EBCDIC */
+                   }
+                   break;
+               case ANYOF_CNTRL:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_CNTRL);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isCNTRL(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   lastvalue = OOB_CHAR8;
+                   break;
+               case ANYOF_NCNTRL:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NCNTRL);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isCNTRL(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_GRAPH:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_GRAPH);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isGRAPH(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NGRAPH:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NGRAPH);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isGRAPH(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_LOWER:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_LOWER);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isLOWER(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NLOWER:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NLOWER);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isLOWER(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_PRINT:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_PRINT);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isPRINT(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NPRINT:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NPRINT);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isPRINT(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_PUNCT:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_PUNCT);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isPUNCT(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NPUNCT:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NPUNCT);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isPUNCT(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_UPPER:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_UPPER);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isUPPER(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NUPPER:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NUPPER);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isUPPER(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_XDIGIT:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_XDIGIT);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (isXDIGIT(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               case ANYOF_NXDIGIT:
+                   if (LOC)
+                       ANYOF_CLASS_SET(ret, ANYOF_NXDIGIT);
+                   else {
+                       for (value = 0; value < 256; value++)
+                           if (!isXDIGIT(value))
+                               ANYOF_BITMAP_SET(ret, value);
+                   }
+                   break;
+               default:
+                   FAIL("invalid [::] class in regexp");
+                   break;
                }
-               break;
-           case ANYOF_NXDIGIT:
                if (LOC)
-                   ANYOF_CLASS_SET(opnd, ANYOF_NXDIGIT);
-               else {
-                   for (value = 0; value < 256; value++)
-                       if (!isXDIGIT(value))
-                           ANYOF_BITMAP_SET(opnd, value);
-               }
-               break;
-           default:
-               FAIL("invalid [::] class in regexp");
-               break;
+                   ANYOF_FLAGS(ret) |= ANYOF_CLASS;
+               continue;
            }
-           if (LOC)
-               ANYOF_FLAGS(opnd) |= ANYOF_CLASS;
-           continue;
        }
        if (range) {
-           if (lastvalue > value)
-               FAIL("invalid [] range in regexp"); /* [b-a] */
+           if (lastvalue > value) /* b-a */ {
+               Perl_croak(aTHX_
+                          "/%.127s/: invalid [] range \"%*.*s\" in regexp",
+                          PL_regprecomp,
+                          PL_regcomp_parse - rangebegin,
+                          PL_regcomp_parse - rangebegin,
+                          rangebegin);
+           }
            range = 0;
        }
        else {
            lastvalue = value;
            if (*PL_regcomp_parse == '-' && PL_regcomp_parse+1 < PL_regxend &&
                PL_regcomp_parse[1] != ']') {
-               if (namedclass > OOB_NAMEDCLASS)
-                   FAIL("invalid [] range in regexp"); /* [\w-a] */
                PL_regcomp_parse++;
-               range = 1;
+               if (namedclass > OOB_NAMEDCLASS) { /* \w-, [:word:]- */
+                   if (ckWARN(WARN_UNSAFE))
+                       Perl_warner(aTHX_ WARN_UNSAFE,
+                                   "/%.127s/: false [] range \"%*.*s\" in regexp",
+                                   PL_regprecomp,
+                                   PL_regcomp_parse - rangebegin,
+                                   PL_regcomp_parse - rangebegin,
+                                   rangebegin);
+                   if (!SIZE_ONLY)
+                       ANYOF_BITMAP_SET(ret, '-');
+               } else
+                   range = 1;
                continue;       /* do it next time */
            }
        }
@@ -2636,36 +2692,42 @@ S_regclass(pTHX)
                if (isLOWER(lastvalue)) {
                    for (i = lastvalue; i <= value; i++)
                        if (isLOWER(i))
-                           ANYOF_BITMAP_SET(opnd, i);
+                           ANYOF_BITMAP_SET(ret, i);
                } else {
                    for (i = lastvalue; i <= value; i++)
                        if (isUPPER(i))
-                           ANYOF_BITMAP_SET(opnd, i);
+                           ANYOF_BITMAP_SET(ret, i);
                }
            }
            else
 #endif
                for ( ; lastvalue <= value; lastvalue++)
-                   ANYOF_BITMAP_SET(opnd, lastvalue);
+                   ANYOF_BITMAP_SET(ret, lastvalue);
         }
        range = 0;
     }
+    if (need_class) {
+       if (SIZE_ONLY)
+           PL_regsize += ANYOF_CLASS_ADD_SKIP;
+       else
+           PL_regcode += ANYOF_CLASS_ADD_SKIP;
+    }
     /* optimize case-insensitive simple patterns (e.g. /[a-z]/i) */
     if (!SIZE_ONLY &&
-       (ANYOF_FLAGS(opnd) & (ANYOF_FLAGS_ALL ^ ANYOF_INVERT)) == ANYOF_FOLD) {
+       (ANYOF_FLAGS(ret) & (ANYOF_FLAGS_ALL ^ ANYOF_INVERT)) == ANYOF_FOLD) {
        for (value = 0; value < 256; ++value) {
-           if (ANYOF_BITMAP_TEST(opnd, value)) {
+           if (ANYOF_BITMAP_TEST(ret, value)) {
                I32 cf = PL_fold[value];
-               ANYOF_BITMAP_SET(opnd, cf);
+               ANYOF_BITMAP_SET(ret, cf);
            }
        }
-       ANYOF_FLAGS(opnd) &= ~ANYOF_FOLD;
+       ANYOF_FLAGS(ret) &= ~ANYOF_FOLD;
     }
     /* optimize inverted simple patterns (e.g. [^a-z]) */
-    if (!SIZE_ONLY && (ANYOF_FLAGS(opnd) & ANYOF_FLAGS_ALL) == ANYOF_INVERT) {
+    if (!SIZE_ONLY && (ANYOF_FLAGS(ret) & ANYOF_FLAGS_ALL) == ANYOF_INVERT) {
        for (value = 0; value < ANYOF_BITMAP_SIZE; ++value)
-           opnd[ANYOF_BITMAP_OFFSET + value] ^= ANYOF_FLAGS_ALL;
-       ANYOF_FLAGS(opnd) = 0;
+           ANYOF_BITMAP(ret)[value] ^= ANYOF_FLAGS_ALL;
+       ANYOF_FLAGS(ret) = 0;
     }
     return ret;
 }
@@ -2674,8 +2736,8 @@ STATIC regnode *
 S_regclassutf8(pTHX)
 {
     dTHR;
-    register char *opnd, *e;
-    register U32 value;
+    register char *e;
+    register UV value;
     register U32 lastvalue = OOB_UTF8;
     register I32 range = 0;
     register regnode *ret;
@@ -2684,6 +2746,7 @@ S_regclassutf8(pTHX)
     SV *listsv;
     U8 flags = 0;
     I32 namedclass;
+    char *rangebegin;
 
     if (*PL_regcomp_parse == '^') {    /* Complement of range. */
        PL_regnaughty++;
@@ -2699,7 +2762,8 @@ S_regclassutf8(pTHX)
        listsv = newSVpvn("# comment\n",10);
     }
 
-    checkposixcc();
+    if (!SIZE_ONLY && ckWARN(WARN_UNSAFE))
+       checkposixcc();
 
     if (*PL_regcomp_parse == ']' || *PL_regcomp_parse == '-')
        goto skipcond;          /* allow 1st char to be ] or - */
@@ -2707,9 +2771,10 @@ S_regclassutf8(pTHX)
     while (PL_regcomp_parse < PL_regxend && *PL_regcomp_parse != ']') {
        skipcond:
        namedclass = OOB_NAMEDCLASS;
+       if (!range)
+           rangebegin = PL_regcomp_parse;
        value = utf8_to_uv((U8*)PL_regcomp_parse, &numlen);
        PL_regcomp_parse += numlen;
-
        if (value == '[')
            namedclass = regpposixcc(value);
        else if (value == '\\') {
@@ -2757,13 +2822,13 @@ S_regclassutf8(pTHX)
                    e = strchr(PL_regcomp_parse++, '}');
                     if (!e)
                         FAIL("Missing right brace on \\x{}");
-                   value = scan_hex(PL_regcomp_parse,
+                   value = (UV)scan_hex(PL_regcomp_parse,
                                     e - PL_regcomp_parse,
                                     &numlen);
                    PL_regcomp_parse = e + 1;
                }
                else {
-                   value = scan_hex(PL_regcomp_parse, 2, &numlen);
+                   value = (UV)scan_hex(PL_regcomp_parse, 2, &numlen);
                    PL_regcomp_parse += numlen;
                }
                break;
@@ -2773,101 +2838,129 @@ S_regclassutf8(pTHX)
                break;
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
-               value = scan_oct(--PL_regcomp_parse, 3, &numlen);
+               value = (UV)scan_oct(--PL_regcomp_parse, 3, &numlen);
                PL_regcomp_parse += numlen;
                break;
+           default:
+               if (!SIZE_ONLY && ckWARN(WARN_UNSAFE) && isALPHA(value))
+                   Perl_warner(aTHX_ WARN_UNSAFE, 
+                               "/%.127s/: Unrecognized escape \\%c in character class passed through",
+                               PL_regprecomp,
+                               value);
+               break;
            }
        }
-       if (!SIZE_ONLY && namedclass > OOB_NAMEDCLASS) {
-           if (range)
-               FAIL("invalid [] range in regexp"); /* [a-\w], [a-[:word:]] */
-           switch (namedclass) {
-           case ANYOF_ALNUM:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsWord\n");        break;
-           case ANYOF_NALNUM:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsWord\n");        break;
-           case ANYOF_ALNUMC:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsAlnum\n");       break;
-           case ANYOF_NALNUMC:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsAlnum\n");       break;
-           case ANYOF_ALPHA:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsAlpha\n");       break;
-           case ANYOF_NALPHA:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsAlpha\n");       break;
-           case ANYOF_ASCII:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsASCII\n");       break;
-           case ANYOF_NASCII:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsASCII\n");       break;
-           case ANYOF_CNTRL:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsCntrl\n");       break;
-           case ANYOF_NCNTRL:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsCntrl\n");       break;
-           case ANYOF_GRAPH:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsGraph\n");       break;
-           case ANYOF_NGRAPH:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsGraph\n");       break;
-           case ANYOF_DIGIT:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsDigit\n");       break;
-           case ANYOF_NDIGIT:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsDigit\n");       break;
-           case ANYOF_LOWER:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsLower\n");       break;
-           case ANYOF_NLOWER:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsLower\n");       break;
-           case ANYOF_PRINT:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsPrint\n");       break;
-           case ANYOF_NPRINT:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsPrint\n");       break;
-           case ANYOF_PUNCT:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsPunct\n");       break;
-           case ANYOF_NPUNCT:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsPunct\n");       break;
-           case ANYOF_SPACE:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsSpace\n");       break;
-           case ANYOF_NSPACE:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsSpace\n");       break;
-           case ANYOF_UPPER:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsUpper\n");       break;
-           case ANYOF_NUPPER:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsUpper\n");       break;
-           case ANYOF_XDIGIT:
-               Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsXDigit\n");      break;
-           case ANYOF_NXDIGIT:
-               Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsXDigit\n");      break;
+       if (namedclass > OOB_NAMEDCLASS) {
+           if (range) { /* a-\d, a-[:digit:] */
+               if (!SIZE_ONLY) {
+                   if (ckWARN(WARN_UNSAFE))
+                       Perl_warner(aTHX_ WARN_UNSAFE,
+                                   "/%.127s/: false [] range \"%*.*s\" in regexp",
+                                   PL_regprecomp,
+                                   PL_regcomp_parse - rangebegin,
+                                   PL_regcomp_parse - rangebegin,
+                                   rangebegin);
+                   Perl_sv_catpvf(aTHX_ listsv,
+                                  /* 0x002D is Unicode for '-' */
+                                  "%04"UVxf"\n002D\n", (UV)lastvalue);
+               }
+               range = 0;
+           }
+           if (!SIZE_ONLY) {
+               switch (namedclass) {
+               case ANYOF_ALNUM:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsWord\n");    break;
+               case ANYOF_NALNUM:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsWord\n");    break;
+               case ANYOF_ALNUMC:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsAlnum\n");   break;
+               case ANYOF_NALNUMC:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsAlnum\n");   break;
+               case ANYOF_ALPHA:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsAlpha\n");   break;
+               case ANYOF_NALPHA:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsAlpha\n");   break;
+               case ANYOF_ASCII:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsASCII\n");   break;
+               case ANYOF_NASCII:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsASCII\n");   break;
+               case ANYOF_CNTRL:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsCntrl\n");   break;
+               case ANYOF_NCNTRL:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsCntrl\n");   break;
+               case ANYOF_GRAPH:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsGraph\n");   break;
+               case ANYOF_NGRAPH:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsGraph\n");   break;
+               case ANYOF_DIGIT:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsDigit\n");   break;
+               case ANYOF_NDIGIT:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsDigit\n");   break;
+               case ANYOF_LOWER:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsLower\n");   break;
+               case ANYOF_NLOWER:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsLower\n");   break;
+               case ANYOF_PRINT:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsPrint\n");   break;
+               case ANYOF_NPRINT:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsPrint\n");   break;
+               case ANYOF_PUNCT:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsPunct\n");   break;
+               case ANYOF_NPUNCT:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsPunct\n");   break;
+               case ANYOF_SPACE:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsSpace\n");   break;
+               case ANYOF_NSPACE:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsSpace\n");   break;
+               case ANYOF_UPPER:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsUpper\n");   break;
+               case ANYOF_NUPPER:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsUpper\n");   break;
+               case ANYOF_XDIGIT:
+                   Perl_sv_catpvf(aTHX_ listsv, "+utf8::IsXDigit\n");  break;
+               case ANYOF_NXDIGIT:
+                   Perl_sv_catpvf(aTHX_ listsv, "!utf8::IsXDigit\n");  break;
+               }
+               continue;
            }
-           continue;
        }
         if (range) {
-           if (lastvalue > value)
-               FAIL("invalid [] range in regexp"); /* [b-a] */
-#ifdef UV_IS_QUAD
-           if (!SIZE_ONLY)
-                Perl_sv_catpvf(aTHX_ listsv, "%04" PERL_PRIx64 "\t%04" PERL_PRIx64 "\n", (UV)lastvalue, (UV)value);
-#else
-           if (!SIZE_ONLY)
-               Perl_sv_catpvf(aTHX_ listsv, "%04x\t%04x\n", lastvalue, value);
-#endif
+           if (lastvalue > value) { /* b-a */
+               Perl_croak(aTHX_
+                          "/%.127s/: invalid [] range \"%*.*s\" in regexp",
+                          PL_regprecomp,
+                          PL_regcomp_parse - rangebegin,
+                          PL_regcomp_parse - rangebegin,
+                          rangebegin);
+           }
            range = 0;
        }
        else {
            lastvalue = value;
            if (*PL_regcomp_parse == '-' && PL_regcomp_parse+1 < PL_regxend &&
                PL_regcomp_parse[1] != ']') {
-               if (namedclass > OOB_NAMEDCLASS)
-                   FAIL("invalid [] range in regexp"); /* [\w-a] */
                PL_regcomp_parse++;
-               range = 1;
+               if (namedclass > OOB_NAMEDCLASS) { /* \w-, [:word:]- */
+                   if (ckWARN(WARN_UNSAFE))
+                       Perl_warner(aTHX_ WARN_UNSAFE,
+                                   "/%.127s/: false [] range \"%*.*s\" in regexp",
+                                   PL_regprecomp,
+                                   PL_regcomp_parse - rangebegin,
+                                   PL_regcomp_parse - rangebegin,
+                                   rangebegin);
+                   if (!SIZE_ONLY)
+                       Perl_sv_catpvf(aTHX_ listsv,
+                                      /* 0x002D is Unicode for '-' */
+                                      "002D\n");
+               } else
+                   range = 1;
                continue;       /* do it next time */
            }
        }
        /* now is the next time */
-#ifdef UV_IS_QUAD
-       if (!SIZE_ONLY)
-           Perl_sv_catpvf(aTHX_ listsv, "%04" PERL_PRIx64 "\n", (UV)value);
-#else
        if (!SIZE_ONLY)
-           Perl_sv_catpvf(aTHX_ listsv, "%04x\n", value);
-#endif
+           Perl_sv_catpvf(aTHX_ listsv, "%04"UVxf"\t%04"UVxf"\n",
+                          (UV)lastvalue, (UV)value);
        range = 0;
     }
 
@@ -3106,12 +3199,12 @@ S_dumpuntil(pTHX_ regnode *start, regnode *node, regnode *last, SV* sv, I32 l)
        if (OP(node) == OPTIMIZED)
            goto after_print;
        regprop(sv, node);
-       PerlIO_printf(Perl_debug_log, "%4d:%*s%s", node - start, 
-                     2*l + 1, "", SvPVX(sv));
+       PerlIO_printf(Perl_debug_log, "%4"IVdf":%*s%s", (IV)(node - start),
+                     (int)(2*l + 1), "", SvPVX(sv));
        if (next == NULL)               /* Next ptr. */
            PerlIO_printf(Perl_debug_log, "(0)");
        else 
-           PerlIO_printf(Perl_debug_log, "(%d)", next - start);
+           PerlIO_printf(Perl_debug_log, "(%"IVdf")", (IV)(next - start));
        (void)PerlIO_putc(Perl_debug_log, '\n');
       after_print:
        if (PL_regkind[(U8)op] == BRANCHJ) {
@@ -3138,7 +3231,7 @@ S_dumpuntil(pTHX_ regnode *start, regnode *node, regnode *last, SV* sv, I32 l)
        }
        else if (op == ANYOF) {
            node = NEXTOPER(node);
-           node += ANY_SKIP;
+           node += ANYOF_SKIP;
        }
        else if (PL_regkind[(U8)op] == EXACT) {
             /* Literal string, where present. */
@@ -3172,21 +3265,23 @@ Perl_regdump(pTHX_ regexp *r)
 
     /* Header fields of interest. */
     if (r->anchored_substr)
-       PerlIO_printf(Perl_debug_log, "anchored `%s%.*s%s'%s at %d ", 
+       PerlIO_printf(Perl_debug_log,
+                     "anchored `%s%.*s%s'%s at %"IVdf" ", 
                      PL_colors[0],
-                     SvCUR(r->anchored_substr) - (SvTAIL(r->anchored_substr)!=0),
+                     (int)(SvCUR(r->anchored_substr) - (SvTAIL(r->anchored_substr)!=0)),
                      SvPVX(r->anchored_substr), 
                      PL_colors[1],
                      SvTAIL(r->anchored_substr) ? "$" : "",
-                     r->anchored_offset);
+                     (IV)r->anchored_offset);
     if (r->float_substr)
-       PerlIO_printf(Perl_debug_log, "floating `%s%.*s%s'%s at %d..%u ", 
+       PerlIO_printf(Perl_debug_log,
+                     "floating `%s%.*s%s'%s at %"IVdf"..%"UVuf" ", 
                      PL_colors[0],
-                     SvCUR(r->float_substr) - (SvTAIL(r->float_substr)!=0), 
+                     (int)(SvCUR(r->float_substr) - (SvTAIL(r->float_substr)!=0)), 
                      SvPVX(r->float_substr),
                      PL_colors[1],
                      SvTAIL(r->float_substr) ? "$" : "",
-                     r->float_min_offset, r->float_max_offset);
+                     (IV)r->float_min_offset, (UV)r->float_max_offset);
     if (r->check_substr)
        PerlIO_printf(Perl_debug_log, 
                      r->check_substr == r->float_substr 
@@ -3245,7 +3340,7 @@ Perl_regprop(pTHX_ SV *sv, regnode *o)
     k = PL_regkind[(U8)OP(o)];
 
     if (k == EXACT)
-       Perl_sv_catpvf(aTHX_ sv, " <%s%*s%s>", PL_colors[0],
+       Perl_sv_catpvf(aTHX_ sv, " <%s%.*s%s>", PL_colors[0],
                       STR_LEN(o), STRING(o), PL_colors[1]);
     else if (k == CURLY) {
        if (OP(o) == CURLYM || OP(o) == CURLYN)
@@ -3287,6 +3382,9 @@ Perl_pregfree(pTHX_ struct regexp *r)
 {
     dTHR;
     DEBUG_r(if (!PL_colorset) reginitcolors());
+
+    if (!r || (--r->refcnt > 0))
+       return;
     DEBUG_r(PerlIO_printf(Perl_debug_log,
                      "%sFreeing REx:%s `%s%.60s%s%s'\n",
                      PL_colors[4],PL_colors[5],PL_colors[0],
@@ -3294,9 +3392,6 @@ Perl_pregfree(pTHX_ struct regexp *r)
                      PL_colors[1],
                      (strlen(r->precomp) > 60 ? "..." : "")));
 
-
-    if (!r || (--r->refcnt > 0))
-       return;
     if (r->precomp)
        Safefree(r->precomp);
     if (RX_MATCH_COPIED(r))
@@ -3419,46 +3514,45 @@ Perl_save_re_context(pTHX)
     SAVEPPTR(PL_reginput);             /* String-input pointer. */
     SAVEPPTR(PL_regbol);               /* Beginning of input, for ^ check. */
     SAVEPPTR(PL_regeol);               /* End of input, for $ check. */
-    SAVESPTR(PL_regstartp);            /* Pointer to startp array. */
-    SAVESPTR(PL_regendp);              /* Ditto for endp. */
-    SAVESPTR(PL_reglastparen);         /* Similarly for lastparen. */
+    SAVEVPTR(PL_regstartp);            /* Pointer to startp array. */
+    SAVEVPTR(PL_regendp);              /* Ditto for endp. */
+    SAVEVPTR(PL_reglastparen);         /* Similarly for lastparen. */
     SAVEPPTR(PL_regtill);              /* How far we are required to go. */
     SAVEI32(PL_regprev);               /* char before regbol, \n if none */
-    SAVESPTR(PL_reg_start_tmp);                /* from regexec.c */
+    SAVEVPTR(PL_reg_start_tmp);                /* from regexec.c */
     PL_reg_start_tmp = 0;
     SAVEFREEPV(PL_reg_start_tmp);
     SAVEI32(PL_reg_start_tmpl);                /* from regexec.c */
     PL_reg_start_tmpl = 0;
-    SAVESPTR(PL_regdata);
+    SAVEVPTR(PL_regdata);
     SAVEI32(PL_reg_flags);             /* from regexec.c */
     SAVEI32(PL_reg_eval_set);          /* from regexec.c */
     SAVEI32(PL_regnarrate);            /* from regexec.c */
-    SAVESPTR(PL_regprogram);           /* from regexec.c */
+    SAVEVPTR(PL_regprogram);           /* from regexec.c */
     SAVEINT(PL_regindent);             /* from regexec.c */
-    SAVESPTR(PL_regcc);                        /* from regexec.c */
-    SAVESPTR(PL_curcop);
-    SAVESPTR(PL_regcomp_rx);           /* from regcomp.c */
+    SAVEVPTR(PL_regcc);                        /* from regexec.c */
+    SAVEVPTR(PL_curcop);
+    SAVEVPTR(PL_regcomp_rx);           /* from regcomp.c */
     SAVEI32(PL_regseen);               /* from regcomp.c */
     SAVEI32(PL_regsawback);            /* Did we see \1, ...? */
     SAVEI32(PL_regnaughty);            /* How bad is this pattern? */
-    SAVESPTR(PL_regcode);              /* Code-emit pointer; &regdummy = don't */
+    SAVEVPTR(PL_regcode);              /* Code-emit pointer; &regdummy = don't */
     SAVEPPTR(PL_regxend);              /* End of input for compile */
     SAVEPPTR(PL_regcomp_parse);                /* Input-scan pointer. */
-    SAVESPTR(PL_reg_call_cc);          /* from regexec.c */
-    SAVESPTR(PL_reg_re);               /* from regexec.c */
+    SAVEVPTR(PL_reg_call_cc);          /* from regexec.c */
+    SAVEVPTR(PL_reg_re);               /* from regexec.c */
     SAVEPPTR(PL_reg_ganch);            /* from regexec.c */
     SAVESPTR(PL_reg_sv);               /* from regexec.c */
-    SAVESPTR(PL_reg_magic);            /* from regexec.c */
+    SAVEVPTR(PL_reg_magic);            /* from regexec.c */
     SAVEI32(PL_reg_oldpos);                    /* from regexec.c */
-    SAVESPTR(PL_reg_oldcurpm);         /* from regexec.c */
-    SAVESPTR(PL_reg_curpm);            /* from regexec.c */
+    SAVEVPTR(PL_reg_oldcurpm);         /* from regexec.c */
+    SAVEVPTR(PL_reg_curpm);            /* from regexec.c */
 #ifdef DEBUGGING
     SAVEPPTR(PL_reg_starttry);         /* from regexec.c */    
 #endif
 }
 
 #ifdef PERL_OBJECT
-#define NO_XSLOCKS
 #include "XSUB.h"
 #undef this
 #define this pPerl