Fix debugger lines with keyword <newline> =>
authorFather Chrysostomos <sprout@cpan.org>
Sun, 1 Sep 2013 20:49:33 +0000 (13:49 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 1 Sep 2013 21:20:57 +0000 (14:20 -0700)
Commit 2179133 (in 5.19.2) modified the parser to look past newlines
when searching for => after a keyword.  In doing so, it stopped the
parser from saving lines correctly for the debugger:

$ PERL5DB='sub DB::DB{}' perl5.18.1 -detime -e'=>;' -e 'print @{"_<-e"}'
sub DB::DB{};
time
=>;
print @{"_<-e"}
$ PERL5DB='sub DB::DB{}' perl5.19.3 -detime -e'=>;' -e 'print @{"_<-e"}'
sub DB::DB{};
=>;
print @{"_<-e"}

Notice how line 1 is missing in 5.19.3.

When peeking ahead past the end of the line, lex_read_space does need
to avoid incrementing the line number from the caller’s (yylex’s) per-
spective, but it still needs to increment it for lex_next_chunk to put
the lines for the debugger in the right slot.  So this commit changes
lex_read_space to increment the line number but set it back again
after calling lex_next_chunk.

Another problem was that the buffer pointer was being restored for a
keyword followed by a line break, but only if there was *no* fat arrow
on the following line.

t/comp/line_debug_0.aux
toke.c

index 2d31d74..c4193e2 100644 (file)
@@ -18,3 +18,6 @@ format Z =
     $z
 .
 $z = 'line twenty';
+$z = time
+=>;
+$z++;
diff --git a/toke.c b/toke.c
index 556f0e7..31eefea 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -1560,6 +1560,7 @@ Perl_lex_read_space(pTHX_ U32 flags)
            s++;
        } else if (c == 0 && s == bufend) {
            bool got_more;
+           line_t l;
 #ifdef PERL_MAD
            if (PL_madskills)
                sv_catpvn(PL_skipwhite, PL_parser->bufptr, s-PL_parser->bufptr);
@@ -1567,9 +1568,10 @@ Perl_lex_read_space(pTHX_ U32 flags)
            if (flags & LEX_NO_NEXT_CHUNK)
                break;
            PL_parser->bufptr = s;
-           if (can_incline) COPLINE_INC_WITH_HERELINES;
+           l = CopLINE(PL_curcop);
+           CopLINE(PL_curcop) += PL_parser->lex_shared->herelines + 1;
            got_more = lex_next_chunk(flags);
-           if (can_incline) CopLINE_dec(PL_curcop);
+           CopLINE_set(PL_curcop, l);
            s = PL_parser->bufptr;
            bufend = PL_parser->bufend;
            if (!got_more)
@@ -7097,12 +7099,15 @@ Perl_yylex(pTHX)
         && (!anydelim || *s != '#')) {
            /* no override, and not s### either; skipspace is safe here
             * check for => on following line */
+           bool arrow;
            STRLEN bufoff = PL_bufptr - SvPVX(PL_linestr);
            STRLEN   soff = s         - SvPVX(PL_linestr);
            s = skipspace_flags(s, LEX_NO_INCLINE);
-           if (*s == '=' && s[1] == '>') goto fat_arrow;
+           arrow = *s == '=' && s[1] == '>';
            PL_bufptr = SvPVX(PL_linestr) + bufoff;
            s         = SvPVX(PL_linestr) +   soff;
+           if (arrow)
+               goto fat_arrow;
        }
 
       reserved_word: