|
|
a4ac56 |
From 07ebe9c4fb1028d17e61caabe8c15abd0cd48983 Mon Sep 17 00:00:00 2001
|
|
|
a4ac56 |
From: Yves Orton <demerphq@gmail.com>
|
|
|
a4ac56 |
Date: Thu, 29 Jun 2017 11:31:14 +0200
|
|
|
a4ac56 |
Subject: [PATCH] Parse caret vars with subscripts the same as normal vars
|
|
|
a4ac56 |
inside of ${..} escaping
|
|
|
a4ac56 |
MIME-Version: 1.0
|
|
|
a4ac56 |
Content-Type: text/plain; charset=UTF-8
|
|
|
a4ac56 |
Content-Transfer-Encoding: 8bit
|
|
|
a4ac56 |
|
|
|
a4ac56 |
This behavior is discussed in perl #131664, which complains that
|
|
|
a4ac56 |
"${^CAPTURE}[0]" does not work as expected. Abigail explains the
|
|
|
a4ac56 |
behavior is by design and Eirik Berg Hanssen expands on that explanation
|
|
|
a4ac56 |
pointing out that what /should/ work, "${^CAPTURE[0]}" does not,
|
|
|
a4ac56 |
which Sawyer then ruled was a bug.
|
|
|
a4ac56 |
|
|
|
a4ac56 |
So this patch makes "${^CAPTURE[0]}" (and "${^CAPTURE [0]}" [hi
|
|
|
a4ac56 |
abigial]) work the same as they would if the var was called @foo.
|
|
|
a4ac56 |
|
|
|
a4ac56 |
Petr Písař: Ported to 5.26.2-RC1.
|
|
|
a4ac56 |
|
|
|
a4ac56 |
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
|
a4ac56 |
---
|
|
|
a4ac56 |
t/base/lex.t | 28 +++++++++++++++++++++++++++-
|
|
|
a4ac56 |
toke.c | 46 +++++++++++++++++++++++++---------------------
|
|
|
a4ac56 |
2 files changed, 52 insertions(+), 22 deletions(-)
|
|
|
a4ac56 |
|
|
|
a4ac56 |
diff --git a/t/base/lex.t b/t/base/lex.t
|
|
|
a4ac56 |
index 99fd3bb..ae17bbd 100644
|
|
|
a4ac56 |
--- a/t/base/lex.t
|
|
|
a4ac56 |
+++ b/t/base/lex.t
|
|
|
a4ac56 |
@@ -1,6 +1,6 @@
|
|
|
a4ac56 |
#!./perl
|
|
|
a4ac56 |
|
|
|
a4ac56 |
-print "1..112\n";
|
|
|
a4ac56 |
+print "1..119\n";
|
|
|
a4ac56 |
|
|
|
a4ac56 |
$x = 'x';
|
|
|
a4ac56 |
|
|
|
a4ac56 |
@@ -154,6 +154,32 @@ my $test = 31;
|
|
|
a4ac56 |
print "not " unless index ($@, 'Can\'t use global $^XYZ in "my"') > -1;
|
|
|
a4ac56 |
print "ok $test\n"; $test++;
|
|
|
a4ac56 |
# print "($@)\n" if $@;
|
|
|
a4ac56 |
+#
|
|
|
a4ac56 |
+ ${^TEST}= "splat";
|
|
|
a4ac56 |
+ @{^TEST}= ("foo", "bar");
|
|
|
a4ac56 |
+ %{^TEST}= ("foo" => "FOO", "bar" => "BAR" );
|
|
|
a4ac56 |
+
|
|
|
a4ac56 |
+ print "not " if "${^TEST}" ne "splat";
|
|
|
a4ac56 |
+ print "ok $test\n"; $test++;
|
|
|
a4ac56 |
+
|
|
|
a4ac56 |
+ print "not " if "${^TEST}[0]" ne "splat[0]";
|
|
|
a4ac56 |
+ print "ok $test\n"; $test++;
|
|
|
a4ac56 |
+
|
|
|
a4ac56 |
+ print "not " if "${^TEST[0]}" ne "foo";
|
|
|
a4ac56 |
+ print "ok $test\n"; $test++;
|
|
|
a4ac56 |
+
|
|
|
a4ac56 |
+ print "not " if "${ ^TEST [1] }" ne "bar";
|
|
|
a4ac56 |
+ print "ok $test\n"; $test++;
|
|
|
a4ac56 |
+
|
|
|
a4ac56 |
+ print "not " if "${^TEST}{foo}" ne "splat{foo}";
|
|
|
a4ac56 |
+ print "ok $test\n"; $test++;
|
|
|
a4ac56 |
+
|
|
|
a4ac56 |
+ print "not " if "${^TEST{foo}}" ne "FOO";
|
|
|
a4ac56 |
+ print "ok $test\n"; $test++;
|
|
|
a4ac56 |
+
|
|
|
a4ac56 |
+ print "not " if "${ ^TEST {bar} }" ne "BAR";
|
|
|
a4ac56 |
+ print "ok $test\n"; $test++;
|
|
|
a4ac56 |
+
|
|
|
a4ac56 |
|
|
|
a4ac56 |
# Now let's make sure that caret variables are all forced into the main package.
|
|
|
a4ac56 |
package Someother;
|
|
|
a4ac56 |
diff --git a/toke.c b/toke.c
|
|
|
a4ac56 |
index ee9c464..aff785b 100644
|
|
|
a4ac56 |
--- a/toke.c
|
|
|
a4ac56 |
+++ b/toke.c
|
|
|
a4ac56 |
@@ -9416,19 +9416,36 @@ S_scan_ident(pTHX_ char *s, char *dest, STRLEN destlen, I32 ck_uni)
|
|
|
a4ac56 |
bool skip;
|
|
|
a4ac56 |
char *s2;
|
|
|
a4ac56 |
/* If we were processing {...} notation then... */
|
|
|
a4ac56 |
- if (isIDFIRST_lazy_if_safe(d, e, is_utf8)) {
|
|
|
a4ac56 |
- /* if it starts as a valid identifier, assume that it is one.
|
|
|
a4ac56 |
- (the later check for } being at the expected point will trap
|
|
|
a4ac56 |
- cases where this doesn't pan out.) */
|
|
|
a4ac56 |
- d += is_utf8 ? UTF8SKIP(d) : 1;
|
|
|
a4ac56 |
- parse_ident(&s, &d, e, 1, is_utf8, TRUE);
|
|
|
a4ac56 |
- *d = '\0';
|
|
|
a4ac56 |
+ if (isIDFIRST_lazy_if_safe(d, e, is_utf8)
|
|
|
a4ac56 |
+ || (!isPRINT(*d) /* isCNTRL(d), plus all non-ASCII */
|
|
|
a4ac56 |
+ && isWORDCHAR(*s))
|
|
|
a4ac56 |
+ ) {
|
|
|
a4ac56 |
+ /* note we have to check for a normal identifier first,
|
|
|
a4ac56 |
+ * as it handles utf8 symbols, and only after that has
|
|
|
a4ac56 |
+ * been ruled out can we look at the caret words */
|
|
|
a4ac56 |
+ if (isIDFIRST_lazy_if_safe(d, e, is_utf8) ) {
|
|
|
a4ac56 |
+ /* if it starts as a valid identifier, assume that it is one.
|
|
|
a4ac56 |
+ (the later check for } being at the expected point will trap
|
|
|
a4ac56 |
+ cases where this doesn't pan out.) */
|
|
|
a4ac56 |
+ d += is_utf8 ? UTF8SKIP(d) : 1;
|
|
|
a4ac56 |
+ parse_ident(&s, &d, e, 1, is_utf8, TRUE);
|
|
|
a4ac56 |
+ *d = '\0';
|
|
|
a4ac56 |
+ }
|
|
|
a4ac56 |
+ else { /* caret word: ${^Foo} ${^CAPTURE[0]} */
|
|
|
a4ac56 |
+ d++;
|
|
|
a4ac56 |
+ while (isWORDCHAR(*s) && d < e) {
|
|
|
a4ac56 |
+ *d++ = *s++;
|
|
|
a4ac56 |
+ }
|
|
|
a4ac56 |
+ if (d >= e)
|
|
|
a4ac56 |
+ Perl_croak(aTHX_ "%s", ident_too_long);
|
|
|
a4ac56 |
+ *d = '\0';
|
|
|
a4ac56 |
+ }
|
|
|
a4ac56 |
tmp_copline = CopLINE(PL_curcop);
|
|
|
a4ac56 |
if (s < PL_bufend && isSPACE(*s)) {
|
|
|
a4ac56 |
s = skipspace(s);
|
|
|
a4ac56 |
}
|
|
|
a4ac56 |
if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) {
|
|
|
a4ac56 |
- /* ${foo[0]} and ${foo{bar}} notation. */
|
|
|
a4ac56 |
+ /* ${foo[0]} and ${foo{bar}} and ${^CAPTURE[0]} notation. */
|
|
|
a4ac56 |
if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest, 0)) {
|
|
|
a4ac56 |
const char * const brack =
|
|
|
a4ac56 |
(const char *)
|
|
|
a4ac56 |
@@ -9447,19 +9464,6 @@ S_scan_ident(pTHX_ char *s, char *dest, STRLEN destlen, I32 ck_uni)
|
|
|
a4ac56 |
return s;
|
|
|
a4ac56 |
}
|
|
|
a4ac56 |
}
|
|
|
a4ac56 |
- /* Handle extended ${^Foo} variables
|
|
|
a4ac56 |
- * 1999-02-27 mjd-perl-patch@plover.com */
|
|
|
a4ac56 |
- else if (! isPRINT(*d) /* isCNTRL(d), plus all non-ASCII */
|
|
|
a4ac56 |
- && isWORDCHAR(*s))
|
|
|
a4ac56 |
- {
|
|
|
a4ac56 |
- d++;
|
|
|
a4ac56 |
- while (isWORDCHAR(*s) && d < e) {
|
|
|
a4ac56 |
- *d++ = *s++;
|
|
|
a4ac56 |
- }
|
|
|
a4ac56 |
- if (d >= e)
|
|
|
a4ac56 |
- Perl_croak(aTHX_ "%s", ident_too_long);
|
|
|
a4ac56 |
- *d = '\0';
|
|
|
a4ac56 |
- }
|
|
|
a4ac56 |
|
|
|
a4ac56 |
if ( !tmp_copline )
|
|
|
a4ac56 |
tmp_copline = CopLINE(PL_curcop);
|
|
|
a4ac56 |
--
|
|
|
a4ac56 |
2.14.3
|
|
|
a4ac56 |
|