This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
64bit ints & Cygwin98 ok
[perl5.git] / gv.c
diff --git a/gv.c b/gv.c
index e4951a0..eb7b3ba 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -72,6 +72,7 @@ Perl_gv_fetchfile(pTHX_ const char *name)
        tmpbuf = smallbuf;
     else
        New(603, tmpbuf, tmplen + 1, char);
+    /* This is where the debugger's %{"::_<$filename"} hash is created */
     tmpbuf[0] = '_';
     tmpbuf[1] = '<';
     strcpy(tmpbuf + 2, name);
@@ -128,13 +129,13 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
        CvGV(GvCV(gv)) = gv;
        CvFILE_set_from_cop(GvCV(gv), PL_curcop);
        CvSTASH(GvCV(gv)) = PL_curstash;
-#ifdef USE_THREADS
+#ifdef USE_5005THREADS
        CvOWNER(GvCV(gv)) = 0;
        if (!CvMUTEXP(GvCV(gv))) {
            New(666, CvMUTEXP(GvCV(gv)), 1, perl_mutex);
            MUTEX_INIT(CvMUTEXP(GvCV(gv)));
        }
-#endif /* USE_THREADS */
+#endif /* USE_5005THREADS */
        if (proto) {
            sv_setpv((SV*)GvCV(gv), proto);
            Safefree(proto);
@@ -411,8 +412,8 @@ Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
 GV*
 Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
 {
-    static char autoload[] = "AUTOLOAD";
-    static STRLEN autolen = 8;
+    char autoload[] = "AUTOLOAD";
+    STRLEN autolen = sizeof(autoload)-1;
     GV* gv;
     CV* cv;
     HV* varstash;
@@ -439,7 +440,7 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
          "Use of inherited AUTOLOAD for non-method %s::%.*s() is deprecated",
             HvNAME(stash), (int)len, name);
 
-#ifndef USE_THREADS
+#ifndef USE_5005THREADS
     if (CvXSUB(cv)) {
         /* rather than lookup/init $AUTOLOAD here
          * only to have the XSUB do another lookup for $AUTOLOAD
@@ -463,14 +464,14 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
     vargv = *(GV**)hv_fetch(varstash, autoload, autolen, TRUE);
     ENTER;
 
-#ifdef USE_THREADS
+#ifdef USE_5005THREADS
     sv_lock((SV *)varstash);
 #endif
     if (!isGV(vargv))
        gv_init(vargv, varstash, autoload, autolen, FALSE);
     LEAVE;
     varsv = GvSV(vargv);
-#ifdef USE_THREADS
+#ifdef USE_5005THREADS
     sv_lock(varsv);
 #endif
     sv_setpv(varsv, HvNAME(stash));
@@ -656,7 +657,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
                  strEQ(name, "ARGVOUT")))
                    global = TRUE;
            }
-           else if (*name == '_' && !name[1])
+           else if (*name == '_' && (!name[1] || strEQ(name,"__ANON__")))
                global = TRUE;
 
            if (global)
@@ -814,20 +815,16 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
        break;
 
     case '&':
-       if (len > 1)
-           break;
-       PL_sawampersand = TRUE;
-       goto ro_magicalize;
-
     case '`':
-       if (len > 1)
-           break;
-       PL_sawampersand = TRUE;
-       goto ro_magicalize;
-
     case '\'':
-       if (len > 1)
-           break;
+       if (
+           len > 1 ||
+           sv_type == SVt_PVAV ||
+           sv_type == SVt_PVHV ||
+           sv_type == SVt_PVCV ||
+           sv_type == SVt_PVFM ||
+           sv_type == SVt_PVIO
+       ) { break; }
        PL_sawampersand = TRUE;
        goto ro_magicalize;
 
@@ -891,13 +888,11 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
     case '\001':       /* $^A */
     case '\003':       /* $^C */
     case '\004':       /* $^D */
-    case '\005':       /* $^E */
     case '\006':       /* $^F */
     case '\010':       /* $^H */
     case '\011':       /* $^I, NOT \t in EBCDIC */
     case '\016':        /* $^N */
     case '\020':       /* $^P */
-    case '\024':       /* $^T */
        if (len > 1)
            break;
        goto magicalize;
@@ -906,6 +901,11 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
            break;
        sv_setiv(GvSV(gv), (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0);
        goto magicalize;
+    case '\005':       /* $^E && $^ENCODING */
+       if (len > 1 && strNE(name, "\005NCODING"))
+           break;
+       goto magicalize;
+
     case '\017':       /* $^O & $^OPEN */
        if (len > 1 && strNE(name, "\017PEN"))
            break;
@@ -914,6 +914,13 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
        if (len > 1)
            break;
        goto ro_magicalize;
+    case '\024':       /* $^T, ${^TAINT} */
+        if (len == 1)
+            goto magicalize;
+        else if (strEQ(name, "\024AINT"))
+            goto ro_magicalize;
+        else
+            break;
     case '\027':       /* $^W & $^WARNING_BITS */
        if (len > 1 && strNE(name, "\027ARNING_BITS")
            && strNE(name, "\027IDE_SYSTEM_CALLS"))
@@ -938,6 +945,17 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
     case '7':
     case '8':
     case '9':
+       /* ensures variable is only digits */
+       /* ${"1foo"} fails this test (and is thus writeable) */
+       /* added by japhy, but borrowed from is_gv_magical */
+
+       if (len > 1) {
+           const char *end = name + len;
+           while (--end > name) {
+               if (!isDIGIT(*end)) return gv;
+           }
+       }
+
       ro_magicalize:
        SvREADONLY_on(GvSV(gv));
       magicalize:
@@ -1279,7 +1297,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash)
            if (GvNAMELEN(CvGV(cv)) == 3 && strEQ(GvNAME(CvGV(cv)), "nil")
                && strEQ(HvNAME(GvSTASH(CvGV(cv))), "overload")) {
                /* GvSV contains the name of the method. */
-               GV *ngv;
+               GV *ngv = Nullgv;
                
                DEBUG_o( Perl_deb(aTHX_ "Resolving method `%.256s' for overloaded `%s' in package `%.256s'\n",
                             SvPV_nolen(GvSV(gv)), cp, HvNAME(stash)) );
@@ -1777,11 +1795,14 @@ Perl_is_gv_magical(pTHX_ char *name, STRLEN len, U32 flags)
     case '\016':   /* $^N */
     case '\020':   /* $^P */
     case '\023':   /* $^S */
-    case '\024':   /* $^T */
     case '\026':   /* $^V */
        if (len == 1)
            goto yes;
        break;
+    case '\024':   /* $^T, ${^TAINT} */
+        if (len == 1 || strEQ(name, "\024AINT"))
+            goto yes;
+        break;
     case '1':
     case '2':
     case '3':