16fb12b70Safresh1#!./perl 26fb12b70Safresh1 36fb12b70Safresh1# Test the core keywords. 46fb12b70Safresh1# 56fb12b70Safresh1# Initially this test file just checked that CORE::foo got correctly 66fb12b70Safresh1# deparsed as CORE::foo, hence the name. It's since been expanded 7b8851fccSafresh1# to fully test both CORE:: versus none, plus that any arguments 86fb12b70Safresh1# are correctly deparsed. It also cross-checks against regen/keywords.pl 96fb12b70Safresh1# to make sure we've tested all keywords, and with the correct strength. 106fb12b70Safresh1# 116fb12b70Safresh1# A keyword can be either weak or strong. Strong keywords can never be 126fb12b70Safresh1# overridden, while weak ones can. So deparsing of weak keywords depends 136fb12b70Safresh1# on whether a sub of that name has been created: 146fb12b70Safresh1# 156fb12b70Safresh1# for both: keyword(..) deparsed as keyword(..) 166fb12b70Safresh1# for weak: CORE::keyword(..) deparsed as CORE::keyword(..) 176fb12b70Safresh1# for strong: CORE::keyword(..) deparsed as keyword(..) 186fb12b70Safresh1# 196fb12b70Safresh1# Three permutations of lex/nonlex args are checked for: 206fb12b70Safresh1# 216fb12b70Safresh1# foo($a,$b,$c,...) 226fb12b70Safresh1# foo(my $a,$b,$c,...) 236fb12b70Safresh1# my ($a,$b,$c,...); foo($a,$b,$c,...) 246fb12b70Safresh1# 256fb12b70Safresh1# Note that tests for prefixing feature.pm-enabled keywords with CORE:: when 266fb12b70Safresh1# feature.pm is not enabled are in deparse.t, as they fit that format better. 276fb12b70Safresh1 286fb12b70Safresh1 296fb12b70Safresh1BEGIN { 306fb12b70Safresh1 require Config; 316fb12b70Safresh1 if (($Config::Config{extensions} !~ /\bB\b/) ){ 326fb12b70Safresh1 print "1..0 # Skip -- Perl configured without B module\n"; 336fb12b70Safresh1 exit 0; 346fb12b70Safresh1 } 356fb12b70Safresh1} 366fb12b70Safresh1 37*3d61058aSafresh1use warnings; 386fb12b70Safresh1use strict; 396fb12b70Safresh1use Test::More; 406fb12b70Safresh1 416fb12b70Safresh1use feature (sprintf(":%vd", $^V)); # to avoid relying on the feature 426fb12b70Safresh1 # logic to add CORE:: 436fb12b70Safresh1use B::Deparse; 44eac174f2Safresh1my $deparse = B::Deparse->new(); 456fb12b70Safresh1 466fb12b70Safresh1my %SEEN; 47eac174f2Safresh1my %SEEN_STRENGTH; 486fb12b70Safresh1 49eac174f2Safresh1# For a given keyword, create a sub of that name, 50eac174f2Safresh1# then deparse 3 different assignment expressions 51eac174f2Safresh1# using that keyword. See if the $expr we get back 52eac174f2Safresh1# matches $expected_expr. 536fb12b70Safresh1 546fb12b70Safresh1sub testit { 55b8851fccSafresh1 my ($keyword, $expr, $expected_expr, $lexsub) = @_; 566fb12b70Safresh1 576fb12b70Safresh1 $expected_expr //= $expr; 586fb12b70Safresh1 $SEEN{$keyword} = 1; 596fb12b70Safresh1 606fb12b70Safresh1 # lex=0: () = foo($a,$b,$c) 616fb12b70Safresh1 # lex=1: my ($a,$b); () = foo($a,$b,$c) 626fb12b70Safresh1 # lex=2: () = foo(my $a,$b,$c) 636fb12b70Safresh1 for my $lex (0, 1, 2) { 64eac174f2Safresh1 next if ($lex and $keyword =~ /local|our|state|my/); 656fb12b70Safresh1 my $vars = $lex == 1 ? 'my($a, $b, $c, $d, $e);' . "\n " : ""; 666fb12b70Safresh1 676fb12b70Safresh1 if ($lex == 2) { 686fb12b70Safresh1 my $repl = 'my $a'; 69b8851fccSafresh1 if ($expr =~ 'CORE::do') { 70b8851fccSafresh1 # do foo() is a syntax error, so B::Deparse emits 71b8851fccSafresh1 # do (foo()), but does not distinguish between foo and my, 72b8851fccSafresh1 # because it is too complicated. 73b8851fccSafresh1 $repl = '(my $a)'; 746fb12b70Safresh1 } 756fb12b70Safresh1 s/\$a/$repl/ for $expr, $expected_expr; 766fb12b70Safresh1 } 776fb12b70Safresh1 786fb12b70Safresh1 my $desc = "$keyword: lex=$lex $expr => $expected_expr"; 79b8851fccSafresh1 $desc .= " (lex sub)" if $lexsub; 806fb12b70Safresh1 819f11ffb7Safresh1 my $code; 826fb12b70Safresh1 my $code_ref; 83b8851fccSafresh1 if ($lexsub) { 84b8851fccSafresh1 package lexsubtest; 85eac174f2Safresh1 no warnings 'experimental::lexical_subs'; 86b8851fccSafresh1 use feature 'lexical_subs'; 87*3d61058aSafresh1 $code = "no warnings 'syntax'; no strict 'vars'; sub { state sub $keyword; ${vars}() = $expr }"; 8856d68f1eSafresh1 $code = "use feature 'isa';\n$code" if $keyword eq "isa"; 89eac174f2Safresh1 $code = "use feature 'switch';\n$code" if $keyword eq "break"; 90eac174f2Safresh1 $code_ref = eval $code or die "$@ in $expr"; 91b8851fccSafresh1 } 92b8851fccSafresh1 else { 936fb12b70Safresh1 package test; 946fb12b70Safresh1 use subs (); 956fb12b70Safresh1 import subs $keyword; 96*3d61058aSafresh1 $code = "no warnings 'syntax'; no strict 'vars'; sub { ${vars}() = $expr }"; 9756d68f1eSafresh1 $code = "use feature 'isa';\n$code" if $keyword eq "isa"; 98eac174f2Safresh1 $code = "use feature 'switch';\n$code" if $keyword eq "break"; 99eac174f2Safresh1 $code_ref = eval $code or die "$@ in $expr"; 1006fb12b70Safresh1 } 1016fb12b70Safresh1 1026fb12b70Safresh1 my $got_text = $deparse->coderef2text($code_ref); 1036fb12b70Safresh1 104b8851fccSafresh1 unless ($got_text =~ / 105b8851fccSafresh1 package (?:lexsub)?test; 1069f11ffb7Safresh1(?: BEGIN \{\$\{\^WARNING_BITS\} = "[^"]+"\} 1079f11ffb7Safresh1)? use strict 'refs', 'subs'; 1086fb12b70Safresh1 use feature [^\n]+ 1099f11ffb7Safresh1(?: (?:CORE::)?state sub \w+; 1109f11ffb7Safresh1)? \Q$vars\E\(\) = (.*) 1119f11ffb7Safresh1\}/s) { 1126fb12b70Safresh1 ::fail($desc); 1136fb12b70Safresh1 ::diag("couldn't extract line from boilerplate\n"); 1146fb12b70Safresh1 ::diag($got_text); 1156fb12b70Safresh1 return; 1166fb12b70Safresh1 } 1176fb12b70Safresh1 1186fb12b70Safresh1 my $got_expr = $1; 1199f11ffb7Safresh1 is $got_expr, $expected_expr, $desc 1209f11ffb7Safresh1 or ::diag("ORIGINAL CODE:\n$code");; 1216fb12b70Safresh1 } 1226fb12b70Safresh1} 1236fb12b70Safresh1 1246fb12b70Safresh1 1256fb12b70Safresh1# Deparse can't distinguish 'and' from '&&' etc 1266fb12b70Safresh1my %infix_map = qw(and && or ||); 1276fb12b70Safresh1 128eac174f2Safresh1# Test a keyword that is a binary infix operator, like 'cmp'. 1296fb12b70Safresh1# $parens - "$a op $b" is deparsed as "($a op $b)" 1306fb12b70Safresh1# $strong - keyword is strong 1316fb12b70Safresh1 1326fb12b70Safresh1sub do_infix_keyword { 1336fb12b70Safresh1 my ($keyword, $parens, $strong) = @_; 134eac174f2Safresh1 $SEEN_STRENGTH{$keyword} = $strong; 1356fb12b70Safresh1 my $nkey = $infix_map{$keyword} // $keyword; 1366fb12b70Safresh1 my $exp = "\$a $nkey \$b"; 1376fb12b70Safresh1 $exp = "($exp)" if $parens; 1386fb12b70Safresh1 $exp .= ";"; 1396fb12b70Safresh1 # with infix notation, a keyword is always interpreted as core, 1406fb12b70Safresh1 # so no need for Deparse to disambiguate with CORE:: 1416fb12b70Safresh1 testit $keyword, "(\$a CORE::$keyword \$b)", $exp; 1426fb12b70Safresh1 testit $keyword, "(\$a $keyword \$b)", $exp; 143b8851fccSafresh1 testit $keyword, "(\$a CORE::$keyword \$b)", $exp, 1; 144b8851fccSafresh1 testit $keyword, "(\$a $keyword \$b)", $exp, 1; 1456fb12b70Safresh1 if (!$strong) { 146b8851fccSafresh1 # B::Deparse fully qualifies any sub whose name is a keyword, 147b8851fccSafresh1 # imported or not, since the importedness may not be reproduced by 148b8851fccSafresh1 # the deparsed code. x is special. 149b8851fccSafresh1 my $pre = "test::" x ($keyword ne 'x'); 150b8851fccSafresh1 testit $keyword, "$keyword(\$a, \$b)", "$pre$keyword(\$a, \$b);"; 1516fb12b70Safresh1 } 152b8851fccSafresh1 testit $keyword, "$keyword(\$a, \$b)", "$keyword(\$a, \$b);", 1; 1536fb12b70Safresh1} 1546fb12b70Safresh1 155eac174f2Safresh1# Test a keyword that is a standard op/function, like 'index(...)'. 156eac174f2Safresh1# $narg - how many args to test it with 1576fb12b70Safresh1# $parens - "foo $a, $b" is deparsed as "foo($a, $b)" 1586fb12b70Safresh1# $dollar - an extra '$_' arg will appear in the deparsed output 1596fb12b70Safresh1# $strong - keyword is strong 1606fb12b70Safresh1 1616fb12b70Safresh1 1626fb12b70Safresh1sub do_std_keyword { 1636fb12b70Safresh1 my ($keyword, $narg, $parens, $dollar, $strong) = @_; 1646fb12b70Safresh1 165eac174f2Safresh1 $SEEN_STRENGTH{$keyword} = $strong; 1666fb12b70Safresh1 1676fb12b70Safresh1 for my $core (0,1) { # if true, add CORE:: to keyword being deparsed 168b8851fccSafresh1 for my $lexsub (0,1) { # if true, define lex sub 1696fb12b70Safresh1 my @code; 1706fb12b70Safresh1 for my $do_exp(0, 1) { # first create expr, then expected-expr 1716fb12b70Safresh1 my @args = map "\$$_", (undef,"a".."z")[1..$narg]; 172b8851fccSafresh1 push @args, '$_' 173b8851fccSafresh1 if $dollar && $do_exp && ($strong && !$lexsub or $core); 1746fb12b70Safresh1 my $args = join(', ', @args); 175b8851fccSafresh1 # XXX $lex_parens is temporary, until lex subs are 176b8851fccSafresh1 # deparsed properly. 177b8851fccSafresh1 my $lex_parens = 178b8851fccSafresh1 !$core && $do_exp && $lexsub && $keyword ne 'map'; 179b8851fccSafresh1 $args = ((!$core && !$strong) || $parens || $lex_parens) 1806fb12b70Safresh1 ? "($args)" 181eac174f2Safresh1 : @args 182eac174f2Safresh1 ? " $args" 183eac174f2Safresh1 : ""; 184eac174f2Safresh1 push @code, ( 185eac174f2Safresh1 ($core && !($do_exp && $strong)) 186b8851fccSafresh1 ? "CORE::" 187b8851fccSafresh1 : $lexsub && $do_exp 188b8851fccSafresh1 ? "CORE::" x $core 189eac174f2Safresh1 : $do_exp && !$core && !$strong 190eac174f2Safresh1 ? "test::" 191eac174f2Safresh1 : "" 192eac174f2Safresh1 ) . "$keyword$args;"; 1936fb12b70Safresh1 } 194b8851fccSafresh1 # code[0]: to run; code[1]: expected 195b8851fccSafresh1 testit $keyword, @code, $lexsub; 196b8851fccSafresh1 } 1976fb12b70Safresh1 } 1986fb12b70Safresh1} 1996fb12b70Safresh1 2006fb12b70Safresh1 2016fb12b70Safresh1while (<DATA>) { 2026fb12b70Safresh1 chomp; 2036fb12b70Safresh1 s/#.*//; 2046fb12b70Safresh1 next unless /\S/; 2056fb12b70Safresh1 2066fb12b70Safresh1 my @fields = split; 2076fb12b70Safresh1 die "not 3 fields" unless @fields == 3; 2086fb12b70Safresh1 my ($keyword, $args, $flags) = @fields; 2096fb12b70Safresh1 2106fb12b70Safresh1 $args = '012' if $args eq '@'; 2116fb12b70Safresh1 2126fb12b70Safresh1 my $parens = $flags =~ s/p//; 2136fb12b70Safresh1 my $invert1 = $flags =~ s/1//; 2146fb12b70Safresh1 my $dollar = $flags =~ s/\$//; 2156fb12b70Safresh1 my $strong = $flags =~ s/\+//; 2166fb12b70Safresh1 die "unrecognised flag(s): '$flags'" unless $flags =~ /^-?$/; 2176fb12b70Safresh1 2186fb12b70Safresh1 if ($args eq 'B') { # binary infix 2196fb12b70Safresh1 die "$keyword: binary (B) op can't have '\$' flag\\n" if $dollar; 2206fb12b70Safresh1 die "$keyword: binary (B) op can't have '1' flag\\n" if $invert1; 2216fb12b70Safresh1 do_infix_keyword($keyword, $parens, $strong); 2226fb12b70Safresh1 } 2236fb12b70Safresh1 else { 2246fb12b70Safresh1 my @narg = split //, $args; 2256fb12b70Safresh1 for my $n (0..$#narg) { 2266fb12b70Safresh1 my $narg = $narg[$n]; 2276fb12b70Safresh1 my $p = $parens; 2286fb12b70Safresh1 $p = !$p if ($n == 0 && $invert1); 2296fb12b70Safresh1 do_std_keyword($keyword, $narg, $p, (!$n && $dollar), $strong); 2306fb12b70Safresh1 } 2316fb12b70Safresh1 } 2326fb12b70Safresh1} 2336fb12b70Safresh1 2346fb12b70Safresh1 2356fb12b70Safresh1# Special cases 2366fb12b70Safresh1 2376fb12b70Safresh1testit dbmopen => 'CORE::dbmopen(%foo, $bar, $baz);'; 2386fb12b70Safresh1testit dbmclose => 'CORE::dbmclose %foo;'; 2396fb12b70Safresh1 2406fb12b70Safresh1testit delete => 'CORE::delete $h{\'foo\'};', 'delete $h{\'foo\'};'; 241b8851fccSafresh1testit delete => 'CORE::delete $h{\'foo\'};', undef, 1; 242b8851fccSafresh1testit delete => 'CORE::delete @h{\'foo\'};', undef, 1; 243b8851fccSafresh1testit delete => 'CORE::delete $h[0];', undef, 1; 244b8851fccSafresh1testit delete => 'CORE::delete @h[0];', undef, 1; 2456fb12b70Safresh1testit delete => 'delete $h{\'foo\'};', 'delete $h{\'foo\'};'; 2466fb12b70Safresh1 2476fb12b70Safresh1# do is listed as strong, but only do { block } is strong; 2486fb12b70Safresh1# do $file is weak, so test it separately here 2496fb12b70Safresh1testit do => 'CORE::do $a;'; 250b8851fccSafresh1testit do => 'do $a;', 'test::do($a);'; 2516fb12b70Safresh1testit do => 'CORE::do { 1 }', 2526fb12b70Safresh1 "do {\n 1\n };"; 253b8851fccSafresh1testit do => 'CORE::do { 1 }', 254b8851fccSafresh1 "CORE::do {\n 1\n };", 1; 2556fb12b70Safresh1testit do => 'do { 1 };', 2566fb12b70Safresh1 "do {\n 1\n };"; 2576fb12b70Safresh1 2586fb12b70Safresh1testit each => 'CORE::each %bar;'; 259b8851fccSafresh1testit each => 'CORE::each @foo;'; 2606fb12b70Safresh1 2616fb12b70Safresh1testit eof => 'CORE::eof();'; 2626fb12b70Safresh1 2636fb12b70Safresh1testit exists => 'CORE::exists $h{\'foo\'};', 'exists $h{\'foo\'};'; 264b8851fccSafresh1testit exists => 'CORE::exists $h{\'foo\'};', undef, 1; 265b8851fccSafresh1testit exists => 'CORE::exists &foo;', undef, 1; 266b8851fccSafresh1testit exists => 'CORE::exists $h[0];', undef, 1; 2676fb12b70Safresh1testit exists => 'exists $h{\'foo\'};', 'exists $h{\'foo\'};'; 2686fb12b70Safresh1 2696fb12b70Safresh1testit exec => 'CORE::exec($foo $bar);'; 2706fb12b70Safresh1 2716fb12b70Safresh1testit glob => 'glob;', 'glob($_);'; 2726fb12b70Safresh1testit glob => 'CORE::glob;', 'CORE::glob($_);'; 2736fb12b70Safresh1testit glob => 'glob $a;', 'glob($a);'; 2746fb12b70Safresh1testit glob => 'CORE::glob $a;', 'CORE::glob($a);'; 2756fb12b70Safresh1 2766fb12b70Safresh1testit grep => 'CORE::grep { $a } $b, $c', 'grep({$a;} $b, $c);'; 2776fb12b70Safresh1 2786fb12b70Safresh1testit keys => 'CORE::keys %bar;'; 279b8851fccSafresh1testit keys => 'CORE::keys @bar;'; 2806fb12b70Safresh1 2816fb12b70Safresh1testit map => 'CORE::map { $a } $b, $c', 'map({$a;} $b, $c);'; 2826fb12b70Safresh1 2836fb12b70Safresh1testit not => '3 unless CORE::not $a && $b;'; 2846fb12b70Safresh1 285b8851fccSafresh1testit pop => 'CORE::pop @foo;'; 286b8851fccSafresh1 287b8851fccSafresh1testit push => 'CORE::push @foo;', 'CORE::push(@foo);'; 288b8851fccSafresh1testit push => 'CORE::push @foo, 1;', 'CORE::push(@foo, 1);'; 289b8851fccSafresh1testit push => 'CORE::push @foo, 1, 2;', 'CORE::push(@foo, 1, 2);'; 290b8851fccSafresh1 2916fb12b70Safresh1testit readline => 'CORE::readline $a . $b;'; 2926fb12b70Safresh1 2936fb12b70Safresh1testit readpipe => 'CORE::readpipe $a + $b;'; 2946fb12b70Safresh1 2956fb12b70Safresh1testit reverse => 'CORE::reverse sort(@foo);'; 2966fb12b70Safresh1 297b8851fccSafresh1testit shift => 'CORE::shift @foo;'; 298b8851fccSafresh1 299b8851fccSafresh1testit splice => q{CORE::splice @foo;}, q{CORE::splice(@foo);}; 300b8851fccSafresh1testit splice => q{CORE::splice @foo, 0;}, q{CORE::splice(@foo, 0);}; 301b8851fccSafresh1testit splice => q{CORE::splice @foo, 0, 1;}, q{CORE::splice(@foo, 0, 1);}; 302b8851fccSafresh1testit splice => q{CORE::splice @foo, 0, 1, 'a';}, q{CORE::splice(@foo, 0, 1, 'a');}; 303b8851fccSafresh1testit splice => q{CORE::splice @foo, 0, 1, 'a', 'b';}, q{CORE::splice(@foo, 0, 1, 'a', 'b');}; 304b8851fccSafresh1 3056fb12b70Safresh1# note that the test does '() = split...' which is why the 3066fb12b70Safresh1# limit is optimised to 1 3076fb12b70Safresh1testit split => 'split;', q{split(' ', $_, 1);}; 3086fb12b70Safresh1testit split => 'CORE::split;', q{split(' ', $_, 1);}; 3096fb12b70Safresh1testit split => 'split $a;', q{split(/$a/u, $_, 1);}; 3106fb12b70Safresh1testit split => 'CORE::split $a;', q{split(/$a/u, $_, 1);}; 3116fb12b70Safresh1testit split => 'split $a, $b;', q{split(/$a/u, $b, 1);}; 3126fb12b70Safresh1testit split => 'CORE::split $a, $b;', q{split(/$a/u, $b, 1);}; 3136fb12b70Safresh1testit split => 'split $a, $b, $c;', q{split(/$a/u, $b, $c);}; 3146fb12b70Safresh1testit split => 'CORE::split $a, $b, $c;', q{split(/$a/u, $b, $c);}; 3156fb12b70Safresh1 3166fb12b70Safresh1testit sub => 'CORE::sub { $a, $b }', 3176fb12b70Safresh1 "sub {\n \$a, \$b;\n }\n ;"; 3186fb12b70Safresh1 3196fb12b70Safresh1testit system => 'CORE::system($foo $bar);'; 3206fb12b70Safresh1 321b8851fccSafresh1testit unshift => 'CORE::unshift @foo;', 'CORE::unshift(@foo);'; 322b8851fccSafresh1testit unshift => 'CORE::unshift @foo, 1;', 'CORE::unshift(@foo, 1);'; 323b8851fccSafresh1testit unshift => 'CORE::unshift @foo, 1, 2;', 'CORE::unshift(@foo, 1, 2);'; 324b8851fccSafresh1 3256fb12b70Safresh1testit values => 'CORE::values %bar;'; 326b8851fccSafresh1testit values => 'CORE::values @foo;'; 3276fb12b70Safresh1 3286fb12b70Safresh1 3296fb12b70Safresh1# XXX These are deparsed wrapped in parens. 3306fb12b70Safresh1# whether they should be, I don't know! 3316fb12b70Safresh1 3326fb12b70Safresh1testit dump => '(CORE::dump);'; 3336fb12b70Safresh1testit dump => '(CORE::dump FOO);'; 3346fb12b70Safresh1testit goto => '(CORE::goto);', '(goto);'; 3356fb12b70Safresh1testit goto => '(CORE::goto FOO);', '(goto FOO);'; 3366fb12b70Safresh1testit last => '(CORE::last);', '(last);'; 3376fb12b70Safresh1testit last => '(CORE::last FOO);', '(last FOO);'; 3386fb12b70Safresh1testit next => '(CORE::next);', '(next);'; 3396fb12b70Safresh1testit next => '(CORE::next FOO);', '(next FOO);'; 3406fb12b70Safresh1testit redo => '(CORE::redo);', '(redo);'; 3416fb12b70Safresh1testit redo => '(CORE::redo FOO);', '(redo FOO);'; 3426fb12b70Safresh1testit redo => '(CORE::redo);', '(redo);'; 3436fb12b70Safresh1testit redo => '(CORE::redo FOO);', '(redo FOO);'; 3446fb12b70Safresh1testit return => '(return);', '(return);'; 3456fb12b70Safresh1testit return => '(CORE::return);', '(return);'; 3466fb12b70Safresh1 3476fb12b70Safresh1# these are the keywords I couldn't think how to test within this framework 3486fb12b70Safresh1 3496fb12b70Safresh1my %not_tested = map { $_ => 1} qw( 3506fb12b70Safresh1 __DATA__ 3516fb12b70Safresh1 __END__ 3526fb12b70Safresh1 __FILE__ 3536fb12b70Safresh1 __LINE__ 3546fb12b70Safresh1 __PACKAGE__ 355*3d61058aSafresh1 __CLASS__ 356e0680481Safresh1 ADJUST 3576fb12b70Safresh1 AUTOLOAD 3586fb12b70Safresh1 BEGIN 3596fb12b70Safresh1 CHECK 3606fb12b70Safresh1 CORE 3616fb12b70Safresh1 DESTROY 3626fb12b70Safresh1 END 3636fb12b70Safresh1 INIT 3646fb12b70Safresh1 UNITCHECK 365eac174f2Safresh1 catch 366e0680481Safresh1 class 3676fb12b70Safresh1 default 368eac174f2Safresh1 defer 3696fb12b70Safresh1 else 3706fb12b70Safresh1 elsif 371e0680481Safresh1 field 372eac174f2Safresh1 finally 3736fb12b70Safresh1 for 3746fb12b70Safresh1 foreach 3756fb12b70Safresh1 format 3766fb12b70Safresh1 given 3776fb12b70Safresh1 if 3786fb12b70Safresh1 m 379e0680481Safresh1 method 3806fb12b70Safresh1 no 3816fb12b70Safresh1 package 3826fb12b70Safresh1 q 3836fb12b70Safresh1 qq 3846fb12b70Safresh1 qr 3856fb12b70Safresh1 qw 3866fb12b70Safresh1 qx 3876fb12b70Safresh1 require 3886fb12b70Safresh1 s 3896fb12b70Safresh1 tr 390eac174f2Safresh1 try 3916fb12b70Safresh1 unless 3926fb12b70Safresh1 until 3936fb12b70Safresh1 use 3946fb12b70Safresh1 when 3956fb12b70Safresh1 while 3966fb12b70Safresh1 y 3976fb12b70Safresh1); 3986fb12b70Safresh1 3996fb12b70Safresh1# Sanity check against keyword data: 4006fb12b70Safresh1# make sure we haven't missed any keywords, 4016fb12b70Safresh1# and that we got the strength right. 4026fb12b70Safresh1 4036fb12b70Safresh1SKIP: 4046fb12b70Safresh1{ 4056fb12b70Safresh1 skip "sanity checks when not PERL_CORE", 1 unless defined $ENV{PERL_CORE}; 4066fb12b70Safresh1 my $count = 0; 4076fb12b70Safresh1 my $file = '../regen/keywords.pl'; 4086fb12b70Safresh1 my $pass = 1; 4096fb12b70Safresh1 if (open my $fh, '<', $file) { 4106fb12b70Safresh1 while (<$fh>) { 4116fb12b70Safresh1 last if /^__END__$/; 4126fb12b70Safresh1 } 4136fb12b70Safresh1 while (<$fh>) { 4146fb12b70Safresh1 next unless /^([+\-])(\w+)$/; 4156fb12b70Safresh1 my ($strength, $key) = ($1, $2); 4166fb12b70Safresh1 $strength = ($strength eq '+') ? 1 : 0; 4176fb12b70Safresh1 $count++; 4186fb12b70Safresh1 if (!$SEEN{$key} && !$not_tested{$key}) { 4196fb12b70Safresh1 diag("keyword '$key' seen in $file, but not tested here!!"); 4206fb12b70Safresh1 $pass = 0; 4216fb12b70Safresh1 } 422eac174f2Safresh1 if (exists $SEEN_STRENGTH{$key} and $SEEN_STRENGTH{$key} != $strength) { 4236fb12b70Safresh1 diag("keyword '$key' strengh as seen in $file doen't match here!!"); 4246fb12b70Safresh1 $pass = 0; 4256fb12b70Safresh1 } 4266fb12b70Safresh1 } 4276fb12b70Safresh1 } 4286fb12b70Safresh1 else { 4296fb12b70Safresh1 diag("Can't open $file: $!"); 4306fb12b70Safresh1 $pass = 0; 4316fb12b70Safresh1 } 4326fb12b70Safresh1 # insanity check 4336fb12b70Safresh1 if ($count < 200) { 4346fb12b70Safresh1 diag("Saw $count keywords: less than 200!"); 4356fb12b70Safresh1 $pass = 0; 4366fb12b70Safresh1 } 4376fb12b70Safresh1 ok($pass, "sanity checks"); 4386fb12b70Safresh1} 4396fb12b70Safresh1 440eac174f2Safresh1done_testing(); 4416fb12b70Safresh1 4426fb12b70Safresh1__DATA__ 4436fb12b70Safresh1# 4446fb12b70Safresh1# format: 4456fb12b70Safresh1# keyword args flags 4466fb12b70Safresh1# 4476fb12b70Safresh1# args consists of: 4486fb12b70Safresh1# * one of more digits indictating which lengths of args the function accepts, 4496fb12b70Safresh1# * or 'B' to indiate a binary infix operator, 4506fb12b70Safresh1# * or '@' to indicate a list function. 4516fb12b70Safresh1# 4526fb12b70Safresh1# Flags consists of the following (or '-' if no flags): 4536fb12b70Safresh1# + : strong keyword: can't be overrriden 4546fb12b70Safresh1# p : the args are parenthesised on deparsing; 4556fb12b70Safresh1# 1 : parenthesising of 1st arg length is inverted 4566fb12b70Safresh1# so '234 p1' means: foo a1,a2; foo(a1,a2,a3); foo(a1,a2,a3,a4) 4576fb12b70Safresh1# $ : on the first argument length, there is an implicit extra 4586fb12b70Safresh1# '$_' arg which will appear on deparsing; 4596fb12b70Safresh1# e.g. 12p$ will be tested as: foo(a1); foo(a1,a2); 4606fb12b70Safresh1# and deparsed as: foo(a1, $_); foo(a1,a2); 4616fb12b70Safresh1# 4626fb12b70Safresh1# XXX Note that we really should get this data from regen/keywords.pl 4636fb12b70Safresh1# and regen/opcodes (augmented if necessary), rather than duplicating it 4646fb12b70Safresh1# here. 4656fb12b70Safresh1 4666fb12b70Safresh1__SUB__ 0 - 4676fb12b70Safresh1abs 01 $ 4686fb12b70Safresh1accept 2 p 4696fb12b70Safresh1alarm 01 $ 4706fb12b70Safresh1and B - 4716fb12b70Safresh1atan2 2 p 4726fb12b70Safresh1bind 2 p 4736fb12b70Safresh1binmode 12 p 4746fb12b70Safresh1bless 1 p 4756fb12b70Safresh1break 0 - 4766fb12b70Safresh1caller 0 - 4776fb12b70Safresh1chdir 01 - 4786fb12b70Safresh1chmod @ p1 4796fb12b70Safresh1chomp @ $ 4806fb12b70Safresh1chop @ $ 4816fb12b70Safresh1chown @ p1 4826fb12b70Safresh1chr 01 $ 4836fb12b70Safresh1chroot 01 $ 4846fb12b70Safresh1close 01 - 4856fb12b70Safresh1closedir 1 - 4866fb12b70Safresh1cmp B - 4876fb12b70Safresh1connect 2 p 4886fb12b70Safresh1continue 0 - 4896fb12b70Safresh1cos 01 $ 4906fb12b70Safresh1crypt 2 p 4916fb12b70Safresh1# dbmopen handled specially 4926fb12b70Safresh1# dbmclose handled specially 4936fb12b70Safresh1defined 01 $+ 4946fb12b70Safresh1# delete handled specially 4956fb12b70Safresh1die @ p1 4966fb12b70Safresh1# do handled specially 4976fb12b70Safresh1# dump handled specially 498b8851fccSafresh1# each handled specially 4996fb12b70Safresh1endgrent 0 - 5006fb12b70Safresh1endhostent 0 - 5016fb12b70Safresh1endnetent 0 - 5026fb12b70Safresh1endprotoent 0 - 5036fb12b70Safresh1endpwent 0 - 5046fb12b70Safresh1endservent 0 - 5056fb12b70Safresh1eof 01 - # also tested specially 5066fb12b70Safresh1eq B - 5076fb12b70Safresh1eval 01 $+ 5086fb12b70Safresh1evalbytes 01 $ 5096fb12b70Safresh1exec @ p1 # also tested specially 5106fb12b70Safresh1# exists handled specially 5116fb12b70Safresh1exit 01 - 5126fb12b70Safresh1exp 01 $ 5136fb12b70Safresh1fc 01 $ 5146fb12b70Safresh1fcntl 3 p 5156fb12b70Safresh1fileno 1 - 5166fb12b70Safresh1flock 2 p 5176fb12b70Safresh1fork 0 - 5186fb12b70Safresh1formline 2 p 5196fb12b70Safresh1ge B - 5206fb12b70Safresh1getc 01 - 5216fb12b70Safresh1getgrent 0 - 5226fb12b70Safresh1getgrgid 1 - 5236fb12b70Safresh1getgrnam 1 - 5246fb12b70Safresh1gethostbyaddr 2 p 5256fb12b70Safresh1gethostbyname 1 - 5266fb12b70Safresh1gethostent 0 - 5276fb12b70Safresh1getlogin 0 - 5286fb12b70Safresh1getnetbyaddr 2 p 5296fb12b70Safresh1getnetbyname 1 - 5306fb12b70Safresh1getnetent 0 - 5316fb12b70Safresh1getpeername 1 - 5326fb12b70Safresh1getpgrp 1 - 5336fb12b70Safresh1getppid 0 - 5346fb12b70Safresh1getpriority 2 p 5356fb12b70Safresh1getprotobyname 1 - 5366fb12b70Safresh1getprotobynumber 1 p 5376fb12b70Safresh1getprotoent 0 - 5386fb12b70Safresh1getpwent 0 - 5396fb12b70Safresh1getpwnam 1 - 5406fb12b70Safresh1getpwuid 1 - 5416fb12b70Safresh1getservbyname 2 p 5426fb12b70Safresh1getservbyport 2 p 5436fb12b70Safresh1getservent 0 - 5446fb12b70Safresh1getsockname 1 - 5456fb12b70Safresh1getsockopt 3 p 5466fb12b70Safresh1# given handled specially 5476fb12b70Safresh1grep 123 p+ # also tested specially 5486fb12b70Safresh1# glob handled specially 5496fb12b70Safresh1# goto handled specially 5506fb12b70Safresh1gmtime 01 - 5516fb12b70Safresh1gt B - 5526fb12b70Safresh1hex 01 $ 5536fb12b70Safresh1index 23 p 5546fb12b70Safresh1int 01 $ 5556fb12b70Safresh1ioctl 3 p 55656d68f1eSafresh1isa B - 557b8851fccSafresh1join 13 p 558b8851fccSafresh1# keys handled specially 5596fb12b70Safresh1kill 123 p 5606fb12b70Safresh1# last handled specially 5616fb12b70Safresh1lc 01 $ 5626fb12b70Safresh1lcfirst 01 $ 5636fb12b70Safresh1le B - 5646fb12b70Safresh1length 01 $ 5656fb12b70Safresh1link 2 p 5666fb12b70Safresh1listen 2 p 5676fb12b70Safresh1local 1 p+ 5686fb12b70Safresh1localtime 01 - 5696fb12b70Safresh1lock 1 - 5706fb12b70Safresh1log 01 $ 5716fb12b70Safresh1lstat 01 $ 5726fb12b70Safresh1lt B - 5736fb12b70Safresh1map 123 p+ # also tested specially 5746fb12b70Safresh1mkdir @ p$ 5756fb12b70Safresh1msgctl 3 p 5766fb12b70Safresh1msgget 2 p 5776fb12b70Safresh1msgrcv 5 p 5786fb12b70Safresh1msgsnd 3 p 5796fb12b70Safresh1my 123 p+ # skip with 0 args, as my() => () 5806fb12b70Safresh1ne B - 5816fb12b70Safresh1# next handled specially 5826fb12b70Safresh1# not handled specially 5836fb12b70Safresh1oct 01 $ 5846fb12b70Safresh1open 12345 p 5856fb12b70Safresh1opendir 2 p 5866fb12b70Safresh1or B - 5876fb12b70Safresh1ord 01 $ 5886fb12b70Safresh1our 123 p+ # skip with 0 args, as our() => () 5896fb12b70Safresh1pack 123 p 5906fb12b70Safresh1pipe 2 p 591b8851fccSafresh1pop 0 1 # also tested specially 5926fb12b70Safresh1pos 01 $+ 5936fb12b70Safresh1print @ p$+ 5946fb12b70Safresh1printf @ p$+ 5956fb12b70Safresh1prototype 1 + 596b8851fccSafresh1# push handled specially 5976fb12b70Safresh1quotemeta 01 $ 5986fb12b70Safresh1rand 01 - 5996fb12b70Safresh1read 34 p 6006fb12b70Safresh1readdir 1 - 6016fb12b70Safresh1# readline handled specially 6026fb12b70Safresh1readlink 01 $ 6036fb12b70Safresh1# readpipe handled specially 6046fb12b70Safresh1recv 4 p 6056fb12b70Safresh1# redo handled specially 6066fb12b70Safresh1ref 01 $ 6076fb12b70Safresh1rename 2 p 6086fb12b70Safresh1# XXX This code prints 'Undefined subroutine &main::require called': 6096fb12b70Safresh1# use subs (); import subs 'require'; 6106fb12b70Safresh1# eval q[no strict 'vars'; sub { () = require; }]; print $@; 6116fb12b70Safresh1# so disable for now 6126fb12b70Safresh1#require 01 $+ 6136fb12b70Safresh1reset 01 - 6146fb12b70Safresh1# return handled specially 6156fb12b70Safresh1reverse @ p1 # also tested specially 6166fb12b70Safresh1rewinddir 1 - 6176fb12b70Safresh1rindex 23 p 6186fb12b70Safresh1rmdir 01 $ 6196fb12b70Safresh1say @ p$+ 6206fb12b70Safresh1scalar 1 + 6216fb12b70Safresh1seek 3 p 6226fb12b70Safresh1seekdir 2 p 6236fb12b70Safresh1select 014 p1 6246fb12b70Safresh1semctl 4 p 6256fb12b70Safresh1semget 3 p 6266fb12b70Safresh1semop 2 p 6276fb12b70Safresh1send 34 p 6286fb12b70Safresh1setgrent 0 - 6296fb12b70Safresh1sethostent 1 - 6306fb12b70Safresh1setnetent 1 - 6316fb12b70Safresh1setpgrp 2 p 6326fb12b70Safresh1setpriority 3 p 6336fb12b70Safresh1setprotoent 1 - 6346fb12b70Safresh1setpwent 0 - 6356fb12b70Safresh1setservent 1 - 6366fb12b70Safresh1setsockopt 4 p 637b8851fccSafresh1shift 0 1 # also tested specially 6386fb12b70Safresh1shmctl 3 p 6396fb12b70Safresh1shmget 3 p 6406fb12b70Safresh1shmread 4 p 6416fb12b70Safresh1shmwrite 4 p 6426fb12b70Safresh1shutdown 2 p 6436fb12b70Safresh1sin 01 $ 6446fb12b70Safresh1sleep 01 - 6456fb12b70Safresh1socket 4 p 6466fb12b70Safresh1socketpair 5 p 647eac174f2Safresh1sort 12 p+ 6486fb12b70Safresh1# split handled specially 649b8851fccSafresh1# splice handled specially 6506fb12b70Safresh1sprintf 123 p 6516fb12b70Safresh1sqrt 01 $ 6526fb12b70Safresh1srand 01 - 6536fb12b70Safresh1stat 01 $ 6549f11ffb7Safresh1state 123 p1+ # skip with 0 args, as state() => () 6556fb12b70Safresh1study 01 $+ 6566fb12b70Safresh1# sub handled specially 6576fb12b70Safresh1substr 234 p 6586fb12b70Safresh1symlink 2 p 6596fb12b70Safresh1syscall 2 p 6606fb12b70Safresh1sysopen 34 p 6616fb12b70Safresh1sysread 34 p 6626fb12b70Safresh1sysseek 3 p 6636fb12b70Safresh1system @ p1 # also tested specially 6646fb12b70Safresh1syswrite 234 p 6656fb12b70Safresh1tell 01 - 6666fb12b70Safresh1telldir 1 - 6676fb12b70Safresh1tie 234 p 6686fb12b70Safresh1tied 1 - 6696fb12b70Safresh1time 0 - 6706fb12b70Safresh1times 0 - 6716fb12b70Safresh1truncate 2 p 6726fb12b70Safresh1uc 01 $ 6736fb12b70Safresh1ucfirst 01 $ 6746fb12b70Safresh1umask 01 - 6756fb12b70Safresh1undef 01 + 6766fb12b70Safresh1unlink @ p$ 6776fb12b70Safresh1unpack 12 p$ 678b8851fccSafresh1# unshift handled specially 6796fb12b70Safresh1untie 1 - 6806fb12b70Safresh1utime @ p1 681b8851fccSafresh1# values handled specially 6826fb12b70Safresh1vec 3 p 6836fb12b70Safresh1wait 0 - 6846fb12b70Safresh1waitpid 2 p 6856fb12b70Safresh1wantarray 0 - 6866fb12b70Safresh1warn @ p1 6876fb12b70Safresh1write 01 - 6886fb12b70Safresh1x B - 6896fb12b70Safresh1xor B p 690