[shell changes from patch from perl5.003_23 to perl5.003_24]
[p5sagit/p5-mst-13.2.git] / mg.c
diff --git a/mg.c b/mg.c
index 816b4b8..1359c91 100644 (file)
--- a/mg.c
+++ b/mg.c
 #  endif
 #endif
 
-#define TAINT_FROM_REGEX(sv,rx) \
-       if ((rx)->exec_tainted) \
-           SvTAINTED_on(sv);   \
-       else                    \
-           SvTAINTED_off(sv);
-
 /*
  * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
  */
@@ -287,10 +281,8 @@ MAGIC *mg;
                (t = rx->endp[paren]))
            {
                i = t - s;
-               if (i >= 0) {
-                   TAINT_IF(rx->exec_tainted);
+               if (i >= 0)
                    return i;
-               }
            }
        }
        return 0;
@@ -298,28 +290,26 @@ MAGIC *mg;
     case '+':
        if (curpm && (rx = curpm->op_pmregexp)) {
            paren = rx->lastparen;
-           if (!paren)
-               return 0;
-           goto getparen;
+           if (paren)
+               goto getparen;
        }
        return 0;
        break;
     case '`':
        if (curpm && (rx = curpm->op_pmregexp)) {
-           if ((s = rx->subbeg)) {
+           if ((s = rx->subbeg) && rx->startp[0]) {
                i = rx->startp[0] - s;
-               if (i >= 0) {
-                   TAINT_IF(rx->exec_tainted);
+               if (i >= 0)
                    return i;
-               }
            }
        }
        return 0;
     case '\'':
        if (curpm && (rx = curpm->op_pmregexp)) {
-           if ((s = rx->endp[0])) {
-               TAINT_IF(rx->exec_tainted);
-               return (STRLEN) (rx->subend - s);
+           if (rx->subend && (s = rx->endp[0])) {
+               i = rx->subend - s;
+               if (i >= 0)
+                   return 0;
            }
        }
        return 0;
@@ -416,9 +406,16 @@ MAGIC *mg;
                (t = rx->endp[paren]))
            {
                i = t - s;
+             getrx:
                if (i >= 0) {
+                   bool was_tainted;
+                   if (tainting) {
+                       was_tainted = tainted;
+                       tainted = FALSE;
+                   }
                    sv_setpvn(sv,s,i);
-                   TAINT_FROM_REGEX(sv,rx);
+                   if (tainting)
+                       tainted = was_tainted || rx->exec_tainted;
                    break;
                }
            }
@@ -435,23 +432,18 @@ MAGIC *mg;
        break;
     case '`':
        if (curpm && (rx = curpm->op_pmregexp)) {
-           if ((s = rx->subbeg)) {
+           if ((s = rx->subbeg) && rx->startp[0]) {
                i = rx->startp[0] - s;
-               if (i >= 0) {
-                   sv_setpvn(sv,s,i);
-                   TAINT_FROM_REGEX(sv,rx);
-                   break;
-               }
+               goto getrx;
            }
        }
        sv_setsv(sv,&sv_undef);
        break;
     case '\'':
        if (curpm && (rx = curpm->op_pmregexp)) {
-           if ((s = rx->endp[0])) {
-               sv_setpvn(sv,s, rx->subend - s);
-               TAINT_FROM_REGEX(sv,rx);
-               break;
+           if (rx->subend && (s = rx->endp[0])) {
+               i = rx->subend - s;
+               goto getrx;
            }
        }
        sv_setsv(sv,&sv_undef);
@@ -1005,6 +997,7 @@ MAGIC* mg;
     else if (pos > len)
        pos = len;
     mg->mg_len = pos;
+    mg->mg_flags &= ~MGf_MINMATCH;
 
     return 0;
 }
@@ -1101,6 +1094,65 @@ MAGIC* mg;
 }
 
 int
+magic_getitervar(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+    SV *targ = Nullsv;
+    if (LvTARGLEN(sv)) {
+       AV* av = (AV*)LvTARG(sv);
+       if (LvTARGOFF(sv) <= AvFILL(av))
+           targ = AvARRAY(av)[LvTARGOFF(sv)];
+    }
+    else
+       targ = LvTARG(sv);
+    sv_setsv(sv, targ ? targ : &sv_undef);
+    return 0;
+}
+
+int
+magic_setitervar(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+    if (LvTARGLEN(sv))
+       vivify_itervar(sv);
+    if (LvTARG(sv))
+       sv_setsv(LvTARG(sv), sv);
+    return 0;
+}
+
+int
+magic_freeitervar(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+    SvREFCNT_dec(LvTARG(sv));
+    return 0;
+}
+
+void
+vivify_itervar(sv)
+SV* sv;
+{
+    AV* av;
+
+    if (!LvTARGLEN(sv))
+       return;
+    av = (AV*)LvTARG(sv);
+    if (LvTARGOFF(sv) <= AvFILL(av)) {
+       SV** svp = AvARRAY(av) + LvTARGOFF(sv);
+       LvTARG(sv) = newSVsv(*svp);
+       SvREFCNT_dec(*svp);
+       *svp = SvREFCNT_inc(LvTARG(sv));
+    }
+    else
+       LvTARG(sv) = Nullsv;
+    SvREFCNT_dec(av);
+    LvTARGLEN(sv) = 0;
+}
+
+int
 magic_setmglob(sv,mg)
 SV* sv;
 MAGIC* mg;
@@ -1142,6 +1194,7 @@ MAGIC* mg;
     return 0;
 }
 
+#ifdef USE_LOCALE_COLLATE
 int
 magic_setcollxfrm(sv,mg)
 SV* sv;
@@ -1151,9 +1204,14 @@ MAGIC* mg;
      * RenĂ© Descartes said "I think not."
      * and vanished with a faint plop.
      */
-    sv_unmagic(sv, 'o');
+    if (mg->mg_ptr) {
+       Safefree(mg->mg_ptr);
+       mg->mg_ptr = NULL;
+       mg->mg_len = -1;
+    }
     return 0;
 }
+#endif /* USE_LOCALE_COLLATE */
 
 int
 magic_set(sv,mg)