BEGIN {
chdir 't' if -d 't';
@INC = ('../lib','.');
+ require Config; import Config;
require './test.pl';
}
-plan tests => 466; # Update this when adding/deleting tests.
+plan tests => 712; # Update this when adding/deleting tests.
run_tests() unless caller;
is(qr/(?u)\b\v$/, '(?^:(?u)\b\v$)', 'Verify (?u) compiles');
my $dual = qr/\b\v$/;
- use locale;
- my $locale = qr/\b\v$/;
- is($locale, '(?^l:\b\v$)', 'Verify has l modifier when compiled under use locale');
- no locale;
+ my $locale;
+
+ SKIP: {
+ skip 'No locale testing without d_setlocale', 1 if(!$Config{d_setlocale});
+
+ BEGIN {
+ if($Config{d_setlocale}) {
+ require locale; import locale;
+ }
+ }
+ $locale = qr/\b\v$/;
+ is($locale, '(?^l:\b\v$)', 'Verify has l modifier when compiled under use locale');
+ no locale;
+ }
use feature 'unicode_strings';
my $unicode = qr/\b\v$/;
is($unicode, '(?^u:\b\v$)', 'Verify has u modifier when compiled under unicode_strings');
is(qr/abc$dual/, '(?^u:abc(?^:\b\v$))', 'Verify retains d meaning when interpolated under locale');
- is(qr/abc$locale/, '(?^u:abc(?^l:\b\v$))', 'Verify retains l when interpolated under unicode_strings');
+
+ SKIP: {
+ skip 'No locale testing without d_setlocale', 1 if(!$Config{d_setlocale});
+
+ is(qr/abc$locale/, '(?^u:abc(?^l:\b\v$))', 'Verify retains l when interpolated under unicode_strings');
+ }
no feature 'unicode_strings';
- is(qr/abc$locale/, '(?^:abc(?^l:\b\v$))', 'Verify retains l when interpolated outside locale and unicode strings');
+ SKIP: {
+ skip 'No locale testing without d_setlocale', 1 if(!$Config{d_setlocale});
+
+ is(qr/abc$locale/, '(?^:abc(?^l:\b\v$))', 'Verify retains l when interpolated outside locale and unicode strings');
+ }
+
is(qr/def$unicode/, '(?^:def(?^u:\b\v$))', 'Verify retains u when interpolated outside locale and unicode strings');
- use locale;
- is(qr/abc$dual/, '(?^l:abc(?^:\b\v$))', 'Verify retains d meaning when interpolated under locale');
- is(qr/abc$unicode/, '(?^l:abc(?^u:\b\v$))', 'Verify retains u when interpolated under locale');
+ SKIP: {
+ skip 'No locale testing without d_setlocale', 2 if(!$Config{d_setlocale});
+
+ BEGIN {
+ if($Config{d_setlocale}) {
+ require locale; import locale;
+ }
+ }
+ is(qr/abc$dual/, '(?^l:abc(?^:\b\v$))', 'Verify retains d meaning when interpolated under locale');
+ is(qr/abc$unicode/, '(?^l:abc(?^u:\b\v$))', 'Verify retains u when interpolated under locale');
+ }
}
{
/.(a)(ba*)?/;
is($#+, 2, $message);
is($#-, 1, $message);
+
+ # Check that values don’t stick
+ " "=~/()()()(.)(..)/;
+ my($m,$p) = (\$-[5], \$+[5]);
+ () = "$$_" for $m, $p; # FETCH (or eqv.)
+ " " =~ /()/;
+ is $$m, undef, 'values do not stick to @- elements';
+ is $$p, undef, 'values do not stick to @+ elements';
}
foreach ('$+[0] = 13', '$-[0] = 13', '@+ = (7, 6, 5)',
like($str, qr/^..\G/, $message);
unlike($str, qr/^...\G/, $message);
ok($str =~ /\G../ && $& eq 'cd', $message);
-
- local $::TODO = $::running_as_thread;
ok($str =~ /.\G./ && $& eq 'bc', $message);
+
+ }
+
+ {
+ my $message = '\G and intuit and anchoring';
+ $_ = "abcdef";
+ pos = 0;
+ ok($_ =~ /\Gabc/, $message);
+ ok($_ =~ /^\Gabc/, $message);
+
+ pos = 3;
+ ok($_ =~ /\Gdef/, $message);
+ pos = 3;
+ ok($_ =~ /\Gdef$/, $message);
+ pos = 3;
+ ok($_ =~ /abc\Gdef$/, $message);
+ pos = 3;
+ ok($_ =~ /^abc\Gdef$/, $message);
+ pos = 3;
+ ok($_ =~ /c\Gd/, $message);
}
{
+ my $s = '123';
+ pos($s) = 1;
+ my @a = $s =~ /(\d)\G/g; # this infinitely looped up till 5.19.1
+ is("@a", "1", '\G looping');
+ }
+
+
+ {
my $message = 'pos inside (?{ })';
my $str = 'abcde';
our ($foo, $bar);
my $message = '\G anchor checks';
my $foo = 'aabbccddeeffgg';
pos ($foo) = 1;
- {
- local $::TODO = $::running_as_thread;
- no warnings 'uninitialized';
- ok($foo =~ /.\G(..)/g, $message);
- is($1, 'ab', $message);
- pos ($foo) += 1;
- ok($foo =~ /.\G(..)/g, $message);
- is($1, 'cc', $message);
+ ok($foo =~ /.\G(..)/g, $message);
+ is($1, 'ab', $message);
- pos ($foo) += 1;
- ok($foo =~ /.\G(..)/g, $message);
- is($1, 'de', $message);
+ pos ($foo) += 1;
+ ok($foo =~ /.\G(..)/g, $message);
+ is($1, 'cc', $message);
- ok($foo =~ /\Gef/g, $message);
- }
+ pos ($foo) += 1;
+ ok($foo =~ /.\G(..)/g, $message);
+ is($1, 'de', $message);
+
+ ok($foo =~ /\Gef/g, $message);
undef pos $foo;
ok($foo =~ /\G(..)/g, $message);
}
{
+ my $message = 'basic \G floating checks';
+ my $foo = 'aabbccddeeffgg';
+ pos ($foo) = 1;
+
+ ok($foo =~ /a+\G(..)/g, "$message: a+\\G");
+ is($1, 'ab', "$message: ab");
+
+ pos ($foo) += 1;
+ ok($foo =~ /b+\G(..)/g, "$message: b+\\G");
+ is($1, 'cc', "$message: cc");
+
+ pos ($foo) += 1;
+ ok($foo =~ /d+\G(..)/g, "$message: d+\\G");
+ is($1, 'de', "$message: de");
+
+ ok($foo =~ /\Gef/g, "$message: \\Gef");
+
+ pos ($foo) = 1;
+
+ ok($foo =~ /(?=a+\G)(..)/g, "$message: (?a+\\G)");
+ is($1, 'aa', "$message: aa");
+
+ pos ($foo) = 2;
+
+ ok($foo =~ /a(?=a+\G)(..)/g, "$message: a(?=a+\\G)");
+ is($1, 'ab', "$message: ab");
+
+ }
+
+ {
$_ = '123x123';
my @res = /(\d*|x)/g;
local $" = '|';
local $SIG{__WARN__} = sub {};
my $str = "\x{110000}";
- # No non-unicode code points match any Unicode property, even inverse
- # ones
- unlike($str, qr/\p{ASCII_Hex_Digit=True}/, "Non-Unicode doesn't match \\p{}");
- unlike($str, qr/\p{ASCII_Hex_Digit=False}/, "Non-Unicode doesn't match \\p{}");
- like($str, qr/\P{ASCII_Hex_Digit=True}/, "Non-Unicode matches \\P{}");
- like($str, qr/\P{ASCII_Hex_Digit=False}/, "Non-Unicode matches \\P{}");
+ unlike($str, qr/\p{ASCII_Hex_Digit=True}/, "Non-Unicode doesn't match \\p{AHEX=True}");
+ like($str, qr/\p{ASCII_Hex_Digit=False}/, "Non-Unicode matches \\p{AHEX=False}");
+ like($str, qr/\P{ASCII_Hex_Digit=True}/, "Non-Unicode matches \\P{AHEX=True}");
+ unlike($str, qr/\P{ASCII_Hex_Digit=False}/, "Non-Unicode matches \\P{AHEX=FALSE}");
}
{
"abc" =~ qr/(?<$char>abc)/;
EOP
utf8::encode($prog);
- fresh_perl_like($prog, qr!Group name must start with a non-digit word character!, "",
+ fresh_perl_like($prog, qr!Group name must start with a non-digit word character!, {},
sprintf("'U+%04X not legal IDFirst'", ord($char)));
}
}
ok("Perl" =~ /P.*$/i, '#116148');
}
+ { # 117327: Sequence (?#...) not recognized in regex
+ # The space between the '(' and '?' is now deprecated; this test should
+ # be removed when the deprecation is made fatal.
+ no warnings;
+ like("ab", qr/a( ?#foo)b/x);
+ }
+
+ { # 118297: Mixing up- and down-graded strings in regex
+ utf8::upgrade(my $u = "\x{e5}");
+ utf8::downgrade(my $d = "\x{e5}");
+ my $warned;
+ local $SIG{__WARN__} = sub { $warned++ if $_[0] =~ /\AMalformed UTF-8/ };
+ my $re = qr/$u$d/;
+ ok(!$warned, "no warnings when interpolating mixed up-/downgraded strings in pattern");
+ my $c = "\x{e5}\x{e5}";
+ utf8::downgrade($c);
+ like($c, $re, "mixed up-/downgraded pattern matches downgraded string");
+ utf8::upgrade($c);
+ like($c, $re, "mixed up-/downgraded pattern matches upgraded string");
+ }
+
+ {
+ # if we have 87 capture buffers defined then \87 should refer to the 87th.
+ # test that this is true for 1..100
+ # Note that this test causes the engine to recurse at runtime, and
+ # hence use a lot of C stack.
+ for my $i (1..100) {
+ my $capture= "a";
+ $capture= "($capture)" for 1 .. $i;
+ for my $mid ("","b") {
+ my $str= "a${mid}a";
+ my $backref= "\\$i";
+ eval {
+ ok($str=~/$capture$mid$backref/,"\\$i works with $i buffers '$str'=~/...$mid$backref/");
+ 1;
+ } or do {
+ is("$@","","\\$i works with $i buffers works with $i buffers '$str'=~/...$mid$backref/");
+ };
+ }
+ }
+ }
+
+ # this mixture of readonly (not COWable) and COWable strings
+ # messed up the capture buffers under COW. The actual test results
+ # are incidental; the issue is was an AddressSanitizer failure
+ {
+ my $c ='AB';
+ my $res = '';
+ for ($c, 'C', $c, 'DE') {
+ ok(/(.)/, "COWable match");
+ $res .= $1;
+ }
+ is($res, "ACAD");
+ }
+
+
+ {
+ # RT #45667
+ # /[#$x]/x didn't interpolate the var $x.
+ my $b = 'cd';
+ my $s = 'abcd$%#&';
+ $s =~ s/[a#$b%]/X/g;
+ is ($s, 'XbXX$XX&', 'RT #45667 without /x');
+ $s = 'abcd$%#&';
+ $s =~ s/[a#$b%]/X/gx;
+ is ($s, 'XbXX$XX&', 'RT #45667 with /x');
+ }
+
+ {
+ no warnings "uninitialized";
+ my @a;
+ $a[1]++;
+ /@a/;
+ pass('no crash with /@a/ when array has nonexistent elems');
+ }
+
+ {
+ is runperl(prog => 'delete $::{qq-\cR-}; //; print qq-ok\n-'),
+ "ok\n",
+ 'deleting *^R does not result in crashes';
+ no warnings 'once';
+ *^R = *caretRglobwithnoscalar;
+ "" =~ /(?{42})/;
+ is $^R, 42, 'assigning to *^R does not result in a crash';
+ is runperl(
+ stderr => 1,
+ prog => 'eval q|'
+ .' q-..- =~ /(??{undef *^R;q--})(?{42})/; '
+ .' print qq-$^R\n-'
+ .'|'
+ ),
+ "42\n",
+ 'undefining *^R within (??{}) does not result in a crash';
+ }
+
+ {
+ # [perl #120446]
+ # this code should be virtually instantaneous. If it takes 10s of
+ # seconds, there a bug in intuit_start.
+ # (this test doesn't actually test for slowness - that involves
+ # too much danger of false positives on loaded machines - but by
+ # putting it here, hopefully someone might notice if it suddenly
+ # runs slowly)
+ my $s = ('a' x 1_000_000) . 'b';
+ my $i = 0;
+ for (1..10_000) {
+ pos($s) = $_;
+ $i++ if $s =~/\Gb/g;
+ }
+ is($i, 0, "RT 120446: mustn't run slowly");
+ }
+
+ # These are based on looking at the code in regcomp.c
+ # We don't look for specific code, just the existence of an SSC
+ foreach my $re (qw( qr/a?c/
+ qr/a?c/i
+ qr/[ab]?c/
+ qr/\R?c/
+ qr/\d?c/d
+ qr/\w?c/l
+ qr/\s?c/a
+ qr/[[:alpha:]]?c/u
+ )) {
+ SKIP: {
+ skip "no re-debug under miniperl" if is_miniperl;
+ my $prog = <<"EOP";
+use re qw(Debug COMPILE);
+$re;
+EOP
+ fresh_perl_like($prog, qr/synthetic stclass/, { stderr=>1 }, "$re generates a synthetic start class");
+ }
+ }
+
+ {
+ like "\x{AA}", qr/a?[\W_]/d, "\\W with /d synthetic start class works";
+ }
+
+
} # End of sub run_tests