Update perly_c.diff, update perly.fixer to edit away
[p5sagit/p5-mst-13.2.git] / pp.c
diff --git a/pp.c b/pp.c
index 1d3e365..ebdf3fd 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -341,7 +341,7 @@ PP(pp_av2arylen)
     if (!sv) {
        AvARYLEN(av) = sv = NEWSV(0,0);
        sv_upgrade(sv, SVt_IV);
-       sv_magic(sv, (SV*)av, '#', Nullch, 0);
+       sv_magic(sv, (SV*)av, PERL_MAGIC_arylen, Nullch, 0);
     }
     SETs(sv);
     RETURN;
@@ -354,7 +354,7 @@ PP(pp_pos)
     if (PL_op->op_flags & OPf_MOD || LVRET) {
        if (SvTYPE(TARG) < SVt_PVLV) {
            sv_upgrade(TARG, SVt_PVLV);
-           sv_magic(TARG, Nullsv, '.', Nullch, 0);
+           sv_magic(TARG, Nullsv, PERL_MAGIC_pos, Nullch, 0);
        }
 
        LvTYPE(TARG) = '.';
@@ -370,7 +370,7 @@ PP(pp_pos)
        MAGIC* mg;
 
        if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
-           mg = mg_find(sv, 'g');
+           mg = mg_find(sv, PERL_MAGIC_regex_global);
            if (mg && mg->mg_len >= 0) {
                I32 i = mg->mg_len;
                if (DO_UTF8(sv))
@@ -448,10 +448,12 @@ PP(pp_prototype)
                    else if (n && str[0] == ';' && seen_question)
                        goto set;       /* XXXX system, exec */
                    if ((oa & (OA_OPTIONAL - 1)) >= OA_AVREF
-                       && (oa & (OA_OPTIONAL - 1)) <= OA_HVREF) {
+                       && (oa & (OA_OPTIONAL - 1)) <= OA_SCALARREF
+                       /* But globs are already references (kinda) */
+                       && (oa & (OA_OPTIONAL - 1)) != OA_FILEREF
+                   ) {
                        str[n++] = '\\';
                    }
-                   /* What to do with R ((un)tie, tied, (sys)read, recv)? */
                    str[n++] = ("?$@@%&*$")[oa & (OA_OPTIONAL - 1)];
                    oa = oa >> 4;
                }
@@ -713,7 +715,8 @@ PP(pp_study)
     }
 
     SvSCREAM_on(sv);
-    sv_magic(sv, Nullsv, 'g', Nullch, 0);      /* piggyback on m//g magic */
+    /* piggyback on m//g magic */
+    sv_magic(sv, Nullsv, PERL_MAGIC_regex_global, Nullch, 0);
     RETPUSHYES;
 }
 
@@ -781,11 +784,13 @@ PP(pp_defined)
        RETPUSHNO;
     switch (SvTYPE(sv)) {
     case SVt_PVAV:
-       if (AvMAX(sv) >= 0 || SvGMAGICAL(sv) || (SvRMAGICAL(sv) && mg_find(sv,'P')))
+       if (AvMAX(sv) >= 0 || SvGMAGICAL(sv)
+               || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
            RETPUSHYES;
        break;
     case SVt_PVHV:
-       if (HvARRAY(sv) || SvGMAGICAL(sv) || (SvRMAGICAL(sv) && mg_find(sv,'P')))
+       if (HvARRAY(sv) || SvGMAGICAL(sv)
+               || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
            RETPUSHYES;
        break;
     case SVt_PVCV:
@@ -1088,13 +1093,13 @@ PP(pp_modulo)
 {
     dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
     {
-       UV left;
-       UV right;
+       UV left  = 0;
+       UV right = 0;
        bool left_neg;
        bool right_neg;
        bool use_double = 0;
-       NV dright;
-       NV dleft;
+       NV dright = 0.0;
+       NV dleft  = 0.0;
 
        if (SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)) {
            IV i = SvIVX(POPs);
@@ -1232,6 +1237,16 @@ PP(pp_repeat)
            (void)SvPOK_only_UTF8(TARG);
        else
            (void)SvPOK_only(TARG);
+
+       if (PL_op->op_private & OPpREPEAT_DOLIST) {
+           /* The parser saw this as a list repeat, and there
+              are probably several items on the stack. But we're
+              in scalar context, and there's no pp_list to save us
+              now. So drop the rest of the items -- robin@kitsite.com
+            */
+           dMARK;
+           SP = MARK;
+       }
        PUSHTARG;
     }
     RETURN;
@@ -1250,8 +1265,8 @@ PP(pp_subtract)
        /* Unless the left argument is integer in range we are going to have to
           use NV maths. Hence only attempt to coerce the right argument if
           we know the left is integer.  */
-       register UV auv;
-       bool auvok;
+       register UV auv = 0;
+       bool auvok = FALSE;
        bool a_valid = 0;
 
        if (!useleft) {
@@ -1704,6 +1719,12 @@ PP(pp_ge)
 PP(pp_ne)
 {
     dSP; tryAMAGICbinSET(ne,0);
+#ifndef NV_PRESERVES_UV
+    if (SvROK(TOPs) && SvROK(TOPm1s)) {
+       SETs(boolSV(SvRV(TOPs) != SvRV(TOPm1s)));
+       RETURN;
+    }
+#endif
 #ifdef PERL_PRESERVE_IVUV
     SvIV_please(TOPs);
     if (SvIOK(TOPs)) {
@@ -1774,6 +1795,12 @@ PP(pp_ne)
 PP(pp_ncmp)
 {
     dSP; dTARGET; tryAMAGICbin(ncmp,0);
+#ifndef NV_PRESERVES_UV
+    if (SvROK(TOPs) && SvROK(TOPm1s)) {
+       SETi(PTR2UV(SvRV(TOPs)) - PTR2UV(SvRV(TOPm1s)));
+       RETURN;
+    }
+#endif
 #ifdef PERL_PRESERVE_IVUV
     /* Fortunately it seems NaN isn't IOK */
     SvIV_please(TOPs);
@@ -1884,7 +1911,7 @@ PP(pp_slt)
     dSP; tryAMAGICbinSET(slt,0);
     {
       dPOPTOPssrl;
-      int cmp = ((PL_op->op_private & OPpLOCALE)
+      int cmp = (IN_LOCALE_RUNTIME
                 ? sv_cmp_locale(left, right)
                 : sv_cmp(left, right));
       SETs(boolSV(cmp < 0));
@@ -1897,7 +1924,7 @@ PP(pp_sgt)
     dSP; tryAMAGICbinSET(sgt,0);
     {
       dPOPTOPssrl;
-      int cmp = ((PL_op->op_private & OPpLOCALE)
+      int cmp = (IN_LOCALE_RUNTIME
                 ? sv_cmp_locale(left, right)
                 : sv_cmp(left, right));
       SETs(boolSV(cmp > 0));
@@ -1910,7 +1937,7 @@ PP(pp_sle)
     dSP; tryAMAGICbinSET(sle,0);
     {
       dPOPTOPssrl;
-      int cmp = ((PL_op->op_private & OPpLOCALE)
+      int cmp = (IN_LOCALE_RUNTIME
                 ? sv_cmp_locale(left, right)
                 : sv_cmp(left, right));
       SETs(boolSV(cmp <= 0));
@@ -1923,7 +1950,7 @@ PP(pp_sge)
     dSP; tryAMAGICbinSET(sge,0);
     {
       dPOPTOPssrl;
-      int cmp = ((PL_op->op_private & OPpLOCALE)
+      int cmp = (IN_LOCALE_RUNTIME
                 ? sv_cmp_locale(left, right)
                 : sv_cmp(left, right));
       SETs(boolSV(cmp >= 0));
@@ -1956,7 +1983,7 @@ PP(pp_scmp)
     dSP; dTARGET;  tryAMAGICbin(scmp,0);
     {
       dPOPTOPssrl;
-      int cmp = ((PL_op->op_private & OPpLOCALE)
+      int cmp = (IN_LOCALE_RUNTIME
                 ? sv_cmp_locale(left, right)
                 : sv_cmp(left, right));
       SETi( cmp );
@@ -2571,7 +2598,16 @@ PP(pp_int)
                  SETu(U_V(value));
              } else {
 #if defined(HAS_MODFL) || defined(LONG_DOUBLE_EQUALS_DOUBLE)
+#   ifdef HAS_MODFL_POW32_BUG
+/* some versions of glibc split (i + d) into (i-1, d+1) for 2^32 <= i < 2^64 */
+                { 
+                    NV offset = Perl_modf(value, &value);
+                    (void)Perl_modf(offset, &offset);
+                    value += offset;
+                }
+#   else
                  (void)Perl_modf(value, &value);
+#   endif
 #else
                  double tmp = (double)value;
                  (void)Perl_modf(tmp, &tmp);
@@ -2585,7 +2621,16 @@ PP(pp_int)
                  SETi(I_V(value));
              } else {
 #if defined(HAS_MODFL) || defined(LONG_DOUBLE_EQUALS_DOUBLE)
+#   ifdef HAS_MODFL_POW32_BUG
+/* some versions of glibc split (i + d) into (i-1, d+1) for 2^32 <= i < 2^64 */
+                 {
+                     NV offset = Perl_modf(-value, &value);
+                     (void)Perl_modf(offset, &offset);
+                     value += offset;
+                 }
+#   else
                  (void)Perl_modf(-value, &value);
+#   endif
                  value = -value;
 #else
                  double tmp = (double)value;
@@ -2639,11 +2684,11 @@ PP(pp_hex)
     dSP; dTARGET;
     char *tmps;
     STRLEN argtype;
-    STRLEN n_a;
+    STRLEN len;
 
-    tmps = POPpx;
+    tmps = (SvPVx(POPs, len));
     argtype = 1;               /* allow underscores */
-    XPUSHn(scan_hex(tmps, 99, &argtype));
+    XPUSHn(scan_hex(tmps, len, &argtype));
     RETURN;
 }
 
@@ -2653,20 +2698,20 @@ PP(pp_oct)
     NV value;
     STRLEN argtype;
     char *tmps;
-    STRLEN n_a;
+    STRLEN len;
 
-    tmps = POPpx;
-    while (*tmps && isSPACE(*tmps))
-       tmps++;
+    tmps = (SvPVx(POPs, len));
+    while (*tmps && len && isSPACE(*tmps))
+       tmps++, len--;
     if (*tmps == '0')
-       tmps++;
+       tmps++, len--;
     argtype = 1;               /* allow underscores */
     if (*tmps == 'x')
-       value = scan_hex(++tmps, 99, &argtype);
+       value = scan_hex(++tmps, --len, &argtype);
     else if (*tmps == 'b')
-       value = scan_bin(++tmps, 99, &argtype);
+       value = scan_bin(++tmps, --len, &argtype);
     else
-       value = scan_oct(tmps, 99, &argtype);
+       value = scan_oct(tmps, len, &argtype);
     XPUSHn(value);
     RETURN;
 }
@@ -2689,41 +2734,53 @@ PP(pp_substr)
 {
     dSP; dTARGET;
     SV *sv;
-    I32 len;
+    I32 len = 0;
     STRLEN curlen;
-    STRLEN utfcurlen;
+    STRLEN utf8_curlen;
     I32 pos;
     I32 rem;
     I32 fail;
     I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET;
     char *tmps;
     I32 arybase = PL_curcop->cop_arybase;
+    SV *repl_sv = NULL;
     char *repl = 0;
     STRLEN repl_len;
     int num_args = PL_op->op_private & 7;
+    bool repl_need_utf8_upgrade = FALSE;
+    bool repl_is_utf8 = FALSE;
 
     SvTAINTED_off(TARG);                       /* decontaminate */
     SvUTF8_off(TARG);                          /* decontaminate */
     if (num_args > 2) {
        if (num_args > 3) {
-           sv = POPs;
-           repl = SvPV(sv, repl_len);
+           repl_sv = POPs;
+           repl = SvPV(repl_sv, repl_len);
+           repl_is_utf8 = DO_UTF8(repl_sv) && SvCUR(repl_sv);
        }
        len = POPi;
     }
     pos = POPi;
     sv = POPs;
     PUTBACK;
+    if (repl_sv) {
+       if (repl_is_utf8) {
+           if (!DO_UTF8(sv))
+               sv_utf8_upgrade(sv);
+       }
+       else if (DO_UTF8(sv))
+           repl_need_utf8_upgrade = TRUE;
+    }
     tmps = SvPV(sv, curlen);
     if (DO_UTF8(sv)) {
-        utfcurlen = sv_len_utf8(sv);
-       if (utfcurlen == curlen)
-           utfcurlen = 0;
+        utf8_curlen = sv_len_utf8(sv);
+       if (utf8_curlen == curlen)
+           utf8_curlen = 0;
        else
-           curlen = utfcurlen;
+           curlen = utf8_curlen;
     }
     else
-       utfcurlen = 0;
+       utf8_curlen = 0;
 
     if (pos >= arybase) {
        pos -= arybase;
@@ -2768,14 +2825,30 @@ PP(pp_substr)
     else {
        I32 upos = pos;
        I32 urem = rem;
-       if (utfcurlen)
+       if (utf8_curlen)
            sv_pos_u2b(sv, &pos, &rem);
        tmps += pos;
        sv_setpvn(TARG, tmps, rem);
-       if (utfcurlen)
+#ifdef USE_LOCALE_COLLATE
+       sv_unmagic(TARG, PERL_MAGIC_collxfrm);
+#endif
+       if (utf8_curlen)
            SvUTF8_on(TARG);
-       if (repl)
+       if (repl) {
+           SV* repl_sv_copy = NULL;
+
+           if (repl_need_utf8_upgrade) {
+               repl_sv_copy = newSVsv(repl_sv);
+               sv_utf8_upgrade(repl_sv_copy);
+               repl = SvPV(repl_sv_copy, repl_len);
+               repl_is_utf8 = DO_UTF8(repl_sv_copy) && SvCUR(sv);
+           }
            sv_insert(sv, pos, rem, repl, repl_len);
+           if (repl_is_utf8)
+               SvUTF8_on(sv);
+           if (repl_sv_copy)
+               SvREFCNT_dec(repl_sv_copy);
+       }
        else if (lvalue) {              /* it's an lvalue! */
            if (!SvGMAGICAL(sv)) {
                if (SvROK(sv)) {
@@ -2793,7 +2866,7 @@ PP(pp_substr)
 
            if (SvTYPE(TARG) < SVt_PVLV) {
                sv_upgrade(TARG, SVt_PVLV);
-               sv_magic(TARG, Nullsv, 'x', Nullch, 0);
+               sv_magic(TARG, Nullsv, PERL_MAGIC_substr, Nullch, 0);
            }
 
            LvTYPE(TARG) = 'x';
@@ -2823,7 +2896,7 @@ PP(pp_vec)
     if (lvalue) {                      /* it's an lvalue! */
        if (SvTYPE(TARG) < SVt_PVLV) {
            sv_upgrade(TARG, SVt_PVLV);
-           sv_magic(TARG, Nullsv, 'v', Nullch, 0);
+           sv_magic(TARG, Nullsv, PERL_MAGIC_vec, Nullch, 0);
        }
        LvTYPE(TARG) = 'v';
        if (LvTARG(TARG) != src) {
@@ -2946,7 +3019,7 @@ PP(pp_chr)
 
     (void)SvUPGRADE(TARG,SVt_PV);
 
-    if (value > 255 && !IN_BYTE) {
+    if (value > 255 && !IN_BYTES) {
        SvGROW(TARG, UNISKIP(value)+1);
        tmps = (char*)uvchr_to_utf8((U8*)SvPVX(TARG), value);
        SvCUR_set(TARG, tmps - SvPVX(TARG));
@@ -2999,7 +3072,7 @@ PP(pp_ucfirst)
        U8 *tend;
        UV uv;
 
-       if (PL_op->op_private & OPpLOCALE) {
+       if (IN_LOCALE_RUNTIME) {
            TAINT;
            SvTAINTED_on(sv);
            uv = toTITLE_LC_uvchr(utf8n_to_uvchr(s, slen, &ulen, 0));
@@ -3031,7 +3104,7 @@ PP(pp_ucfirst)
        }
        s = (U8*)SvPV_force(sv, slen);
        if (*s) {
-           if (PL_op->op_private & OPpLOCALE) {
+           if (IN_LOCALE_RUNTIME) {
                TAINT;
                SvTAINTED_on(sv);
                *s = toUPPER_LC(*s);
@@ -3058,7 +3131,7 @@ PP(pp_lcfirst)
        U8 *tend;
        UV uv;
 
-       if (PL_op->op_private & OPpLOCALE) {
+       if (IN_LOCALE_RUNTIME) {
            TAINT;
            SvTAINTED_on(sv);
            uv = toLOWER_LC_uvchr(utf8n_to_uvchr(s, slen, &ulen, 0));
@@ -3090,7 +3163,7 @@ PP(pp_lcfirst)
        }
        s = (U8*)SvPV_force(sv, slen);
        if (*s) {
-           if (PL_op->op_private & OPpLOCALE) {
+           if (IN_LOCALE_RUNTIME) {
                TAINT;
                SvTAINTED_on(sv);
                *s = toLOWER_LC(*s);
@@ -3129,7 +3202,7 @@ PP(pp_uc)
            (void)SvPOK_only(TARG);
            d = (U8*)SvPVX(TARG);
            send = s + len;
-           if (PL_op->op_private & OPpLOCALE) {
+           if (IN_LOCALE_RUNTIME) {
                TAINT;
                SvTAINTED_on(TARG);
                while (s < send) {
@@ -3161,7 +3234,7 @@ PP(pp_uc)
        if (len) {
            register U8 *send = s + len;
 
-           if (PL_op->op_private & OPpLOCALE) {
+           if (IN_LOCALE_RUNTIME) {
                TAINT;
                SvTAINTED_on(sv);
                for (; s < send; s++)
@@ -3203,7 +3276,7 @@ PP(pp_lc)
            (void)SvPOK_only(TARG);
            d = (U8*)SvPVX(TARG);
            send = s + len;
-           if (PL_op->op_private & OPpLOCALE) {
+           if (IN_LOCALE_RUNTIME) {
                TAINT;
                SvTAINTED_on(TARG);
                while (s < send) {
@@ -3236,7 +3309,7 @@ PP(pp_lc)
        if (len) {
            register U8 *send = s + len;
 
-           if (PL_op->op_private & OPpLOCALE) {
+           if (IN_LOCALE_RUNTIME) {
                TAINT;
                SvTAINTED_on(sv);
                for (; s < send; s++)
@@ -3508,7 +3581,9 @@ PP(pp_hslice)
        while (++MARK <= SP) {
            SV *keysv = *MARK;
            SV **svp;
-           I32 preeminent = SvRMAGICAL(hv) ? 1 : hv_exists_ent(hv, keysv, 0);
+           I32 preeminent = SvRMAGICAL(hv) ? 1 :
+                               realhv ? hv_exists_ent(hv, keysv, 0)
+                                      : avhv_exists_ent((AV*)hv, keysv, 0);
            if (realhv) {
                HE *he = hv_fetch_ent(hv, keysv, lval, 0);
                svp = he ? &HeVAL(he) : 0;
@@ -3656,7 +3731,7 @@ PP(pp_splice)
     SV **tmparyval = 0;
     MAGIC *mg;
 
-    if ((mg = SvTIED_mg((SV*)ary, 'P'))) {
+    if ((mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied))) {
        *MARK-- = SvTIED_obj((SV*)ary, mg);
        PUSHMARK(MARK);
        PUTBACK;
@@ -3850,7 +3925,7 @@ PP(pp_push)
     register SV *sv = &PL_sv_undef;
     MAGIC *mg;
 
-    if ((mg = SvTIED_mg((SV*)ary, 'P'))) {
+    if ((mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied))) {
        *MARK-- = SvTIED_obj((SV*)ary, mg);
        PUSHMARK(MARK);
        PUTBACK;
@@ -3906,7 +3981,7 @@ PP(pp_unshift)
     register I32 i = 0;
     MAGIC *mg;
 
-    if ((mg = SvTIED_mg((SV*)ary, 'P'))) {
+    if ((mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied))) {
        *MARK-- = SvTIED_obj((SV*)ary, mg);
        PUSHMARK(MARK);
        PUTBACK;
@@ -3962,7 +4037,7 @@ PP(pp_reverse)
                U8* s = (U8*)SvPVX(TARG);
                U8* send = (U8*)(s + len);
                while (s < send) {
-                   if (UTF8_IS_ASCII(*s)) {
+                   if (UTF8_IS_INVARIANT(*s)) {
                        s++;
                        continue;
                    }
@@ -4060,7 +4135,7 @@ PP(pp_unpack)
     register char *patend = pat + llen;
     I32 datumtype;
     register I32 len;
-    register I32 bits;
+    register I32 bits = 0;
     register char *str;
 
     /* These must not be in registers: */
@@ -4080,8 +4155,8 @@ PP(pp_unpack)
     float afloat;
     double adouble;
     I32 checksum = 0;
-    register U32 culong;
-    NV cdouble;
+    register U32 culong = 0;
+    NV cdouble = 0.0;
     int commas = 0;
     int star;
 #ifdef PERL_NATINT_PACK
@@ -4789,7 +4864,8 @@ PP(pp_unpack)
                
                while ((len > 0) && (s < strend)) {
                    auv = (auv << 7) | (*s & 0x7f);
-                   if (UTF8_IS_ASCII(*s++)) {
+                   /* UTF8_IS_XXXXX not right here - using constant 0x80 */
+                   if ((U8)(*s++) < 0x80) {
                        bytes = 0;
                        sv = NEWSV(40, 0);
                        sv_setuv(sv, auv);
@@ -5407,9 +5483,26 @@ PP(pp_pack)
        case 'c':
            while (len-- > 0) {
                fromstr = NEXTFROM;
-               aint = SvIV(fromstr);
-               achar = aint;
-               sv_catpvn(cat, &achar, sizeof(char));
+               switch (datumtype) {
+               case 'C':
+                   aint = SvIV(fromstr);
+                   if ((aint < 0 || aint > 255) &&
+                       ckWARN(WARN_PACK))
+                       Perl_warner(aTHX_ WARN_PACK,
+                                   "Character in \"C\" format wrapped");
+                   achar = aint & 255;
+                   sv_catpvn(cat, &achar, sizeof(char));
+                   break;
+               case 'c':
+                   aint = SvIV(fromstr);
+                   if ((aint < -128 || aint > 127) &&
+                       ckWARN(WARN_PACK))
+                       Perl_warner(aTHX_ WARN_PACK,
+                                   "Character in \"c\" format wrapped");
+                   achar = aint & 255;
+                   sv_catpvn(cat, &achar, sizeof(char));
+                   break;
+               }
            }
            break;
        case 'U':
@@ -5788,7 +5881,7 @@ PP(pp_split)
        av_extend(ary,0);
        av_clear(ary);
        SPAGAIN;
-       if ((mg = SvTIED_mg((SV*)ary, 'P'))) {
+       if ((mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied))) {
            PUSHMARK(SP);
            XPUSHs(SvTIED_obj((SV*)ary, mg));
        }
@@ -6035,7 +6128,7 @@ PP(pp_split)
 void
 Perl_unlock_condpair(pTHX_ void *svv)
 {
-    MAGIC *mg = mg_find((SV*)svv, 'm');
+    MAGIC *mg = mg_find((SV*)svv, PERL_MAGIC_mutex);
 
     if (!mg)
        Perl_croak(aTHX_ "panic: unlock_condpair unlocking non-mutex");