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