From 485f6c2b0f3c69c94458b67c797e4d4eb63c6c3e Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 22 Jul 2013 18:33:38 -0400 Subject: work around bugs in lex_next_chunk --- Keyword.xs | 15 +++++++++++++++ lib/Parse/Keyword.pm | 16 +++++++++++++++- t/peek.t | 22 ++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 t/peek.t diff --git a/Keyword.xs b/Keyword.xs index ba99b4a..eaaa9dd 100644 --- a/Keyword.xs +++ b/Keyword.xs @@ -95,14 +95,29 @@ lex_peek(len = 1) UV len CODE: PL_curcop = &PL_compiling; + + /* XXX before 5.19.2, lex_next_chunk when we aren't at the end of a line + * just breaks things entirely (the parser no longer sees the text that is + * read in). this is (i think inadvertently) fixed in 5.19.2 (21791330a), + * but it still screws up the line numbers of everything that follows. so, + * the workaround is just to not call lex_next_chunk unless we're at the + * end of a line. this is a bit limiting, but should rarely come up in + * practice. + */ + /* while (PL_parser->bufend - PL_parser->bufptr < len) { if (!lex_next_chunk(0)) { break; } } + */ + if (PL_parser->bufptr == PL_parser->bufend) { + lex_next_chunk(0); + } if (PL_parser->bufend - PL_parser->bufptr < len) { len = PL_parser->bufend - PL_parser->bufptr; } + RETVAL = newSVpvn(PL_parser->bufptr, len); /* XXX unicode? */ OUTPUT: RETVAL diff --git a/lib/Parse/Keyword.pm b/lib/Parse/Keyword.pm index afb2079..78a580a 100644 --- a/lib/Parse/Keyword.pm +++ b/lib/Parse/Keyword.pm @@ -73,6 +73,12 @@ current position in the buffer to be parsed is not moved. See L<< perlapi/PL_parser->linestr >> and L for more information. +NOTE: This function currently only returns text that is on the current line, +unless the current line has been fully read (via C). This is due to a +bug in perl itself, and this restriction will hopefully be lifted in a future +version of this module, so don't depend on it. See the L section for +more information. + =func lex_read($n) Moves the current position in the parsing buffer forward by C<$n> characters @@ -147,7 +153,15 @@ sub import { =head1 BUGS -This module inherits the limitation from L that custom +Peeking into the next line is currently (as of 5.19.2) broken in perl if the +current line hasn't been fully consumed. This module works around this by just +not doing that. This shouldn't be an issue for the most part, since it will +only come up if you need to conditionally parse something based on a token that +can span multiple lines. Just keep in mind that if you're reading in a large +chunk of text, you'll need to alternate between calling C and +C, or else you'll only be able to see text on the current line. + +This module also inherits the limitation from L that custom parsing is only triggered if the keyword is called by its unqualified name (C, not C, for instance). diff --git a/t/peek.t b/t/peek.t new file mode 100644 index 0000000..6d2d989 --- /dev/null +++ b/t/peek.t @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; + +{ + package Parser; + + use Parse::Keyword { foo => \&parse_foo }; + + sub foo {} + sub parse_foo { + lex_peek(99999999); + return sub {}; + } + + ::is_deeply([ foo ], []); +} + +is(__LINE__, 20); + +done_testing; -- cgit v1.2.3-54-g00ecf