The best way not to have the missing subroutines hash trample all over
Nicholas Clark [Mon, 10 Sep 2007 11:10:37 +0000 (11:10 +0000)]
someone else's namespace is by not having it in their namespace in the
first place :-)

p4raw-id: //depot/perl@31839

lib/ExtUtils/Constant/ProxySubs.pm

index 5ae56db..af8c458 100644 (file)
@@ -242,6 +242,52 @@ static MGVTBL not_defined_vtbl = {
 
 EXPLODE
 
+{
+    my $key = $symbol_table;
+    # Just seems tidier (and slightly more space efficient) not to have keys
+    # such as Fcntl::
+    $key =~ s/::$//;
+    my $key_len = length $key;
+
+    print $c_fh <<"MISSING";
+
+#ifndef SYMBIAN
+
+/* Store a hash of all symbols missing from the package. To avoid trampling on
+   the package namespace (uninvited) put each package's hash in our namespace.
+   To avoid creating lots of typeblogs and symbol tables for sub-packages, put
+   each package's hash into one hash in our namespace.  */
+
+static HV *
+get_missing_hash(pTHX) {
+    HV *const parent
+       = get_hv("ExtUtils::Constant::ProxySubs::Missing", GVf_MULTI);
+    /* We could make a hash of hashes directly, but this would confuse anything
+       at Perl space that looks at us, and as we're visible in Perl space,
+       best to play nice. */
+    SV *const *const ref
+       = hv_fetch(parent, "$key", $key_len, TRUE);
+    HV *new_hv;
+
+    if (!ref)
+       return NULL;
+
+    if (SvROK(*ref))
+       return (HV*) SvRV(*ref);
+
+    new_hv = newHV();
+    SvUPGRADE(*ref, SVt_RV);
+    SvRV_set(*ref, (SV *)new_hv);
+    SvROK_on(*ref);
+    return new_hv;
+}
+
+#endif
+
+MISSING
+
+}
+
     print $xs_fh <<"EOBOOT";
 BOOT:
   {
@@ -312,10 +358,7 @@ EOBOOT
 
     print $xs_fh <<"EOBOOT";
 #ifndef SYMBIAN
-       ${c_subname}_missing = get_hv("${symbol_table}${c_subname}_M!55!NG", TRUE);
-       /* When we create the 'missing' hash, it generates a 'used only once'
-        * warning.  Avoid this: */
-       ${c_subname}_missing = get_hv("${symbol_table}${c_subname}_M!55!NG", TRUE);
+       ${c_subname}_missing = get_missing_hash(aTHX);
 #endif
 EOBOOT
 
@@ -464,7 +507,7 @@ $xs_subname(sv)
 #ifdef SYMBIAN
        sv = newSVpvf("%"SVf" is not a valid $package_sprintf_safe macro", sv);
 #else
-       HV *${c_subname}_missing = get_hv("${c_subname}_M!55!NG", FALSE);
+       HV *${c_subname}_missing = get_missing_hash(aTHX);
        if (hv_exists(${c_subname}_missing, s, SvUTF8(sv) ? -(I32)len : (I32)len)) {
            sv = newSVpvf("Your vendor has not defined $package_sprintf_safe macro %" SVf
                          ", used", sv);