summaryrefslogtreecommitdiffstats
path: root/Stash.xs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2010-11-12 15:02:18 -0600
committerJesse Luehrs <doy@tozt.net>2010-11-12 15:02:18 -0600
commitfca4ed0c33214a7710c5b4bd20858863d0be7ed4 (patch)
tree1e5361b3dd0999bc7c989ea42ab9524dc110fd21 /Stash.xs
parent301f570b58526c2263a537fefda6667aa73eacab (diff)
downloadpackage-stash-xs-fca4ed0c33214a7710c5b4bd20858863d0be7ed4.tar.gz
package-stash-xs-fca4ed0c33214a7710c5b4bd20858863d0be7ed4.zip
implement the rest of get_package_symbol
Diffstat (limited to 'Stash.xs')
-rw-r--r--Stash.xs73
1 files changed, 48 insertions, 25 deletions
diff --git a/Stash.xs b/Stash.xs
index 42b3ee5..ff8cf70 100644
--- a/Stash.xs
+++ b/Stash.xs
@@ -396,37 +396,30 @@ get_package_symbol(self, variable, ...)
HV *namespace;
SV **entry;
GV *glob;
+ int i, vivify = 0;
+ SV *val;
CODE:
- namespace = _get_namespace(self);
-
- if (!hv_exists(namespace, variable.name, strlen(variable.name))) {
- int i, vivify = 0;
- if ((items - 2) % 2)
- croak("get_package_symbol: Odd number of elements in %%opts");
-
- for (i = 2; i < items; i += 2) {
- char *key;
- key = SvPV_nolen(ST(i));
- if (strEQ(key, "vivify")) {
- vivify = SvTRUE(ST(i + 1));
- }
- }
+ if (items > 2 && (items - 2) % 2)
+ croak("get_package_symbol: Odd number of elements in %%opts");
- if (vivify) {
- /* XXX: vivify */
+ for (i = 2; i < items; i += 2) {
+ char *key;
+ key = SvPV_nolen(ST(i));
+ if (strEQ(key, "vivify")) {
+ vivify = SvTRUE(ST(i + 1));
}
}
- entry = hv_fetch(namespace, variable.name, strlen(variable.name), 0);
+ namespace = _get_namespace(self);
+ entry = hv_fetch(namespace, variable.name, strlen(variable.name), vivify);
if (!entry)
XSRETURN_UNDEF;
glob = (GV*)(*entry);
-
- if (!isGV(*entry)) {
+ if (!isGV(glob)) {
SV *namesv;
char *name;
- int len;
+ STRLEN len;
namesv = newSVsv(_get_name(self));
sv_catpvs(namesv, "::");
@@ -437,23 +430,53 @@ get_package_symbol(self, variable, ...)
gv_init(glob, namespace, name, len, 1);
}
+ if (vivify) {
+ switch (variable.type) {
+ case VAR_SCALAR:
+ if (!GvSV(glob))
+ GvSV(glob) = newSV(0);
+ break;
+ case VAR_ARRAY:
+ if (!GvAV(glob))
+ GvAV(glob) = newAV();
+ break;
+ case VAR_HASH:
+ if (!GvHV(glob))
+ GvHV(glob) = newHV();
+ break;
+ case VAR_CODE:
+ croak("Don't know how to vivify CODE variables");
+ case VAR_IO:
+ if (!GvIO(glob))
+ GvIOp(glob) = newIO();
+ break;
+ default:
+ croak("Unknown type in vivication");
+ }
+ }
+
switch (variable.type) {
case VAR_SCALAR:
- RETVAL = newRV(GvSV(glob));
+ val = GvSV(glob);
break;
case VAR_ARRAY:
- RETVAL = newRV((SV*)GvAV(glob));
+ val = (SV*)GvAV(glob);
break;
case VAR_HASH:
- RETVAL = newRV((SV*)GvHV(glob));
+ val = (SV*)GvHV(glob);
break;
case VAR_CODE:
- RETVAL = newRV((SV*)GvCV(glob));
+ val = (SV*)GvCV(glob);
break;
case VAR_IO:
- RETVAL = newRV((SV*)GvIO(glob));
+ val = (SV*)GvIO(glob);
break;
}
+
+ if (!val)
+ XSRETURN_UNDEF;
+
+ RETVAL = newRV(val);
OUTPUT:
RETVAL