xref: /openbsd-src/gnu/usr.bin/perl/t/re/recompile.t (revision 56d68f1e19ff848c889ecfa71d3a06340ff64892)
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