summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-08-31 17:47:23 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-09-01 11:32:07 -0700
commit25502127feba592f2312380b350122c445020707 (patch)
tree114d7f6ac5b79b5922af4dded2493bc732952083 /util.c
parentecadf9b7005812a5eb20b351ef9bcd042c7e3daf (diff)
downloadperl-25502127feba592f2312380b350122c445020707.tar.gz
[perl #115768] improve (caller)[2] line numbers
warn and die have special code (closest_cop) to find a nulled nextstate op closest to the warn or die op, to get the line number from it. This commit extends that capability to caller, so that if (1) { foo(); } sub foo { warn +(caller)[2] } shows the right line number.
Diffstat (limited to 'util.c')
-rw-r--r--util.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/util.c b/util.c
index 00f3821bbe..0cd99f3f5f 100644
--- a/util.c
+++ b/util.c
@@ -1178,15 +1178,20 @@ Perl_mess(pTHX_ const char *pat, ...)
return retval;
}
-STATIC const COP*
-S_closest_cop(pTHX_ const COP *cop, const OP *o)
+const COP*
+Perl_closest_cop(pTHX_ const COP *cop, const OP *o, const OP *curop,
+ bool opnext)
{
dVAR;
- /* Look for PL_op starting from o. cop is the last COP we've seen. */
+ /* Look for curop starting from o. cop is the last COP we've seen. */
+ /* opnext means that curop is actually the ->op_next of the op we are
+ seeking. */
PERL_ARGS_ASSERT_CLOSEST_COP;
- if (!o || o == PL_op)
+ if (!o || !curop || (
+ opnext ? o->op_next == curop && o->op_type != OP_SCOPE : o == curop
+ ))
return cop;
if (o->op_flags & OPf_KIDS) {
@@ -1202,7 +1207,7 @@ S_closest_cop(pTHX_ const COP *cop, const OP *o)
/* Keep searching, and return when we've found something. */
- new_cop = closest_cop(cop, kid);
+ new_cop = closest_cop(cop, kid, curop, opnext);
if (new_cop)
return new_cop;
}
@@ -1272,7 +1277,8 @@ Perl_mess_sv(pTHX_ SV *basemsg, bool consume)
* from the sibling of PL_curcop.
*/
- const COP *cop = closest_cop(PL_curcop, PL_curcop->op_sibling);
+ const COP *cop =
+ closest_cop(PL_curcop, PL_curcop->op_sibling, PL_op, FALSE);
if (!cop)
cop = PL_curcop;