From fca4ed0c33214a7710c5b4bd20858863d0be7ed4 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 12 Nov 2010 15:02:18 -0600 Subject: implement the rest of get_package_symbol --- Stash.xs | 73 ++++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 25 deletions(-) (limited to 'Stash.xs') 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 -- cgit v1.2.3-54-g00ecf