Porting/Maintainers.pl
[p5sagit/p5-mst-13.2.git] / pp.c
diff --git a/pp.c b/pp.c
index 02e530f..3e22feb 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -416,7 +416,7 @@ PP(pp_prototype)
                char str[ MAX_ARGS_OP * 2 + 2 ]; /* One ';', one '\0' */
 
                if (code == -KEY_chop || code == -KEY_chomp
-                       || code == -KEY_exec || code == -KEY_system || code == -KEY_err)
+                       || code == -KEY_exec || code == -KEY_system)
                    goto set;
                if (code == -KEY_mkdir) {
                    ret = sv_2mortal(newSVpvs("_;$"));
@@ -2874,22 +2874,40 @@ PP(pp_int)
 {
     dVAR; dSP; dTARGET; tryAMAGICun(int);
     {
-      const IV iv = TOPi; /* attempt to convert to IV if possible. */
+      SV *sv = TOPs;
+      IV iv;
       /* XXX it's arguable that compiler casting to IV might be subtly
         different from modf (for numbers inside (IV_MIN,UV_MAX)) in which
         else preferring IV has introduced a subtle behaviour change bug. OTOH
         relying on floating point to be accurate is a bug.  */
 
-      if (!SvOK(TOPs))
+      while (SvAMAGIC(sv)) {
+       SV *tsv = AMG_CALLun(sv,numer);
+       if (!tsv)
+           break;
+       if (SvROK(tsv) && SvRV(tsv) == SvRV(sv)) {
+           SETi(PTR2IV(SvRV(sv)));
+           RETURN;
+       }
+       else
+           sv = tsv;
+      }
+      iv = SvIV(sv); /* attempt to convert to IV if possible. */
+
+      if (!SvOK(sv)) {
         SETu(0);
-      else if (SvIOK(TOPs)) {
-       if (SvIsUV(TOPs)) {
-           const UV uv = TOPu;
-           SETu(uv);
-       } else
+      }
+      else if (SvIOK(sv)) {
+       if (SvIsUV(sv))
+           SETu(SvUV(sv));
+       else
            SETi(iv);
-      } else {
-         const NV value = TOPn;
+      }
+      else if (SvROK(sv)) {
+           SETi(iv);
+      }
+      else {
+         const NV value = SvNV(sv);
          if (value >= 0.0) {
              if (value < (NV)UV_MAX + 0.5) {
                  SETu(U_V(value));
@@ -4066,7 +4084,7 @@ PP(pp_hslice)
         }
 
         he = hv_fetch_ent(hv, keysv, lval, 0);
-        svp = he ? &HeVAL(he) : 0;
+        svp = he ? &HeVAL(he) : NULL;
 
         if (lval) {
             if (!svp || *svp == &PL_sv_undef) {
@@ -4420,12 +4438,17 @@ PP(pp_push)
        PUSHi( AvFILL(ary) + 1 );
     }
     else {
+       PL_delaymagic = DM_DELAY;
        for (++MARK; MARK <= SP; MARK++) {
            SV * const sv = newSV(0);
            if (*MARK)
                sv_setsv(sv, *MARK);
            av_store(ary, AvFILLp(ary)+1, sv);
        }
+       if (PL_delaymagic & DM_ARRAY)
+           mg_set((SV*)ary);
+
+       PL_delaymagic = 0;
        SP = ORIGMARK;
        PUSHi( AvFILLp(ary) + 1 );
     }
@@ -4726,26 +4749,36 @@ PP(pp_split)
         else
             EXTEND(SP, slen);
 
-        while (--limit) {
-            m = s;
-            
-            if (do_utf8)
+        if (do_utf8) {
+            while (--limit) {
+                /* keep track of how many bytes we skip over */
+                m = s;
                 s += UTF8SKIP(s);
-            else
-                ++s;
+                dstr = newSVpvn(m, s-m);
 
-            dstr = newSVpvn(m, s-m);
+                if (make_mortal)
+                    sv_2mortal(dstr);
 
-            if (make_mortal)
-                sv_2mortal(dstr);
-            if (do_utf8)
                 (void)SvUTF8_on(dstr);
+                PUSHs(dstr);
+
+                if (s >= strend)
+                    break;
+            }
+        } else {
+            while (--limit) {
+                dstr = newSVpvn(s, 1);
 
-            PUSHs(dstr);
+                s++;
 
-            /* are we there yet? */
-            if (s >= strend)
-                break;
+                if (make_mortal)
+                    sv_2mortal(dstr);
+
+                PUSHs(dstr);
+
+                if (s >= strend)
+                    break;
+            }
         }
     }
     else if (do_utf8 == ((rx->extflags & RXf_UTF8) != 0) &&
@@ -4917,6 +4950,19 @@ PP(pp_split)
     RETURN;
 }
 
+PP(pp_once)
+{
+    dSP;
+    SV *const sv = PAD_SVl(PL_op->op_targ);
+
+    if (SvPADSTALE(sv)) {
+       /* First time. */
+       SvPADSTALE_off(sv);
+       RETURNOP(cLOGOP->op_other);
+    }
+    RETURNOP(cLOGOP->op_next);
+}
+
 PP(pp_lock)
 {
     dVAR;