Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package perl-PPIx-QuoteLike for
openSUSE:Factory checked in at 2021-02-15 23:14:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-PPIx-QuoteLike (Old)
and /work/SRC/openSUSE:Factory/.perl-PPIx-QuoteLike.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-PPIx-QuoteLike"
Mon Feb 15 23:14:41 2021 rev:10 rq:871186 version:0.015
Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-PPIx-QuoteLike/perl-PPIx-QuoteLike.changes
2021-01-20 18:29:13.795617030 +0100
+++
/work/SRC/openSUSE:Factory/.perl-PPIx-QuoteLike.new.28504/perl-PPIx-QuoteLike.changes
2021-02-15 23:16:53.811449267 +0100
@@ -1,0 +2,13 @@
+Sat Feb 6 03:07:26 UTC 2021 - Tina M??ller <[email protected]>
+
+- updated to 0.015
+ see /usr/share/doc/packages/perl-PPIx-QuoteLike/Changes
+
+ 0.015 2021-02-05 T. R. Wyant
+ Handle <<\EOD and <<~\EOD, which are equivalent to <<'EOD' and
+ <<~'EOD', respectively.
+
+ Recognize indented here documents. Thanks to Olaf Alders (oalders)
+ for alerting me to this omission.
+
+-------------------------------------------------------------------
Old:
----
PPIx-QuoteLike-0.014.tar.gz
New:
----
PPIx-QuoteLike-0.015.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ perl-PPIx-QuoteLike.spec ++++++
--- /var/tmp/diff_new_pack.CZ3iyn/_old 2021-02-15 23:16:54.435450199 +0100
+++ /var/tmp/diff_new_pack.CZ3iyn/_new 2021-02-15 23:16:54.439450205 +0100
@@ -18,7 +18,7 @@
%define cpan_name PPIx-QuoteLike
Name: perl-PPIx-QuoteLike
-Version: 0.014
+Version: 0.015
Release: 0
Summary: Parse Perl string literals and string-literal-like things
License: Artistic-1.0 OR GPL-1.0-or-later
@@ -43,6 +43,12 @@
like string literals. Its real reason for being is to find interpolated
variables for Perl::Critic policies and similar code.
+The parse is fairly straightforward, and a little poking around with
+_eg/pqldump_ should show how it normally goes.
+
+But there is at least one quote-like thing that probably needs some
+explanation.
+
%prep
%autosetup -n %{cpan_name}-%{version}
find . -type f ! -path "*/t/*" ! -name "*.pl" ! -path "*/bin/*" ! -path
"*/script/*" ! -name "configure" -print0 | xargs -0 chmod 644
++++++ PPIx-QuoteLike-0.014.tar.gz -> PPIx-QuoteLike-0.015.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/Changes
new/PPIx-QuoteLike-0.015/Changes
--- old/PPIx-QuoteLike-0.014/Changes 2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/Changes 2021-02-05 15:22:31.000000000 +0100
@@ -1,3 +1,10 @@
+0.015 2021-02-05 T. R. Wyant
+ Handle <<\EOD and <<~\EOD, which are equivalent to <<'EOD' and
+ <<~'EOD', respectively.
+
+ Recognize indented here documents. Thanks to Olaf Alders (oalders)
+ for alerting me to this omission.
+
0.014 2021-01-14 T. R. Wyant
Add Travis CI testing.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/META.json
new/PPIx-QuoteLike-0.015/META.json
--- old/PPIx-QuoteLike-0.014/META.json 2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/META.json 2021-02-05 15:22:31.000000000 +0100
@@ -48,51 +48,51 @@
"provides" : {
"PPIx::QuoteLike" : {
"file" : "lib/PPIx/QuoteLike.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Constant" : {
"file" : "lib/PPIx/QuoteLike/Constant.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Dumper" : {
"file" : "lib/PPIx/QuoteLike/Dumper.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Token" : {
"file" : "lib/PPIx/QuoteLike/Token.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Token::Control" : {
"file" : "lib/PPIx/QuoteLike/Token/Control.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Token::Delimiter" : {
"file" : "lib/PPIx/QuoteLike/Token/Delimiter.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Token::Interpolation" : {
"file" : "lib/PPIx/QuoteLike/Token/Interpolation.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Token::String" : {
"file" : "lib/PPIx/QuoteLike/Token/String.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Token::Structure" : {
"file" : "lib/PPIx/QuoteLike/Token/Structure.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Token::Unknown" : {
"file" : "lib/PPIx/QuoteLike/Token/Unknown.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Token::Whitespace" : {
"file" : "lib/PPIx/QuoteLike/Token/Whitespace.pm",
- "version" : "0.014"
+ "version" : "0.015"
},
"PPIx::QuoteLike::Utils" : {
"file" : "lib/PPIx/QuoteLike/Utils.pm",
- "version" : "0.014"
+ "version" : "0.015"
}
},
"release_status" : "stable",
@@ -110,6 +110,6 @@
"web" : "https://github.com/trwyant/perl-PPIx-QuoteLike"
}
},
- "version" : "0.014",
- "x_serialization_backend" : "JSON::PP version 4.05"
+ "version" : "0.015",
+ "x_serialization_backend" : "JSON::PP version 4.06"
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/META.yml
new/PPIx-QuoteLike-0.015/META.yml
--- old/PPIx-QuoteLike-0.014/META.yml 2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/META.yml 2021-02-05 15:22:31.000000000 +0100
@@ -19,40 +19,40 @@
provides:
PPIx::QuoteLike:
file: lib/PPIx/QuoteLike.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Constant:
file: lib/PPIx/QuoteLike/Constant.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Dumper:
file: lib/PPIx/QuoteLike/Dumper.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Token:
file: lib/PPIx/QuoteLike/Token.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Token::Control:
file: lib/PPIx/QuoteLike/Token/Control.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Token::Delimiter:
file: lib/PPIx/QuoteLike/Token/Delimiter.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Token::Interpolation:
file: lib/PPIx/QuoteLike/Token/Interpolation.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Token::String:
file: lib/PPIx/QuoteLike/Token/String.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Token::Structure:
file: lib/PPIx/QuoteLike/Token/Structure.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Token::Unknown:
file: lib/PPIx/QuoteLike/Token/Unknown.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Token::Whitespace:
file: lib/PPIx/QuoteLike/Token/Whitespace.pm
- version: '0.014'
+ version: '0.015'
PPIx::QuoteLike::Utils:
file: lib/PPIx/QuoteLike/Utils.pm
- version: '0.014'
+ version: '0.015'
requires:
Carp: '0'
Encode: '0'
@@ -72,5 +72,5 @@
bugtracker: https://github.com/trwyant/perl-PPIx-QuoteLike/issues
license: http://dev.perl.org/licenses/
repository: git://github.com/trwyant/perl-PPIx-QuoteLike.git
-version: '0.014'
+version: '0.015'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/eg/pqldump
new/PPIx-QuoteLike-0.015/eg/pqldump
--- old/PPIx-QuoteLike-0.014/eg/pqldump 2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/eg/pqldump 2021-02-05 15:22:31.000000000 +0100
@@ -9,7 +9,7 @@
use Pod::Usage;
use PPIx::QuoteLike::Dumper;
-our $VERSION = '0.014';
+our $VERSION = '0.015';
my %opt;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/eg/variables
new/PPIx-QuoteLike-0.015/eg/variables
--- old/PPIx-QuoteLike-0.014/eg/variables 2021-01-14 06:23:37.000000000
+0100
+++ new/PPIx-QuoteLike-0.015/eg/variables 2021-02-05 15:22:31.000000000
+0100
@@ -10,7 +10,7 @@
use PPI::Document;
use PPIx::QuoteLike::Utils qw{ __variables };
-our $VERSION = '0.014';
+our $VERSION = '0.015';
my %opt;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/inc/My/Module/Recommend/Any.pm
new/PPIx-QuoteLike-0.015/inc/My/Module/Recommend/Any.pm
--- old/PPIx-QuoteLike-0.014/inc/My/Module/Recommend/Any.pm 2021-01-14
06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/inc/My/Module/Recommend/Any.pm 2021-02-05
15:22:31.000000000 +0100
@@ -12,7 +12,7 @@
BEGIN {
*import = \&Exporter::import;
}
-our $VERSION = '0.014';
+our $VERSION = '0.015';
our @EXPORT_OK = qw{ __any };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Constant.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Constant.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Constant.pm 2021-01-14
06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Constant.pm 2021-02-05
15:22:31.000000000 +0100
@@ -8,7 +8,7 @@
use Carp;
use base qw{ Exporter };
-our $VERSION = '0.014';
+our $VERSION = '0.015';
our @CARP_NOT = qw{
PPIx::QuoteLike
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Dumper.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Dumper.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Dumper.pm 2021-01-14
06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Dumper.pm 2021-02-05
15:22:31.000000000 +0100
@@ -12,7 +12,7 @@
use PPIx::QuoteLike::Utils qw{ __instance };
use Scalar::Util ();
-our $VERSION = '0.014';
+our $VERSION = '0.015';
use constant SCALAR_REF => ref \0;
@@ -100,7 +100,8 @@
qw{ type start finish };
push @rslt,
join "\t", $self->_class_name( $obj ), $string,
- _format_attr( $obj, qw{ encoding failures interpolates } ),
+ _format_attr( $obj, qw{ encoding failures interpolates
+ indentation } ),
$self->_perl_version( $obj ),
$self->_variables( $obj ),
;
@@ -205,10 +206,11 @@
sub _format_content {
my ( $obj, $method, @arg ) = @_;
- my $val = $obj->$method( @arg );
- ref $val
- and $val = $val->content();
- return defined $val ? $val : '?';
+ my @val = map { $_->content() }
+ grep { $_->significant() }
+ $obj->$method( @arg )
+ or return '?';
+ return join '', @val;
}
sub _isa {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Control.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Control.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Control.pm
2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Control.pm
2021-02-05 15:22:31.000000000 +0100
@@ -9,7 +9,7 @@
use PPIx::QuoteLike::Constant qw{ @CARP_NOT };
-our $VERSION = '0.014';
+our $VERSION = '0.015';
{
# TODO make this a state variable when we can require Perl 5.10.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Delimiter.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Delimiter.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Delimiter.pm
2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Delimiter.pm
2021-02-05 15:22:31.000000000 +0100
@@ -9,7 +9,7 @@
use PPIx::QuoteLike::Constant qw{ MINIMUM_PERL @CARP_NOT };
-our $VERSION = '0.014';
+our $VERSION = '0.015';
# Perl 5.29.0 disallows unassigned code points and combining code points
# as delimiters. Unfortunately for me non-characters and illegal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Interpolation.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Interpolation.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Interpolation.pm
2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Interpolation.pm
2021-02-05 15:22:31.000000000 +0100
@@ -20,7 +20,7 @@
use base qw{ PPIx::QuoteLike::Token };
-our $VERSION = '0.014';
+our $VERSION = '0.015';
sub ppi {
my ( $self ) = @_;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/String.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/String.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/String.pm 2021-01-14
06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/String.pm 2021-02-05
15:22:31.000000000 +0100
@@ -9,7 +9,7 @@
use PPIx::QuoteLike::Constant qw{ @CARP_NOT };
-our $VERSION = '0.014';
+our $VERSION = '0.015';
1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Structure.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Structure.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Structure.pm
2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Structure.pm
2021-02-05 15:22:31.000000000 +0100
@@ -9,7 +9,7 @@
use PPIx::QuoteLike::Constant qw{ @CARP_NOT };
-our $VERSION = '0.014';
+our $VERSION = '0.015';
1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Unknown.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Unknown.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Unknown.pm
2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Unknown.pm
2021-02-05 15:22:31.000000000 +0100
@@ -9,7 +9,7 @@
use PPIx::QuoteLike::Constant qw{ @CARP_NOT };
-our $VERSION = '0.014';
+our $VERSION = '0.015';
1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Whitespace.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Whitespace.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token/Whitespace.pm
2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token/Whitespace.pm
2021-02-05 15:22:31.000000000 +0100
@@ -9,7 +9,7 @@
use PPIx::QuoteLike::Constant qw{ @CARP_NOT };
-our $VERSION = '0.014';
+our $VERSION = '0.015';
sub significant {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Token.pm 2021-01-14
06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Token.pm 2021-02-05
15:22:31.000000000 +0100
@@ -16,7 +16,7 @@
visual_column_number
};
-our $VERSION = '0.014';
+our $VERSION = '0.015';
# Private to this package.
sub __new {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Utils.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Utils.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike/Utils.pm 2021-01-14
06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike/Utils.pm 2021-02-05
15:22:31.000000000 +0100
@@ -39,7 +39,7 @@
__variables
};
-our $VERSION = '0.014';
+our $VERSION = '0.015';
# Readonly::Scalar my $BRACED_RE => __match_enclosed( LEFT_CURLY );
Readonly::Scalar my $BRACKETED_RE => __match_enclosed( '[' ); # ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike.pm
new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike.pm
--- old/PPIx-QuoteLike-0.014/lib/PPIx/QuoteLike.pm 2021-01-14
06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/lib/PPIx/QuoteLike.pm 2021-02-05
15:22:31.000000000 +0100
@@ -40,7 +40,7 @@
use Scalar::Util ();
use Text::Tabs ();
-our $VERSION = '0.014';
+our $VERSION = '0.015';
use constant CLASS_CONTROL => 'PPIx::QuoteLike::Token::Control';
use constant CLASS_DELIMITER => 'PPIx::QuoteLike::Token::Delimiter';
@@ -56,6 +56,8 @@
'Tokenizer found illegal first characters';
use constant MISMATCHED_DELIM =>
'Tokenizer found mismatched delimiters';
+use constant NO_INDENTATION =>
+ 'No indentation string found';
{
my $match_sq = __match_enclosed( qw< ' > );
@@ -102,7 +104,7 @@
defined( my $string = $self->_stringify_source( $source ) )
or return;
- my ( $type, $gap, $content, $end_delim, $start_delim );
+ my ( $type, $gap, $gap2, $content, $end_delim, $indented, $start_delim
);
$arg{trace}
and warn "Initial match of $string\n";
@@ -130,15 +132,28 @@
# Note that the regexp used here is slightly wrong in that white
# space between the '<<' and the termination string is not
# allowed if the termination string is not quoted in some way.
- } elsif ( $string =~ m/ \A \s* ( << ) ( \s* )
- ( \w+ | $match_sq | $match_dq | $match_bt ) \n /smxgc ) {
- ( $type, $gap, $start_delim ) = ( $1, $2, $3 );
+ } elsif ( $string =~ m/ \A \s* ( << ) ( \s* ) ( ~? ) ( \s* )
+ ( [\\]? \w+ | $match_sq | $match_dq | $match_bt ) \n /smxgc ) {
+ ( $type, $gap, $indented, $gap2, $start_delim ) = (
+ $1, $2, $3, $4, $5 );
$arg{trace}
- and warn "Initial match '$type$start_delim$gap'\n";
- $self->{interpolates} = $start_delim !~ m/ \A ' /smx;
+ and warn "Initial match '$type$start_delim$gap$indented'\n";
+ $self->{interpolates} = $start_delim !~ m/ \A [\\'] /smx;
$content = substr $string, ( pos $string || 0 );
$end_delim = _unquote( $start_delim );
- if ( $content =~ s/ ^ \Q$end_delim\E \n? \z //smx ) {
+ # NOTE that the indentation is specifically space or tab
+ # only.
+ if ( $content =~ s/ ^ ( [ \t]* ) \Q$end_delim\E \n? \z //smx ) {
+ # NOTE PPI::Token::HereDoc does not preserve the
+ # indentation of an indented here document, so the
+ # indentation will appear to be '' if we came from PPI.
+ if ( $indented ) {
+ # Version per perldelta.pod for that release.
+ $self->{perl_version_introduced} = '5.025007';
+ $self->{indentation} = "$1";
+ $self->{_indentation_re} = qr/
+ ^ \Q$self->{indentation}\E /smx;
+ }
} else {
$end_delim = '';
}
@@ -182,6 +197,12 @@
length $gap ?
$self->_make_token( CLASS_WHITESPACE, $gap ) :
(),
+ length $indented ?
+ $self->_make_token( CLASS_STRUCTURE, $indented ) :
+ (),
+ length $gap2 ?
+ $self->_make_token( CLASS_WHITESPACE, $gap2 ) :
+ (),
];
$self->{start} ||= [
$self->_make_token( CLASS_DELIMITER, $start_delim ),
@@ -198,7 +219,9 @@
if ( $content =~ m/ \G ( \\ [ULulQEF] ) /smxgc ) {
push @children, [ CLASS_CONTROL, "$1" ];
- } elsif ( $content =~ m/ \G ( \\ N [{] ( [^}]+ ) [}] ) /smxgc )
{
+ } elsif (
+ $content =~ m/ \G ( \\ N [{] ( [^}]+ ) [}] ) /smxgc
+ ) {
# Handle \N{...} separately because it can not
# contain an interpolation even inside of an
# otherwise-interpolating string. That is to say,
@@ -220,19 +243,16 @@
} elsif ( $content =~ m/ \G ( [\$\@] \#? \$* ) /smxgc ) {
push @children, $self->_interpolation( "$1", $content );
} elsif ( $content =~ m/ \G ( \\ . | [^\\\$\@]+ ) /smxgc ) {
- push @children, [ CLASS_STRING, "$1" ];
+ push @children, $self->_remove_here_doc_indentation(
+ "$1",
+ sibling => \@children,
+ );
} else {
last;
}
- } continue {
- # We might have consecutive strings for various reasons.
- # Merge these.
- if ( CLASS_STRING eq $children[-1][0] &&
- CLASS_STRING eq $children[-2][0] ) {
- my $merge = pop @children;
- $children[-1][1] .= $merge->[1];
- }
}
+
+ @children = _merge_strings( @children );
shift @children; # remove the priming
# Make the tokens, at long last.
@@ -243,11 +263,18 @@
} else {
length $content
- and push @children, $self->_make_token(
- CLASS_STRING, $content );
+ and push @children, map { $self->_make_token( @{ $_ } ) }
+ _merge_strings(
+ $self->_remove_here_doc_indentation( $content )
+ );
}
+ # Add the indentation before the end marker, if needed
+ $self->{indentation}
+ and push @children, $self->_make_token(
+ CLASS_WHITESPACE, $self->{indentation} );
+
if ( $self->{finish} ) {
# If we already have something here it is data, not objects.
foreach ( @{ $self->{finish} } ) {
@@ -386,6 +413,11 @@
return $self->_stringify_source( $string, test => 1 );
}
+sub indentation {
+ my ( $self ) = @_;
+ return $self->{indentation};
+}
+
sub interpolates {
my ( $self ) = @_;
return $self->{interpolates};
@@ -753,6 +785,89 @@
}
}
+# For various reasons we may get consecutive literals -- typically
+# strings. We want to merge these. The arguments are array refs, with
+# the class name of the token in [0] and the content in [1]. I know of
+# no way we can generate consecutive white space tokens, but if I did I
+# would want them merged.
+#
+# NOTE that merger loses all attributes of the second token, so we MUST
+# NOT merge CLASS_UNKNOWN tokens, or any class that might have
+# attributes other than content.
+{
+ my %can_merge = map { $_ => 1 } CLASS_STRING, CLASS_WHITESPACE;
+
+ sub _merge_strings {
+ my @arg = @_;
+ my @rslt;
+ foreach my $elem ( @arg ) {
+ if ( @rslt && $can_merge{$elem->[0]}
+ && $elem->[0] eq $rslt[-1][0]
+ ) {
+ $rslt[-1][1] .= $elem->[1];
+ } else {
+ push @rslt, $elem;
+ }
+ }
+ return @rslt;
+ }
+}
+
+# If we're processing an indented here document, strings must be split
+# on new lines and un-indented. We return array refs rather than
+# objects because we may be called before we're ready to build the
+# objects.
+sub _remove_here_doc_indentation {
+ my ( $self, $string, %arg ) = @_;
+
+ # NOTE that we rely on the fact that both undef (not indented) and
+ # '' (indented by zero characters) evaluate false.
+ $self->{indentation}
+ or return [ CLASS_STRING, $string ];
+
+ my $ignore_first;
+ if ( $arg{sibling} ) {
+ # Because the calling code primes the pump, @sibling will never
+ # be empty, even when processing the first token. So:
+ # * The pump-priming specifies class '', so if that is what we
+ # see we must process the first line; otherwise
+ # * If the previous token is a string ending in "\n", we must
+ # process the first line.
+ $ignore_first = '' ne $arg{sibling}[-1][0] && (
+ CLASS_STRING ne $arg{sibling}[-1][0] ||
+ $arg{sibling}[-1][1] !~ m/ \n \z /smx );
+ } else {
+ # Without @sibling, we unconditionally process the first line.
+ $ignore_first = 0;
+ }
+
+ my @rslt;
+
+ foreach ( split qr/ (?<= \n ) /smx, $string ) {
+ if ( $ignore_first ) {
+ push @rslt, [ CLASS_STRING, "$_" ];
+ $ignore_first = 0;
+ } else {
+ if ( "\n" eq $_ ) {
+ push @rslt,
+ [ CLASS_STRING, "$_" ],
+ ;
+ } elsif ( s/ ( $self->{_indentation_re} ) //smx ) {
+ push @rslt,
+ [ CLASS_WHITESPACE, "$1" ],
+ [ CLASS_STRING, "$_" ],
+ ;
+ } else {
+ push @rslt,
+ [ CLASS_UNKNOWN, "$_", error => NO_INDENTATION ],
+ ;
+ }
+ }
+ }
+
+ return @rslt;
+}
+
sub _stringify_source {
my ( $self, $string, %opt ) = @_;
@@ -836,6 +951,46 @@
interpolated variables for L<Perl::Critic|Perl::Critic> policies and
similar code.
+The parse is fairly straightforward, and a little poking around with
+F<eg/pqldump> should show how it normally goes.
+
+But there is at least one quote-like thing that probably needs some
+explanation.
+
+=head2 Indented Here Documents
+
+These were introduced in Perl 5.25.7 (November 2016) but not recognized
+by this module until its version 0.015 (February 2021). The indentation
+is parsed as
+L<PPIx::QuoteLike::Token::Whitespace|PPIx::Regexp::Token::Whitespace>
+objects, provided it is at least one character wide, otherwise it is not
+represented in the parse. That is to say,
+
+ <<~EOD
+ How doth the little crocodile
+ Improve his shining tail
+ EOD
+
+will have the three indentations represented by whitespace objects and
+each line of the literal represented by its own string object, but
+
+ <<~EOD
+ How doth the little crocodile
+ Improve his shining tail
+ EOD
+
+will parse the same as the non-indented version, except for the addition
+of the token representing the C<'~'>.
+
+L<PPI|PPI> is ahead of this module, and recognized indented here
+documents as of its version 1.246 (May 2019). Unfortunately, as of
+version 1.270 the indent gets lost in the parse, so a C<PPIx::QuoteLike>
+object initialized from such a
+L<PPI::Token::HereDoc|PPI::Token::HereDoc> will be seen as having an
+indentation of C<''> regardless of the actual indentation in the source.
+I believe this restriction will go away when
+L<https://github.com/adamkennedy/PPI/issues/251> is resolved.
+
=head1 DEPRECATION NOTICE
The L<postderef|/postderef> argument to L<new()|/new> is being put
@@ -870,7 +1025,8 @@
this method will return nothing. The scalar representation of a here
document is a multi-line string whose first line consists of the leading
C< << > and the start delimiter, and whose subsequent lines consist of
-the content of the here document and the end delimiter.
+the content of the here document and the end delimiter. Indented here
+documents were not supported by this class until version C<0.015>.
C<PPI> classes that can be handled are
L<PPI::Token::Quote|PPI::Token::Quote>,
@@ -1031,6 +1187,15 @@
be expected to handle the content of C<$string> (be it scalar or
object), and a false value otherwise.
+=head2 indentation
+
+This method returns the indentation string if the object represents an
+indented here document, or C<undef> if it represents anything else,
+including an unindented here document.
+
+B<Note> that if indented syntax is used but the here document is not in
+fact indented, this will return C<''>, which evaluates to false.
+
=head2 interpolates
say $str->interpolates() ?
@@ -1217,6 +1382,12 @@
thing would change based on what is interpolated, but neither can I rule
it out. I<Caveat user>.
+=head2 PPI Restrictions
+
+As of version 0.015 of this module, the only known instance of this is
+the handling of indented here documents, as discussed above under
+L<Indented Here Documents|/Indented Here Documents>.
+
=head2 Non-Standard Syntax
There are modules out there that alter the syntax of Perl. If the syntax
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/t/parse.t
new/PPIx-QuoteLike-0.015/t/parse.t
--- old/PPIx-QuoteLike-0.014/t/parse.t 2021-01-14 06:23:37.000000000 +0100
+++ new/PPIx-QuoteLike-0.015/t/parse.t 2021-02-05 15:22:31.000000000 +0100
@@ -598,6 +598,7 @@
if ( ok $obj, q{Able to parse HERE_DOCUMENT} ) {
cmp_ok $obj->failures(), '==', 0, q{Failures parsing HERE_DOCUMENT};
cmp_ok $obj->interpolates(), '==', 1, q{Does HERE_DOCUMENT interpolate};
+ is $obj->indentation(), undef, 'HERE_DOCUMENT indentation';
is $obj->content(), $here_doc, q{Can recover HERE_DOCUMENT};
is $obj->__get_value( 'type' ), '<<', q{Type of HERE_DOCUMENT};
is $obj->delimiters(), q{"EOD"EOD}, q{Delimiters of HERE_DOCUMENT};
@@ -1221,6 +1222,191 @@
}
+{
+ my $here_doc = <<'__END_OF_HERE_DOCUMENT';
+<< ~'EOD'
+ The $1,000,000 Bank-Note
+ EOD
+__END_OF_HERE_DOCUMENT
+
+ $obj = PPIx::QuoteLike->new( $here_doc );
+ if ( ok $obj, q{Able to parse HERE_DOCUMENT} ) {
+ cmp_ok $obj->failures(), '==', 0, q{Failures parsing HERE_DOCUMENT};
+ cmp_ok $obj->interpolates(), '==', 0, q{Does HERE_DOCUMENT interpolate};
+ is $obj->indentation(), ' ' x 4, 'HERE_DOCUMENT indentation';
+ is $obj->content(), $here_doc, q{Can recover HERE_DOCUMENT};
+ is $obj->__get_value( 'type' ), '<<', q{Type of HERE_DOCUMENT};
+ is $obj->delimiters(), q{'EOD'EOD}, q{Delimiters of HERE_DOCUMENT};
+ is $obj->__get_value( 'start' ), q{'EOD'},
+ q{Start delimiter of HERE_DOCUMENT};
+ is $obj->__get_value( 'finish' ), q{EOD},
+ q{Finish delimiter of HERE_DOCUMENT};
+ is $obj->encoding(), undef, q{Encoding of HERE_DOCUMENT};
+ is_deeply [ sort $obj->variables() ],
+ [ ],
+ q{HERE_DOCUMENT interpolated variables};
+
+ cmp_ok scalar $obj->elements(), '==', 10,
+ q{Number of elements of HERE_DOCUMENT};
+ cmp_ok scalar $obj->children(), '==', 3,
+ q{Number of children of HERE_DOCUMENT};
+
+ if ( my $kid = $obj->child( 0 ) ) {
+ ok $kid->isa( 'PPIx::QuoteLike::Token::Whitespace' ),
+ q{HERE_DOCUMENT child 0 class};
+ is $kid->content(), ' ' x 4,
+ q{HERE_DOCUMENT child 0 content};
+ is $kid->error(), undef,
+ q{HERE_DOCUMENT child 0 error};
+ cmp_ok $kid->parent(), '==', $obj,
+ q{HERE_DOCUMENT child 0 parent};
+ cmp_ok $kid->previous_sibling() || 0, '==', $obj->__kid( 0 - 1 ),
+ q{HERE_DOCUMENT child 0 previous sibling};
+ cmp_ok $kid->next_sibling() || 0, '==', $obj->__kid( 0 + 1 ),
+ q{HERE_DOCUMENT child 0 next sibling};
+ }
+
+ if ( my $kid = $obj->child( 1 ) ) {
+ ok $kid->isa( 'PPIx::QuoteLike::Token::String' ),
+ q{HERE_DOCUMENT child 1 class};
+ is $kid->content(), "The \$1,000,000 Bank-Note\n",
+ q{HERE_DOCUMENT child 1 content};
+ is $kid->error(), undef,
+ q{HERE_DOCUMENT child 1 error};
+ cmp_ok $kid->parent(), '==', $obj,
+ q{HERE_DOCUMENT child 1 parent};
+ cmp_ok $kid->previous_sibling() || 0, '==', $obj->__kid( 1 - 1 ),
+ q{HERE_DOCUMENT child 1 previous sibling};
+ cmp_ok $kid->next_sibling() || 0, '==', $obj->__kid( 1 + 1 ),
+ q{HERE_DOCUMENT child 1 next sibling};
+ }
+
+ if ( my $kid = $obj->child( 2 ) ) {
+ ok $kid->isa( 'PPIx::QuoteLike::Token::Whitespace' ),
+ q{HERE_DOCUMENT child 2 class};
+ is $kid->content(), ' ' x 4,
+ q{HERE_DOCUMENT child 2 content};
+ is $kid->error(), undef,
+ q{HERE_DOCUMENT child 2 error};
+ cmp_ok $kid->parent(), '==', $obj,
+ q{HERE_DOCUMENT child 2 parent};
+ cmp_ok $kid->previous_sibling() || 2, '==', $obj->__kid( 2 - 1 ),
+ q{HERE_DOCUMENT child 2 previous sibling};
+ cmp_ok $kid->next_sibling() || 0, '==', $obj->__kid( 2 + 1 ),
+ q{HERE_DOCUMENT child 2 next sibling};
+ }
+
+ }
+}
+
+{
+ my $here_doc = <<'__END_OF_HERE_DOCUMENT';
+<< ~"EOD"
+ The $1,000,000 Bank-Note
+
+ EOD
+__END_OF_HERE_DOCUMENT
+
+ $obj = PPIx::QuoteLike->new( $here_doc );
+ if ( ok $obj, q{Able to parse HERE_DOCUMENT} ) {
+ cmp_ok $obj->failures(), '==', 0, q{Failures parsing HERE_DOCUMENT};
+ cmp_ok $obj->interpolates(), '==', 1, q{Does HERE_DOCUMENT interpolate};
+ is $obj->indentation(), ' ' x 4, 'HERE_DOCUMENT indentation';
+ is $obj->content(), $here_doc, q{Can recover HERE_DOCUMENT};
+ is $obj->__get_value( 'type' ), '<<', q{Type of HERE_DOCUMENT};
+ is $obj->delimiters(), q{"EOD"EOD}, q{Delimiters of HERE_DOCUMENT};
+ is $obj->__get_value( 'start' ), q{"EOD"},
+ q{Start delimiter of HERE_DOCUMENT};
+ is $obj->__get_value( 'finish' ), q{EOD},
+ q{Finish delimiter of HERE_DOCUMENT};
+ is $obj->encoding(), undef, q{Encoding of HERE_DOCUMENT};
+ is_deeply [ sort $obj->variables() ],
+ [ qw{ $1 } ],
+ q{HERE_DOCUMENT interpolated variables};
+
+ cmp_ok scalar $obj->elements(), '==', 12,
+ q{Number of elements of HERE_DOCUMENT};
+ cmp_ok scalar $obj->children(), '==', 5,
+ q{Number of children of HERE_DOCUMENT};
+
+ if ( my $kid = $obj->child( 0 ) ) {
+ ok $kid->isa( 'PPIx::QuoteLike::Token::Whitespace' ),
+ q{HERE_DOCUMENT child 0 class};
+ is $kid->content(), ' ' x 4,
+ q{HERE_DOCUMENT child 0 content};
+ is $kid->error(), undef,
+ q{HERE_DOCUMENT child 0 error};
+ cmp_ok $kid->parent(), '==', $obj,
+ q{HERE_DOCUMENT child 0 parent};
+ cmp_ok $kid->previous_sibling() || 0, '==', $obj->__kid( 0 - 1 ),
+ q{HERE_DOCUMENT child 0 previous sibling};
+ cmp_ok $kid->next_sibling() || 0, '==', $obj->__kid( 0 + 1 ),
+ q{HERE_DOCUMENT child 0 next sibling};
+ }
+
+ if ( my $kid = $obj->child( 1 ) ) {
+ ok $kid->isa( 'PPIx::QuoteLike::Token::String' ),
+ q{HERE_DOCUMENT child 1 class};
+ is $kid->content(), 'The ',
+ q{HERE_DOCUMENT child 1 content};
+ is $kid->error(), undef,
+ q{HERE_DOCUMENT child 1 error};
+ cmp_ok $kid->parent(), '==', $obj,
+ q{HERE_DOCUMENT child 1 parent};
+ cmp_ok $kid->previous_sibling() || 0, '==', $obj->__kid( 1 - 1 ),
+ q{HERE_DOCUMENT child 1 previous sibling};
+ cmp_ok $kid->next_sibling() || 0, '==', $obj->__kid( 1 + 1 ),
+ q{HERE_DOCUMENT child 1 next sibling};
+ }
+
+ if ( my $kid = $obj->child( 2 ) ) {
+ ok $kid->isa( 'PPIx::QuoteLike::Token::Interpolation' ),
+ q{HERE_DOCUMENT child 2 class};
+ is $kid->content(), '$1',
+ q{HERE_DOCUMENT child 2 content};
+ is $kid->error(), undef,
+ q{HERE_DOCUMENT child 2 error};
+ cmp_ok $kid->parent(), '==', $obj,
+ q{HERE_DOCUMENT child 2 parent};
+ cmp_ok $kid->previous_sibling() || 2, '==', $obj->__kid( 2 - 1 ),
+ q{HERE_DOCUMENT child 2 previous sibling};
+ cmp_ok $kid->next_sibling() || 0, '==', $obj->__kid( 2 + 1 ),
+ q{HERE_DOCUMENT child 2 next sibling};
+ }
+
+ if ( my $kid = $obj->child( 3 ) ) {
+ ok $kid->isa( 'PPIx::QuoteLike::Token::String' ),
+ q{HERE_DOCUMENT child 3 class};
+ is $kid->content(), ",000,000 Bank-Note\n\n",
+ q{HERE_DOCUMENT child 3 content};
+ is $kid->error(), undef,
+ q{HERE_DOCUMENT child 3 error};
+ cmp_ok $kid->parent(), '==', $obj,
+ q{HERE_DOCUMENT child 3 parent};
+ cmp_ok $kid->previous_sibling() || 3, '==', $obj->__kid( 3 - 1 ),
+ q{HERE_DOCUMENT child 3 previous sibling};
+ cmp_ok $kid->next_sibling() || 0, '==', $obj->__kid( 3 + 1 ),
+ q{HERE_DOCUMENT child 3 next sibling};
+ }
+
+ if ( my $kid = $obj->child( 4 ) ) {
+ ok $kid->isa( 'PPIx::QuoteLike::Token::Whitespace' ),
+ q{HERE_DOCUMENT child 4 class};
+ is $kid->content(), ' ' x 4,
+ q{HERE_DOCUMENT child 4 content};
+ is $kid->error(), undef,
+ q{HERE_DOCUMENT child 4 error};
+ cmp_ok $kid->parent(), '==', $obj,
+ q{HERE_DOCUMENT child 4 parent};
+ cmp_ok $kid->previous_sibling() || 4, '==', $obj->__kid( 4 - 1 ),
+ q{HERE_DOCUMENT child 4 previous sibling};
+ cmp_ok $kid->next_sibling() || 0, '==', $obj->__kid( 4 + 1 ),
+ q{HERE_DOCUMENT child 4 next sibling};
+ }
+
+ }
+}
+
done_testing;
sub PPIx::QuoteLike::__get_value {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/t/unit-adhoc.t
new/PPIx-QuoteLike-0.015/t/unit-adhoc.t
--- old/PPIx-QuoteLike-0.014/t/unit-adhoc.t 2021-01-14 06:23:37.000000000
+0100
+++ new/PPIx-QuoteLike-0.015/t/unit-adhoc.t 2021-02-05 15:22:31.000000000
+0100
@@ -30,6 +30,36 @@
}
+{
+ my $code = <<'END_OF_DOCUMENT';
+<<\EOD
+$foo
+EOD
+END_OF_DOCUMENT
+
+ my $pql = PPIx::QuoteLike->new( $code );
+
+ cmp_ok $pql->failures(), '==', 0, '<<\\EOD here doc parses';
+
+ ok ! $pql->interpolates(), '<<\\EOD here doc does not interpolate';
+
+}
+
+{
+ my $code = <<'END_OF_DOCUMENT';
+<<~\EOD
+ $foo
+ EOD
+END_OF_DOCUMENT
+
+ my $pql = PPIx::QuoteLike->new( $code );
+
+ cmp_ok $pql->failures(), '==', 0, '<<~\\EOD here doc parses';
+
+ ok ! $pql->interpolates(), '<<~\\EOD here doc does not interpolate';
+
+}
+
done_testing;
1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/PPIx-QuoteLike-0.014/t/version.t
new/PPIx-QuoteLike-0.015/t/version.t
--- old/PPIx-QuoteLike-0.014/t/version.t 2021-01-14 06:23:37.000000000
+0100
+++ new/PPIx-QuoteLike-0.015/t/version.t 2021-02-05 15:22:31.000000000
+0100
@@ -106,6 +106,16 @@
'Case-folded string was introduced in 5.15.8';
is $obj->perl_version_removed(), undef, 'Case-folded string is still here';
+$obj = PPIx::QuoteLike->new( <<HERE_DOC );
+<<~'EOD'
+ How doth the little crocodile
+ Improve its shining tail
+ EOD
+HERE_DOC
+is $obj->perl_version_introduced(), '5.025007',
+ 'Indented here-doc was introduced in 5.25.7';
+is $obj->perl_version_removed(), undef, 'Indented here-doc is still here';
+
done_testing;
1;