diff options
author | Karl Williamson <public@khwilliamson.com> | 2011-12-18 20:45:14 -0700 |
---|---|---|
committer | Karl Williamson <public@khwilliamson.com> | 2011-12-20 22:02:42 -0700 |
commit | fbb93542d6662666a88828fb4c15803f8ba377f0 (patch) | |
tree | 300d9b114ad07a3281c6575d2abb02b7645389b7 /toke.c | |
parent | f8988b416c244747b17eb3004ac6f8bbcf366e7a (diff) | |
download | perl-fbb93542d6662666a88828fb4c15803f8ba377f0.tar.gz |
Autoload charnames for \N{name}
This autoloads charnames.pm when needed. It uses the :full and :short
options. :loose is not used because of its relative unfamiliarity in
the Perl community, and is slower. (If someone later added a typical
"use charnames qw(:full)", things that previously matched under :loose
would start to fail, causing confustion. If :loose does become more
common, we can change this in the future to use it; the converse isn't
true.)
The callable functions in the module are not automatically loaded. To
access them, an explicity "use charnames" must be provided.
Thanks to Tony Cook for doing a code inspection and finding a missing
SPAGAIN.
Diffstat (limited to 'toke.c')
-rw-r--r-- | toke.c | 64 |
1 files changed, 39 insertions, 25 deletions
@@ -8610,7 +8610,7 @@ S_new_constant(pTHX_ const char *s, STRLEN len, const char *key, STRLEN keylen, SV *sv, SV *pv, const char *type, STRLEN typelen) { dVAR; dSP; - HV * const table = GvHV(PL_hintgv); /* ^H */ + HV * table = GvHV(PL_hintgv); /* ^H */ SV *res; SV **cvp; SV *cv, *typesv; @@ -8622,39 +8622,53 @@ S_new_constant(pTHX_ const char *s, STRLEN len, const char *key, STRLEN keylen, if (PL_error_count > 0 && strEQ(key,"charnames")) return &PL_sv_undef; - if (!table || !(PL_hints & HINT_LOCALIZE_HH)) { + if (!table + || ! (PL_hints & HINT_LOCALIZE_HH) + || ! (cvp = hv_fetch(table, key, keylen, FALSE)) + || ! SvOK(*cvp)) + { SV *msg; - why2 = (const char *) - (strEQ(key,"charnames") - ? "(possibly a missing \"use charnames ...\")" - : ""); - msg = Perl_newSVpvf(aTHX_ "Constant(%s) unknown: %s", - (type ? type: "undef"), why2); - - /* This is convoluted and evil ("goto considered harmful") - * but I do not understand the intricacies of all the different - * failure modes of %^H in here. The goal here is to make - * the most probable error message user-friendly. --jhi */ - - goto msgdone; - + /* Here haven't found what we're looking for. If it is charnames, + * perhaps it needs to be loaded. Try doing that before giving up */ + if (strEQ(key,"charnames")) { + Perl_load_module(aTHX_ + 0, + newSVpvs("_charnames"), + /* version parameter; no need to specify it, as if + * we get too early a version, will fail anyway, + * not being able to find '_charnames' */ + NULL, + newSVpvs(":full"), + newSVpvs(":short"), + NULL); + SPAGAIN; + table = GvHV(PL_hintgv); + if (table + && (PL_hints & HINT_LOCALIZE_HH) + && (cvp = hv_fetch(table, key, keylen, FALSE)) + && SvOK(*cvp)) + { + goto now_ok; + } + } + if (!table || !(PL_hints & HINT_LOCALIZE_HH)) { + msg = Perl_newSVpvf(aTHX_ + "Constant(%s) unknown", (type ? type: "undef")); + } + else { + why1 = "$^H{"; + why2 = key; + why3 = "} is not defined"; report: msg = Perl_newSVpvf(aTHX_ "Constant(%s): %s%s%s", (type ? type: "undef"), why1, why2, why3); - msgdone: + } yyerror(SvPVX_const(msg)); SvREFCNT_dec(msg); return sv; } - - cvp = hv_fetch(table, key, keylen, FALSE); - if (!cvp || !SvOK(*cvp)) { - why1 = "$^H{"; - why2 = key; - why3 = "} is not defined"; - goto report; - } +now_ok: sv_2mortal(sv); /* Parent created it permanently */ cv = *cvp; if (!pv && s) |