diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 1998-08-08 22:18:54 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1998-08-08 22:18:54 +0000 |
commit | 84df6dbaac5dcce30923bafc61c52f3ffa1b669b (patch) | |
tree | cf12e2c57eeb3ade406af6984e8a91a4ea05a830 /t | |
parent | 527cc686938e627799b4befb57128e2e7c3272c2 (diff) | |
parent | 1eccc87f4ae921520ce1893dd988f4a8a1fa061d (diff) | |
download | perl-84df6dbaac5dcce30923bafc61c52f3ffa1b669b.tar.gz |
integrate maint-5.005 changes into mainline
p4raw-id: //depot/perl@1760
Diffstat (limited to 't')
-rwxr-xr-x | t/TEST | 10 | ||||
-rwxr-xr-x | t/base/rs.t | 2 | ||||
-rwxr-xr-x | t/base/term.t | 12 | ||||
-rwxr-xr-x | t/cmd/subval.t | 9 | ||||
-rwxr-xr-x | t/comp/package.t | 6 | ||||
-rwxr-xr-x | t/comp/require.t | 26 | ||||
-rwxr-xr-x | t/io/fs.t | 57 | ||||
-rwxr-xr-x | t/lib/bigintpm.t | 1 | ||||
-rwxr-xr-x | t/lib/cgi-html.t | 3 | ||||
-rwxr-xr-x | t/lib/filehand.t | 2 | ||||
-rwxr-xr-x | t/lib/io_pipe.t | 7 | ||||
-rwxr-xr-x | t/lib/io_sock.t | 7 | ||||
-rwxr-xr-x | t/lib/ipc_sysv.t | 21 | ||||
-rwxr-xr-x | t/lib/ph.t | 2 | ||||
-rwxr-xr-x | t/lib/posix.t | 3 | ||||
-rwxr-xr-x | t/op/auto.t | 6 | ||||
-rwxr-xr-x | t/op/bop.t | 21 | ||||
-rwxr-xr-x | t/op/defins.t | 1 | ||||
-rwxr-xr-x | t/op/die_exit.t | 9 | ||||
-rwxr-xr-x | t/op/each.t | 3 | ||||
-rwxr-xr-x | t/op/exec.t | 7 | ||||
-rwxr-xr-x | t/op/magic.t | 6 | ||||
-rwxr-xr-x | t/op/misc.t | 1 | ||||
-rwxr-xr-x | t/op/ord.t | 8 | ||||
-rwxr-xr-x | t/op/pack.t | 53 | ||||
-rwxr-xr-x | t/op/quotemeta.t | 26 | ||||
-rw-r--r-- | t/op/re_tests | 8 | ||||
-rwxr-xr-x | t/op/regexp.t | 7 | ||||
-rwxr-xr-x | t/op/sort.t | 37 | ||||
-rwxr-xr-x | t/op/sprintf.t | 2 | ||||
-rwxr-xr-x | t/op/stat.t | 29 | ||||
-rwxr-xr-x | t/op/subst.t | 22 | ||||
-rwxr-xr-x | t/op/taint.t | 8 | ||||
-rwxr-xr-x | t/op/universal.t | 12 | ||||
-rwxr-xr-x | t/pragma/constant.t | 2 | ||||
-rwxr-xr-x | t/pragma/overload.t | 263 | ||||
-rwxr-xr-x | t/pragma/subs.t | 1 |
37 files changed, 601 insertions, 99 deletions
@@ -48,6 +48,14 @@ EOT $total = @tests; $files = 0; $totmax = 0; + $maxlen = 0; + foreach (@tests) { + $len = length; + $maxlen = $len if $len > $maxlen; + } + # +3 : we want three dots between the test name and the "ok" + # -2 : the .t suffix + $dotdotdot = $maxlen + 3 - 2; while ($test = shift @tests) { if ( $infinite{$test} && $type eq 'compile' ) { @@ -59,7 +67,7 @@ EOT } $te = $test; chop($te); - print "$te" . '.' x (18 - length($te)); + print "$te" . '.' x ($dotdotdot - length($te)); open(SCRIPT,"<$test") or die "Can't run $test.\n"; $_ = <SCRIPT>; diff --git a/t/base/rs.t b/t/base/rs.t index 5428603304..52a957260f 100755 --- a/t/base/rs.t +++ b/t/base/rs.t @@ -85,6 +85,7 @@ $bar = <TESTFILE>; if ($bar eq "78") {print "ok 10\n";} else {print "not ok 10\n";} # Get rid of the temp file +close TESTFILE; unlink "./foo"; # Now for the tricky bit--full record reading @@ -120,6 +121,7 @@ if ($^O eq 'VMS') { $bar = <TESTFILE>; if ($bar eq "z\n") {print "ok 14\n";} else {print "not ok 14\n";} + close TESTFILE; unlink "./foo.bar"; unlink "./foo.com"; } else { diff --git a/t/base/term.t b/t/base/term.t index 782ad397d3..e96313dec5 100755 --- a/t/base/term.t +++ b/t/base/term.t @@ -2,12 +2,22 @@ # $RCSfile: term.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:07 $ +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; +} + +use Config; + print "1..7\n"; # check "" interpretation $x = "\n"; -if ($x eq chr(10)) {print "ok 1\n";} else {print "not ok 1\n";} +# 10 is ASCII/Iso Latin, 21 is EBCDIC. +if ($x eq chr(10) || + ($Config{ebcdic} eq 'define' && $x eq chr(21))) {print "ok 1\n";} +else {print "not ok 1\n";} # check `` processing diff --git a/t/cmd/subval.t b/t/cmd/subval.t index 3c1ffb89ea..3c60690ebf 100755 --- a/t/cmd/subval.t +++ b/t/cmd/subval.t @@ -33,7 +33,7 @@ sub foo6 { 'true2' unless $_[0]; } -print "1..34\n"; +print "1..36\n"; if (&foo1(0) eq '0') {print "ok 1\n";} else {print "not ok 1 $foo\n";} if (&foo1(1) eq 'true2') {print "ok 2\n";} else {print "not ok 2\n";} @@ -177,3 +177,10 @@ sub iseof { eof UNIQ ? print "not ok $main'i\n" : print "ok $main'i\n"; } } + +sub autov { $_[0] = 23 }; + +my $href = {}; +print keys %$href ? 'not ' : '', "ok 35\n"; +autov($href->{b}); +print join(':', %$href) eq 'b:23' ? '' : 'not ', "ok 36\n"; diff --git a/t/comp/package.t b/t/comp/package.t index cef02c5cb4..d7d19ae882 100755 --- a/t/comp/package.t +++ b/t/comp/package.t @@ -23,7 +23,11 @@ $main = join(':', sort(keys %main::)); $xyz = join(':', sort(keys %xyz::)); $ABC = join(':', sort(keys %ABC::)); -print $xyz eq 'ABC:bar:main:xyz' ? "ok 1\n" : "not ok 1 '$xyz'\n"; +if ('a' lt 'A') { + print $xyz eq 'bar:main:xyz:ABC' ? "ok 1\n" : "not ok 1 '$xyz'\n"; +} else { + print $xyz eq 'ABC:bar:main:xyz' ? "ok 1\n" : "not ok 1 '$xyz'\n"; +} print $ABC eq 'blurfl:dyick' ? "ok 2\n" : "not ok 2 '$ABC'\n"; print $main'blurfl == 123 ? "ok 3\n" : "not ok 3\n"; diff --git a/t/comp/require.t b/t/comp/require.t index bae0712dfa..203b996e06 100755 --- a/t/comp/require.t +++ b/t/comp/require.t @@ -7,17 +7,27 @@ BEGIN { # don't make this lexical $i = 1; -print "1..3\n"; +print "1..4\n"; sub do_require { %INC = (); - open(REQ,">bleah.pm") or die "Can't write 'bleah.pm': $!"; - print REQ @_; - close REQ; + write_file('bleah.pm',@_); eval { require "bleah.pm" }; my @a; # magic guard for scope violations (must be first lexical in file) } +sub write_file { + my $f = shift; + open(REQ,">$f") or die "Can't write '$f': $!"; + print REQ @_; + close REQ; +} + +# interaction with pod (see the eof) +write_file('bleah.pm', "print 'ok $i\n'; 1;\n"); +require "bleah.pm"; +$i++; + # run-time failure in require do_require "0;\n"; print "# $@\nnot " unless $@ =~ /did not return a true/; @@ -25,7 +35,7 @@ print "ok ",$i++,"\n"; # compile-time failure in require do_require "1)\n"; -print "# $@\nnot " unless $@ =~ /syntax error/; +print "# $@\nnot " unless $@ =~ /syntax error/i; print "ok ",$i++,"\n"; # successful require @@ -33,4 +43,8 @@ do_require "1"; print "# $@\nnot " if $@; print "ok ",$i++,"\n"; -unlink 'bleah.pm'; +END { unlink 'bleah.pm'; } + +# ***interaction with pod (don't put any thing after here)*** + +=pod @@ -9,7 +9,7 @@ BEGIN { use Config; -$Is_Dos=$^O eq 'dos'; +$Is_Dosish = ($^O eq 'dos' or $^O eq 'os2'); # avoid win32 (for now) do { print "1..0\n"; exit(0); } if $^O eq 'MSWin32'; @@ -32,35 +32,56 @@ close(fh); open(fh,'>a') || die "Can't create a"; close(fh); -if (eval {link('a','b')} || $Is_Dos) {print "ok 2\n";} else {print "not ok 2\n";} +if ($Is_Dosish) {print "ok 2 # skipped: no link\n";} +elsif (eval {link('a','b')}) {print "ok 2\n";} +else {print "not ok 2\n";} -if (eval {link('b','c')} || $Is_Dos) {print "ok 3\n";} else {print "not ok 3\n";} +if ($Is_Dosish) {print "ok 3 # skipped: no link\n";} +elsif (eval {link('b','c')}) {print "ok 3\n";} +else {print "not ok 3\n";} ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat('c'); -if ($Config{dont_use_nlink} || $nlink == 3 || $Is_Dos) - {print "ok 4\n";} else {print "not ok 4\n";} +if ($Config{dont_use_nlink} || $Is_Dosish) + {print "ok 4 # skipped: no link\n";} +elsif ($nlink == 3) + {print "ok 4\n";} +else {print "not ok 4\n";} -if (($mode & 0777) == 0666 || $^O eq 'amigaos' || $Is_Dos) - {print "ok 5\n";} else {print "not ok 5\n";} +if ($^O eq 'amigaos' || $Is_Dosish) + {print "ok 5 # skipped: no link\n";} +elsif (($mode & 0777) == 0666) + {print "ok 5\n";} +else {print "not ok 5\n";} if ((chmod 0777,'a') == 1) {print "ok 6\n";} else {print "not ok 6\n";} ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat('c'); -if (($mode & 0777) == 0777 || $Is_Dos) {print "ok 7\n";} else {print "not ok 7\n";} +if ($Is_Dosish) {print "ok 7 # skipped: no link\n";} +elsif (($mode & 0777) == 0777) {print "ok 7\n";} +else {print "not ok 7\n";} -if ((chmod 0700,'c','x') == 2 || $Is_Dos) {print "ok 8\n";} else {print "not ok 8\n";} +if ($Is_Dosish) {print "ok 8 # skipped: no link\n";} +elsif ((chmod 0700,'c','x') == 2) {print "ok 8\n";} +else {print "not ok 8\n";} ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat('c'); -if (($mode & 0777) == 0700 || $Is_Dos) {print "ok 9\n";} else {print "not ok 9\n";} +if ($Is_Dosish) {print "ok 9 # skipped: no link\n";} +elsif (($mode & 0777) == 0700) {print "ok 9\n";} +else {print "not ok 9\n";} + ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat('x'); -if (($mode & 0777) == 0700 || $Is_Dos) {print "ok 10\n";} else {print "not ok 10\n";} +if ($Is_Dosish) {print "ok 10 # skipped: no link\n";} +elsif (($mode & 0777) == 0700) {print "ok 10\n";} +else {print "not ok 10\n";} -if ((unlink 'b','x') == 2 || $Is_Dos) {print "ok 11\n";} else {print "not ok 11\n";} +if ($Is_Dosish) {print "ok 11 # skipped: no link\n"; unlink 'b','x'; } +elsif ((unlink 'b','x') == 2) {print "ok 11\n";} +else {print "not ok 11\n";} ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat('b'); if ($ino == 0) {print "ok 12\n";} else {print "not ok 12\n";} @@ -72,13 +93,15 @@ if (rename('a','b')) {print "ok 14\n";} else {print "not ok 14\n";} ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat('a'); if ($ino == 0) {print "ok 15\n";} else {print "not ok 15\n";} -$foo = (utime 500000000,500000001,'b'); +$delta = $Is_Dosish ? 2 : 1; # Granularity of time on the filesystem +$foo = (utime 500000000,500000000 + $delta,'b'); if ($foo == 1) {print "ok 16\n";} else {print "not ok 16 $foo\n";} ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat('b'); if ($ino) {print "ok 17\n";} else {print "not ok 17\n";} -if (($atime == 500000000 && $mtime == 500000001) - || $wd =~ m#/afs/# || $^O eq 'amigaos' || $Is_Dos) +if ($wd =~ m#/afs/# || $^O eq 'amigaos') + {print "ok 18 # skipped: granularity of the filetime\n";} +elsif ($atime == 500000000 && $mtime == 500000000 + $delta) {print "ok 18\n";} else {print "not ok 18 $atime $mtime\n";} @@ -122,12 +145,12 @@ else { { select FH; $| = 1; select STDOUT } print FH "helloworld\n"; truncate FH, 5; - if ($Is_Dos) { + if ($^O eq 'dos') { close (FH); open (FH, ">>Iofs.tmp") or die "Can't reopen Iofs.tmp"; } if (-s "Iofs.tmp" == 5) {print "ok 25\n"} else {print "not ok 25\n"} truncate FH, 0; - if ($Is_Dos) { + if ($^O eq 'dos') { close (FH); open (FH, ">>Iofs.tmp") or die "Can't reopen Iofs.tmp"; } if (-z "Iofs.tmp") {print "ok 26\n"} else {print "not ok 26\n"} diff --git a/t/lib/bigintpm.t b/t/lib/bigintpm.t index 4357975f2b..e7cac26323 100755 --- a/t/lib/bigintpm.t +++ b/t/lib/bigintpm.t @@ -5,7 +5,6 @@ BEGIN { @INC = '../lib'; } -use Config; use Math::BigInt; $test = 0; diff --git a/t/lib/cgi-html.t b/t/lib/cgi-html.t index d7f3ffb4aa..16aa824c51 100755 --- a/t/lib/cgi-html.t +++ b/t/lib/cgi-html.t @@ -9,7 +9,8 @@ BEGIN { } BEGIN {$| = 1; print "1..17\n"; } -BEGIN {$eol = $^O eq 'VMS' ? "\n" : "\cM\cJ";} +BEGIN {$eol = $^O eq 'VMS' ? "\n" : "\cM\cJ"; + $eol = "\r\n" if $^O eq 'os390'; } END {print "not ok 1\n" unless $loaded;} use CGI (':standard','-no_debug'); $loaded = 1; diff --git a/t/lib/filehand.t b/t/lib/filehand.t index 08cae71872..b8ec95f320 100755 --- a/t/lib/filehand.t +++ b/t/lib/filehand.t @@ -31,7 +31,7 @@ $buffer = <$fh>; print $buffer eq "#!./perl\n" ? "ok 3\n" : "not ok 3\n"; -ungetc $fh 65; +ungetc $fh ord 'A'; CORE::read($fh, $buf,1); print $buf eq 'A' ? "ok 4\n" : "not ok 4\n"; diff --git a/t/lib/io_pipe.t b/t/lib/io_pipe.t index e1c48b6a7e..e617c92432 100755 --- a/t/lib/io_pipe.t +++ b/t/lib/io_pipe.t @@ -41,6 +41,13 @@ print $pipe "not ok 3\n" ; $pipe->close or print "# \$!=$!\nnot "; print "ok 4\n"; +# Check if can fork with dynamic extensions (bug in CRT): +if ($^O eq 'os2' and + system "$^X -I../lib -MOpcode -e 'defined fork or die' > /dev/null 2>&1") { + print "ok $_ # skipped: broken fork\n" for 5..10; + exit 0; +} + $pipe = new IO::Pipe; $pid = fork(); diff --git a/t/lib/io_sock.t b/t/lib/io_sock.t index 9fab56b237..8fc52e4026 100755 --- a/t/lib/io_sock.t +++ b/t/lib/io_sock.t @@ -32,6 +32,13 @@ $listen = IO::Socket::INET->new(Listen => 2, print "ok 1\n"; +# Check if can fork with dynamic extensions (bug in CRT): +if ($^O eq 'os2' and + system "$^X -I../lib -MOpcode -e 'defined fork or die' > /dev/null 2>&1") { + print "ok $_ # skipped: broken fork\n" for 2..5; + exit 0; +} + $port = $listen->sockport; if($pid = fork()) { diff --git a/t/lib/ipc_sysv.t b/t/lib/ipc_sysv.t index f74c5fa060..30ea48d999 100755 --- a/t/lib/ipc_sysv.t +++ b/t/lib/ipc_sysv.t @@ -28,6 +28,27 @@ my $sem; $SIG{__DIE__} = 'cleanup'; # will cleanup $msg and $sem if needed +# FreeBSD is known to throw this if there's no SysV IPC in the kernel. +$SIG{SYS} = sub { + print STDERR <<EOM; +SIGSYS caught. +It may be that your kernel does not have SysV IPC configured. + +EOM + if ($^O eq 'freebsd') { + print STDERR <<EOM; +You must have following options in your kernel: + +options SYSVSHM +options SYSVSEM +options SYSVMSG + +See config(8). +EOM + } + exit(1); +}; + if ($Config{'d_msgget'} eq 'define' && $Config{'d_msgctl'} eq 'define' && $Config{'d_msgsnd'} eq 'define' && diff --git a/t/lib/ph.t b/t/lib/ph.t index d0a48f6c51..de27dee5e2 100755 --- a/t/lib/ph.t +++ b/t/lib/ph.t @@ -9,8 +9,6 @@ BEGIN { @INC = '../lib'; } -use Config; - # All the constants which Socket.pm tries to make available: my @possibly_defined = qw( INADDR_ANY INADDR_LOOPBACK INADDR_NONE AF_802 AF_APPLETALK AF_CCITT diff --git a/t/lib/posix.t b/t/lib/posix.t index c071c3b067..8dafc80387 100755 --- a/t/lib/posix.t +++ b/t/lib/posix.t @@ -96,5 +96,6 @@ print &POSIX::acos(1.0) == 0.0 ? "ok 17\n" : "not ok 17\n"; print POSIX::strftime("ok 18 # %H:%M, on %D\n", localtime()); $| = 0; -print '@#!*$@(!@#$'; +# The following line assumes buffered output, which may be not true with EMX: +print '@#!*$@(!@#$' unless $^O eq 'os2'; _exit(0); diff --git a/t/op/auto.t b/t/op/auto.t index 93a42f8472..2eb0097650 100755 --- a/t/op/auto.t +++ b/t/op/auto.t @@ -2,7 +2,7 @@ # $RCSfile: auto.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:39 $ -print "1..34\n"; +print "1..37\n"; $x = 10000; if (0 + ++$x - 1 == 10000) { print "ok 1\n";} else {print "not ok 1\n";} @@ -46,3 +46,7 @@ if (++($foo = '99') eq '100') {print "ok 31\n";} else {print "not ok 31\n";} if (++($foo = 'a0') eq 'a1') {print "ok 32\n";} else {print "not ok 32\n";} if (++($foo = 'Az') eq 'Ba') {print "ok 33\n";} else {print "not ok 33\n";} if (++($foo = 'zz') eq 'aaa') {print "ok 34\n";} else {print "not ok 34\n";} +if (++($foo = 'A99') eq 'B00') {print "ok 35\n";} else {print "not ok 35\n";} +# EBCDIC guards: i and j, r and s, are not contiguous. +if (++($foo = 'zi') eq 'zj') {print "ok 36\n";} else {print "not ok 36\n";} +if (++($foo = 'zr') eq 'zs') {print "ok 37\n";} else {print "not ok 37\n";} diff --git a/t/op/bop.t b/t/op/bop.t index 0c55029b93..b247341417 100755 --- a/t/op/bop.t +++ b/t/op/bop.t @@ -42,14 +42,23 @@ print ((($cusp >> 1) == ($cusp / 2) && do { use integer; $cusp >> 1 } == -($cusp / 2)) ? "ok 12\n" : "not ok 12\n"); +$Aaz = chr(ord("A") & ord("z")); +$Aoz = chr(ord("A") | ord("z")); +$Axz = chr(ord("A") ^ ord("z")); + # short strings -print (("AAAAA" & "zzzzz") eq '@@@@@' ? "ok 13\n" : "not ok 13\n"); -print (("AAAAA" | "zzzzz") eq '{{{{{' ? "ok 14\n" : "not ok 14\n"); -print (("AAAAA" ^ "zzzzz") eq ';;;;;' ? "ok 15\n" : "not ok 15\n"); +print (("AAAAA" & "zzzzz") eq ($Aaz x 5) ? "ok 13\n" : "not ok 13\n"); +print (("AAAAA" | "zzzzz") eq ($Aoz x 5) ? "ok 14\n" : "not ok 14\n"); +print (("AAAAA" ^ "zzzzz") eq ($Axz x 5) ? "ok 15\n" : "not ok 15\n"); # long strings $foo = "A" x 150; $bar = "z" x 75; -print (($foo & $bar) eq ('@'x75 ) ? "ok 16\n" : "not ok 16\n"); -print (($foo | $bar) eq ('{'x75 . 'A'x75) ? "ok 17\n" : "not ok 17\n"); -print (($foo ^ $bar) eq (';'x75 . 'A'x75) ? "ok 18\n" : "not ok 18\n"); +$zap = "A" x 75; +# & truncates +print (($foo & $bar) eq ($Aaz x 75 ) ? "ok 16\n" : "not ok 16\n"); +# | does not truncate +print (($foo | $bar) eq ($Aoz x 75 . $zap) ? "ok 17\n" : "not ok 17\n"); +# ^ does not truncate +print (($foo ^ $bar) eq ($Axz x 75 . $zap) ? "ok 18\n" : "not ok 18\n"); + diff --git a/t/op/defins.t b/t/op/defins.t index 0ed61ce2fb..33c74ea28e 100755 --- a/t/op/defins.t +++ b/t/op/defins.t @@ -61,6 +61,7 @@ while ($where{$seen} = <FILE>) } print "not " unless $seen; print "ok 5\n"; +close FILE; opendir(DIR,'.'); $seen = 0; diff --git a/t/op/die_exit.t b/t/op/die_exit.t index b5760d6fa0..ffbb1e015e 100755 --- a/t/op/die_exit.t +++ b/t/op/die_exit.t @@ -30,6 +30,8 @@ my %tests = ( 14 => [ 255, 0], 15 => [ 255, 1], 16 => [ 255, 256], + # see if implicit close preserves $? + 17 => [ 42, 42, '{ local *F; open F, q[TEST]; close F } die;'], ); my $max = keys %tests; @@ -37,11 +39,12 @@ my $max = keys %tests; print "1..$max\n"; foreach my $test (1 .. $max) { - my($bang, $query) = @{$tests{$test}}; + my($bang, $query, $code) = @{$tests{$test}}; + $code ||= 'die;'; my $exit = ($^O eq 'MSWin32' - ? system qq($perl -e "\$! = $bang; \$? = $query; die;" 2> nul) - : system qq($perl -e '\$! = $bang; \$? = $query; die;' 2> /dev/null)); + ? system qq($perl -e "\$! = $bang; \$? = $query; $code" 2> nul) + : system qq($perl -e '\$! = $bang; \$? = $query; $code' 2> /dev/null)); printf "# 0x%04x 0x%04x 0x%04x\nnot ", $exit, $bang, $query unless $exit == (($bang || ($query >> 8) || 255) << 8); diff --git a/t/op/each.t b/t/op/each.t index 420fdc09c3..9063c2c3ed 100755 --- a/t/op/each.t +++ b/t/op/each.t @@ -43,7 +43,8 @@ if ($#keys == 29 && $#values == 29) {print "ok 1\n";} else {print "not ok 1\n";} $i = 0; # stop -w complaints while (($key,$value) = each(%h)) { - if ($key eq $keys[$i] && $value eq $values[$i] && $key eq lc($value)) { + if ($key eq $keys[$i] && $value eq $values[$i] + && (('a' lt 'A' && $key lt $value) || $key gt $value)) { $key =~ y/a-z/A-Z/; $i++ if $key eq $value; } diff --git a/t/op/exec.t b/t/op/exec.t index 506fc09fbd..098a455455 100755 --- a/t/op/exec.t +++ b/t/op/exec.t @@ -13,7 +13,12 @@ if ($^O eq 'MSWin32') { print "1..8\n"; -print "not ok 1\n" if system "echo ok \\1"; # shell interpreted +if ($^O ne 'os2') { + print "not ok 1\n" if system "echo ok \\1"; # shell interpreted +} +else { + print "ok 1 # skipped: bug/feature of pdksh\n"; # shell interpreted +} print "not ok 2\n" if system "echo ok 2"; # split and directly called print "not ok 3\n" if system "echo", "ok", "3"; # directly called diff --git a/t/op/magic.t b/t/op/magic.t index 61e4522913..7f08e06f85 100755 --- a/t/op/magic.t +++ b/t/op/magic.t @@ -135,6 +135,12 @@ __END__ :endofperl EOT } + if ($^O eq 'os390') { # no shebang + $headmaybe = <<EOH ; + eval 'exec ./perl -S \$0 \${1+"\$\@"}' + if 0; +EOH + } $s1 = $s2 = "\$^X is $perl, \$0 is $script\n"; ok 19, open(SCRIPT, ">$script"), $!; ok 20, print(SCRIPT $headmaybe . <<EOB . <<'EOF' . $tailmaybe), $!; diff --git a/t/op/misc.t b/t/op/misc.t index 449d87cea1..7292ffebd4 100755 --- a/t/op/misc.t +++ b/t/op/misc.t @@ -36,6 +36,7 @@ for (@prgs){ $status = $?; $results = `$CAT $tmpfile`; $results =~ s/\n+$//; + $results =~ s/syntax error/syntax error/i; $expected =~ s/\n+$//; if ( $results ne $expected){ print STDERR "PROG: $switch\n$prog\n"; diff --git a/t/op/ord.t b/t/op/ord.t index 37128382d8..ba943f4e8c 100755 --- a/t/op/ord.t +++ b/t/op/ord.t @@ -6,11 +6,13 @@ print "1..3\n"; # compile time evaluation -if (ord('A') == 65) {print "ok 1\n";} else {print "not ok 1\n";} +# 65 ASCII +# 193 EBCDIC +if (ord('A') == 65 || ord('A') == 193) {print "ok 1\n";} else {print "not ok 1\n";} # run time evaluation $x = 'ABC'; -if (ord($x) == 65) {print "ok 2\n";} else {print "not ok 2\n";} +if (ord($x) == 65 || ord($x) == 193) {print "ok 2\n";} else {print "not ok 2\n";} -if (chr 65 == A) {print "ok 3\n";} else {print "not ok 3\n";} +if (chr 65 == 'A' || chr 193 == 'A') {print "ok 3\n";} else {print "not ok 3\n";} diff --git a/t/op/pack.t b/t/op/pack.t index b8aece6b6b..9b7bc351f9 100755 --- a/t/op/pack.t +++ b/t/op/pack.t @@ -2,7 +2,7 @@ # $RCSfile: pack.t,v $$Revision: 4.1 $$Date: 92/08/07 18:28:11 $ -print "1..56\n"; +print "1..60\n"; $format = "c2 x5 C C x s d i l a6"; # Need the expression in here to force ary[5] to be numeric. This avoids @@ -30,7 +30,10 @@ print +($x = unpack("%32b69", "\001\002\004\010\020\040\100\200\017")) == 12 print +($x = unpack("%32B69", "\001\002\004\010\020\040\100\200\017")) == 9 ? "ok 6\n" : "not ok 6 $x\n"; -print +($x = unpack("%32B*", "Now is the time for all good blurfl")) == 129 +my $sum = 129; # ASCII +$sum = 103 if ($^O eq 'os390'); # An EBCDIC variant. + +print +($x = unpack("%32B*", "Now is the time for all good blurfl")) == $sum ? "ok 7\n" : "not ok 7 $x\n"; open(BIN, "./perl") || open(BIN, "./perl.exe") @@ -154,3 +157,49 @@ foreach my $t (@templates) { unless @t == 2 and (($t[0] == 12 and $t[1] == 34) or ($t =~ /[nv]/i)); print "ok ", $test++, "\n"; } + +# 57..60: uuencode/decode + +$in = join "", map { chr } 0..255; + +# just to be anal, we do some random tr/`/ / +$uu = <<'EOUU'; +M` $"`P0%!@<("0H+# T.#Q`1$A,4%187&!D:&QP='A\@(2(C)"4F)R@I*BLL +M+2XO,#$R,S0U-C<X.3H[/#T^/T!!0D-$149'2$E*2TQ-3D]045)35%565UA9 +M6EM<75Y?8&%B8V1E9F=H:6IK;&UN;W!Q<G-T=79W>'EZ>WQ]?G^`@8*#A(6& +MAXB)BHN,C8Z/D)&2DY25EI>8F9J;G)V>GZ"AHJ.DI::GJ*FJJZRMKJ^PL;*S +MM+6VM[BYNKN\O;Z_P,'"P\3%QL?(R<K+S,W.S]#1TM/4U=;7V-G:V]S=WM_@ +?X>+CY.7FY^CIZNOL[>[O\/'R\_3U]O?X^?K[_/W^_P ` +EOUU + +$_ = $uu; +tr/ /`/; +print "not " unless pack('u', $in) eq $_; +print "ok ", $test++, "\n"; + +print "not " unless unpack('u', $uu) eq $in; +print "ok ", $test++, "\n"; + +$in = "\x1f\x8b\x08\x08\x58\xdc\xc4\x35\x02\x03\x4a\x41\x50\x55\x00\xf3\x2a\x2d\x2e\x51\x48\xcc\xcb\x2f\xc9\x48\x2d\x52\x08\x48\x2d\xca\x51\x28\x2d\x4d\xce\x4f\x49\x2d\xe2\x02\x00\x64\x66\x60\x5c\x1a\x00\x00\x00"; +$uu = <<'EOUU'; +M'XL("%C<Q#4"`TI!4%4`\RHM+E%(S,LOR4@M4@A(+<I1*"U-SD])+>("`&1F +&8%P:```` +EOUU + +print "not " unless unpack('u', $uu) eq $in; +print "ok ", $test++, "\n"; + +# 60 identical to 59 except that backquotes have been changed to spaces + +$uu = <<'EOUU'; +M'XL("%C<Q#4" TI!4%4 \RHM+E%(S,LOR4@M4@A(+<I1*"U-SD])+>(" &1F +&8%P: +EOUU + +print "not " unless unpack('u', $uu) eq $in; +print "ok ", $test++, "\n"; + +# Note that first uuencoding known 'text' data and then checking the +# binary values of the uuencoded version would not be portable between +# character sets. Uuencoding is meant for encoding binary data, not +# text data. diff --git a/t/op/quotemeta.t b/t/op/quotemeta.t index 20dd312b31..913e07cdd6 100755 --- a/t/op/quotemeta.t +++ b/t/op/quotemeta.t @@ -1,14 +1,26 @@ #!./perl + print "1..15\n"; -$_=join "", map chr($_), 32..127; +if ($^O eq 'os390') { # An EBCDIC variant. + $_=join "", map chr($_), 129..233; + + # 105 characters - 52 letters = 53 backslashes + # 105 characters + 53 backslashes = 158 characters + $_=quotemeta $_; + if ( length == 158 ){print "ok 1\n"} else {print "not ok 1\n"} + # 104 non-backslash characters + if (tr/\\//cd == 104){print "ok 2\n"} else {print "not ok 2\n"} +} else { # some ASCII descendant, then. + $_=join "", map chr($_), 32..127; -# 96 characters - 52 letters - 10 digits - 1 underscore = 33 backslashes -# 96 characters + 33 backslashes = 129 characters -$_=quotemeta $_; -if ( length == 129 ){print "ok 1\n"} else {print "not ok 1\n"} -# 95 non-backslash characters -if (tr/\\//cd == 95){print "ok 2\n"} else {print "not ok 2\n"} + # 96 characters - 52 letters - 10 digits - 1 underscore = 33 backslashes + # 96 characters + 33 backslashes = 129 characters + $_=quotemeta $_; + if ( length == 129 ){print "ok 1\n"} else {print "not ok 1\n"} + # 95 non-backslash characters + if (tr/\\//cd == 95){print "ok 2\n"} else {print "not ok 2\n"} +} if (length quotemeta "" == 0){print "ok 3\n"} else {print "not ok 3\n"} diff --git a/t/op/re_tests b/t/op/re_tests index 7ac20c3852..a5295f5aae 100644 --- a/t/op/re_tests +++ b/t/op/re_tests @@ -151,8 +151,8 @@ a[bcd]+dcdcde adcdcde n - - (bc+d$|ef*g.|h?i(j|k)) reffgz y $&-$1-$2 effgz-effgz- ((((((((((a)))))))))) a y $10 a ((((((((((a))))))))))\10 aa y $& aa -((((((((((a))))))))))\41 aa n - - -((((((((((a))))))))))\41 a! y $& a! +((((((((((a))))))))))${bang} aa n - - +((((((((((a))))))))))${bang} a! y $& a! (((((((((a))))))))) a y $& a multiple words of text uh-uh n - - multiple words multiple words, yeah y $& multiple words @@ -291,8 +291,8 @@ a[-]?c ac y $& ac '(bc+d$|ef*g.|h?i(j|k))'i REFFGZ y $&-$1-$2 EFFGZ-EFFGZ- '((((((((((a))))))))))'i A y $10 A '((((((((((a))))))))))\10'i AA y $& AA -'((((((((((a))))))))))\41'i AA n - - -'((((((((((a))))))))))\41'i A! y $& A! +'((((((((((a))))))))))${bang}'i AA n - - +'((((((((((a))))))))))${bang}'i A! y $& A! '(((((((((a)))))))))'i A y $& A '(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))'i A y $1 A '(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))'i C y $1 C diff --git a/t/op/regexp.t b/t/op/regexp.t index 0ec069b19a..11b3ee31da 100755 --- a/t/op/regexp.t +++ b/t/op/regexp.t @@ -24,7 +24,7 @@ $ENV{PERL_DESTRUCT_LEVEL} = 0 unless $ENV{PERL_DESTRUCT_LEVEL} > 3; # Column 5 contains the expected result of double-quote # interpolating that string after the match, or start of error message. # -# \n in the tests are interpolated. +# \n in the tests are interpolated, as are variables of the form ${\w+}. # # If you want to add a regular expression test that can't be expressed # in this format, don't add it here: put it in op/pat.t instead. @@ -34,8 +34,6 @@ BEGIN { @INC = '../lib' if -d '../lib'; } -use re 'eval'; - $iters = shift || 1; # Poor man performance suite, 10000 is OK. open(TESTS,'op/re_tests') || open(TESTS,'t/op/re_tests') || @@ -46,6 +44,8 @@ $numtests = $.; seek(TESTS,0,0); $. = 0; +$bang = sprintf "\\%03o", ord "!"; # \41 would not be portable. + $| = 1; print "1..$numtests\n# $iters iterations\n"; TEST: @@ -58,6 +58,7 @@ while (<TESTS>) { infty_subst(\$expect); $pat = "'$pat'" unless $pat =~ /^[:']/; $pat =~ s/\\n/\n/g; + $pat =~ s/(\$\{\w+\})/$1/eeg; $subject =~ s/\\n/\n/g; $expect =~ s/\\n/\n/g; $expect = $repl = '-' if $skip_amp and $input =~ /\$[&\`\']/; diff --git a/t/op/sort.t b/t/op/sort.t index a6829e01e4..70341b9106 100755 --- a/t/op/sort.t +++ b/t/op/sort.t @@ -6,20 +6,41 @@ print "1..21\n"; sub backwards { $a lt $b ? 1 : $a gt $b ? -1 : 0 } +my $upperfirst = 'A' lt 'a'; + +# Beware: in future this may become hairier because of possible +# collation complications: qw(A a B c) can be sorted at least as +# any of the following +# +# A a B b +# A B a b +# a b A B +# a A b B +# +# All the above orders make sense. +# +# That said, EBCDIC sorts all small letters first, as opposed +# to ASCII which sorts all big letters first. + @harry = ('dog','cat','x','Cain','Abel'); @george = ('gone','chased','yz','punished','Axed'); $x = join('', sort @harry); -print ($x eq 'AbelCaincatdogx' ? "ok 1\n" : "not ok 1\n"); -print "# x = '$x'\n"; +$expected = $upperfirst ? 'AbelCaincatdogx' : 'catdogxAbelCain'; +print "# 1: x = '$x', expected = '$expected'\n"; +print ($x eq $expected ? "ok 1\n" : "not ok 1\n"); $x = join('', sort( backwards @harry)); -print ($x eq 'xdogcatCainAbel' ? "ok 2\n" : "not ok 2\n"); -print "# x = '$x'\n"; +$expected = $upperfirst ? 'xdogcatCainAbel' : 'CainAbelxdogcat'; +print "# 2: x = '$x', expected = '$expected'\n"; +print ($x eq $expected ? "ok 2\n" : "not ok 2\n"); $x = join('', sort @george, 'to', @harry); -print ($x eq 'AbelAxedCaincatchaseddoggonepunishedtoxyz'?"ok 3\n":"not ok 3\n"); -print "# x = '$x'\n"; +$expected = $upperfirst ? + 'AbelAxedCaincatchaseddoggonepunishedtoxyz' : + 'catchaseddoggonepunishedtoxyzAbelAxedCain' ; +print "# 3: x = '$x', expected = '$expected'\n"; +print ($x eq $expected ?"ok 3\n":"not ok 3\n"); @a = (); @b = reverse @a; @@ -47,7 +68,9 @@ print ("@b" eq "2 3 4 10" ? "ok 9\n" : "not ok 9 (@b)\n"); $sub = 'backwards'; $x = join('', sort $sub @harry); -print ($x eq 'xdogcatCainAbel' ? "ok 10\n" : "not ok 10\n"); +$expected = $upperfirst ? 'xdogcatCainAbel' : 'CainAbelxdogcat'; +print "# 10: x = $x, expected = '$expected'\n"; +print ($x eq $expected ? "ok 10\n" : "not ok 10\n"); # literals, combinations diff --git a/t/op/sprintf.t b/t/op/sprintf.t index 7556c80a41..b9b4751c79 100755 --- a/t/op/sprintf.t +++ b/t/op/sprintf.t @@ -14,7 +14,7 @@ $SIG{__WARN__} = sub { }; $w = 0; -$x = sprintf("%3s %-4s%%foo %.0d%5d %#x%c%3.1f","hi",123,0,456,0,65,3.0999); +$x = sprintf("%3s %-4s%%foo %.0d%5d %#x%c%3.1f","hi",123,0,456,0,ord('A'),3.0999); if ($x eq ' hi 123 %foo 456 0A3.1' && $w == 0) { print "ok 1\n"; } else { diff --git a/t/op/stat.t b/t/op/stat.t index 03bfd8da39..2207b40e30 100755 --- a/t/op/stat.t +++ b/t/op/stat.t @@ -13,9 +13,10 @@ print "1..58\n"; $Is_MSWin32 = $^O eq 'MSWin32'; $Is_Dos = $^O eq 'dos'; +$Is_Dosish = $Is_Dos || $^O eq 'os2' || $Is_MSWin32; chop($cwd = ($Is_MSWin32 ? `cd` : `pwd`)); -$DEV = `ls -l /dev` unless ($Is_MSWin32 || $Is_Dos); +$DEV = `ls -l /dev` unless $Is_Dosish; unlink "Op.stat.tmp"; open(FOO, ">Op.stat.tmp"); @@ -34,7 +35,7 @@ close(FOO); sleep 2; -if ($Is_MSWin32 || $Is_Dos) { unlink "Op.stat.tmp2" } +if ($Is_Dosish) { unlink "Op.stat.tmp2" } else { `rm -f Op.stat.tmp2;ln Op.stat.tmp Op.stat.tmp2; chmod 644 Op.stat.tmp`; } @@ -42,15 +43,19 @@ else { ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat('Op.stat.tmp'); -if ($Is_MSWin32 || $Is_Dos || $Config{dont_use_nlink} || $nlink == 2) - {print "ok 3\n";} else {print "# \$nlink is |$nlink|\nnot ok 3\n";} +if ($Is_Dosish || $Config{dont_use_nlink}) + {print "ok 3 # skipped: no link count\n";} +elsif ($nlink == 2) + {print "ok 3\n";} +else {print "# \$nlink is |$nlink|\nnot ok 3\n";} -if ( ($mtime && $mtime != $ctime) - || $Is_MSWin32 - || $Is_Dos +if ( $Is_Dosish || ($cwd =~ m#^/tmp# and $mtime && $mtime==$ctime) # Solaris tmpfs bug || $cwd =~ m#/afs/# || $^O eq 'amigaos') { + print "ok 4 # skipped: different semantic of mtime/ctime\n"; +} +elsif ( ($mtime && $mtime != $ctime) ) { print "ok 4\n"; } else { @@ -91,7 +96,9 @@ foreach ((12,13,14,15,16,17)) { chmod 0700,'Op.stat.tmp'; if (-r 'Op.stat.tmp') {print "ok 18\n";} else {print "not ok 18\n";} if (-w 'Op.stat.tmp') {print "ok 19\n";} else {print "not ok 19\n";} -if ($Is_MSWin32 or $Is_Dos or -x 'Op.stat.tmp') {print "ok 20\n";} else {print "not ok 20\n";} +if ($Is_Dosish) {print "ok 20 # skipped: -x by extension\n";} +elsif (-x 'Op.stat.tmp') {print "ok 20\n";} +else {print "not ok 20\n";} if (-f 'Op.stat.tmp') {print "ok 21\n";} else {print "not ok 21\n";} if (! -d 'Op.stat.tmp') {print "ok 22\n";} else {print "not ok 22\n";} @@ -99,7 +106,7 @@ if (! -d 'Op.stat.tmp') {print "ok 22\n";} else {print "not ok 22\n";} if (-d '.') {print "ok 23\n";} else {print "not ok 23\n";} if (! -f '.') {print "ok 24\n";} else {print "not ok 24\n";} -if (!($Is_MSWin32 || $Is_Dos) and `ls -l perl` =~ /^l.*->/) { +if (!$Is_Dosish and `ls -l perl` =~ /^l.*->/) { if (-l 'perl') {print "ok 25\n";} else {print "not ok 25\n";} } else { @@ -142,7 +149,9 @@ else {print "not ok 33\n";} if (! -b '.') {print "ok 34\n";} else {print "not ok 34\n";} -if ($^O eq 'amigaos' or $Is_MSWin32 || $Is_Dos) {print "ok 35\n"; goto tty_test;} +if ($^O eq 'amigaos' or $Is_Dosish) { + print "ok 35 # skipped: no -u\n"; goto tty_test; +} $cnt = $uid = 0; diff --git a/t/op/subst.t b/t/op/subst.t index 2d42eeb386..afa06ab772 100755 --- a/t/op/subst.t +++ b/t/op/subst.t @@ -1,11 +1,5 @@ #!./perl - -BEGIN { - chdir 't' if -d 't'; - @INC = '../lib' if -d '../lib'; -} - print "1..71\n"; $x = 'foo'; @@ -187,13 +181,21 @@ tr/a-z/A-Z/; print $_ eq 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' ? "ok 52\n" : "not ok 52\n"; # same as tr/A-Z/a-z/; -y[\101-\132][\141-\172]; +if ($^O eq 'os390') { # An EBCDIC variant. + y[\301-\351][\201-\251]; +} else { # Ye Olde ASCII. Or something like it. + y[\101-\132][\141-\172]; +} print $_ eq 'abcdefghijklmnopqrstuvwxyz0123456789' ? "ok 53\n" : "not ok 53\n"; -$_ = '+,-'; -tr/+--/a-c/; -print $_ eq 'abc' ? "ok 54\n" : "not ok 54\n"; +if (ord("+") == ord(",") - 1 && ord(",") == ord("-") - 1 && + ord("a") == ord("b") - 1 && ord("b") == ord("c") - 1) { + $_ = '+,-'; + tr/+--/a-c/; + print "not " unless $_ eq 'abc'; +} +print "ok 54\n"; $_ = '+,-'; tr/+\--/a\/c/; diff --git a/t/op/taint.t b/t/op/taint.t index f2181d82fd..d2cae8e70a 100755 --- a/t/op/taint.t +++ b/t/op/taint.t @@ -15,6 +15,10 @@ BEGIN { use strict; use Config; +# We do not want the whole taint.t to fail +# just because Errno possibly failing. +eval { require Errno; import Errno }; + my $Is_VMS = $^O eq 'VMS'; my $Is_MSWin32 = $^O eq 'MSWin32'; my $Is_Dos = $^O eq 'dos'; @@ -360,7 +364,9 @@ else { test 71, eval { open FOO, $foo } eq '', 'open for read'; test 72, $@ eq '', $@; # NB: This should be allowed - test 73, $! == 2 || ($Is_Dos && $! == 22); # File not found + + # Try first new style but allow also old style. + test 73, $!{ENOENT} || $! == 2 || ($Is_Dos && $! == 22); # File not found test 74, eval { open FOO, "> $foo" } eq '', 'open for write'; test 75, $@ =~ /^Insecure dependency/, $@; diff --git a/t/op/universal.t b/t/op/universal.t index bd6c73afe9..bde78fd04c 100755 --- a/t/op/universal.t +++ b/t/op/universal.t @@ -75,7 +75,11 @@ test ! (eval { $a->VERSION(2.719) }) && test (eval { $a->VERSION(2.718) }) && ! $@; my $subs = join ' ', sort grep { defined &{"UNIVERSAL::$_"} } keys %UNIVERSAL::; -test $subs eq "VERSION can isa"; +if ('a' lt 'A') { + test $subs eq "can isa VERSION"; +} else { + test $subs eq "VERSION can isa"; +} test $a->isa("UNIVERSAL"); @@ -86,7 +90,11 @@ test $a->isa("UNIVERSAL"); my $sub2 = join ' ', sort grep { defined &{"UNIVERSAL::$_"} } keys %UNIVERSAL::; # XXX import being here is really a bug -test $sub2 eq "VERSION can import isa"; +if ('a' lt 'A') { + test $sub2 eq "can import isa VERSION"; +} else { + test $sub2 eq "VERSION can import isa"; +} eval 'sub UNIVERSAL::sleep {}'; test $a->can("sleep"); diff --git a/t/pragma/constant.t b/t/pragma/constant.t index 0095f3b627..0b58bae607 100755 --- a/t/pragma/constant.t +++ b/t/pragma/constant.t @@ -81,7 +81,7 @@ test 18, (COUNTLIST)[1] == 4; use constant ABC => 'ABC'; test 19, "abc${\( ABC )}abc" eq "abcABCabc"; -use constant DEF => 'D', "\x45", chr 70; +use constant DEF => 'D', 'E', chr ord 'F'; test 20, "d e f @{[ DEF ]} d e f" eq "d e f D E F d e f"; use constant SINGLE => "'"; diff --git a/t/pragma/overload.t b/t/pragma/overload.t index 05035c612d..afba8a3221 100755 --- a/t/pragma/overload.t +++ b/t/pragma/overload.t @@ -5,8 +5,6 @@ BEGIN { @INC = '../lib'; } -use Config; - package Oscalar; use overload ( # Anonymous subroutines: @@ -436,6 +434,265 @@ test($b, "_<oups1 >_"); # 134 test($c, "bareword"); # 135 +{ + package symbolic; # Primitive symbolic calculator + use overload nomethod => \&wrap, '""' => \&str, '0+' => \&num, + '=' => \&cpy, '++' => \&inc, '--' => \&dec; + + sub new { shift; bless ['n', @_] } + sub cpy { + my $self = shift; + bless [@$self], ref $self; + } + sub inc { $_[0] = bless ['++', $_[0], 1]; } + sub dec { $_[0] = bless ['--', $_[0], 1]; } + sub wrap { + my ($obj, $other, $inv, $meth) = @_; + if ($meth eq '++' or $meth eq '--') { + @$obj = ($meth, (bless [@$obj]), 1); # Avoid circular reference + return $obj; + } + ($obj, $other) = ($other, $obj) if $inv; + bless [$meth, $obj, $other]; + } + sub str { + my ($meth, $a, $b) = @{+shift}; + $a = 'u' unless defined $a; + if (defined $b) { + "[$meth $a $b]"; + } else { + "[$meth $a]"; + } + } + my %subr = ( 'n' => sub {$_[0]} ); + foreach my $op (split " ", $overload::ops{with_assign}) { + $subr{$op} = $subr{"$op="} = eval "sub {shift() $op shift()}"; + } + my @bins = qw(binary 3way_comparison num_comparison str_comparison); + foreach my $op (split " ", "@overload::ops{ @bins }") { + $subr{$op} = eval "sub {shift() $op shift()}"; + } + foreach my $op (split " ", "@overload::ops{qw(unary func)}") { + $subr{$op} = eval "sub {$op shift()}"; + } + $subr{'++'} = $subr{'+'}; + $subr{'--'} = $subr{'-'}; + + sub num { + my ($meth, $a, $b) = @{+shift}; + my $subr = $subr{$meth} + or die "Do not know how to ($meth) in symbolic"; + $a = $a->num if ref $a eq __PACKAGE__; + $b = $b->num if ref $b eq __PACKAGE__; + $subr->($a,$b); + } + sub TIESCALAR { my $pack = shift; $pack->new(@_) } + sub FETCH { shift } + sub nop { } # Around a bug + sub vars { my $p = shift; tie($_, $p), $_->nop foreach @_; } + sub STORE { + my $obj = shift; + $#$obj = 1; + @$obj->[0,1] = ('=', shift); + } +} + +{ + my $foo = new symbolic 11; + my $baz = $foo++; + test( (sprintf "%d", $foo), '12'); + test( (sprintf "%d", $baz), '11'); + my $bar = $foo; + $baz = ++$foo; + test( (sprintf "%d", $foo), '13'); + test( (sprintf "%d", $bar), '12'); + test( (sprintf "%d", $baz), '13'); + my $ban = $foo; + $baz = ($foo += 1); + test( (sprintf "%d", $foo), '14'); + test( (sprintf "%d", $bar), '12'); + test( (sprintf "%d", $baz), '14'); + test( (sprintf "%d", $ban), '13'); + $baz = 0; + $baz = $foo++; + test( (sprintf "%d", $foo), '15'); + test( (sprintf "%d", $baz), '14'); + test( "$foo", '[++ [+= [++ [++ [n 11] 1] 1] 1] 1]'); +} + +{ + my $iter = new symbolic 2; + my $side = new symbolic 1; + my $cnt = $iter; + + while ($cnt) { + $cnt = $cnt - 1; # The "simple" way + $side = (sqrt(1 + $side**2) - 1)/$side; + } + my $pi = $side*(2**($iter+2)); + test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]'; + test( (sprintf "%f", $pi), '3.182598'); +} + +{ + my $iter = new symbolic 2; + my $side = new symbolic 1; + my $cnt = $iter; + + while ($cnt--) { + $side = (sqrt(1 + $side**2) - 1)/$side; + } + my $pi = $side*(2**($iter+2)); + test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]'; + test( (sprintf "%f", $pi), '3.182598'); +} + +{ + my ($a, $b); + symbolic->vars($a, $b); + my $c = sqrt($a**2 + $b**2); + $a = 3; $b = 4; + test( (sprintf "%d", $c), '5'); + $a = 12; $b = 5; + test( (sprintf "%d", $c), '13'); +} + +{ + package symbolic1; # Primitive symbolic calculator + # Mutator inc/dec + use overload nomethod => \&wrap, '""' => \&str, '0+' => \&num, '=' => \&cpy; + + sub new { shift; bless ['n', @_] } + sub cpy { + my $self = shift; + bless [@$self], ref $self; + } + sub wrap { + my ($obj, $other, $inv, $meth) = @_; + if ($meth eq '++' or $meth eq '--') { + @$obj = ($meth, (bless [@$obj]), 1); # Avoid circular reference + return $obj; + } + ($obj, $other) = ($other, $obj) if $inv; + bless [$meth, $obj, $other]; + } + sub str { + my ($meth, $a, $b) = @{+shift}; + $a = 'u' unless defined $a; + if (defined $b) { + "[$meth $a $b]"; + } else { + "[$meth $a]"; + } + } + my %subr = ( 'n' => sub {$_[0]} ); + foreach my $op (split " ", $overload::ops{with_assign}) { + $subr{$op} = $subr{"$op="} = eval "sub {shift() $op shift()}"; + } + my @bins = qw(binary 3way_comparison num_comparison str_comparison); + foreach my $op (split " ", "@overload::ops{ @bins }") { + $subr{$op} = eval "sub {shift() $op shift()}"; + } + foreach my $op (split " ", "@overload::ops{qw(unary func)}") { + $subr{$op} = eval "sub {$op shift()}"; + } + $subr{'++'} = $subr{'+'}; + $subr{'--'} = $subr{'-'}; + + sub num { + my ($meth, $a, $b) = @{+shift}; + my $subr = $subr{$meth} + or die "Do not know how to ($meth) in symbolic"; + $a = $a->num if ref $a eq __PACKAGE__; + $b = $b->num if ref $b eq __PACKAGE__; + $subr->($a,$b); + } + sub TIESCALAR { my $pack = shift; $pack->new(@_) } + sub FETCH { shift } + sub nop { } # Around a bug + sub vars { my $p = shift; tie($_, $p), $_->nop foreach @_; } + sub STORE { + my $obj = shift; + $#$obj = 1; + @$obj->[0,1] = ('=', shift); + } +} + +{ + my $foo = new symbolic1 11; + my $baz = $foo++; + test( (sprintf "%d", $foo), '12'); + test( (sprintf "%d", $baz), '11'); + my $bar = $foo; + $baz = ++$foo; + test( (sprintf "%d", $foo), '13'); + test( (sprintf "%d", $bar), '12'); + test( (sprintf "%d", $baz), '13'); + my $ban = $foo; + $baz = ($foo += 1); + test( (sprintf "%d", $foo), '14'); + test( (sprintf "%d", $bar), '12'); + test( (sprintf "%d", $baz), '14'); + test( (sprintf "%d", $ban), '13'); + $baz = 0; + $baz = $foo++; + test( (sprintf "%d", $foo), '15'); + test( (sprintf "%d", $baz), '14'); + test( "$foo", '[++ [+= [++ [++ [n 11] 1] 1] 1] 1]'); +} + +{ + my $iter = new symbolic1 2; + my $side = new symbolic1 1; + my $cnt = $iter; + + while ($cnt) { + $cnt = $cnt - 1; # The "simple" way + $side = (sqrt(1 + $side**2) - 1)/$side; + } + my $pi = $side*(2**($iter+2)); + test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]'; + test( (sprintf "%f", $pi), '3.182598'); +} + +{ + my $iter = new symbolic1 2; + my $side = new symbolic1 1; + my $cnt = $iter; + + while ($cnt--) { + $side = (sqrt(1 + $side**2) - 1)/$side; + } + my $pi = $side*(2**($iter+2)); + test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]'; + test( (sprintf "%f", $pi), '3.182598'); +} + +{ + my ($a, $b); + symbolic1->vars($a, $b); + my $c = sqrt($a**2 + $b**2); + $a = 3; $b = 4; + test( (sprintf "%d", $c), '5'); + $a = 12; $b = 5; + test( (sprintf "%d", $c), '13'); +} + +{ + package two_face; # Scalars with separate string and + # numeric values. + sub new { my $p = shift; bless [@_], $p } + use overload '""' => \&str, '0+' => \&num, fallback => 1; + sub num {shift->[1]} + sub str {shift->[0]} +} + +{ + my $seven = new two_face ("vii", 7); + test( (sprintf "seven=$seven, seven=%d, eight=%d", $seven, $seven+1), + 'seven=vii, seven=7, eight=8'); + test( scalar ($seven =~ /i/), '1') +} # Last test is: -sub last {135} +sub last {173} diff --git a/t/pragma/subs.t b/t/pragma/subs.t index 056c4bd7cf..680564f843 100755 --- a/t/pragma/subs.t +++ b/t/pragma/subs.t @@ -55,6 +55,7 @@ for (@prgs){ # allow expected output to be written as if $prog is on STDIN $results =~ s/tmp\d+/-/g; $results =~ s/\n%[A-Z]+-[SIWEF]-.*$// if $Is_VMS; # clip off DCL status msg + $results =~ s/Syntax/syntax/; # non-standard yacc $expected =~ s/\n+$//; my $prefix = ($results =~ s/^PREFIX\n//) ; if ( $results =~ s/^SKIPPED\n//) { |