xref: /openbsd-src/gnu/usr.bin/perl/t/op/coreamp.t (revision c90a81c56dcebd6a1b73fe4aff9b03385b8e63b3)
1#!./perl
2
3# This file tests the results of calling subroutines in the CORE::
4# namespace with ampersand syntax.  In other words, it tests the bodies of
5# the subroutines themselves, not the ops that they might inline themselves
6# as when called as barewords.
7
8# Other tests for CORE subs are in coresubs.t
9
10BEGIN {
11    chdir 't' if -d 't';
12    @INC = qw(. ../lib ../dist/if);
13    require "./test.pl"; require './charset_tools.pl';
14    $^P |= 0x100;
15}
16
17no warnings 'experimental::smartmatch';
18
19sub lis($$;$) {
20  &is(map(@$_ ? "[@{[map $_//'~~u~~', @$_]}]" : 'nought', @_[0,1]), $_[2]);
21}
22
23package hov {
24  use overload '%{}' => sub { +{} }
25}
26package sov {
27  use overload '${}' => sub { \my $x }
28}
29
30my %op_desc = (
31 evalbytes=> 'eval "string"',
32 join     => 'join or string',
33 pos      => 'match position',
34 prototype=> 'subroutine prototype',
35 readline => '<HANDLE>',
36 readpipe => 'quoted execution (``, qx)',
37 reset    => 'symbol reset',
38 ref      => 'reference-type operator',
39 undef    => 'undef operator',
40);
41sub op_desc($) {
42  return $op_desc{$_[0]} || $_[0];
43}
44
45
46# This tests that the &{} syntax respects the number of arguments implied
47# by the prototype, plus some extra tests for the (_) prototype.
48sub test_proto {
49  my($o) = shift;
50
51  # Create an alias, for the caller’s convenience.
52  *{"my$o"} = \&{"CORE::$o"};
53
54  my $p = prototype "CORE::$o";
55  $p = '$;$' if $p eq '$_';
56
57  if ($p eq '') {
58    $tests ++;
59
60    eval " &CORE::$o(1) ";
61    like $@, qr/^Too many arguments for $o at /, "&$o with too many args";
62
63  }
64  elsif ($p =~ /^_;?\z/) {
65    $tests ++;
66
67    eval " &CORE::$o(1,2) ";
68    my $desc = quotemeta op_desc($o);
69    like $@, qr/^Too many arguments for $desc at /,
70      "&$o with too many args";
71
72    if (!@_) { return }
73
74    $tests += 3;
75
76    my($in,$out) = @_; # for testing implied $_
77
78    # Since we have $in and $out values, we might as well test basic amper-
79    # sand calls, too.
80
81    is &{"CORE::$o"}($in), $out, "&$o";
82    lis [&{"CORE::$o"}($in)], [$out], "&$o in list context";
83
84    $_ = $in;
85    is &{"CORE::$o"}(), $out, "&$o with no args";
86  }
87  elsif ($p =~ '^;([$*]+)\z') { # ;$ ;* ;$$ etc.
88    my $maxargs = length $1;
89    $tests += 1;
90    eval " &CORE::$o((1)x($maxargs+1)) ";
91    my $desc = quotemeta op_desc($o);
92    like $@, qr/^Too many arguments for $desc at /,
93        "&$o with too many args";
94  }
95  elsif ($p =~ '^([$*]+);?\z') { # Fixed-length $$$ or ***
96    my $args = length $1;
97    $tests += 2;
98    my $desc = quotemeta op_desc($o);
99    eval " &CORE::$o((1)x($args-1)) ";
100    like $@, qr/^Not enough arguments for $desc at /, "&$o w/too few args";
101    eval " &CORE::$o((1)x($args+1)) ";
102    like $@, qr/^Too many arguments for $desc at /, "&$o w/too many args";
103  }
104  elsif ($p =~ '^([$*]+);([$*]+)\z') { # Variable-length $$$ or ***
105    my $minargs = length $1;
106    my $maxargs = $minargs + length $2;
107    $tests += 2;
108    eval " &CORE::$o((1)x($minargs-1)) ";
109    like $@, qr/^Not enough arguments for $o at /, "&$o with too few args";
110    eval " &CORE::$o((1)x($maxargs+1)) ";
111    like $@, qr/^Too many arguments for $o at /, "&$o with too many args";
112  }
113  elsif ($p eq '_;$') {
114    $tests += 1;
115
116    eval " &CORE::$o(1,2,3) ";
117    like $@, qr/^Too many arguments for $o at /, "&$o with too many args";
118  }
119  elsif ($p eq '@') {
120    # Do nothing, as we cannot test for too few or too many arguments.
121  }
122  elsif ($p =~ '^[$*;]+@\z') {
123    $tests ++;
124    $p =~ ';@';
125    my $minargs = $-[0];
126    eval " &CORE::$o((1)x($minargs-1)) ";
127    my $desc = quotemeta op_desc($o);
128    like $@, qr/^Not enough arguments for $desc at /,
129       "&$o with too few args";
130  }
131  elsif ($p =~ /^\*\\\$\$(;?)\$\z/) { #  *\$$$ and *\$$;$
132    $tests += 5;
133
134    eval "&CORE::$o(1,1,1,1,1)";
135    like $@, qr/^Too many arguments for $o at /,
136         "&$o with too many args";
137    eval " &CORE::$o((1)x(\$1?2:3)) ";
138    like $@, qr/^Not enough arguments for $o at /,
139         "&$o with too few args";
140    eval " &CORE::$o(1,[],1,1) ";
141    like $@, qr/^Type of arg 2 to &CORE::$o must be scalar reference at /,
142        "&$o with array ref arg";
143    eval " &CORE::$o(1,1,1,1) ";
144    like $@, qr/^Type of arg 2 to &CORE::$o must be scalar reference at /,
145        "&$o with scalar arg";
146    eval " &CORE::$o(1,bless([], 'sov'),1,1) ";
147    like $@, qr/^Type of arg 2 to &CORE::$o must be scalar reference at /,
148        "&$o with non-scalar arg w/scalar overload (which does not count)";
149  }
150  elsif ($p =~ /^\\%\$*\z/) { #  \% and \%$$
151    $tests += 5;
152
153    eval "&CORE::$o(" . join(",", (1) x length $p) . ")";
154    like $@, qr/^Too many arguments for $o at /,
155         "&$o with too many args";
156    eval " &CORE::$o(" . join(",", (1) x (length($p)-2)) . ") ";
157    like $@, qr/^Not enough arguments for $o at /,
158         "&$o with too few args";
159    my $moreargs = ",1" x (length($p) - 2);
160    eval " &CORE::$o([]$moreargs) ";
161    like $@, qr/^Type of arg 1 to &CORE::$o must be hash reference at /,
162        "&$o with array ref arg";
163    eval " &CORE::$o(*foo$moreargs) ";
164    like $@, qr/^Type of arg 1 to &CORE::$o must be hash reference at /,
165        "&$o with typeglob arg";
166    eval " &CORE::$o(bless([], 'hov')$moreargs) ";
167    like $@, qr/^Type of arg 1 to &CORE::$o must be hash reference at /,
168        "&$o with non-hash arg with hash overload (which does not count)";
169  }
170  elsif ($p =~ /^(;)?\\\[(\$\@%&?\*)](\$\@)?\z/) {
171    $tests += 3;
172
173    unless ($3) {
174      $tests ++;
175      eval " &CORE::$o(1,2) ";
176      like $@, qr/^Too many arguments for ${\op_desc($o)} at /,
177        "&$o with too many args";
178    }
179    unless ($1) {
180      $tests ++;
181      eval { &{"CORE::$o"}($3 ? 1 : ()) };
182      like $@, qr/^Not enough arguments for $o at /,
183         "&$o with too few args";
184    }
185    my $more_args = $3 ? ',1' : '';
186    eval " &CORE::$o(2$more_args) ";
187    like $@, qr/^Type of arg 1 to &CORE::$o must be reference to one of(?x:
188                ) \[\Q$2\E] at /,
189        "&$o with non-ref arg";
190    eval " &CORE::$o(*STDOUT{IO}$more_args) ";
191    like $@, qr/^Type of arg 1 to &CORE::$o must be reference to one of(?x:
192                ) \[\Q$2\E] at /,
193        "&$o with ioref arg";
194    my $class = ref *DATA{IO};
195    eval " &CORE::$o(bless(*DATA{IO}, 'hov')$more_args) ";
196    like $@, qr/^Type of arg 1 to &CORE::$o must be reference to one of(?x:
197                ) \[\Q$2\E] at /,
198        "&$o with ioref arg with hash overload (which does not count)";
199    bless *DATA{IO}, $class;
200    if (do {$2 !~ /&/}) {
201      $tests++;
202      eval " &CORE::$o(\\&scriggle$more_args) ";
203      like $@, qr/^Type of arg 1 to &CORE::$o must be reference to one (?x:
204                  )of \[\Q$2\E] at /,
205        "&$o with coderef arg";
206    }
207  }
208  elsif ($p eq ';\[$*]') {
209    $tests += 4;
210
211    my $desc = quotemeta op_desc($o);
212    eval " &CORE::$o(1,2) ";
213    like $@, qr/^Too many arguments for $desc at /,
214        "&$o with too many args";
215    eval " &CORE::$o([]) ";
216    like $@, qr/^Type of arg 1 to &CORE::$o must be scalar reference at /,
217        "&$o with array ref arg";
218    eval " &CORE::$o(1) ";
219    like $@, qr/^Type of arg 1 to &CORE::$o must be scalar reference at /,
220        "&$o with scalar arg";
221    eval " &CORE::$o(bless([], 'sov')) ";
222    like $@, qr/^Type of arg 1 to &CORE::$o must be scalar reference at /,
223        "&$o with non-scalar arg w/scalar overload (which does not count)";
224  }
225
226  else {
227    die "Please add tests for the $p prototype";
228  }
229}
230
231# Test that &CORE::foo calls without parentheses (no new @_) can handle the
232# total absence of any @_ without crashing.
233undef *_;
234&CORE::wantarray;
235$tests++;
236pass('no crash with &CORE::foo when *_{ARRAY} is undef');
237
238test_proto '__FILE__';
239test_proto '__LINE__';
240test_proto '__PACKAGE__';
241test_proto '__SUB__';
242
243is file(), 'frob'    , '__FILE__ does check its caller'   ; ++ $tests;
244is line(),  5        , '__LINE__ does check its caller'   ; ++ $tests;
245is pakg(), 'stribble', '__PACKAGE__ does check its caller'; ++ $tests;
246sub __SUB__test { &my__SUB__ }
247is __SUB__test, \&__SUB__test, '&__SUB__';                  ++ $tests;
248
249test_proto 'abs', -5, 5;
250
251SKIP:
252{
253    if ($^O eq "MSWin32" && is_miniperl) {
254        $tests += 8;
255        skip "accept() not available in Win32 miniperl", 8
256    }
257    $tests += 6;
258    test_proto 'accept';
259    eval q{
260      is &CORE::accept(qw{foo bar}), undef, "&accept";
261      lis [&{"CORE::accept"}(qw{foo bar})], [undef], "&accept in list context";
262
263      &myaccept(my $foo, my $bar);
264      is ref $foo, 'GLOB', 'CORE::accept autovivifies its first argument';
265      is $bar, undef, 'CORE::accept does not autovivify its second argument';
266      use strict;
267      undef $foo;
268      eval { 'myaccept'->($foo, $bar) };
269      like $@, qr/^Can't use an undefined value as a symbol reference at/,
270      'CORE::accept will not accept undef 2nd arg under strict';
271      is ref $foo, 'GLOB', 'CORE::accept autovivs its first arg under strict';
272    };
273}
274
275test_proto 'alarm';
276test_proto 'atan2';
277
278test_proto 'bind';
279$tests += 3;
280SKIP:
281{
282    skip "bind() not available in Win32 miniperl", 3
283      if $^O eq "MSWin32" && is_miniperl();
284    is &CORE::bind('foo', 'bear'), undef, "&bind";
285    lis [&CORE::bind('foo', 'bear')], [undef], "&bind in list context";
286    eval { &mybind(my $foo, "bear") };
287    like $@, qr/^Bad symbol for filehandle at/,
288         'CORE::bind dies with undef first arg';
289}
290
291test_proto 'binmode';
292$tests += 3;
293is &CORE::binmode(qw[foo bar]), undef, "&binmode";
294lis [&CORE::binmode(qw[foo bar])], [undef], "&binmode in list context";
295is &mybinmode(foo), undef, '&binmode with one arg';
296
297test_proto 'bless';
298$tests += 3;
299like &CORE::bless([],'parcel'), qr/^parcel=ARRAY/, "&bless";
300like join(" ", &CORE::bless([],'parcel')),
301     qr/^parcel=ARRAY(?!.* )/, "&bless in list context";
302like &mybless([]), qr/^main=ARRAY/, '&bless with one arg';
303
304test_proto 'break';
305{ $tests ++;
306  my $tmp;
307  CORE::given(1) {
308    CORE::when(1) {
309      &mybreak;
310      $tmp = 'bad';
311    }
312  }
313  is $tmp, undef, '&break';
314}
315
316test_proto 'caller';
317$tests += 4;
318sub caller_test {
319    is scalar &CORE::caller, 'hadhad', '&caller';
320    is scalar &CORE::caller(1), 'main', '&caller(1)';
321    lis [&CORE::caller], [caller], '&caller in list context';
322    # The last element of caller in list context is a hint hash, which
323    # may be a different hash for caller vs &CORE::caller, so an eq com-
324    # parison (which lis() uses for convenience) won’t work.  So just
325    # pop the last element, since the rest are sufficient to prove that
326    # &CORE::caller works.
327    my @ampcaller = &CORE::caller(1);
328    my @caller    = caller(1);
329    pop @ampcaller; pop @caller;
330    lis \@ampcaller, \@caller, '&caller(1) in list context';
331}
332sub {
333   package hadhad;
334   ::caller_test();
335}->();
336
337test_proto 'chmod';
338$tests += 3;
339is &CORE::chmod(), 0, '&chmod with no args';
340is &CORE::chmod(0666), 0, '&chmod';
341lis [&CORE::chmod(0666)], [0], '&chmod in list context';
342
343test_proto 'chown';
344$tests += 4;
345is &CORE::chown(), 0, '&chown with no args';
346is &CORE::chown(1), 0, '&chown with 1 arg';
347is &CORE::chown(1,2), 0, '&chown';
348lis [&CORE::chown(1,2)], [0], '&chown in list context';
349
350test_proto 'chr', 5, "\5";
351test_proto 'chroot';
352
353test_proto 'close';
354{
355  last if is_miniperl;
356  $tests += 3;
357
358  open my $fh, ">", \my $buffalo;
359  print $fh 'an address in the outskirts of Jersey';
360  ok &CORE::close($fh), '&CORE::close retval';
361  print $fh 'lalala';
362  is $buffalo, 'an address in the outskirts of Jersey',
363     'effect of &CORE::close';
364  # This has to be a separate variable from $fh, as re-using the same
365  # variable can cause the tests to pass by accident.  That actually hap-
366  # pened during developement, because the second close() was reading
367  # beyond the end of the stack and finding a $fh left over from before.
368  open my $fh2, ">", \($buffalo = '');
369  select+(select($fh2), do {
370     print "Nasusiro Tokasoni";
371     &CORE::close();
372     print "jfd";
373     is $buffalo, "Nasusiro Tokasoni", '&CORE::close with no args';
374  })[0];
375}
376lis [&CORE::close('tototootot')], [''], '&close in list context'; ++$tests;
377
378test_proto 'closedir';
379$tests += 2;
380is &CORE::closedir(foo), undef, '&CORE::closedir';
381lis [&CORE::closedir(foo)], [undef], '&CORE::closedir in list context';
382
383test_proto 'connect';
384$tests += 2;
385SKIP:
386{
387    skip "connect() not available in Win32 miniperl", 2
388      if $^O eq "MSWin32" && is_miniperl();
389    is &CORE::connect('foo','bar'), undef, '&connect';
390    lis [&myconnect('foo','bar')], [undef], '&connect in list context';
391}
392
393test_proto 'continue';
394$tests ++;
395CORE::given(1) {
396  CORE::when(1) {
397    &mycontinue();
398  }
399  pass "&continue";
400}
401
402test_proto 'cos';
403test_proto 'crypt';
404
405test_proto 'dbmclose';
406test_proto 'dbmopen';
407{
408  last unless eval { require AnyDBM_File };
409  $tests ++;
410  my $filename = tempfile();
411  &mydbmopen(\my %db, $filename, 0666);
412  $db{1} = 2; $db{3} = 4;
413  &mydbmclose(\%db);
414  is scalar keys %db, 0, '&dbmopen and &dbmclose';
415  my $Dfile = "$filename.pag";
416  if (! -e $Dfile) {
417    ($Dfile) = <$filename*>;
418  }
419  if ($^O eq 'VMS') {
420    unlink "$filename.sdbm_dir", $Dfile;
421  } else {
422    unlink "$filename.dir", $Dfile;
423  }
424}
425
426test_proto 'die';
427eval { dier('quinquangle') };
428is $@, "quinquangle at frob line 6.\n", '&CORE::die'; $tests ++;
429
430test_proto $_ for qw(
431 endgrent endhostent endnetent endprotoent endpwent endservent
432);
433
434test_proto 'evalbytes';
435$tests += 4;
436{
437  my $U_100_bytes = byte_utf8a_to_utf8n("\xc4\x80");
438  chop(my $upgraded = "use utf8; $U_100_bytes" . chr 256);
439  is &myevalbytes($upgraded), chr 256, '&evalbytes';
440  # Test hints
441  require strict;
442  strict->import;
443  &myevalbytes('
444    is someone, "someone", "run-time hint bits do not leak into &evalbytes"
445  ');
446  use strict;
447  BEGIN { $^H{coreamp} = 42 }
448  $^H{coreamp} = 75;
449  &myevalbytes('
450    BEGIN {
451      is $^H{coreamp}, 42, "compile-time hh propagates into &evalbytes";
452    }
453    ${"frobnicate"}
454  ');
455  like $@, qr/strict/, 'compile-time hint bits propagate into &evalbytes';
456}
457
458test_proto 'exit';
459$tests ++;
460is runperl(prog => '&CORE::exit; END { print qq-ok\n- }'), "ok\n",
461  '&exit with no args';
462
463test_proto 'fork';
464
465test_proto 'formline';
466$tests += 3;
467is &myformline(' @<<< @>>>', 1, 2), 1, '&myformline retval';
468is $^A,        ' 1       2', 'effect of &myformline';
469lis [&myformline('@')], [1], '&myformline in list context';
470
471test_proto 'exp';
472
473test_proto 'fc';
474$tests += 2;
475{
476  my $sharp_s = uni_to_native("\xdf");
477  is &myfc($sharp_s), $sharp_s, '&fc, no unicode_strings';
478  use feature 'unicode_strings';
479  is &myfc($sharp_s), "ss", '&fc, unicode_strings';
480}
481
482test_proto 'fcntl';
483
484test_proto 'fileno';
485$tests += 2;
486is &CORE::fileno(\*STDIN), fileno STDIN, '&CORE::fileno';
487lis [&CORE::fileno(\*STDIN)], [fileno STDIN], '&CORE::fileno in list cx';
488
489test_proto 'flock';
490test_proto 'fork';
491
492test_proto 'getc';
493{
494  last if is_miniperl;
495  $tests += 3;
496  local *STDIN;
497  open my $fh, "<", \(my $buf='falo');
498  open STDIN, "<", \(my $buf2 = 'bison');
499  is &mygetc($fh), 'f', '&mygetc';
500  is &mygetc(), 'b', '&mygetc with no args';
501  lis [&mygetc($fh)], ['a'], '&mygetc in list context';
502}
503
504test_proto "get$_" for qw '
505  grent grgid grnam hostbyaddr hostbyname hostent login netbyaddr netbyname
506  netent peername
507';
508
509test_proto 'getpgrp';
510eval {&mygetpgrp()};
511pass '&getpgrp with no args does not crash'; $tests++;
512
513test_proto "get$_" for qw '
514  ppid priority protobyname protobynumber protoent
515  pwent pwnam pwuid servbyname servbyport servent sockname sockopt
516';
517
518# Make sure the following tests test what we think they are testing.
519ok ! $CORE::{glob}, '*CORE::glob not autovivified yet'; $tests ++;
520{
521  # Make sure ck_glob does not respect the override when &CORE::glob is
522  # autovivified (by test_proto).
523  local *CORE::GLOBAL::glob = sub {};
524  test_proto 'glob';
525}
526$_ = "t/*.t";
527@_ = &myglob($_);
528is join($", &myglob()), "@_", '&glob without arguments';
529is join($", &myglob("t/*.t")), "@_", '&glob with an arg';
530$tests += 2;
531
532test_proto 'gmtime';
533&CORE::gmtime;
534pass '&gmtime without args does not crash'; ++$tests;
535
536test_proto 'hex', ff=>255;
537
538test_proto 'index';
539$tests += 3;
540is &myindex("foffooo","o",2),4,'&index';
541lis [&myindex("foffooo","o",2)],[4],'&index in list context';
542is &myindex("foffooo","o"),1,'&index with 2 args';
543
544test_proto 'int', 1.5=>1;
545test_proto 'ioctl';
546
547test_proto 'join';
548$tests += 2;
549is &myjoin('a','b','c'), 'bac', '&join';
550lis [&myjoin('a','b','c')], ['bac'], '&join in list context';
551
552test_proto 'kill'; # set up mykill alias
553if ($^O ne 'riscos') {
554    $tests ++;
555    ok( &mykill(0, $$), '&kill' );
556}
557
558test_proto 'lc', 'A', 'a';
559test_proto 'lcfirst', 'AA', 'aA';
560test_proto 'length', 'aaa', 3;
561test_proto 'link';
562test_proto 'listen';
563
564test_proto 'localtime';
565&CORE::localtime;
566pass '&localtime without args does not crash'; ++$tests;
567
568test_proto 'lock';
569$tests += 6;
570is \&mylock(\$foo), \$foo, '&lock retval when passed a scalar ref';
571lis [\&mylock(\$foo)], [\$foo], '&lock in list context';
572is &mylock(\@foo), \@foo, '&lock retval when passed an array ref';
573is &mylock(\%foo), \%foo, '&lock retval when passed a ash ref';
574is &mylock(\&foo), \&foo, '&lock retval when passed a code ref';
575is \&mylock(\*foo), \*foo, '&lock retval when passed a glob ref';
576
577test_proto 'log';
578
579test_proto 'mkdir';
580# mkdir is tested with implicit $_ at the end, to make the test easier
581
582test_proto "msg$_" for qw( ctl get rcv snd );
583
584test_proto 'not';
585$tests += 2;
586is &mynot(1), !1, '&not';
587lis [&mynot(0)], [!0], '&not in list context';
588
589test_proto 'oct', '666', 438;
590
591test_proto 'open';
592$tests += 5;
593$file = 'test.pl';
594ok &myopen('file'), '&open with 1 arg' or warn "1-arg open: $!";
595like <file>, qr|^#|, 'result of &open with 1 arg';
596close file;
597{
598  ok &myopen(my $fh, "test.pl"), 'two-arg &open';
599  ok $fh, '&open autovivifies';
600  like <$fh>, qr '^#', 'result of &open with 2 args';
601  last if is_miniperl;
602  $tests +=2;
603  ok &myopen(my $fh2, "<", \"sharummbles"), 'retval of 3-arg &open';
604  is <$fh2>, 'sharummbles', 'result of three-arg &open';
605}
606
607test_proto 'opendir';
608test_proto 'ord', chr(utf8::unicode_to_native(64)), utf8::unicode_to_native(64);
609
610test_proto 'pack';
611$tests += 2;
612my $Perl_as_a_hex_string = join "", map
613                                    { sprintf("%2X", utf8::unicode_to_native($_)) }
614                                    0x50, 0x65, 0x72, 0x6c;
615is &mypack("H*", $Perl_as_a_hex_string), 'Perl', '&pack';
616lis [&mypack("H*", $Perl_as_a_hex_string)], ['Perl'], '&pack in list context';
617
618test_proto 'pipe';
619
620test_proto 'pos';
621$tests += 4;
622$_ = "hello";
623pos = 3;
624is &mypos, 3, 'reading &pos without args';
625&mypos = 4;
626is pos, 4, 'writing to &pos without args';
627{
628  my $x = "gubai";
629  pos $x = 3;
630  is &mypos(\$x), 3, 'reading &pos without args';
631  &mypos(\$x) = 4;
632  is pos $x, 4, 'writing to &pos without args';
633}
634
635test_proto 'prototype';
636$tests++;
637is &myprototype(\&myprototype), prototype("CORE::prototype"), '&prototype';
638
639test_proto 'quotemeta', '$', '\$';
640
641test_proto 'rand';
642$tests += 3;
643my $r = &CORE::rand;
644ok eval {
645    use warnings FATAL => qw{numeric uninitialized};
646    $r >= 0 && $r < 1;
647}, '&rand returns a valid number';
648unlike join(" ", &CORE::rand), qr/ /, '&rand in list context';
649&cmp_ok(&CORE::rand(78), qw '< 78', '&rand with 1 arg');
650
651test_proto 'read';
652{
653  last if is_miniperl;
654  $tests += 5;
655  open my $fh, "<", \(my $buff = 'morays have their mores');
656  ok &myread($fh, \my $input, 6), '&read with 3 args';
657  is $input, 'morays', 'value read by 3-arg &read';
658  ok &myread($fh, \$input, 6, 6), '&read with 4 args';
659  is $input, 'morays have ', 'value read by 4-arg &read';
660  is +()=&myread($fh, \$input, 6), 1, '&read in list context';
661}
662
663test_proto 'readdir';
664
665test_proto 'readline';
666{
667  local *ARGV = *DATA;
668  $tests ++;
669  is scalar &myreadline,
670    "I wandered lonely as a cloud\n", '&readline w/no args';
671}
672{
673  last if is_miniperl;
674  $tests += 2;
675  open my $fh, "<", \(my $buff = <<END);
676The Recursive Problem
677---------------------
678I have a problem I cannot solve.
679The problem is that I cannot solve it.
680END
681  is &myreadline($fh), "The Recursive Problem\n",
682    '&readline with 1 arg';
683  lis [&myreadline($fh)], [
684       "---------------------\n",
685       "I have a problem I cannot solve.\n",
686       "The problem is that I cannot solve it.\n",
687      ], '&readline in list context';
688}
689
690test_proto 'readlink';
691test_proto 'readpipe';
692test_proto 'recv';
693
694use if !is_miniperl, File::Spec::Functions, qw "catfile";
695use if !is_miniperl, File::Temp, 'tempdir';
696
697test_proto 'rename';
698{
699    last if is_miniperl;
700    $tests ++;
701    my $dir = tempdir(uc cleanup => 1);
702    my $tmpfilenam = catfile $dir, 'aaa';
703    open my $fh, ">", $tmpfilenam or die "cannot open $tmpfilenam: $!";
704    close $fh or die "cannot close $tmpfilenam: $!";
705    &myrename("$tmpfilenam", $tmpfilenam = catfile $dir,'bbb');
706    ok open(my $fh, '>', $tmpfilenam), '&rename';
707}
708
709test_proto 'ref', [], 'ARRAY';
710
711test_proto 'reset';
712$tests += 2;
713my $oncer = sub { "a" =~ m?a? };
714&$oncer;
715&myreset;
716ok &$oncer, '&reset with no args';
717package resettest {
718  $b = "c";
719  $banana = "cream";
720  &::myreset('b');
721  ::lis [$b,$banana],[(undef)x2], '1-arg &reset';
722}
723
724test_proto 'reverse';
725$tests += 2;
726is &myreverse('reward'), 'drawer', '&reverse';
727lis [&myreverse(qw 'dog bites man')], [qw 'man bites dog'],
728  '&reverse in list context';
729
730test_proto 'rewinddir';
731
732test_proto 'rindex';
733$tests += 3;
734is &myrindex("foffooo","o",2),1,'&rindex';
735lis [&myrindex("foffooo","o",2)],[1],'&rindex in list context';
736is &myrindex("foffooo","o"),6,'&rindex with 2 args';
737
738test_proto 'rmdir';
739
740test_proto 'scalar';
741$tests += 2;
742is &myscalar(3), 3, '&scalar';
743lis [&myscalar(3)], [3], '&scalar in list cx';
744
745test_proto 'seek';
746{
747    last if is_miniperl;
748    $tests += 1;
749    open my $fh, "<", \"misled" or die $!;
750    &myseek($fh, 2, 0);
751    is <$fh>, 'sled', '&seek in action';
752}
753
754test_proto 'seekdir';
755
756# Can’t test_proto, as it has none
757$tests += 8;
758*myselect = \&CORE::select;
759is defined prototype &myselect, defined prototype "CORE::select",
760   'prototype of &select (or lack thereof)';
761is &myselect, select, '&select with no args';
762{
763  my $prev = select;
764  is &myselect(my $fh), $prev, '&select($arg) retval';
765  is lc ref $fh, 'glob', '&select autovivifies';
766  is select=~s/\*//rug, (*$fh."")=~s/\*//rug, '&select selects';
767  select $prev;
768}
769eval { &myselect(1,2) };
770like $@, qr/^Not enough arguments for select system call at /,
771      ,'&myselect($two,$args)';
772eval { &myselect(1,2,3) };
773like $@, qr/^Not enough arguments for select system call at /,
774      ,'&myselect($with,$three,$args)';
775eval { &myselect(1,2,3,4,5) };
776like $@, qr/^Too many arguments for select system call at /,
777      ,'&myselect($a,$total,$of,$five,$args)';
778unless ($^O eq "MSWin32" && is_miniperl) {
779    &myselect((undef)x3,.25);
780    # Just have to assume that worked. :-) If we get here, at least it didn’t
781    # crash or anything.
782    # select() is unimplemented in Win32 miniperl
783}
784
785test_proto "sem$_" for qw "ctl get op";
786
787test_proto 'send';
788
789test_proto "set$_" for qw '
790  grent hostent netent
791';
792
793test_proto 'setpgrp';
794$tests +=2;
795eval { &mysetpgrp( 0) };
796pass "&setpgrp with one argument";
797eval { &mysetpgrp };
798pass "&setpgrp with no arguments";
799
800test_proto "set$_" for qw '
801  priority protoent pwent servent sockopt
802';
803
804test_proto "shm$_" for qw "ctl get read write";
805test_proto 'shutdown';
806test_proto 'sin';
807test_proto 'sleep';
808test_proto "socket$_" for "", "pair";
809
810test_proto 'sprintf';
811$tests += 2;
812is &mysprintf("%x", 65), '41', '&sprintf';
813lis [&mysprintf("%x", '65')], ['41'], '&sprintf in list context';
814
815test_proto 'sqrt', 4, 2;
816
817test_proto 'srand';
818$tests ++;
819&CORE::srand;
820() = &CORE::srand;
821pass '&srand with no args does not crash';
822
823test_proto 'study';
824
825test_proto 'substr';
826$tests += 5;
827$_ = "abc";
828is &mysubstr($_, 1, 1, "d"), 'b', '4-arg &substr';
829is $_, 'adc', 'what 4-arg &substr does';
830is &mysubstr("abc", 1, 1), 'b', '3-arg &substr';
831is &mysubstr("abc", 1), 'bc', '2-arg &substr';
832&mysubstr($_, 1) = 'long';
833is $_, 'along', 'lvalue &substr';
834
835test_proto 'symlink';
836test_proto 'syscall';
837
838test_proto 'sysopen';
839$tests +=2;
840{
841  &mysysopen(my $fh, 'test.pl', 0);
842  pass '&sysopen does not crash with 3 args';
843  ok $fh, 'sysopen autovivifies';
844}
845
846test_proto 'sysread';
847test_proto 'sysseek';
848test_proto 'syswrite';
849
850test_proto 'tell';
851{
852  $tests += 2;
853  open my $fh, "test.pl" or die "Cannot open test.pl";
854  <$fh>;
855  is &mytell(), tell($fh), '&tell with no args';
856  is &mytell($fh), tell($fh), '&tell with an arg';
857}
858
859test_proto 'telldir';
860
861test_proto 'tie';
862test_proto 'tied';
863$tests += 3;
864{
865  my $fetches;
866  package tier {
867    sub TIESCALAR { bless[] }
868    sub FETCH { ++$fetches }
869  }
870  my $tied;
871  my $obj = &mytie(\$tied, 'tier');
872  is &mytied(\$tied), $obj, '&tie and &tied retvals';
873  () = "$tied";
874  is $fetches, 1, '&tie actually ties';
875  &CORE::untie(\$tied);
876  () = "$tied";
877  is $fetches, 1, '&untie unties';
878}
879
880test_proto 'time';
881$tests += 2;
882like &mytime, qr/^\d+\z/, '&time in scalar context';
883like join('-', &mytime), qr/^\d+\z/, '&time in list context';
884
885test_proto 'times';
886$tests += 2;
887like &mytimes, qr/^[\d.]+\z/, '&times in scalar context';
888like join('-',&mytimes), qr/^[\d.]+-[\d.]+-[\d.]+-[\d.]+\z/,
889   '&times in list context';
890
891test_proto 'uc', 'aa', 'AA';
892test_proto 'ucfirst', 'aa', "Aa";
893
894test_proto 'umask';
895$tests ++;
896is &myumask, umask, '&umask with no args';
897
898test_proto 'undef';
899$tests += 12;
900is &myundef(), undef, '&undef returns undef';
901lis [&myundef()], [undef], '&undef returns undef in list cx';
902lis [&myundef(\$_)], [undef], '&undef(...) returns undef in list cx';
903is \&myundef(), \undef, '&undef returns the right undef';
904$_ = 'anserine questions';
905&myundef(\$_);
906is $_, undef, '&undef(\$_) undefines $_';
907@_ = 1..3;
908&myundef(\@_);
909is @_, 0, '&undef(\@_) undefines @_';
910%_ = 1..4;
911&myundef(\%_);
912ok !%_, '&undef(\%_) undefines %_';
913&myundef(\&utf8::valid); # nobody should be using this :-)
914ok !defined &utf8::valid, '&undef(\&foo) undefines &foo';
915@_ = \*_;
916&myundef;
917is *_{ARRAY}, undef, '@_=\*_, &undef undefines *_';
918@_ = \*_;
919&myundef(\*_);
920is *_{ARRAY}, undef, '&undef(\*_) undefines *_';
921(&myundef(), @_) = 1..10;
922lis \@_, [2..10], 'list assignment to &undef()';
923ok !defined undef, 'list assignment to &undef() does not affect undef';
924undef @_;
925
926test_proto 'unpack';
927$tests += 2;
928my $abcd_as_a_hex_string = join "", map
929                                    { sprintf("%2X", utf8::unicode_to_native($_)) }
930                                    0x61, 0x62, 0x63, 0x64;
931my $bcde_as_a_hex_string = join "", map
932                                    { sprintf("%2X", utf8::unicode_to_native($_)) }
933                                    0x62, 0x63, 0x64, 0x65;
934$_ = 'abcd';
935is &myunpack("H*"), $abcd_as_a_hex_string, '&unpack with one arg';
936is &myunpack("H*", "bcde"), $bcde_as_a_hex_string, '&unpack with two arg';
937
938
939test_proto 'untie'; # behaviour already tested along with tie(d)
940
941test_proto 'utime';
942$tests += 2;
943is &myutime(undef,undef), 0, '&utime';
944lis [&myutime(undef,undef)], [0], '&utime in list context';
945
946test_proto 'vec';
947$tests += 3;
948is &myvec("foo", 0, 4), 6, '&vec';
949lis [&myvec("foo", 0, 4)], [6], '&vec in list context';
950$tmp = "foo";
951++&myvec($tmp,0,4);
952is $tmp, "goo", 'lvalue &vec';
953
954test_proto 'wait';
955test_proto 'waitpid';
956
957test_proto 'wantarray';
958$tests += 4;
959my $context;
960my $cx_sub = sub {
961  $context = qw[void scalar list][&mywantarray + defined mywantarray()]
962};
963() = &$cx_sub;
964is $context, 'list', '&wantarray with caller in list context';
965scalar &$cx_sub;
966is($context, 'scalar', '&wantarray with caller in scalar context');
967&$cx_sub;
968is($context, 'void', '&wantarray with caller in void context');
969lis [&mywantarray],[wantarray], '&wantarray itself in list context';
970
971test_proto 'warn';
972{ $tests += 3;
973  my $w;
974  local $SIG{__WARN__} = sub { $w = shift };
975  is &mywarn('a'), 1, '&warn retval';
976  is $w, "a at " . __FILE__ . " line " . (__LINE__-1) . ".\n", 'warning';
977  lis [&mywarn()], [1], '&warn retval in list context';
978}
979
980test_proto 'write';
981$tests ++;
982eval {&mywrite};
983like $@, qr'^Undefined format "STDOUT" called',
984   "&write without arguments can handle the null";
985
986# This is just a check to make sure we have tested everything.  If we
987# haven’t, then either the sub needs to be tested or the list in
988# gv.c is wrong.
989{
990  last if is_miniperl;
991  require File::Spec::Functions;
992  my $keywords_file =
993   File::Spec::Functions::catfile(
994      File::Spec::Functions::updir,'regen','keywords.pl'
995   );
996  open my $kh, $keywords_file
997    or die "$0 cannot open $keywords_file: $!";
998  while(<$kh>) {
999    if (m?__END__?..${\0} and /^[-+](.*)/) {
1000      my $word = $1;
1001      next if
1002       $word =~ /^(?:s(?:tate|ort|ay|ub)?|d(?:ef
1003                  ault|ump|o)|p(?:rintf?|ackag
1004                  e)|e(?:ls(?:if|e)|val|q)|g(?:[et]|iven|oto
1005                  |rep)|u(?:n(?:less|til)|se)|l(?:(?:as)?t|ocal|e)|re
1006                  (?:quire|turn|do)|__(?:DATA|END)__|for(?:each|mat)?|(?:
1007                  AUTOLOA|EN)D|n(?:e(?:xt)?|o)|C(?:HECK|ORE)|wh(?:ile|en)
1008                  |(?:ou?|t)r|m(?:ap|y)?|UNITCHECK|q[qrwx]?|x(?:or)?|DEST
1009                  ROY|BEGIN|INIT|and|cmp|if|y)\z/x;
1010      $tests ++;
1011      ok   exists &{"my$word"}
1012        || (eval{&{"CORE::$word"}}, $@ =~ /cannot be called directly/),
1013     "$word either has been tested or is not ampable";
1014    }
1015  }
1016}
1017
1018# Add new tests above this line.
1019
1020# This test must come last (before the test count test):
1021
1022{
1023  last if is_miniperl;
1024  require Cwd;
1025  import Cwd;
1026  $tests += 3;
1027  require File::Temp ;
1028  my $dir = File::Temp::tempdir(uc cleanup => 1);
1029  my $cwd = cwd();
1030  chdir($dir);
1031
1032  # Make sure that implicit $_ is not applied to mkdir’s second argument.
1033  local $^W = 1;
1034  my $warnings;
1035  local $SIG{__WARN__} = sub { ++$warnings };
1036
1037  local $_ = 'Phoo';
1038  ok &mymkdir(), '&mkdir';
1039  like <*>, qr/^phoo(.DIR)?\z/i, 'mkdir works with implicit $_';
1040
1041  is $warnings, undef, 'no implicit $_ for second argument to mkdir';
1042
1043  chdir($cwd); # so auto-cleanup can remove $dir
1044}
1045
1046# ------------ END TESTING ----------- #
1047
1048done_testing $tests;
1049
1050#line 3 frob
1051
1052sub file { &CORE::__FILE__ }
1053sub line { &CORE::__LINE__ } # 5
1054sub dier { &CORE::die(@_)  } # 6
1055package stribble;
1056sub main::pakg { &CORE::__PACKAGE__ }
1057
1058# Please do not add new tests here.
1059package main;
1060CORE::__DATA__
1061I wandered lonely as a cloud
1062That floats on high o'er vales and hills,
1063And all at once I saw a crowd,
1064A host of golden daffodils!
1065Beside the lake, beneath the trees,
1066Fluttering, dancing, in the breeze.
1067-- Wordsworth
1068