diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-07-25 22:33:40 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-07-26 00:09:04 -0700 |
commit | b8c38f0a2a65800ef71a3715d0a31299fcfb4986 (patch) | |
tree | 59c92ee641df16c144dd57596edc22421381e102 /pp.c | |
parent | 69f26f522d3144d15f7bf1df76cb51db6af43d05 (diff) | |
download | perl-b8c38f0a2a65800ef71a3715d0a31299fcfb4986.tar.gz |
Add core_prototype; make pp_prototype use it
This commit moves the code for generating core prototypes into a sepa-
rate function, core_prototype, in op.c. This serves two porpoises:
• It allows the lock and tie exceptional cases to be incorporated into
the main prototype=generation code, which requires the use of a
static function in op.c.
• It allows other parts of the core (e.g., the upcoming \&CORE::foo
feature) to use the same code.
The docs for it are in a section boringly entitled ‘Functions in
op.c’, for lack of a better name. This, I believe, is the only op.c
function that is in perlintern currently, so it’s hard to see what to
name a section that will, at least for now, contain nothing else.
Diffstat (limited to 'pp.c')
-rw-r--r-- | pp.c | 82 |
1 files changed, 3 insertions, 79 deletions
@@ -438,85 +438,9 @@ PP(pp_prototype) if (SvPOK(TOPs) && SvCUR(TOPs) >= 7) { const char * s = SvPVX_const(TOPs); if (strnEQ(s, "CORE::", 6)) { - const int code = keyword(s + 6, SvCUR(TOPs) - 6, 1); - if (code < 0) { /* Overridable. */ -#define MAX_ARGS_OP ((sizeof(I32) - 1) * 2) - int i = 0, n = 0, seen_question = 0, defgv = 0; - I32 oa; - char str[ MAX_ARGS_OP * 2 + 2 ]; /* One ';', one '\0' */ - - switch (-code) { - case KEY_and : case KEY_chop: case KEY_chomp: - case KEY_cmp : case KEY_exec: case KEY_eq : - case KEY_ge : case KEY_gt : case KEY_le : - case KEY_lt : case KEY_ne : case KEY_or : - case KEY_system: case KEY_x : case KEY_xor : - goto set; - case KEY_mkdir: - ret = newSVpvs_flags("_;$", SVs_TEMP); - goto set; - case KEY_keys: case KEY_values: case KEY_each: - ret = newSVpvs_flags("+", SVs_TEMP); - goto set; - case KEY_push: case KEY_unshift: - ret = newSVpvs_flags("+@", SVs_TEMP); - goto set; - case KEY_pop: case KEY_shift: - ret = newSVpvs_flags(";+", SVs_TEMP); - goto set; - case KEY_splice: - ret = newSVpvs_flags("+;$$@", SVs_TEMP); - goto set; - case KEY_lock: case KEY_tied: case KEY_untie: - ret = newSVpvs_flags("\\[$@%*]", SVs_TEMP); - goto set; - case KEY_tie: - ret = newSVpvs_flags("\\[$@%*]$@", SVs_TEMP); - goto set; - case KEY___FILE__: case KEY___LINE__: case KEY___PACKAGE__: - ret = newSVpvs_flags("", SVs_TEMP); - goto set; - case KEY_readpipe: - s = "CORE::backtick"; - } - while (i < MAXO) { /* The slow way. */ - if (strEQ(s + 6, PL_op_name[i]) - || strEQ(s + 6, PL_op_desc[i])) - { - goto found; - } - i++; - } - goto nonesuch; /* Should not happen... */ - found: - defgv = PL_opargs[i] & OA_DEFGV; - oa = PL_opargs[i] >> OASHIFT; - while (oa) { - if (oa & OA_OPTIONAL && !seen_question && !defgv) { - seen_question = 1; - str[n++] = ';'; - } - if ((oa & (OA_OPTIONAL - 1)) >= OA_AVREF - && (oa & (OA_OPTIONAL - 1)) <= OA_SCALARREF - /* But globs are already references (kinda) */ - && (oa & (OA_OPTIONAL - 1)) != OA_FILEREF - ) { - str[n++] = '\\'; - } - str[n++] = ("?$@@%&*$")[oa & (OA_OPTIONAL - 1)]; - oa = oa >> 4; - } - if (defgv && str[n - 1] == '$') - str[n - 1] = '_'; - str[n++] = '\0'; - ret = newSVpvn_flags(str, n - 1, SVs_TEMP); - } - else if (code) /* Non-Overridable */ - goto set; - else { /* None such */ - nonesuch: - DIE(aTHX_ "Can't find an opnumber for \"%s\"", s+6); - } + SV *const sv = core_prototype(NULL, s + 6, SvCUR(TOPs) - 6, 1); + if (sv) ret = sv; + goto set; } } cv = sv_2cv(TOPs, &stash, &gv, 0); |