Oops. Forgot to add this file.
[p5sagit/p5-mst-13.2.git] / mg.c
diff --git a/mg.c b/mg.c
index d1bed8e..c277576 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -83,13 +83,13 @@ struct magic_state {
 STATIC void
 S_save_magic(pTHX_ I32 mgs_ix, SV *sv)
 {
+    dVAR;
     MGS* mgs;
     assert(SvMAGICAL(sv));
-#ifdef PERL_OLD_COPY_ON_WRITE
-    /* Turning READONLY off for a copy-on-write scalar is a bad idea.  */
+    /* Turning READONLY off for a copy-on-write scalar (including shared
+       hash keys) is a bad idea.  */
     if (SvIsCOW(sv))
       sv_force_normal_flags(sv, 0);
-#endif
 
     SAVEDESTRUCTOR_X(S_restore_magic, INT2PTR(void*, (IV)mgs_ix));
 
@@ -139,6 +139,7 @@ Do magic after a value is retrieved from the SV.  See C<sv_magic>.
 int
 Perl_mg_get(pTHX_ SV *sv)
 {
+    dVAR;
     const I32 mgs_ix = SSNEW(sizeof(MGS));
     const bool was_temp = (bool)SvTEMP(sv);
     int have_new = 0;
@@ -219,6 +220,7 @@ Do magic after a value is assigned to the SV.  See C<sv_magic>.
 int
 Perl_mg_set(pTHX_ SV *sv)
 {
+    dVAR;
     const I32 mgs_ix = SSNEW(sizeof(MGS));
     MAGIC* mg;
     MAGIC* nextmg;
@@ -251,6 +253,7 @@ Report on the SV's length.  See C<sv_magic>.
 U32
 Perl_mg_length(pTHX_ SV *sv)
 {
+    dVAR;
     MAGIC* mg;
     STRLEN len;
 
@@ -402,9 +405,10 @@ doesn't (eg taint, pos).
 void
 Perl_mg_localize(pTHX_ SV *sv, SV *nsv)
 {
+    dVAR;
     MAGIC *mg;
     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
-       const MGVTBL* const vtbl = mg->mg_virtual;
+       MGVTBL* const vtbl = mg->mg_virtual;
        switch (mg->mg_type) {
        /* value magic types: don't copy */
        case PERL_MAGIC_bm:
@@ -485,6 +489,7 @@ Perl_mg_free(pTHX_ SV *sv)
 U32
 Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     PERL_UNUSED_ARG(sv);
 
     if (PL_curpm) {
@@ -502,6 +507,7 @@ Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     if (PL_curpm) {
        register const REGEXP * const rx = PM_GETRE(PL_curpm);
        if (rx) {
@@ -544,6 +550,7 @@ Perl_magic_regdatum_set(pTHX_ SV *sv, MAGIC *mg)
 U32
 Perl_magic_len(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     register I32 paren;
     register I32 i;
     register const REGEXP *rx;
@@ -634,10 +641,14 @@ Perl_magic_len(pTHX_ SV *sv, MAGIC *mg)
 }
 
 #define SvRTRIM(sv) STMT_START { \
-    STRLEN len = SvCUR(sv); \
-    while (len > 0 && isSPACE(SvPVX(sv)[len-1])) \
-       --len; \
-    SvCUR_set(sv, len); \
+    if (SvPOK(sv)) { \
+        STRLEN len = SvCUR(sv); \
+        char * const p = SvPVX(sv); \
+       while (len > 0 && isSPACE(p[len-1])) \
+          --len; \
+       SvCUR_set(sv, len); \
+       p[len] = '\0'; \
+    } \
 } STMT_END
 
 int
@@ -669,15 +680,14 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
        break;
     case '\005':  /* ^E */
         if (nextchar == '\0') {
-#ifdef MACOS_TRADITIONAL
+#if defined(MACOS_TRADITIONAL)
             {
                  char msg[256];
 
                  sv_setnv(sv,(double)gMacPerl_OSErr);
                  sv_setpv(sv, gMacPerl_OSErr ? GetSysErrText(gMacPerl_OSErr, msg) : "");
             }
-#else
-#ifdef VMS
+#elif defined(VMS)
             {
 #                include <descrip.h>
 #                include <starlet.h>
@@ -689,8 +699,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
                  else
                       sv_setpvn(sv,"",0);
             }
-#else
-#ifdef OS2
+#elif defined(OS2)
             if (!(_emx_env & 0x200)) { /* Under DOS */
                  sv_setnv(sv, (NV)errno);
                  sv_setpv(sv, errno ? Strerror(errno) : "");
@@ -703,8 +712,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
                  sv_setnv(sv, (NV)Perl_rc);
                  sv_setpv(sv, os2error(Perl_rc));
             }
-#else
-#ifdef WIN32
+#elif defined(WIN32)
             {
                  DWORD dwErr = GetLastError();
                  sv_setnv(sv, (NV)dwErr);
@@ -723,9 +731,6 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
                 errno = saveerrno;
             }
 #endif
-#endif
-#endif
-#endif
             SvRTRIM(sv);
             SvNOK_on(sv);      /* what a wonderful hack! */
         }
@@ -808,7 +813,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
                 * it could have been extended by warnings::register */
                SV **bits_all;
                HV * const bits=get_hv("warnings::Bits", FALSE);
-               if (bits && (bits_all=hv_fetch(bits, "all", 3, FALSE))) {
+               if (bits && (bits_all=hv_fetchs(bits, "all", FALSE))) {
                    sv_setsv(sv, *bits_all);
                }
                else {
@@ -994,29 +999,22 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
        break;
     case '(':
        sv_setiv(sv, (IV)PL_gid);
-#ifdef HAS_GETGROUPS
-       Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, (long unsigned int)PL_gid);
-#endif
        goto add_groups;
     case ')':
        sv_setiv(sv, (IV)PL_egid);
-#ifdef HAS_GETGROUPS
-       Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, (long unsigned int)PL_egid);
-#endif
       add_groups:
 #ifdef HAS_GETGROUPS
        {
            Groups_t *gary = NULL;
-           I32 num_groups = getgroups(0, gary);
+           I32 i, num_groups = getgroups(0, gary);
             Newx(gary, num_groups, Groups_t);
             num_groups = getgroups(num_groups, gary);
-           while (--num_groups >= 0)
-               Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f,
-                    (long unsigned int)gary[num_groups]);
+           for (i = 0; i < num_groups; i++)
+               Perl_sv_catpvf(aTHX_ sv, " %"IVdf, (IV)gary[i]);
             Safefree(gary);
        }
-#endif
        (void)SvIOK_on(sv);     /* what a wonderful hack! */
+#endif
        break;
 #ifndef MACOS_TRADITIONAL
     case '0':
@@ -1124,6 +1122,7 @@ Perl_magic_clearenv(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     PERL_UNUSED_ARG(mg);
 #if defined(VMS)
     Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
@@ -1168,6 +1167,7 @@ restore_sigmask(pTHX_ SV *save_sv)
 int
 Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     /* Are we fetching a signal entry? */
     const I32 i = whichsig(MgPV_nolen_const(mg));
     if (i > 0) {
@@ -1247,7 +1247,7 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
                PL_psig_name[i]=0;
            }
            if(PL_psig_ptr[i]) {
-                SV *to_dec=PL_psig_ptr[i];
+               SV * const to_dec=PL_psig_ptr[i];
                PL_psig_ptr[i]=0;
                LEAVE;
                SvREFCNT_dec(to_dec);
@@ -1262,6 +1262,7 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
 static void
 S_raise_signal(pTHX_ int sig)
 {
+    dVAR;
     /* Set a flag to say this signal is pending */
     PL_psig_pend[sig]++;
     /* And one to say _a_ signal is pending */
@@ -1324,6 +1325,7 @@ Perl_csighandler_init(void)
 void
 Perl_despatch_signals(pTHX)
 {
+    dVAR;
     int sig;
     PL_sig_pending = 0;
     for (sig = 1; sig < SIG_SIZE; sig++) {
@@ -1463,6 +1465,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     PERL_UNUSED_ARG(sv);
     PERL_UNUSED_ARG(mg);
     PL_sub_generation++;
@@ -1472,6 +1475,7 @@ Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     PERL_UNUSED_ARG(sv);
     PERL_UNUSED_ARG(mg);
     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
@@ -1515,6 +1519,7 @@ Perl_magic_setnkeys(pTHX_ SV *sv, MAGIC *mg)
 STATIC int
 S_magic_methcall(pTHX_ SV *sv, const MAGIC *mg, const char *meth, I32 flags, int n, SV *val)
 {
+    dVAR;
     dSP;
 
     PUSHMARK(SP);
@@ -1691,6 +1696,7 @@ Perl_magic_scalarpack(pTHX_ HV *hv, MAGIC *mg)
 int
 Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     GV * const gv = PL_DBline;
     const I32 i = SvTRUE(sv);
     SV ** const svp = av_fetch(GvAV(gv),
@@ -1711,6 +1717,7 @@ Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_getarylen(pTHX_ SV *sv, const MAGIC *mg)
 {
+    dVAR;
     const AV * const obj = (AV*)mg->mg_obj;
     if (obj) {
        sv_setiv(sv, AvFILL(obj) + PL_curcop->cop_arybase);
@@ -1723,6 +1730,7 @@ Perl_magic_getarylen(pTHX_ SV *sv, const MAGIC *mg)
 int
 Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     AV * const obj = (AV*)mg->mg_obj;
     if (obj) {
        av_fill(obj, SvIV(sv) - PL_curcop->cop_arybase);
@@ -1737,6 +1745,7 @@ Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_freearylen_p(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     PERL_UNUSED_ARG(sv);
     /* during global destruction, mg_obj may already have been freed */
     if (PL_in_clean_all)
@@ -1758,6 +1767,7 @@ Perl_magic_freearylen_p(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     SV* const lsv = LvTARG(sv);
 
     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
@@ -1777,6 +1787,7 @@ Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     SV* const lsv = LvTARG(sv);
     SSize_t pos;
     STRLEN len;
@@ -1882,6 +1893,7 @@ Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     STRLEN len;
     const char *tmps = SvPV_const(sv, len);
     SV * const lsv = LvTARG(sv);
@@ -1915,6 +1927,7 @@ Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     PERL_UNUSED_ARG(sv);
     TAINT_IF((PL_localizing != 1) && (mg->mg_len & 1));
     return 0;
@@ -1923,6 +1936,7 @@ Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_settaint(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     PERL_UNUSED_ARG(sv);
     /* update taint status unless we're restoring at scope exit */
     if (PL_localizing != 2) {
@@ -1940,12 +1954,11 @@ Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg)
     SV * const lsv = LvTARG(sv);
     PERL_UNUSED_ARG(mg);
 
-    if (!lsv) {
+    if (lsv)
+       sv_setuv(sv, do_vecget(lsv, LvTARGOFF(sv), LvTARGLEN(sv)));
+    else
        SvOK_off(sv);
-       return 0;
-    }
 
-    sv_setuv(sv, do_vecget(lsv, LvTARGOFF(sv), LvTARGLEN(sv)));
     return 0;
 }
 
@@ -1960,6 +1973,7 @@ Perl_magic_setvec(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     SV *targ = Nullsv;
     if (LvTARGLEN(sv)) {
        if (mg->mg_obj) {
@@ -2005,6 +2019,7 @@ Perl_magic_setdefelem(pTHX_ SV *sv, MAGIC *mg)
 void
 Perl_vivify_defelem(pTHX_ SV *sv)
 {
+    dVAR;
     MAGIC *mg;
     SV *value = Nullsv;
 
@@ -2090,6 +2105,7 @@ Perl_magic_setregexp(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_freeregexp(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     regexp * const re = (regexp *)mg->mg_obj;
     PERL_UNUSED_ARG(sv);
 
@@ -2129,6 +2145,7 @@ Perl_magic_setutf8(pTHX_ SV *sv, MAGIC *mg)
 int
 Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
 {
+    dVAR;
     register const char *s;
     I32 i;
     STRLEN len;
@@ -2512,7 +2529,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
        /* The BSDs don't show the argv[] in ps(1) output, they
         * show a string from the process struct and provide
         * the setproctitle() routine to manipulate that. */
-       {
+       if (PL_origalen != 1) {
            s = SvPV_const(sv, len);
 #   if __FreeBSD_version > 410001
            /* The leading "-" removes the "perl: " prefix,
@@ -2533,35 +2550,37 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
        }
 #endif
 #if defined(__hpux) && defined(PSTAT_SETCMD)
-       {
+       if (PL_origalen != 1) {
             union pstun un;
             s = SvPV_const(sv, len);
             un.pst_command = (char *)s;
             pstat(PSTAT_SETCMD, un, len, 0, 0);
        }
 #endif
-       /* PL_origalen is set in perl_parse(). */
-       s = SvPV_force(sv,len);
-       if (len >= (STRLEN)PL_origalen-1) {
-           /* Longer than original, will be truncated. We assume that
-             * PL_origalen bytes are available. */
-           Copy(s, PL_origargv[0], PL_origalen-1, char);
+       if (PL_origalen > 1) {
+           /* PL_origalen is set in perl_parse(). */
+           s = SvPV_force(sv,len);
+           if (len >= (STRLEN)PL_origalen-1) {
+               /* Longer than original, will be truncated. We assume that
+                * PL_origalen bytes are available. */
+               Copy(s, PL_origargv[0], PL_origalen-1, char);
+           }
+           else {
+               /* Shorter than original, will be padded. */
+               Copy(s, PL_origargv[0], len, char);
+               PL_origargv[0][len] = 0;
+               memset(PL_origargv[0] + len + 1,
+                      /* Is the space counterintuitive?  Yes.
+                       * (You were expecting \0?)  
+                       * Does it work?  Seems to.  (In Linux 2.4.20 at least.)
+                       * --jhi */
+                      (int)' ',
+                      PL_origalen - len - 1);
+           }
+           PL_origargv[0][PL_origalen-1] = 0;
+           for (i = 1; i < PL_origargc; i++)
+               PL_origargv[i] = 0;
        }
-       else {
-           /* Shorter than original, will be padded. */
-           Copy(s, PL_origargv[0], len, char);
-           PL_origargv[0][len] = 0;
-           memset(PL_origargv[0] + len + 1,
-                  /* Is the space counterintuitive?  Yes.
-                   * (You were expecting \0?)  
-                   * Does it work?  Seems to.  (In Linux 2.4.20 at least.)
-                   * --jhi */
-                  (int)' ',
-                  PL_origalen - len - 1);
-       }
-       PL_origargv[0][PL_origalen-1] = 0;
-       for (i = 1; i < PL_origargc; i++)
-           PL_origargv[i] = 0;
        UNLOCK_DOLLARZERO_MUTEX;
        break;
 #endif
@@ -2741,6 +2760,7 @@ cleanup:
 static void
 S_restore_magic(pTHX_ const void *p)
 {
+    dVAR;
     MGS* const mgs = SSPTR(PTR2IV(p), MGS*);
     SV* const sv = mgs->mgs_sv;