summaryrefslogtreecommitdiff
path: root/toke.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-11-06 05:42:34 -0800
committerFather Chrysostomos <sprout@cpan.org>2013-11-06 05:56:04 -0800
commit6a5c965b97b7f9a780ccdeec9c6e753bc9c15806 (patch)
tree041c0182ce19064b2d8e78724ced4155604bb5b8 /toke.c
parent9ce1fb7d2323e20e2cf2480171cbfb4f2b1153ea (diff)
downloadperl-6a5c965b97b7f9a780ccdeec9c6e753bc9c15806.tar.gz
Fix qx, `` and <<`` overrides
This resolves two RT tickets: • #115330 is that qx and `` overrides do not support interpolation. • #119827 is that <<`` does not support readpipe overrides at all. The obvious fix for #115330 fixes #119827 at the same time. When quote-like operators are parsed, after the string has been scanned S_sublex_push is called, which decides which of two paths to follow: 1) For things not requiring interpolation, the string is passed to tokeq (originally called q, it handles double backslashes and back- slashed delimiters) and returned to the parser immediately. 2) For anything that interpolates, the lexer enters a special inter- polation mode (LEX_INTERPPUSH) and goes through a more complex sequence over the next few calls (e.g., qq"a.$b.c" is turned into ‘stringify ( "a." . $ b . ".c" )’). When commit e3f73d4ed (Oct 2006, perl 5.10) added support for overrid- ing `` and qx with a readpipe sub, it did so by creating an entersub op in toke.c and making S_sublex_push follow path no. 1, taking the result if tokeq and inserting it into the already-constructed op tree for the sub call. That approach caused interpolation to be skipped when qx or `` is overridden. Furthermore it didn’t touch <<`` at all. The easiest solution is to let toke.c follow its normal path and create a backtick op (instead of trying to half-intercept it), and to deal with override lookup afterwards in ck_backtick, the same way require overrides are handled. Since <<`` also turns into a backtick op, it gets handled too that way.
Diffstat (limited to 'toke.c')
-rw-r--r--toke.c33
1 files changed, 2 insertions, 31 deletions
diff --git a/toke.c b/toke.c
index b42929e422..66447e3677 100644
--- a/toke.c
+++ b/toke.c
@@ -2606,14 +2606,6 @@ S_sublex_start(pTHX)
PL_expect = XTERMORDORDOR;
return THING;
}
- else if (op_type == OP_BACKTICK && PL_lex_op) {
- /* readpipe() was overridden */
- cSVOPx(cLISTOPx(cUNOPx(PL_lex_op)->op_first)->op_first->op_sibling)->op_sv = tokeq(PL_lex_stuff);
- pl_yylval.opval = PL_lex_op;
- PL_lex_op = NULL;
- PL_lex_stuff = NULL;
- return THING;
- }
PL_sublex_info.super_state = PL_lex_state;
PL_sublex_info.sub_inwhat = (U16)op_type;
@@ -4472,27 +4464,6 @@ S_find_in_my_stash(pTHX_ const char *pkgname, STRLEN len)
return gv_stashpvn(pkgname, len, UTF ? SVf_UTF8 : 0);
}
-/*
- * S_readpipe_override
- * Check whether readpipe() is overridden, and generates the appropriate
- * optree, provided sublex_start() is called afterwards.
- */
-STATIC void
-S_readpipe_override(pTHX)
-{
- GV **gvp;
- GV *gv_readpipe = gv_fetchpvs("readpipe", GV_NOTQUAL, SVt_PVCV);
- pl_yylval.ival = OP_BACKTICK;
- if ((gv_readpipe = gv_override("readpipe",8)))
- {
- COPLINE_SET_FROM_MULTI_END;
- PL_lex_op = (OP*)newUNOP(OP_ENTERSUB, OPf_STACKED,
- op_append_elem(OP_LIST,
- newSVOP(OP_CONST, 0, &PL_sv_undef), /* value will be read later */
- newCVREF(0, newGVOP(OP_GV, 0, gv_readpipe))));
- }
-}
-
#ifdef PERL_MAD
/*
* Perl_madlex
@@ -6933,7 +6904,7 @@ Perl_yylex(pTHX)
no_op("Backticks",s);
if (!s)
missingterm(NULL);
- readpipe_override();
+ pl_yylval.ival = OP_BACKTICK;
TERM(sublex_start());
case '\\':
@@ -8489,7 +8460,7 @@ Perl_yylex(pTHX)
s = scan_str(s,!!PL_madskills,FALSE,FALSE, FALSE);
if (!s)
missingterm(NULL);
- readpipe_override();
+ pl_yylval.ival = OP_BACKTICK;
TERM(sublex_start());
case KEY_return: