1#!./perl 2# 3# Contributed by Graham Barr <Graham.Barr@tiuk.ti.com> 4# 5# So far there are tests for the following prototypes. 6# none, () ($) ($@) ($%) ($;$) (&) (&\@) (&@) (%) (\%) (\@) 7# 8# It is impossible to test every prototype that can be specified, but 9# we should test as many as we can. 10# 11 12BEGIN { 13 chdir 't' if -d 't'; 14 @INC = '../lib'; 15} 16 17use strict; 18 19print "1..122\n"; 20 21my $i = 1; 22 23sub testing (&$) { 24 my $p = prototype(shift); 25 my $c = shift; 26 my $what = defined $c ? '(' . $p . ')' : 'no prototype'; 27 print '#' x 25,"\n"; 28 print '# Testing ',$what,"\n"; 29 print '#' x 25,"\n"; 30 print "not " 31 if((defined($p) && defined($c) && $p ne $c) 32 || (defined($p) != defined($c))); 33 printf "ok %d\n",$i++; 34} 35 36@_ = qw(a b c d); 37my @array; 38my %hash; 39 40## 41## 42## 43 44testing \&no_proto, undef; 45 46sub no_proto { 47 print "# \@_ = (",join(",",@_),")\n"; 48 scalar(@_) 49} 50 51print "not " unless 0 == no_proto(); 52printf "ok %d\n",$i++; 53 54print "not " unless 1 == no_proto(5); 55printf "ok %d\n",$i++; 56 57print "not " unless 4 == &no_proto; 58printf "ok %d\n",$i++; 59 60print "not " unless 1 == no_proto +6; 61printf "ok %d\n",$i++; 62 63print "not " unless 4 == no_proto(@_); 64printf "ok %d\n",$i++; 65 66## 67## 68## 69 70 71testing \&no_args, ''; 72 73sub no_args () { 74 print "# \@_ = (",join(",",@_),")\n"; 75 scalar(@_) 76} 77 78print "not " unless 0 == no_args(); 79printf "ok %d\n",$i++; 80 81print "not " unless 0 == no_args; 82printf "ok %d\n",$i++; 83 84print "not " unless 5 == no_args +5; 85printf "ok %d\n",$i++; 86 87print "not " unless 4 == &no_args; 88printf "ok %d\n",$i++; 89 90print "not " unless 2 == &no_args(1,2); 91printf "ok %d\n",$i++; 92 93eval "no_args(1)"; 94print "not " unless $@; 95printf "ok %d\n",$i++; 96 97## 98## 99## 100 101testing \&one_args, '$'; 102 103sub one_args ($) { 104 print "# \@_ = (",join(",",@_),")\n"; 105 scalar(@_) 106} 107 108print "not " unless 1 == one_args(1); 109printf "ok %d\n",$i++; 110 111print "not " unless 1 == one_args +5; 112printf "ok %d\n",$i++; 113 114print "not " unless 4 == &one_args; 115printf "ok %d\n",$i++; 116 117print "not " unless 2 == &one_args(1,2); 118printf "ok %d\n",$i++; 119 120eval "one_args(1,2)"; 121print "not " unless $@; 122printf "ok %d\n",$i++; 123 124eval "one_args()"; 125print "not " unless $@; 126printf "ok %d\n",$i++; 127 128sub one_a_args ($) { 129 print "# \@_ = (",join(",",@_),")\n"; 130 print "not " unless @_ == 1 && $_[0] == 4; 131 printf "ok %d\n",$i++; 132} 133 134one_a_args(@_); 135 136## 137## 138## 139 140testing \&over_one_args, '$@'; 141 142sub over_one_args ($@) { 143 print "# \@_ = (",join(",",@_),")\n"; 144 scalar(@_) 145} 146 147print "not " unless 1 == over_one_args(1); 148printf "ok %d\n",$i++; 149 150print "not " unless 2 == over_one_args(1,2); 151printf "ok %d\n",$i++; 152 153print "not " unless 1 == over_one_args +5; 154printf "ok %d\n",$i++; 155 156print "not " unless 4 == &over_one_args; 157printf "ok %d\n",$i++; 158 159print "not " unless 2 == &over_one_args(1,2); 160printf "ok %d\n",$i++; 161 162print "not " unless 5 == &over_one_args(1,@_); 163printf "ok %d\n",$i++; 164 165eval "over_one_args()"; 166print "not " unless $@; 167printf "ok %d\n",$i++; 168 169sub over_one_a_args ($@) { 170 print "# \@_ = (",join(",",@_),")\n"; 171 print "not " unless @_ >= 1 && $_[0] == 4; 172 printf "ok %d\n",$i++; 173} 174 175over_one_a_args(@_); 176over_one_a_args(@_,1); 177over_one_a_args(@_,1,2); 178over_one_a_args(@_,@_); 179 180## 181## 182## 183 184testing \&scalar_and_hash, '$%'; 185 186sub scalar_and_hash ($%) { 187 print "# \@_ = (",join(",",@_),")\n"; 188 scalar(@_) 189} 190 191print "not " unless 1 == scalar_and_hash(1); 192printf "ok %d\n",$i++; 193 194print "not " unless 3 == scalar_and_hash(1,2,3); 195printf "ok %d\n",$i++; 196 197print "not " unless 1 == scalar_and_hash +5; 198printf "ok %d\n",$i++; 199 200print "not " unless 4 == &scalar_and_hash; 201printf "ok %d\n",$i++; 202 203print "not " unless 2 == &scalar_and_hash(1,2); 204printf "ok %d\n",$i++; 205 206print "not " unless 5 == &scalar_and_hash(1,@_); 207printf "ok %d\n",$i++; 208 209eval "scalar_and_hash()"; 210print "not " unless $@; 211printf "ok %d\n",$i++; 212 213sub scalar_and_hash_a ($@) { 214 print "# \@_ = (",join(",",@_),")\n"; 215 print "not " unless @_ >= 1 && $_[0] == 4; 216 printf "ok %d\n",$i++; 217} 218 219scalar_and_hash_a(@_); 220scalar_and_hash_a(@_,1); 221scalar_and_hash_a(@_,1,2); 222scalar_and_hash_a(@_,@_); 223 224## 225## 226## 227 228testing \&one_or_two, '$;$'; 229 230sub one_or_two ($;$) { 231 print "# \@_ = (",join(",",@_),")\n"; 232 scalar(@_) 233} 234 235print "not " unless 1 == one_or_two(1); 236printf "ok %d\n",$i++; 237 238print "not " unless 2 == one_or_two(1,3); 239printf "ok %d\n",$i++; 240 241print "not " unless 1 == one_or_two +5; 242printf "ok %d\n",$i++; 243 244print "not " unless 4 == &one_or_two; 245printf "ok %d\n",$i++; 246 247print "not " unless 3 == &one_or_two(1,2,3); 248printf "ok %d\n",$i++; 249 250print "not " unless 5 == &one_or_two(1,@_); 251printf "ok %d\n",$i++; 252 253eval "one_or_two()"; 254print "not " unless $@; 255printf "ok %d\n",$i++; 256 257eval "one_or_two(1,2,3)"; 258print "not " unless $@; 259printf "ok %d\n",$i++; 260 261sub one_or_two_a ($;$) { 262 print "# \@_ = (",join(",",@_),")\n"; 263 print "not " unless @_ >= 1 && $_[0] == 4; 264 printf "ok %d\n",$i++; 265} 266 267one_or_two_a(@_); 268one_or_two_a(@_,1); 269one_or_two_a(@_,@_); 270 271## 272## 273## 274 275testing \&a_sub, '&'; 276 277sub a_sub (&) { 278 print "# \@_ = (",join(",",@_),")\n"; 279 &{$_[0]}; 280} 281 282sub tmp_sub_1 { printf "ok %d\n",$i++ } 283 284a_sub { printf "ok %d\n",$i++ }; 285a_sub \&tmp_sub_1; 286 287@array = ( \&tmp_sub_1 ); 288eval 'a_sub @array'; 289print "not " unless $@; 290printf "ok %d\n",$i++; 291 292## 293## 294## 295 296testing \&a_subx, '\&'; 297 298sub a_subx (\&) { 299 print "# \@_ = (",join(",",@_),")\n"; 300 &{$_[0]}; 301} 302 303sub tmp_sub_2 { printf "ok %d\n",$i++ } 304a_subx &tmp_sub_2; 305 306@array = ( \&tmp_sub_2 ); 307eval 'a_subx @array'; 308print "not " unless $@; 309printf "ok %d\n",$i++; 310 311## 312## 313## 314 315testing \&sub_aref, '&\@'; 316 317sub sub_aref (&\@) { 318 print "# \@_ = (",join(",",@_),")\n"; 319 my($sub,$array) = @_; 320 print "not " unless @_ == 2 && @{$array} == 4; 321 print map { &{$sub}($_) } @{$array} 322} 323 324@array = (qw(O K)," ", $i++); 325sub_aref { lc shift } @array; 326print "\n"; 327 328## 329## 330## 331 332testing \&sub_array, '&@'; 333 334sub sub_array (&@) { 335 print "# \@_ = (",join(",",@_),")\n"; 336 print "not " unless @_ == 5; 337 my $sub = shift; 338 print map { &{$sub}($_) } @_ 339} 340 341@array = (qw(O K)," ", $i++); 342sub_array { lc shift } @array; 343print "\n"; 344 345## 346## 347## 348 349testing \&a_hash, '%'; 350 351sub a_hash (%) { 352 print "# \@_ = (",join(",",@_),")\n"; 353 scalar(@_); 354} 355 356print "not " unless 1 == a_hash 'a'; 357printf "ok %d\n",$i++; 358 359print "not " unless 2 == a_hash 'a','b'; 360printf "ok %d\n",$i++; 361 362## 363## 364## 365 366testing \&a_hash_ref, '\%'; 367 368sub a_hash_ref (\%) { 369 print "# \@_ = (",join(",",@_),")\n"; 370 print "not " unless ref($_[0]) && $_[0]->{'a'}; 371 printf "ok %d\n",$i++; 372 $_[0]->{'b'} = 2; 373} 374 375%hash = ( a => 1); 376a_hash_ref %hash; 377print "not " unless $hash{'b'} == 2; 378printf "ok %d\n",$i++; 379 380## 381## 382## 383 384testing \&array_ref_plus, '\@@'; 385 386sub array_ref_plus (\@@) { 387 print "# \@_ = (",join(",",@_),")\n"; 388 print "not " unless @_ == 2 && ref($_[0]) && 1 == @{$_[0]} && $_[1] eq 'x'; 389 printf "ok %d\n",$i++; 390 @{$_[0]} = (qw(ok)," ",$i++,"\n"); 391} 392 393@array = ('a'); 394{ my @more = ('x'); 395 array_ref_plus @array, @more; } 396print "not " unless @array == 4; 397print @array; 398 399my $p; 400print "not " if defined prototype('CORE::print'); 401print "ok ", $i++, "\n"; 402 403print "not " if defined prototype('CORE::system'); 404print "ok ", $i++, "\n"; 405 406print "# CORE::open => ($p)\nnot " if ($p = prototype('CORE::open')) ne '*;$@'; 407print "ok ", $i++, "\n"; 408 409print "# CORE:Foo => ($p), \$@ => `$@'\nnot " 410 if defined ($p = eval { prototype('CORE::Foo') or 1 }) or $@ !~ /^Can't find an opnumber/; 411print "ok ", $i++, "\n"; 412 413# correctly note too-short parameter lists that don't end with '$', 414# a possible regression. 415 416sub foo1 ($\@); 417eval q{ foo1 "s" }; 418print "not " unless $@ =~ /^Not enough/; 419print "ok ", $i++, "\n"; 420 421sub foo2 ($\%); 422eval q{ foo2 "s" }; 423print "not " unless $@ =~ /^Not enough/; 424print "ok ", $i++, "\n"; 425 426sub X::foo3; 427*X::foo3 = sub {'ok'}; 428print "# $@not " unless eval {X->foo3} eq 'ok'; 429print "ok ", $i++, "\n"; 430 431sub X::foo4 ($); 432*X::foo4 = sub ($) {'ok'}; 433print "not " unless X->foo4 eq 'ok'; 434print "ok ", $i++, "\n"; 435 436# test if the (*) prototype allows barewords, constants, scalar expressions, 437# globs and globrefs (just as CORE::open() does), all under stricture 438sub star (*&) { &{$_[1]} } 439sub star2 (**&) { &{$_[2]} } 440sub BAR { "quux" } 441sub Bar::BAZ { "quuz" } 442my $star = 'FOO'; 443star FOO, sub { print "ok $i\n" if $_[0] eq 'FOO' }; $i++; 444star(FOO, sub { print "ok $i\n" if $_[0] eq 'FOO' }); $i++; 445star "FOO", sub { print "ok $i\n" if $_[0] eq 'FOO' }; $i++; 446star("FOO", sub { print "ok $i\n" if $_[0] eq 'FOO' }); $i++; 447star $star, sub { print "ok $i\n" if $_[0] eq 'FOO' }; $i++; 448star($star, sub { print "ok $i\n" if $_[0] eq 'FOO' }); $i++; 449star *FOO, sub { print "ok $i\n" if $_[0] eq \*FOO }; $i++; 450star(*FOO, sub { print "ok $i\n" if $_[0] eq \*FOO }); $i++; 451star \*FOO, sub { print "ok $i\n" if $_[0] eq \*FOO }; $i++; 452star(\*FOO, sub { print "ok $i\n" if $_[0] eq \*FOO }); $i++; 453star2 FOO, BAR, sub { print "ok $i\n" 454 if $_[0] eq 'FOO' and $_[1] eq 'BAR' }; $i++; 455star2(Bar::BAZ, FOO, sub { print "ok $i\n" 456 if $_[0] eq 'Bar::BAZ' and $_[1] eq 'FOO' }); $i++; 457star2 BAR(), FOO, sub { print "ok $i\n" 458 if $_[0] eq 'quux' and $_[1] eq 'FOO' }; $i++; 459star2(FOO, BAR(), sub { print "ok $i\n" 460 if $_[0] eq 'FOO' and $_[1] eq 'quux' }); $i++; 461star2 "FOO", "BAR", sub { print "ok $i\n" 462 if $_[0] eq 'FOO' and $_[1] eq 'BAR' }; $i++; 463star2("FOO", "BAR", sub { print "ok $i\n" 464 if $_[0] eq 'FOO' and $_[1] eq 'BAR' }); $i++; 465star2 $star, $star, sub { print "ok $i\n" 466 if $_[0] eq 'FOO' and $_[1] eq 'FOO' }; $i++; 467star2($star, $star, sub { print "ok $i\n" 468 if $_[0] eq 'FOO' and $_[1] eq 'FOO' }); $i++; 469star2 *FOO, *BAR, sub { print "ok $i\n" 470 if $_[0] eq \*FOO and $_[1] eq \*BAR }; $i++; 471star2(*FOO, *BAR, sub { print "ok $i\n" 472 if $_[0] eq \*FOO and $_[1] eq \*BAR }); $i++; 473star2 \*FOO, \*BAR, sub { no strict 'refs'; print "ok $i\n" 474 if $_[0] eq \*{'FOO'} and $_[1] eq \*{'BAR'} }; $i++; 475star2(\*FOO, \*BAR, sub { no strict 'refs'; print "ok $i\n" 476 if $_[0] eq \*{'FOO'} and $_[1] eq \*{'BAR'} }); $i++; 477 478# test scalarref prototype 479sub sreftest (\$$) { 480 print "ok $_[1]\n" if ref $_[0]; 481} 482{ 483 no strict 'vars'; 484 sreftest my $sref, $i++; 485 sreftest($helem{$i}, $i++); 486 sreftest $aelem[0], $i++; 487} 488 489# test prototypes when they are evaled and there is a syntax error 490# 491for my $p ( "", qw{ () ($) ($@) ($%) ($;$) (&) (&\@) (&@) (%) (\%) (\@) } ) { 492 no warnings 'redefine'; 493 my $eval = "sub evaled_subroutine $p { &void *; }"; 494 eval $eval; 495 # The /Syntax error/ is seen on OS/390. It's /syntax error/ elsewhere 496 print "# eval[$eval]\nnot " unless $@ && $@ =~ /[Ss]yntax error/; 497 print "ok ", $i++, "\n"; 498} 499