Fix test for overload in given() with smart match after last change
[p5sagit/p5-mst-13.2.git] / t / op / magic.t
1 #!./perl
2
3 BEGIN {
4     $| = 1;
5     chdir 't' if -d 't';
6     @INC = '../lib';
7     $SIG{__WARN__} = sub { die "Dying on warning: ", @_ };
8     require './test.pl';
9 }
10
11 use warnings;
12 use Config;
13
14 plan (tests => 79);
15
16 $Is_MSWin32  = $^O eq 'MSWin32';
17 $Is_NetWare  = $^O eq 'NetWare';
18 $Is_VMS      = $^O eq 'VMS';
19 $Is_Dos      = $^O eq 'dos';
20 $Is_os2      = $^O eq 'os2';
21 $Is_Cygwin   = $^O eq 'cygwin';
22 $Is_MacOS    = $^O eq 'MacOS';
23 $Is_MPE      = $^O eq 'mpeix';          
24 $Is_miniperl = $ENV{PERL_CORE_MINITEST};
25 $Is_BeOS     = $^O eq 'beos';
26
27 $PERL = $ENV{PERL}
28     || ($Is_NetWare           ? 'perl'   :
29        ($Is_MacOS || $Is_VMS) ? $^X      :
30        $Is_MSWin32            ? '.\perl' :
31        './perl');
32
33 eval '$ENV{"FOO"} = "hi there";';       # check that ENV is inited inside eval
34 # cmd.exe will echo 'variable=value' but 4nt will echo just the value
35 # -- Nikola Knezevic
36 if ($Is_MSWin32)  { like `set FOO`, qr/^(?:FOO=)?hi there$/; }
37 elsif ($Is_MacOS) { ok "1 # skipped", 1; }
38 elsif ($Is_VMS)   { is `write sys\$output f\$trnlnm("FOO")`, "hi there\n"; }
39 else              { is `echo \$FOO`, "hi there\n"; }
40
41 unlink 'ajslkdfpqjsjfk';
42 $! = 0;
43 open(FOO,'ajslkdfpqjsjfk');
44 isnt($!, 0);
45 close FOO; # just mention it, squelch used-only-once
46
47 SKIP: {
48     skip('SIGINT not safe on this platform', 5)
49         if $Is_MSWin32 || $Is_NetWare || $Is_Dos || $Is_MPE || $Is_MacOS;
50   # the next tests are done in a subprocess because sh spits out a
51   # newline onto stderr when a child process kills itself with SIGINT.
52   # We use a pipe rather than system() because the VMS command buffer
53   # would overflow with a command that long.
54
55     open( CMDPIPE, "| $PERL");
56
57     print CMDPIPE <<'END';
58
59     $| = 1;             # command buffering
60
61     $SIG{"INT"} = "ok3";     kill "INT",$$; sleep 1;
62     $SIG{"INT"} = "IGNORE";  kill "INT",$$; sleep 1; print "ok 4\n";
63     $SIG{"INT"} = "DEFAULT"; kill "INT",$$; sleep 1; print "not ok 4\n";
64
65     sub ok3 {
66         if (($x = pop(@_)) eq "INT") {
67             print "ok 3\n";
68         }
69         else {
70             print "not ok 3 ($x @_)\n";
71         }
72     }
73
74 END
75
76     close CMDPIPE;
77
78     open( CMDPIPE, "| $PERL");
79     print CMDPIPE <<'END';
80
81     { package X;
82         sub DESTROY {
83             kill "INT",$$;
84         }
85     }
86     sub x {
87         my $x=bless [], 'X';
88         return sub { $x };
89     }
90     $| = 1;             # command buffering
91     $SIG{"INT"} = "ok5";
92     {
93         local $SIG{"INT"}=x();
94         print ""; # Needed to expose failure in 5.8.0 (why?)
95     }
96     sleep 1;
97     delete $SIG{"INT"};
98     kill "INT",$$; sleep 1;
99     sub ok5 {
100         print "ok 5\n";
101     }
102 END
103     close CMDPIPE;
104     $? >>= 8 if $^O eq 'VMS'; # POSIX status hiding in 2nd byte
105     my $todo = ($^O eq 'os2' ? ' # TODO: EMX v0.9d_fix4 bug: wrong nibble? ' : '');
106     print $? & 0xFF ? "ok 6$todo\n" : "not ok 6$todo\n";
107
108     open(CMDPIPE, "| $PERL");
109     print CMDPIPE <<'END';
110
111     sub PVBM () { 'foo' }
112     index 'foo', PVBM;
113     my $pvbm = PVBM;
114
115     sub foo { exit 0 }
116
117     $SIG{"INT"} = $pvbm;
118     kill "INT", $$; sleep 1;
119 END
120     close CMDPIPE;
121     $? >>= 8 if $^O eq 'VMS';
122     print $? ? "not ok 7\n" : "ok 7\n";
123
124     curr_test(curr_test() + 5);
125 }
126
127 # can we slice ENV?
128 @val1 = @ENV{keys(%ENV)};
129 @val2 = values(%ENV);
130 is join(':',@val1), join(':',@val2);
131 cmp_ok @val1, '>', 1;
132
133 # regex vars
134 'foobarbaz' =~ /b(a)r/;
135 is $`, 'foo';
136 is $&, 'bar';
137 is $', 'baz';
138 is $+, 'a';
139
140 # $"
141 @a = qw(foo bar baz);
142 is "@a", "foo bar baz";
143 {
144     local $" = ',';
145     is "@a", "foo,bar,baz";
146 }
147
148 # $;
149 %h = ();
150 $h{'foo', 'bar'} = 1;
151 is((keys %h)[0], "foo\034bar");
152 {
153     local $; = 'x';
154     %h = ();
155     $h{'foo', 'bar'} = 1;
156     is((keys %h)[0], 'fooxbar');
157 }
158
159 # $?, $@, $$
160 SKIP:  {
161     skip('$? + system are broken on MacPerl', 2) if $Is_MacOS;
162     system qq[$PERL "-I../lib" -e "use vmsish qw(hushed); exit(0)"];
163     is $?, 0;
164     system qq[$PERL "-I../lib" -e "use vmsish qw(hushed); exit(1)"];
165     isnt $?, 0;
166 }
167
168 eval { die "foo\n" };
169 is $@, "foo\n";
170
171 cmp_ok($$, '>', 0);
172 eval { $$++ };
173 like ($@, qr/^Modification of a read-only value attempted/);
174
175 # $^X and $0
176 {
177     if ($^O eq 'qnx') {
178         chomp($wd = `/usr/bin/fullpath -t`);
179     }
180     elsif($Is_Cygwin || $Config{'d_procselfexe'}) {
181        # Cygwin turns the symlink into the real file
182        chomp($wd = `pwd`);
183        $wd =~ s#/t$##;
184        if ($Is_Cygwin) {
185            $wd = Cygwin::win_to_posix_path(Cygwin::posix_to_win_path($wd, 1));
186        }
187     }
188     elsif($Is_os2) {
189        $wd = Cwd::sys_cwd();
190     }
191     elsif($Is_MacOS) {
192        $wd = ':';
193     }
194     else {
195         $wd = '.';
196     }
197     my $perl = ($Is_MacOS || $Is_VMS) ? $^X : "$wd/perl";
198     my $headmaybe = '';
199     my $middlemaybe = '';
200     my $tailmaybe = '';
201     $script = "$wd/show-shebang";
202     if ($Is_MSWin32) {
203         chomp($wd = `cd`);
204         $wd =~ s|\\|/|g;
205         $perl = "$wd/perl.exe";
206         $script = "$wd/show-shebang.bat";
207         $headmaybe = <<EOH ;
208 \@rem ='
209 \@echo off
210 $perl -x \%0
211 goto endofperl
212 \@rem ';
213 EOH
214         $tailmaybe = <<EOT ;
215
216 __END__
217 :endofperl
218 EOT
219     }
220     elsif ($Is_os2) {
221       $script = "./show-shebang";
222     }
223     elsif ($Is_MacOS) {
224       $script = ":show-shebang";
225     }
226     elsif ($Is_VMS) {
227       $script = "[]show-shebang";
228     }
229     elsif ($Is_Cygwin) {
230       $middlemaybe = <<'EOX'
231 $^X = Cygwin::win_to_posix_path(Cygwin::posix_to_win_path($^X, 1));
232 $0 = Cygwin::win_to_posix_path(Cygwin::posix_to_win_path($0, 1));
233 EOX
234     }
235     if ($^O eq 'os390' or $^O eq 'posix-bc' or $^O eq 'vmesa') {  # no shebang
236         $headmaybe = <<EOH ;
237     eval 'exec ./perl -S \$0 \${1+"\$\@"}'
238         if 0;
239 EOH
240     }
241     $s1 = "\$^X is $perl, \$0 is $script\n";
242     ok open(SCRIPT, ">$script") or diag $!;
243     ok print(SCRIPT $headmaybe . <<EOB . $middlemaybe . <<'EOF' . $tailmaybe) or diag $!;
244 #!$wd/perl
245 EOB
246 print "\$^X is $^X, \$0 is $0\n";
247 EOF
248     ok close(SCRIPT) or diag $!;
249     ok chmod(0755, $script) or diag $!;
250     $_ = ($Is_MacOS || $Is_VMS) ? `$perl $script` : `$script`;
251     s/\.exe//i if $Is_Dos or $Is_Cygwin or $Is_os2;
252     s{./$script}{$script} if $Is_BeOS; # revert BeOS execvp() side-effect
253     s{\bminiperl\b}{perl}; # so that test doesn't fail with miniperl
254     s{is perl}{is $perl}; # for systems where $^X is only a basename
255     s{\\}{/}g;
256     if ($Is_MSWin32 || $Is_os2) {
257         is uc $_, uc $s1;
258     } else {
259         is $_, $s1;
260     }
261     $_ = `$perl $script`;
262     s/\.exe//i if $Is_Dos or $Is_os2 or $Is_Cygwin;
263     s{./$perl}{$perl} if $Is_BeOS; # revert BeOS execvp() side-effect
264     s{\\}{/}g;
265     if ($Is_MSWin32 || $Is_os2) {
266         is uc $_, uc $s1;
267     } else {
268         is $_, $s1;
269     }
270     ok unlink($script) or diag $!;
271 }
272
273 # $], $^O, $^T
274 cmp_ok $], '>=', 5.00319;
275 ok $^O;
276 cmp_ok $^T, '>', 850000000;
277
278 # Test change 25062 is working
279 my $orig_osname = $^O;
280 {
281 local $^I = '.bak';
282 is $^O, $orig_osname, 'Assigning $^I does not clobber $^O';
283 }
284 $^O = $orig_osname;
285
286 SKIP: {
287     skip("%ENV manipulations fail or aren't safe on $^O", 4)
288         if $Is_VMS || $Is_Dos || $Is_MacOS;
289
290  SKIP: {
291         skip("clearing \%ENV is not safe when running under valgrind")
292             if $ENV{PERL_VALGRIND};
293
294             $PATH = $ENV{PATH};
295             $PDL = $ENV{PERL_DESTRUCT_LEVEL} || 0;
296             $ENV{foo} = "bar";
297             %ENV = ();
298             $ENV{PATH} = $PATH;
299             $ENV{PERL_DESTRUCT_LEVEL} = $PDL || 0;
300             if ($Is_MSWin32) {
301                 is `set foo 2>NUL`, "";
302             } else {
303                 is `echo \$foo`, "\n";
304             }
305         }
306
307         $ENV{__NoNeSuCh} = "foo";
308         $0 = "bar";
309 # cmd.exe will echo 'variable=value' but 4nt will echo just the value
310 # -- Nikola Knezevic
311         if ($Is_MSWin32) {
312             like `set __NoNeSuCh`, qr/^(?:__NoNeSuCh=)?foo$/;
313         } else {
314             is `echo \$__NoNeSuCh`, "foo\n";
315         }
316     SKIP: {
317             skip("\$0 check only on Linux and FreeBSD", 2)
318                 unless $^O =~ /^(linux|freebsd)$/
319                     && open CMDLINE, "/proc/$$/cmdline";
320
321             chomp(my $line = scalar <CMDLINE>);
322             my $me = (split /\0/, $line)[0];
323             is $me, $0, 'altering $0 is effective (testing with /proc/)';
324             close CMDLINE;
325             # perlbug #22811
326             my $mydollarzero = sub {
327               my($arg) = shift;
328               $0 = $arg if defined $arg;
329               # In FreeBSD the ps -o command= will cause
330               # an empty header line, grab only the last line.
331               my $ps = (`ps -o command= -p $$`)[-1];
332               return if $?;
333               chomp $ps;
334               printf "# 0[%s]ps[%s]\n", $0, $ps;
335               $ps;
336             };
337             my $ps = $mydollarzero->("x");
338             ok(!$ps  # we allow that something goes wrong with the ps command
339                # In Linux 2.4 we would get an exact match ($ps eq 'x') but
340                # in Linux 2.2 there seems to be something funny going on:
341                # it seems as if the original length of the argv[] would
342                # be stored in the proc struct and then used by ps(1),
343                # no matter what characters we use to pad the argv[].
344                # (And if we use \0:s, they are shown as spaces.)  Sigh.
345                || $ps =~ /^x\s*$/
346                # FreeBSD cannot get rid of both the leading "perl :"
347                # and the trailing " (perl)": some FreeBSD versions
348                # can get rid of the first one.
349                || ($^O eq 'freebsd' && $ps =~ m/^(?:perl: )?x(?: \(perl\))?$/),
350                        'altering $0 is effective (testing with `ps`)');
351         }
352 }
353
354 {
355     my $ok = 1;
356     my $warn = '';
357     local $SIG{'__WARN__'} = sub { $ok = 0; $warn = join '', @_; $warn =~ s/\n$//; };
358     $! = undef;
359     local $TODO = $Is_VMS ? "'\$!=undef' does throw a warning" : '';
360     ok($ok, $warn);
361 }
362
363 # test case-insignificance of %ENV (these tests must be enabled only
364 # when perl is compiled with -DENV_IS_CASELESS)
365 SKIP: {
366     skip('no caseless %ENV support', 4) unless $Is_MSWin32 || $Is_NetWare;
367
368     %ENV = ();
369     $ENV{'Foo'} = 'bar';
370     $ENV{'fOo'} = 'baz';
371     is scalar(keys(%ENV)), 1;
372     ok exists $ENV{'FOo'};
373     is delete $ENV{'foO'}, 'baz';
374     is scalar(keys(%ENV)), 0;
375 }
376
377 SKIP: {
378     skip ("miniperl can't rely on loading %Errno", 2) if $Is_miniperl;
379    no warnings 'void';
380
381 # Make sure Errno hasn't been prematurely autoloaded
382
383    ok !keys %Errno::;
384
385 # Test auto-loading of Errno when %! is used
386
387    ok scalar eval q{
388       %!;
389       defined %Errno::;
390    }, $@;
391 }
392
393 SKIP:  {
394     skip ("miniperl can't rely on loading %Errno") if $Is_miniperl;
395     # Make sure that Errno loading doesn't clobber $!
396
397     undef %Errno::;
398     delete $INC{"Errno.pm"};
399
400     open(FOO, "nonesuch"); # Generate ENOENT
401     my %errs = %{"!"}; # Cause Errno.pm to be loaded at run-time
402     ok ${"!"}{ENOENT};
403 }
404
405 is $^S, 0;
406 eval { is $^S,1 };
407 eval " BEGIN { ok ! defined \$^S } ";
408 is $^S, 0;
409
410 is ${^TAINT}, 0;
411 eval { ${^TAINT} = 1 };
412 is ${^TAINT}, 0;
413
414 # 5.6.1 had a bug: @+ and @- were not properly interpolated
415 # into double-quoted strings
416 # 20020414 mjd-perl-patch+@plover.com
417 "I like pie" =~ /(I) (like) (pie)/;
418 is "@-",  "0 0 2 7";
419 is "@+", "10 1 6 10";
420
421 # Tests for the magic get of $\
422 {
423     my $ok = 0;
424     # [perl #19330]
425     {
426         local $\ = undef;
427         $\++; $\++;
428         $ok = $\ eq 2;
429     }
430     ok $ok;
431     $ok = 0;
432     {
433         local $\ = "a\0b";
434         $ok = "a$\b" eq "aa\0bb";
435     }
436     ok $ok;
437 }
438
439 # Test for bug [perl #27839]
440 {
441     my $x;
442     sub f {
443         "abc" =~ /(.)./;
444         $x = "@+";
445         return @+;
446     };
447     my @y = f();
448     is $x, "@y", "return a magic array ($x) vs (@y)";
449 }
450
451 # Test for bug [perl #36434]
452 # Can not do this test on VMS, EPOC, and SYMBIAN according to comments
453 # in mg.c/Perl_magic_clear_all_env()
454 SKIP: {
455     skip('Can\'t make assignment to \%ENV on this system', 3) if $Is_VMS;
456
457     local @ISA;
458     local %ENV;
459     # This used to be __PACKAGE__, but that causes recursive
460     #  inheritance, which is detected earlier now and broke
461     #  this test
462     eval { push @ISA, __FILE__ };
463     is $@, '', 'Push a constant on a magic array';
464     $@ and print "# $@";
465     eval { %ENV = (PATH => __PACKAGE__) };
466     is $@, '', 'Assign a constant to a magic hash';
467     $@ and print "# $@";
468     eval { my %h = qw(A B); %ENV = (PATH => (keys %h)[0]) };
469     is $@, '', 'Assign a shared key to a magic hash';
470     $@ and print "# $@";
471 }
472
473 # Tests for Perl_magic_clearsig
474 foreach my $sig (qw(__WARN__ INT)) {
475     $SIG{$sig} = lc $sig;
476     is $SIG{$sig}, 'main::' . lc $sig, "Can assign to $sig";
477     is delete $SIG{$sig}, 'main::' . lc $sig, "Can delete from $sig";
478     is $SIG{$sig}, undef, "$sig is now gone";
479     is delete $SIG{$sig}, undef, "$sig remains gone";
480 }
481
482 # And now one which doesn't exist;
483 {
484     no warnings 'signal';
485     $SIG{HUNGRY} = 'mmm, pie';
486 }
487 is $SIG{HUNGRY}, 'mmm, pie', 'Can assign to HUNGRY';
488 is delete $SIG{HUNGRY}, 'mmm, pie', 'Can delete from HUNGRY';
489 is $SIG{HUNGRY}, undef, "HUNGRY is now gone";
490 is delete $SIG{HUNGRY}, undef, "HUNGRY remains gone";
491
492 # Test deleting signals that we never set
493 foreach my $sig (qw(__DIE__ _BOGUS_HOOK PIPE THIRSTY)) {
494     is $SIG{$sig}, undef, "$sig is not present";
495     is delete $SIG{$sig}, undef, "delete of $sig returns undef";
496 }