diff options
author | Jesse Luehrs <doy@tozt.net> | 2010-11-12 15:02:18 -0600 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2010-11-12 15:02:18 -0600 |
commit | fca4ed0c33214a7710c5b4bd20858863d0be7ed4 (patch) | |
tree | 1e5361b3dd0999bc7c989ea42ab9524dc110fd21 /Stash.xs | |
parent | 301f570b58526c2263a537fefda6667aa73eacab (diff) | |
download | package-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.xs | 73 |
1 files changed, 48 insertions, 25 deletions
@@ -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 |