191f110e0Safresh1#!./perl 291f110e0Safresh1 391f110e0Safresh1# Check that we don't recompile runtime patterns when the pattern hasn't 491f110e0Safresh1# changed 591f110e0Safresh1# 691f110e0Safresh1# Works by checking the debugging output of 'use re debug' and, if 791f110e0Safresh1# available, -Dr. We use both to check that the different code paths 8b8851fccSafresh1# with Perl_foo() versus the my_foo() under ext/re/ don't cause any 991f110e0Safresh1# changes. 1091f110e0Safresh1 1191f110e0Safresh1$| = 1; 1291f110e0Safresh1 1391f110e0Safresh1BEGIN { 1491f110e0Safresh1 chdir 't' if -d 't'; 1591f110e0Safresh1 require './test.pl'; 169f11ffb7Safresh1 set_up_inc( '../lib', '.' ); 1791f110e0Safresh1 skip_all_if_miniperl("no dynamic loading on miniperl, no re"); 1891f110e0Safresh1} 1991f110e0Safresh1 20b8851fccSafresh1use strict; 21b8851fccSafresh1use warnings; 2291f110e0Safresh1 236fb12b70Safresh1plan tests => 48; 2491f110e0Safresh1 2591f110e0Safresh1my $results = runperl( 2691f110e0Safresh1 switches => [ '-Dr' ], 2791f110e0Safresh1 prog => '1', 2891f110e0Safresh1 stderr => 1, 2991f110e0Safresh1 ); 3091f110e0Safresh1my $has_Dr = $results !~ /Recompile perl with -DDEBUGGING/; 3191f110e0Safresh1 3291f110e0Safresh1my $tmpfile = tempfile(); 3391f110e0Safresh1 3491f110e0Safresh1 3591f110e0Safresh1# Check that a pattern triggers a regex compilation exactly N times, 3691f110e0Safresh1# using either -Dr or 'use re debug' 3791f110e0Safresh1# This is partially based on _fresh_perl() in test.pl 3891f110e0Safresh1 3991f110e0Safresh1sub _comp_n { 4091f110e0Safresh1 my ($use_Dr, $n, $prog, $desc) = @_; 4191f110e0Safresh1 open my $tf, ">$tmpfile" or die "Cannot open $tmpfile: $!"; 4291f110e0Safresh1 4391f110e0Safresh1 my $switches = []; 4491f110e0Safresh1 if ($use_Dr) { 4591f110e0Safresh1 push @$switches, '-Dr'; 4691f110e0Safresh1 } 4791f110e0Safresh1 else { 4891f110e0Safresh1 $prog = qq{use re qw(debug);\n$prog}; 4991f110e0Safresh1 } 5091f110e0Safresh1 5191f110e0Safresh1 print $tf $prog; 5291f110e0Safresh1 close $tf or die "Cannot close $tmpfile: $!"; 5391f110e0Safresh1 my $results = runperl( 5491f110e0Safresh1 switches => $switches, 5591f110e0Safresh1 progfile => $tmpfile, 5691f110e0Safresh1 stderr => 1, 5791f110e0Safresh1 ); 5891f110e0Safresh1 5991f110e0Safresh1 my $status = $?; 6091f110e0Safresh1 6191f110e0Safresh1 my $count = () = $results =~ /Final program:/g; 6291f110e0Safresh1 if ($count == $n && !$status) { 6391f110e0Safresh1 pass($desc); 6491f110e0Safresh1 } 6591f110e0Safresh1 else { 6691f110e0Safresh1 fail($desc); 6791f110e0Safresh1 _diag "# COUNT: $count EXPECTED $n\n"; 6891f110e0Safresh1 _diag "# STATUS: $status\n"; 6991f110e0Safresh1 _diag "# SWITCHES: @$switches\n"; 7091f110e0Safresh1 _diag "# PROG: \n$prog\n"; 7191f110e0Safresh1 # this is verbose; uncomment for debugging 7291f110e0Safresh1 #_diag "# OUTPUT:\n------------------\n $results-------------------\n"; 7391f110e0Safresh1 } 7491f110e0Safresh1} 7591f110e0Safresh1 7691f110e0Safresh1# Check that a pattern triggers a regex compilation exactly N times, 7791f110e0Safresh1 7891f110e0Safresh1sub comp_n { 7991f110e0Safresh1 my ($n, $prog, $desc) = @_; 8091f110e0Safresh1 if ($has_Dr) { 8191f110e0Safresh1 _comp_n(1, $n, $prog, "$desc -Dr"); 8291f110e0Safresh1 } 8391f110e0Safresh1 else { 8491f110e0Safresh1 SKIP: { 8591f110e0Safresh1 skip("-Dr not compiled in"); 8691f110e0Safresh1 } 8791f110e0Safresh1 } 8891f110e0Safresh1 _comp_n(0, @_); 8991f110e0Safresh1} 9091f110e0Safresh1 9191f110e0Safresh1# Check that a pattern triggers a regex compilation exactly once. 9291f110e0Safresh1 9391f110e0Safresh1sub comp_1 { 9491f110e0Safresh1 comp_n(1, @_); 9591f110e0Safresh1} 9691f110e0Safresh1 9791f110e0Safresh1 9891f110e0Safresh1comp_1(<<'CODE', 'simple'); 9991f110e0Safresh1"a" =~ /$_/ for qw(a a a); 10091f110e0Safresh1CODE 10191f110e0Safresh1 10291f110e0Safresh1comp_1(<<'CODE', 'simple qr'); 10391f110e0Safresh1"a" =~ qr/$_/ for qw(a a a); 10491f110e0Safresh1CODE 10591f110e0Safresh1 10691f110e0Safresh1comp_1(<<'CODE', 'literal utf8'); 10791f110e0Safresh1"a" =~ /$_/ for "\x{100}", "\x{100}", "\x{100}"; 10891f110e0Safresh1CODE 10991f110e0Safresh1 11091f110e0Safresh1comp_1(<<'CODE', 'literal utf8 qr'); 11191f110e0Safresh1"a" =~ qr/$_/ for "\x{100}", "\x{100}", "\x{100}"; 11291f110e0Safresh1CODE 11391f110e0Safresh1 11491f110e0Safresh1comp_1(<<'CODE', 'longjmp literal utf8'); 11591f110e0Safresh1my $x = chr(0x80); 11691f110e0Safresh1"a" =~ /$x$_/ for "\x{100}", "\x{100}", "\x{100}"; 11791f110e0Safresh1CODE 11891f110e0Safresh1 11991f110e0Safresh1comp_1(<<'CODE', 'longjmp literal utf8 qr'); 12091f110e0Safresh1my $x = chr(0x80); 12191f110e0Safresh1"a" =~ qr/$x$_/ for "\x{100}", "\x{100}", "\x{100}"; 12291f110e0Safresh1CODE 12391f110e0Safresh1 12491f110e0Safresh1comp_1(<<'CODE', 'utf8'); 12591f110e0Safresh1"a" =~ /$_/ for '\x{100}', '\x{100}', '\x{100}'; 12691f110e0Safresh1CODE 12791f110e0Safresh1 12891f110e0Safresh1comp_1(<<'CODE', 'utf8 qr'); 12991f110e0Safresh1"a" =~ qr/$_/ for '\x{100}', '\x{100}', '\x{100}'; 13091f110e0Safresh1CODE 13191f110e0Safresh1 13291f110e0Safresh1comp_1(<<'CODE', 'longjmp utf8'); 13391f110e0Safresh1my $x = chr(0x80); 13491f110e0Safresh1"a" =~ /$x$_/ for '\x{100}', '\x{100}', '\x{100}'; 13591f110e0Safresh1CODE 13691f110e0Safresh1 13791f110e0Safresh1comp_1(<<'CODE', 'longjmp utf8'); 13891f110e0Safresh1my $x = chr(0x80); 13991f110e0Safresh1"a" =~ qr/$x$_/ for '\x{100}', '\x{100}', '\x{100}'; 14091f110e0Safresh1CODE 14191f110e0Safresh1 14291f110e0Safresh1comp_n(3, <<'CODE', 'mixed utf8'); 14391f110e0Safresh1"a" =~ /$_/ for "\x{c4}\x{80}", "\x{100}", "\x{c4}\x{80}"; 14491f110e0Safresh1CODE 14591f110e0Safresh1 14691f110e0Safresh1comp_n(3, <<'CODE', 'mixed utf8 qr'); 14791f110e0Safresh1"a" =~ qr/$_/ for "\x{c4}\x{80}", "\x{100}", "\x{c4}\x{80}"; 14891f110e0Safresh1CODE 14991f110e0Safresh1 150*56d68f1eSafresh1# note that for runtime code, each pattern is compiled twice; the 15191f110e0Safresh1# second time to allow the parser to see the code. 15291f110e0Safresh1 15391f110e0Safresh1comp_n(6, <<'CODE', 'runtime code'); 15491f110e0Safresh1my $x = '(?{1})'; 15591f110e0Safresh1BEGIN { $^H |= 0x00200000 } # lightweight "use re 'eval'" 15691f110e0Safresh1"a" =~ /a$_/ for $x, $x, $x; 15791f110e0Safresh1CODE 15891f110e0Safresh1 15991f110e0Safresh1comp_n(6, <<'CODE', 'runtime code qr'); 16091f110e0Safresh1my $x = '(?{1})'; 16191f110e0Safresh1BEGIN { $^H |= 0x00200000 } # lightweight "use re 'eval'" 16291f110e0Safresh1"a" =~ qr/a$_/ for $x, $x, $x; 16391f110e0Safresh1CODE 16491f110e0Safresh1 16591f110e0Safresh1comp_n(4, <<'CODE', 'embedded code'); 16691f110e0Safresh1my $x = qr/(?{1})/; 16791f110e0Safresh1"a" =~ /a$_/ for $x, $x, $x; 16891f110e0Safresh1CODE 16991f110e0Safresh1 17091f110e0Safresh1comp_n(4, <<'CODE', 'embedded code qr'); 17191f110e0Safresh1my $x = qr/(?{1})/; 17291f110e0Safresh1"a" =~ qr/a$_/ for $x, $x, $x; 17391f110e0Safresh1CODE 17491f110e0Safresh1 17591f110e0Safresh1comp_n(7, <<'CODE', 'mixed code'); 17691f110e0Safresh1my $x = qr/(?{1})/; 17791f110e0Safresh1my $y = '(?{1})'; 17891f110e0Safresh1BEGIN { $^H |= 0x00200000 } # lightweight "use re 'eval'" 17991f110e0Safresh1"a" =~ /a$x$_/ for $y, $y, $y; 18091f110e0Safresh1CODE 18191f110e0Safresh1 18291f110e0Safresh1comp_n(7, <<'CODE', 'mixed code qr'); 18391f110e0Safresh1my $x = qr/(?{1})/; 18491f110e0Safresh1my $y = '(?{1})'; 18591f110e0Safresh1BEGIN { $^H |= 0x00200000 } # lightweight "use re 'eval'" 18691f110e0Safresh1"a" =~ qr/a$x$_/ for $y, $y, $y; 18791f110e0Safresh1CODE 18891f110e0Safresh1 18991f110e0Safresh1comp_n(6, <<'CODE', 'embedded code qr'); 19091f110e0Safresh1my $x = qr/a/i; 19191f110e0Safresh1my $y = qr/a/; 19291f110e0Safresh1"a" =~ qr/a$_/ for $x, $y, $x, $y; 19391f110e0Safresh1CODE 1946fb12b70Safresh1 1956fb12b70Safresh1comp_n(2, <<'CODE', '(??{"constant"})'); 1966fb12b70Safresh1"bb" =~ /(??{"abc"})/; 1976fb12b70Safresh1CODE 1986fb12b70Safresh1 1996fb12b70Safresh1comp_n(2, <<'CODE', '(??{"folded"."constant"})'); 2006fb12b70Safresh1"bb" =~ /(??{"ab"."c"})/; 2016fb12b70Safresh1CODE 2026fb12b70Safresh1 2036fb12b70Safresh1comp_n(2, <<'CODE', '(??{$preused_scalar})'); 2046fb12b70Safresh1$s = "abc"; 2056fb12b70Safresh1"bb" =~ /(??{$s})/; 2066fb12b70Safresh1CODE 2076fb12b70Safresh1 2086fb12b70Safresh1comp_n(2, <<'CODE', '(??{number})'); 2096fb12b70Safresh1"bb" =~ /(??{123})/; 2106fb12b70Safresh1CODE 2116fb12b70Safresh1 2126fb12b70Safresh1comp_n(2, <<'CODE', '(??{$pvlv_regexp})'); 2136fb12b70Safresh1sub { 2146fb12b70Safresh1 $_[0] = ${qr/abc/}; 2156fb12b70Safresh1 "bb" =~ /(??{$_[0]})/; 2166fb12b70Safresh1}->($_[0]); 2176fb12b70Safresh1CODE 218