change#2879 broke rvalue autovivification of magicals such as ${$num}
[p5sagit/p5-mst-13.2.git] / gv.c
diff --git a/gv.c b/gv.c
index 587d3dc..1868114 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -448,10 +448,10 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
 /*
 =for apidoc gv_stashpv
 
-Returns a pointer to the stash for a specified package.  If C<create> is
-set then the package will be created if it does not already exist.  If
-C<create> is not set and the package does not exist then NULL is
-returned.
+Returns a pointer to the stash for a specified package.  C<name> should
+be a valid UTF-8 string.  If C<create> is set then the package will be
+created if it does not already exist.  If C<create> is not set and the
+package does not exist then NULL is returned.
 
 =cut
 */
@@ -494,8 +494,8 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 create)
 /*
 =for apidoc gv_stashsv
 
-Returns a pointer to the stash for a specified package.  See
-C<gv_stashpv>.
+Returns a pointer to the stash for a specified package, which must be a
+valid UTF-8 string.  See C<gv_stashpv>.
 
 =cut
 */
@@ -520,7 +520,6 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
     I32 len;
     register const char *namend;
     HV *stash = 0;
-    U32 add_gvflags = 0;
 
     if (*name == '*' && isALPHA(name[1])) /* accidental stringify on a GV? */
        name++;
@@ -631,7 +630,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
                            sv_type == SVt_PVHV ? '%' : '$',
                            name);
                        if (GvCVu(*gvp))
-                           Perl_warn(aTHX_ "(Did you mean &%s instead?)\n", name);
+                           Perl_warn(aTHX_ "\t(Did you mean &%s instead?)\n", name);
                        stash = 0;
                    }
                }
@@ -653,8 +652,10 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
                  : sv_type == SVt_PVAV ? "@"
                  : sv_type == SVt_PVHV ? "%"
                  : ""), name));
+           stash = PL_nullstash;
        }
-       return Nullgv;
+       else
+           return Nullgv;
     }
 
     if (!SvREFCNT(stash))      /* symbol table under destruction */
@@ -680,7 +681,6 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
        Perl_warner(aTHX_ WARN_INTERNAL, "Had to create %s unexpectedly", nambeg);
     gv_init(gv, stash, name, len, add & GV_ADDMULTI);
     gv_init_sv(gv, sv_type);
-    GvFLAGS(gv) |= add_gvflags;
 
     if (isLEXWARN_on && isALPHA(name[0]) && ! ckWARN(WARN_ONCE))
         GvMULTI_on(gv) ;
@@ -1580,3 +1580,110 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
     }
   }
 }
+
+/*
+=for apidoc is_gv_magical
+
+Returns C<TRUE> if given the name of a magical GV.
+
+Currently only useful internally when determining if a GV should be
+created even in rvalue contexts.
+
+C<flags> is not used at present but available for future extension to
+allow selecting particular classes of magical variable.
+
+=cut
+*/
+bool
+Perl_is_gv_magical(pTHX_ char *name, STRLEN len, U32 flags)
+{
+    if (!len)
+       return FALSE;
+
+    switch (*name) {
+    case 'I':
+       if (len == 3 && strEQ(name, "ISA"))
+           goto yes;
+       break;
+    case 'O':
+       if (len == 8 && strEQ(name, "OVERLOAD"))
+           goto yes;
+       break;
+    case 'S':
+       if (len == 3 && strEQ(name, "SIG"))
+           goto yes;
+       break;
+    case '\027':   /* $^W & $^WARNING_BITS */
+       if (len == 1
+           || (len == 12 && strEQ(name, "\027ARNING_BITS"))
+           || (len == 17 && strEQ(name, "\027IDE_SYSTEM_CALLS")))
+       {
+           goto yes;
+       }
+       break;
+
+    case '&':
+    case '`':
+    case '\'':
+    case ':':
+    case '?':
+    case '!':
+    case '-':
+    case '#':
+    case '*':
+    case '[':
+    case '^':
+    case '~':
+    case '=':
+    case '%':
+    case '.':
+    case '(':
+    case ')':
+    case '<':
+    case '>':
+    case ',':
+    case '\\':
+    case '/':
+    case '|':
+    case '+':
+    case ';':
+    case ']':
+    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 '\014':   /* $^L */
+    case '\017':   /* $^O */
+    case '\020':   /* $^P */
+    case '\023':   /* $^S */
+    case '\024':   /* $^T */
+    case '\026':   /* $^V */
+       if (len == 1)
+           goto yes;
+       break;
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+       if (len > 1) {
+           char *end = name + len;
+           while (--end > name) {
+               if (!isDIGIT(*end))
+                   return FALSE;
+           }
+       }
+    yes:
+       return TRUE;
+    default:
+       break;
+    }
+    return FALSE;
+}