diff options
author | Paul Johnson <paul@pjcj.net> | 2001-07-12 06:14:11 +0200 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2001-07-12 13:05:46 +0000 |
commit | ae7d165c0b89e5ee4f4efe1fcd0b5806caf58351 (patch) | |
tree | 3ca6dd40179096c5469c469bc0ef784721e793a0 /util.c | |
parent | 983f8c39d1d673620d5153b40c61e46afb5d2df5 (diff) | |
download | perl-ae7d165c0b89e5ee4f4efe1fcd0b5806caf58351.tar.gz |
More accurate line numbers in messages
Message-ID: <20010712041411.A3467@pjcj.net>
(With prototyping and multiplicity tweaks.)
p4raw-id: //depot/perl@11305
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 47 |
1 files changed, 45 insertions, 2 deletions
@@ -1003,17 +1003,60 @@ Perl_mess(pTHX_ const char *pat, ...) return retval; } +STATIC COP* +S_closest_cop(pTHX_ COP *cop, OP *o) +{ + /* Look for PL_op starting from o. cop is the last COP we've seen. */ + + if (!o || o == PL_op) return cop; + + if (o->op_flags & OPf_KIDS) { + OP *kid; + for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) + { + COP *new_cop; + + /* If the OP_NEXTSTATE has been optimised away we can still use it + * the get the file and line number. */ + + if (kid->op_type == OP_NULL && kid->op_targ == OP_NEXTSTATE) + cop = (COP *)kid; + + /* Keep searching, and return when we've found something. */ + + new_cop = closest_cop(cop, kid); + if (new_cop) return new_cop; + } + } + + /* Nothing found. */ + + return 0; +} + SV * Perl_vmess(pTHX_ const char *pat, va_list *args) { SV *sv = mess_alloc(); static char dgd[] = " during global destruction.\n"; + COP *cop; sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') { - if (CopLINE(PL_curcop)) + + /* + * Try and find the file and line for PL_op. This will usually be + * PL_curcop, but it might be a cop that has been optimised away. We + * can try to find such a cop by searching through the optree starting + * from the sibling of PL_curcop. + */ + + cop = closest_cop(PL_curcop, PL_curcop->op_sibling); + if (!cop) cop = PL_curcop; + + if (CopLINE(cop)) Perl_sv_catpvf(aTHX_ sv, " at %s line %"IVdf, - CopFILE(PL_curcop), (IV)CopLINE(PL_curcop)); + CopFILE(cop), (IV)CopLINE(cop)); if (GvIO(PL_last_in_gv) && IoLINES(GvIOp(PL_last_in_gv))) { bool line_mode = (RsSIMPLE(PL_rs) && SvCUR(PL_rs) == 1 && *SvPVX(PL_rs) == '\n'); |