Allow option to treat barewords at start of Unix paths as simple words rather than...
[p5sagit/p5-mst-13.2.git] / sv.c
diff --git a/sv.c b/sv.c
index a61d2ea..4bdf847 100644 (file)
--- a/sv.c
+++ b/sv.c
 #endif
 
 #ifdef PERL_OBJECT
-#define FCALL this->*f
 #define VTBL this->*vtbl
 #else /* !PERL_OBJECT */
 #define VTBL *vtbl
-#define FCALL *f
 #endif /* PERL_OBJECT */
 
+#define FCALL *f
 #define SV_CHECK_THINKFIRST(sv) if (SvTHINKFIRST(sv)) sv_force_normal(sv)
 
+static void do_report_used(pTHXo_ SV *sv);
+static void do_clean_objs(pTHXo_ SV *sv);
+#ifndef DISABLE_DESTRUCTOR_KLUDGE
+static void do_clean_named_objs(pTHXo_ SV *sv);
+#endif
+static void do_clean_all(pTHXo_ SV *sv);
+
+
 #ifdef PURIFY
 
 #define new_SV(p) \
@@ -205,7 +212,9 @@ S_del_sv(pTHX_ SV *p)
                ok = 1;
        }
        if (!ok) {
-           Perl_warn(aTHX_ "Attempt to free non-arena SV: 0x%lx", (unsigned long)p);
+           if (ckWARN_d(WARN_INTERNAL))        
+               Perl_warner(aTHX_ WARN_INTERNAL,
+                      "Attempt to free non-arena SV: 0x%lx", (unsigned long)p);
            return;
        }
     }
@@ -275,87 +284,36 @@ S_visit(pTHX_ SVFUNC_t f)
        svend = &sva[SvREFCNT(sva)];
        for (sv = sva + 1; sv < svend; ++sv) {
            if (SvTYPE(sv) != SVTYPEMASK)
-               (FCALL)(aTHX_ sv);
+               (FCALL)(aTHXo_ sv);
        }
     }
 }
 
 #endif /* PURIFY */
 
-STATIC void
-S_do_report_used(pTHX_ SV *sv)
-{
-    if (SvTYPE(sv) != SVTYPEMASK) {
-       /* XXX Perhaps this ought to go to Perl_debug_log, if DEBUGGING. */
-       PerlIO_printf(PerlIO_stderr(), "****\n");
-       sv_dump(sv);
-    }
-}
-
 void
 Perl_sv_report_used(pTHX)
 {
-    visit(FUNC_NAME_TO_PTR(S_do_report_used));
-}
-
-STATIC void
-S_do_clean_objs(pTHX_ SV *sv)
-{
-    SV* rv;
-
-    if (SvROK(sv) && SvOBJECT(rv = SvRV(sv))) {
-       DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning object ref:\n "), sv_dump(sv));)
-       SvROK_off(sv);
-       SvRV(sv) = 0;
-       SvREFCNT_dec(rv);
-    }
-
-    /* XXX Might want to check arrays, etc. */
-}
-
-#ifndef DISABLE_DESTRUCTOR_KLUDGE
-STATIC void
-S_do_clean_named_objs(pTHX_ SV *sv)
-{
-    if (SvTYPE(sv) == SVt_PVGV) {
-       if ( SvOBJECT(GvSV(sv)) ||
-            GvAV(sv) && SvOBJECT(GvAV(sv)) ||
-            GvHV(sv) && SvOBJECT(GvHV(sv)) ||
-            GvIO(sv) && SvOBJECT(GvIO(sv)) ||
-            GvCV(sv) && SvOBJECT(GvCV(sv)) )
-       {
-           DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning named glob object:\n "), sv_dump(sv));)
-           SvREFCNT_dec(sv);
-       }
-    }
+    visit(do_report_used);
 }
-#endif
 
 void
 Perl_sv_clean_objs(pTHX)
 {
     PL_in_clean_objs = TRUE;
-    visit(FUNC_NAME_TO_PTR(S_do_clean_objs));
+    visit(do_clean_objs);
 #ifndef DISABLE_DESTRUCTOR_KLUDGE
     /* some barnacles may yet remain, clinging to typeglobs */
-    visit(FUNC_NAME_TO_PTR(S_do_clean_named_objs));
+    visit(do_clean_named_objs);
 #endif
     PL_in_clean_objs = FALSE;
 }
 
-STATIC void
-S_do_clean_all(pTHX_ SV *sv)
-{
-    DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning loops: SV at 0x%lx\n", sv) );)
-    SvFLAGS(sv) |= SVf_BREAK;
-    SvREFCNT_dec(sv);
-}
-
 void
 Perl_sv_clean_all(pTHX)
 {
     PL_in_clean_all = TRUE;
-    visit(FUNC_NAME_TO_PTR(S_do_clean_all));
+    visit(do_clean_all);
     PL_in_clean_all = FALSE;
 }
 
@@ -1149,17 +1107,10 @@ Perl_sv_2iv(pTHX_ register SV *sv)
              return SvIV(tmpstr);
          return (IV)SvRV(sv);
        }
-       if (SvREADONLY(sv)) {
-           if (SvNOKp(sv)) {
-               return I_V(SvNVX(sv));
-           }
-           if (SvPOKp(sv) && SvLEN(sv))
-               return asIV(sv);
-           {
-               dTHR;
-               if (ckWARN(WARN_UNINITIALIZED))
-                   Perl_warner(aTHX_ WARN_UNINITIALIZED, PL_warn_uninit);
-           }
+       if (SvREADONLY(sv) && !SvOK(sv)) {
+           dTHR;
+           if (ckWARN(WARN_UNINITIALIZED))
+               Perl_warner(aTHX_ WARN_UNINITIALIZED, PL_warn_uninit);
            return 0;
        }
     }
@@ -1294,17 +1245,10 @@ Perl_sv_2uv(pTHX_ register SV *sv)
              return SvUV(tmpstr);
          return (UV)SvRV(sv);
        }
-       if (SvREADONLY(sv)) {
-           if (SvNOKp(sv)) {
-               return U_V(SvNVX(sv));
-           }
-           if (SvPOKp(sv) && SvLEN(sv))
-               return asUV(sv);
-           {
-               dTHR;
-               if (ckWARN(WARN_UNINITIALIZED))
-                   Perl_warner(aTHX_ WARN_UNINITIALIZED, PL_warn_uninit);
-           }
+       if (SvREADONLY(sv) && !SvOK(sv)) {
+           dTHR;
+           if (ckWARN(WARN_UNINITIALIZED))
+               Perl_warner(aTHX_ WARN_UNINITIALIZED, PL_warn_uninit);
            return 0;
        }
     }
@@ -1465,19 +1409,8 @@ Perl_sv_2nv(pTHX_ register SV *sv)
              return SvNV(tmpstr);
          return (NV)(unsigned long)SvRV(sv);
        }
-       if (SvREADONLY(sv)) {
+       if (SvREADONLY(sv) && !SvOK(sv)) {
            dTHR;
-           if (SvPOKp(sv) && SvLEN(sv)) {
-               if (ckWARN(WARN_NUMERIC) && !SvIOKp(sv) && !looks_like_number(sv))
-                   not_a_number(sv);
-               return Atof(SvPVX(sv));
-           }
-           if (SvIOKp(sv)) {
-               if (SvIsUV(sv)) 
-                   return (NV)SvUVX(sv);
-               else
-                   return (NV)SvIVX(sv);
-           }
            if (ckWARN(WARN_UNINITIALIZED))
                Perl_warner(aTHX_ WARN_UNINITIALIZED, PL_warn_uninit);
            return 0.0;
@@ -1859,29 +1792,10 @@ Perl_sv_2pv(pTHX_ register SV *sv, STRLEN *lp)
            *lp = strlen(s);
            return s;
        }
-       if (SvREADONLY(sv)) {
-           if (SvNOKp(sv)) {           /* See note in sv_2uv() */
-               /* XXXX 64-bit?  IV may have better precision... */
-               Gconvert(SvNVX(sv), DBL_DIG, 0, tmpbuf);
-               tsv = Nullsv;
-               goto tokensave;
-           }
-           if (SvIOKp(sv)) {
-               char *ebuf;
-
-               if (SvIsUV(sv))
-                   tmpbuf = uiv_2buf(tbuf, 0, SvUVX(sv), 1, &ebuf);
-               else
-                   tmpbuf = uiv_2buf(tbuf, SvIVX(sv), 0, 0, &ebuf);
-               *ebuf = 0;
-               tsv = Nullsv;
-               goto tokensave;
-           }
-           {
-               dTHR;
-               if (ckWARN(WARN_UNINITIALIZED))
-                   Perl_warner(aTHX_ WARN_UNINITIALIZED, PL_warn_uninit);
-           }
+       if (SvREADONLY(sv) && !SvOK(sv)) {
+           dTHR;
+           if (ckWARN(WARN_UNINITIALIZED))
+               Perl_warner(aTHX_ WARN_UNINITIALIZED, PL_warn_uninit);
            *lp = 0;
            return "";
        }
@@ -1914,30 +1828,36 @@ Perl_sv_2pv(pTHX_ register SV *sv, STRLEN *lp)
     }
     else if (SvIOKp(sv)) {
        U32 isIOK = SvIOK(sv);
+       U32 isUIOK = SvIsUV(sv);
        char buf[TYPE_CHARS(UV)];
        char *ebuf, *ptr;
 
        if (SvTYPE(sv) < SVt_PVIV)
            sv_upgrade(sv, SVt_PVIV);
-       if (SvIsUV(sv)) {
+       if (isUIOK)
            ptr = uiv_2buf(buf, 0, SvUVX(sv), 1, &ebuf);
-           sv_setpvn(sv, ptr, ebuf - ptr);
-           SvIsUV_on(sv);
-       }
-       else {
+       else
            ptr = uiv_2buf(buf, SvIVX(sv), 0, 0, &ebuf);
-           sv_setpvn(sv, ptr, ebuf - ptr);
-       }
+       SvGROW(sv, ebuf - ptr + 1);     /* inlined from sv_setpvn */
+       Move(ptr,SvPVX(sv),ebuf - ptr,char);
+       SvCUR_set(sv, ebuf - ptr);
        s = SvEND(sv);
+       *s = '\0';
        if (isIOK)
            SvIOK_on(sv);
        else
            SvIOKp_on(sv);
+       if (isUIOK)
+           SvIsUV_on(sv);
+       SvPOK_on(sv);
     }
     else {
        dTHR;
-       if (ckWARN(WARN_UNINITIALIZED) && !PL_localizing && !(SvFLAGS(sv) & SVs_PADTMP))
+       if (ckWARN(WARN_UNINITIALIZED)
+           && !PL_localizing && !(SvFLAGS(sv) & SVs_PADTMP))
+       {
            Perl_warner(aTHX_ WARN_UNINITIALIZED, PL_warn_uninit);
+       }
        *lp = 0;
        if (SvTYPE(sv) < SVt_PV)
            /* Typically the caller expects that sv_any is not NULL now.  */
@@ -1947,7 +1867,8 @@ Perl_sv_2pv(pTHX_ register SV *sv, STRLEN *lp)
     *lp = s - SvPVX(sv);
     SvCUR_set(sv, *lp);
     SvPOK_on(sv);
-    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2pv(%s)\n",(unsigned long)sv,SvPVX(sv)));
+    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2pv(%s)\n",
+                         (unsigned long)sv,SvPVX(sv)));
     return SvPVX(sv);
 
   tokensave:
@@ -2966,10 +2887,11 @@ Perl_sv_insert(pTHX_ SV *bigstr, STRLEN offset, STRLEN len, char *little, STRLEN
 void
 Perl_sv_replace(pTHX_ register SV *sv, register SV *nsv)
 {
+    dTHR;
     U32 refcnt = SvREFCNT(sv);
     SV_CHECK_THINKFIRST(sv);
-    if (SvREFCNT(nsv) != 1)
-       Perl_warn(aTHX_ "Reference miscount in sv_replace()");
+    if (SvREFCNT(nsv) != 1 && ckWARN_d(WARN_INTERNAL))
+       Perl_warner(aTHX_ WARN_INTERNAL, "Reference miscount in sv_replace()");
     if (SvMAGICAL(sv)) {
        if (SvMAGICAL(nsv))
            mg_free(nsv);
@@ -3057,7 +2979,7 @@ Perl_sv_clear(pTHX_ register SV *sv)
            IoIFP(sv) != PerlIO_stdout() &&
            IoIFP(sv) != PerlIO_stderr())
        {
-         io_close((IO*)sv);
+           io_close((IO*)sv, FALSE);
        }
        if (IoDIRP(sv)) {
            PerlDir_close(IoDIRP(sv));
@@ -3186,6 +3108,7 @@ Perl_sv_newref(pTHX_ SV *sv)
 void
 Perl_sv_free(pTHX_ SV *sv)
 {
+    dTHR;
     int refcount_is_zero;
 
     if (!sv)
@@ -3200,7 +3123,8 @@ Perl_sv_free(pTHX_ SV *sv)
            SvREFCNT(sv) = (~(U32)0)/2;
            return;
        }
-       Perl_warn(aTHX_ "Attempt to free unreferenced scalar");
+       if (ckWARN_d(WARN_INTERNAL))
+           Perl_warner(aTHX_ WARN_INTERNAL, "Attempt to free unreferenced scalar");
        return;
     }
     ATOMIC_DEC_AND_TEST(refcount_is_zero, SvREFCNT(sv));
@@ -3208,7 +3132,9 @@ Perl_sv_free(pTHX_ SV *sv)
        return;
 #ifdef DEBUGGING
     if (SvTEMP(sv)) {
-       Perl_warn(aTHX_ "Attempt to free temp prematurely: SV 0x%lx", (unsigned long)sv);
+       if (ckWARN_d(WARN_DEBUGGING))
+           Perl_warner(aTHX_ WARN_DEBUGGING,
+                       "Attempt to free temp prematurely: SV 0x%lx", (unsigned long)sv);
        return;
     }
 #endif
@@ -3314,7 +3240,9 @@ Perl_sv_pos_b2u(pTHX_ register SV *sv, I32* offsetp)
        ++len;
     }
     if (s != send) {
-       Perl_warn(aTHX_ "Malformed UTF-8 character");
+        dTHR;
+       if (ckWARN_d(WARN_UTF8))    
+           Perl_warner(aTHX_ WARN_UTF8, "Malformed UTF-8 character");
        --len;
     }
     *offsetp = len;
@@ -3984,10 +3912,8 @@ Perl_newSVpvf_nocontext(const char* pat, ...)
     dTHX;
     register SV *sv;
     va_list args;
-
-    new_SV(sv);
     va_start(args, pat);
-    sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv = vnewSVpvf(pat, &args);
     va_end(args);
     return sv;
 }
@@ -3998,15 +3924,22 @@ Perl_newSVpvf(pTHX_ const char* pat, ...)
 {
     register SV *sv;
     va_list args;
-
-    new_SV(sv);
     va_start(args, pat);
-    sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv = vnewSVpvf(pat, &args);
     va_end(args);
     return sv;
 }
 
 SV *
+Perl_vnewSVpvf(pTHX_ const char* pat, va_list* args)
+{
+    register SV *sv;
+    new_SV(sv);
+    sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
+    return sv;
+}
+
+SV *
 Perl_newSVnv(pTHX_ NV n)
 {
     register SV *sv;
@@ -4051,12 +3984,14 @@ Perl_newRV(pTHX_ SV *tmpRef)
 SV *
 Perl_newSVsv(pTHX_ register SV *old)
 {
+    dTHR;
     register SV *sv;
 
     if (!old)
        return Nullsv;
     if (SvTYPE(old) == SVTYPEMASK) {
-       Perl_warn(aTHX_ "semi-panic: attempt to dup freed string");
+        if (ckWARN_d(WARN_INTERNAL))
+           Perl_warner(aTHX_ WARN_INTERNAL, "semi-panic: attempt to dup freed string");
        return Nullsv;
     }
     new_SV(sv);
@@ -4079,7 +4014,7 @@ Perl_sv_reset(pTHX_ register char *s, HV *stash)
     register I32 i;
     register PMOP *pm;
     register I32 max;
-    char todo[256];
+    char todo[PERL_UCHAR_MAX+1];
 
     if (!stash)
        return;
@@ -4098,11 +4033,11 @@ Perl_sv_reset(pTHX_ register char *s, HV *stash)
 
     Zero(todo, 256, char);
     while (*s) {
-       i = *s;
+       i = (unsigned char)*s;
        if (s[1] == '-') {
            s += 2;
        }
-       max = *s++;
+       max = (unsigned char)*s++;
        for ( ; i <= max; i++) {
            todo[i] = 1;
        }
@@ -4612,7 +4547,7 @@ Perl_sv_setpvf_nocontext(SV *sv, const char* pat, ...)
     dTHX;
     va_list args;
     va_start(args, pat);
-    sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv_vsetpvf(sv, pat, &args);
     va_end(args);
 }
 
@@ -4623,9 +4558,8 @@ Perl_sv_setpvf_mg_nocontext(SV *sv, const char* pat, ...)
     dTHX;
     va_list args;
     va_start(args, pat);
-    sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv_vsetpvf_mg(sv, pat, &args);
     va_end(args);
-    SvSETMAGIC(sv);
 }
 #endif
 
@@ -4634,18 +4568,29 @@ Perl_sv_setpvf(pTHX_ SV *sv, const char* pat, ...)
 {
     va_list args;
     va_start(args, pat);
-    sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv_vsetpvf(sv, pat, &args);
     va_end(args);
 }
 
+void
+Perl_sv_vsetpvf(pTHX_ SV *sv, const char* pat, va_list* args)
+{
+    sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
+}
 
 void
 Perl_sv_setpvf_mg(pTHX_ SV *sv, const char* pat, ...)
 {
     va_list args;
     va_start(args, pat);
-    sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv_vsetpvf_mg(sv, pat, &args);
     va_end(args);
+}
+
+void
+Perl_sv_vsetpvf_mg(pTHX_ SV *sv, const char* pat, va_list* args)
+{
+    sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
     SvSETMAGIC(sv);
 }
 
@@ -4656,7 +4601,7 @@ Perl_sv_catpvf_nocontext(SV *sv, const char* pat, ...)
     dTHX;
     va_list args;
     va_start(args, pat);
-    sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv_vcatpvf(sv, pat, &args);
     va_end(args);
 }
 
@@ -4666,9 +4611,8 @@ Perl_sv_catpvf_mg_nocontext(SV *sv, const char* pat, ...)
     dTHX;
     va_list args;
     va_start(args, pat);
-    sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv_vcatpvf_mg(sv, pat, &args);
     va_end(args);
-    SvSETMAGIC(sv);
 }
 #endif
 
@@ -4677,17 +4621,29 @@ Perl_sv_catpvf(pTHX_ SV *sv, const char* pat, ...)
 {
     va_list args;
     va_start(args, pat);
-    sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv_vcatpvf(sv, pat, &args);
     va_end(args);
 }
 
 void
+Perl_sv_vcatpvf(pTHX_ SV *sv, const char* pat, va_list* args)
+{
+    sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
+}
+
+void
 Perl_sv_catpvf_mg(pTHX_ SV *sv, const char* pat, ...)
 {
     va_list args;
     va_start(args, pat);
-    sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+    sv_vcatpvf_mg(sv, pat, &args);
     va_end(args);
+}
+
+void
+Perl_sv_vcatpvf_mg(pTHX_ SV *sv, const char* pat, va_list* args)
+{
+    sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
     SvSETMAGIC(sv);
 }
 
@@ -5230,3 +5186,61 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
        SvCUR(sv) = p - SvPVX(sv);
     }
 }
+
+
+#ifdef PERL_OBJECT
+#define NO_XSLOCKS
+#include "XSUB.h"
+#endif
+
+static void
+do_report_used(pTHXo_ SV *sv)
+{
+    if (SvTYPE(sv) != SVTYPEMASK) {
+       /* XXX Perhaps this ought to go to Perl_debug_log, if DEBUGGING. */
+       PerlIO_printf(PerlIO_stderr(), "****\n");
+       sv_dump(sv);
+    }
+}
+
+static void
+do_clean_objs(pTHXo_ SV *sv)
+{
+    SV* rv;
+
+    if (SvROK(sv) && SvOBJECT(rv = SvRV(sv))) {
+       DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning object ref:\n "), sv_dump(sv));)
+       SvROK_off(sv);
+       SvRV(sv) = 0;
+       SvREFCNT_dec(rv);
+    }
+
+    /* XXX Might want to check arrays, etc. */
+}
+
+#ifndef DISABLE_DESTRUCTOR_KLUDGE
+static void
+do_clean_named_objs(pTHXo_ SV *sv)
+{
+    if (SvTYPE(sv) == SVt_PVGV) {
+       if ( SvOBJECT(GvSV(sv)) ||
+            GvAV(sv) && SvOBJECT(GvAV(sv)) ||
+            GvHV(sv) && SvOBJECT(GvHV(sv)) ||
+            GvIO(sv) && SvOBJECT(GvIO(sv)) ||
+            GvCV(sv) && SvOBJECT(GvCV(sv)) )
+       {
+           DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning named glob object:\n "), sv_dump(sv));)
+           SvREFCNT_dec(sv);
+       }
+    }
+}
+#endif
+
+static void
+do_clean_all(pTHXo_ SV *sv)
+{
+    DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning loops: SV at 0x%lx\n", sv) );)
+    SvFLAGS(sv) |= SVf_BREAK;
+    SvREFCNT_dec(sv);
+}
+