From 4871b1a089d2ccfc436fb1891f8186a4c80bbc06 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 12 Nov 2010 15:15:44 -0600 Subject: get_or_add_package_symbol --- Stash.xs | 159 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 81 insertions(+), 78 deletions(-) (limited to 'Stash.xs') diff --git a/Stash.xs b/Stash.xs index ff8cf70..ce062ba 100644 --- a/Stash.xs +++ b/Stash.xs @@ -195,6 +195,73 @@ SV *_get_name(SV *self) return ret; } +SV *_get_package_symbol(SV *self, varspec_t *variable, int vivify) +{ + HV *namespace; + SV **entry; + GV *glob; + + namespace = _get_namespace(self); + entry = hv_fetch(namespace, variable->name, strlen(variable->name), vivify); + if (!entry) + return NULL; + + glob = (GV*)(*entry); + if (!isGV(glob)) { + SV *namesv; + char *name; + STRLEN len; + + namesv = newSVsv(_get_name(self)); + sv_catpvs(namesv, "::"); + sv_catpv(namesv, variable->name); + + name = SvPV(namesv, len); + + 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: + return GvSV(glob); + case VAR_ARRAY: + return (SV*)GvAV(glob); + case VAR_HASH: + return (SV*)GvHV(glob); + case VAR_CODE: + return (SV*)GvCV(glob); + case VAR_IO: + return (SV*)GvIO(glob); + default: + return NULL; + } +} + MODULE = Package::Stash PACKAGE = Package::Stash PROTOTYPES: DISABLE @@ -389,93 +456,29 @@ has_package_symbol(self, variable) RETVAL SV* -get_package_symbol(self, variable, ...) +get_package_symbol(self, variable) SV *self varspec_t variable PREINIT: - HV *namespace; - SV **entry; - GV *glob; - int i, vivify = 0; SV *val; CODE: - if (items > 2 && (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)); - } - } - - namespace = _get_namespace(self); - entry = hv_fetch(namespace, variable.name, strlen(variable.name), vivify); - if (!entry) + val = _get_package_symbol(self, &variable, 0); + if (!val) XSRETURN_UNDEF; + RETVAL = newRV(val); + OUTPUT: + RETVAL - glob = (GV*)(*entry); - if (!isGV(glob)) { - SV *namesv; - char *name; - STRLEN len; - - namesv = newSVsv(_get_name(self)); - sv_catpvs(namesv, "::"); - sv_catpv(namesv, variable.name); - - name = SvPV(namesv, len); - - 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: - val = GvSV(glob); - break; - case VAR_ARRAY: - val = (SV*)GvAV(glob); - break; - case VAR_HASH: - val = (SV*)GvHV(glob); - break; - case VAR_CODE: - val = (SV*)GvCV(glob); - break; - case VAR_IO: - val = (SV*)GvIO(glob); - break; - } - +SV* +get_or_add_package_symbol(self, variable) + SV *self + varspec_t variable + PREINIT: + SV *val; + CODE: + val = _get_package_symbol(self, &variable, 1); if (!val) XSRETURN_UNDEF; - RETVAL = newRV(val); OUTPUT: RETVAL -- cgit v1.2.3-54-g00ecf