Add release date
[gitmo/Class-MOP.git] / MOP.xs
diff --git a/MOP.xs b/MOP.xs
index e4bdb81..cc532e1 100644 (file)
--- a/MOP.xs
+++ b/MOP.xs
@@ -13,6 +13,9 @@ U32 hash_name;
 SV *key_package;
 U32 hash_package;
 
+SV *key_package_name;
+U32 hash_package_name;
+
 SV *key_body;
 U32 hash_body;
 
@@ -29,10 +32,12 @@ BOOT:
     key_name = newSVpvs("name");
     key_body = newSVpvs("body");
     key_package = newSVpvs("package");
+    key_package_name = newSVpvs("package_name");
 
     PERL_HASH(hash_name, "name", 4);
     PERL_HASH(hash_body, "body", 4);
     PERL_HASH(hash_package, "package", 7);
+    PERL_HASH(hash_package_name, "package_name", 12);
 
 
 PROTOTYPES: ENABLE
@@ -80,6 +85,9 @@ get_all_package_symbols(self, ...)
         SV *type_filter = NULL;
         register HE *he;
     PPCODE:
+        if (! SvROK(self)) {
+            die("Cannot call get_all_package_symbols as a class method");
+        }
 
         switch ( GIMME_V ) {
             case G_VOID: return; break;
@@ -90,7 +98,7 @@ get_all_package_symbols(self, ...)
 
         PUTBACK;
 
-        if (SvROK(self) && (he = hv_fetch_ent((HV *)SvRV(self), key_package, 0, hash_package)))
+        if ((he = hv_fetch_ent((HV *)SvRV(self), key_package, 0, hash_package)))
             stash = gv_stashsv(HeVAL(he),0);
 
         if ( stash ) {
@@ -100,16 +108,13 @@ get_all_package_symbols(self, ...)
             if ( type_filter && SvPOK(type_filter) ) {
                 const char *const type = SvPV_nolen(type_filter);
 
-
                 while ((he = hv_iternext(stash))) {
                     SV *const gv = HeVAL(he);
                     SV *sv;
-                    char *package = HvNAME(stash);
-                    STRLEN pkglen = strlen(package);
                     char *key;
                     STRLEN keylen;
-                    char *fq;
-                    STRLEN fqlen;
+                    char *package;
+                    SV *fq;
 
                     switch( SvTYPE(gv) ) {
                         case SVt_PVGV:
@@ -125,12 +130,17 @@ get_all_package_symbols(self, ...)
                             break;
                         case SVt_RV:
                             /* BAH! constants are horrible */
+
+                            if (!SvROK (gv)) {
+                                continue;
+                            }
+
+                            /* we don't really care about the length,
+                               but that's the API */
                             key = HePV(he, keylen);
-                            fqlen = pkglen + keylen + 3;
-                            fq = (char *)alloca(fqlen);
-                            snprintf(fq, fqlen, "%s::%s", package, key);
-                            sv = (SV*)get_cv(fq, 0);
-                            sv_2mortal(sv);
+                            package = HvNAME(stash);
+                            fq = newSVpvf("%s::%s", package, key);
+                            sv = (SV*)get_cv(SvPV_nolen(fq), 0);
                             break;
                         default:
                             continue;
@@ -160,50 +170,81 @@ get_all_package_symbols(self, ...)
 
         }
 
-SV *
+void
 name(self)
     SV *self
     PREINIT:
         register HE *he;
     PPCODE:
-        if (SvROK(self) && (he = hv_fetch_ent((HV *)SvRV(self), key_package, 0, hash_package)))
+        if (! SvROK(self)) {
+            die("Cannot call name as a class method");
+        }
+
+        if ((he = hv_fetch_ent((HV *)SvRV(self), key_package, 0, hash_package)))
             XPUSHs(HeVAL(he));
         else
             ST(0) = &PL_sv_undef;
 
-MODULE = Class::MOP   PACKAGE = Class::Attribute
+MODULE = Class::MOP   PACKAGE = Class::MOP::Attribute
 
-SV *
+void
 name(self)
     SV *self
     PREINIT:
         register HE *he;
     PPCODE:
-        if (SvROK(self) && (he = hv_fetch_ent((HV *)SvRV(self), key_name, 0, hash_name)))
+        if (! SvROK(self)) {
+            die("Cannot call name as a class method");
+        }
+
+        if ((he = hv_fetch_ent((HV *)SvRV(self), key_name, 0, hash_name)))
             XPUSHs(HeVAL(he));
         else
             ST(0) = &PL_sv_undef;
 
-MODULE = Class::MOP   PACKAGE = Class::Method
+MODULE = Class::MOP   PACKAGE = Class::MOP::Method
 
-SV *
+void
 name(self)
     SV *self
     PREINIT:
         register HE *he;
     PPCODE:
-        if (SvROK(self) && (he = hv_fetch_ent((HV *)SvRV(self), key_name, 0, hash_name)))
+        if (! SvROK(self)) {
+            die("Cannot call name as a class method");
+        }
+
+        if ((he = hv_fetch_ent((HV *)SvRV(self), key_name, 0, hash_name)))
             XPUSHs(HeVAL(he));
         else
             ST(0) = &PL_sv_undef;
 
-SV *
+void
+package_name(self)
+    SV *self
+    PREINIT:
+        register HE *he;
+    PPCODE:
+        if (! SvROK(self)) {
+            die("Cannot call package_name as a class method");
+        }
+
+        if ((he = hv_fetch_ent((HV *)SvRV(self), key_package_name, 0, hash_package_name)))
+            XPUSHs(HeVAL(he));
+        else
+            ST(0) = &PL_sv_undef;
+
+void
 body(self)
     SV *self
     PREINIT:
         register HE *he;
     PPCODE:
-        if (SvROK(self) && (he = hv_fetch_ent((HV *)SvRV(self), key_body, 0, hash_body)))
+        if (! SvROK(self)) {
+            die("Cannot call body as a class method");
+        }
+
+        if ((he = hv_fetch_ent((HV *)SvRV(self), key_body, 0, hash_body)))
             XPUSHs(HeVAL(he));
         else
             ST(0) = &PL_sv_undef;