| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- #!./perl
- my $PERLIO;
- BEGIN {
- unshift @INC, 't/CORE/lib';
- require 't/CORE/test.pl';
- # Makes testing easier.
- $ENV{PERLIO} = 'stdio' if exists $ENV{PERLIO} && $ENV{PERLIO} eq '';
- skip_all("PERLIO='$ENV{PERLIO}' unknown")
- if exists $ENV{PERLIO} && $ENV{PERLIO} !~ /^(stdio|perlio|mmap)$/;
- $PERLIO = exists $ENV{PERLIO} ? $ENV{PERLIO} : "(undef)";
- }
- use Config;
- my $DOSISH = $^O =~ /^(?:MSWin32|os2|dos|NetWare)$/ ? 1 : 0;
- $DOSISH = 1 if !$DOSISH and $^O =~ /^uwin/;
- my $NONSTDIO = exists $ENV{PERLIO} && $ENV{PERLIO} ne 'stdio' ? 1 : 0;
- my $FASTSTDIO = $Config{d_faststdio} && $Config{usefaststdio} ? 1 : 0;
- my $UTF8_STDIN;
- if (${^UNICODE} & 1) {
- if (${^UNICODE} & 64) {
- # Conditional on the locale
- $UTF8_STDIN = ${^UTF8LOCALE};
- } else {
- # Unconditional
- $UTF8_STDIN = 1;
- }
- } else {
- $UTF8_STDIN = 0;
- }
- my $NTEST = 62 - (($DOSISH || !$FASTSTDIO) ? 7 : 0) - ($DOSISH ? 7 : 0)
- + $UTF8_STDIN;
- sub PerlIO::F_UTF8 () { 0x00008000 } # from perliol.h
- plan tests => $NTEST;
- print <<__EOH__;
- # PERLIO = $PERLIO
- # DOSISH = $DOSISH
- # NONSTDIO = $NONSTDIO
- # FASTSTDIO = $FASTSTDIO
- # UNICODE = ${^UNICODE}
- # UTF8LOCALE = ${^UTF8LOCALE}
- # UTF8_STDIN = $UTF8_STDIN
- __EOH__
- {
- sub check {
- my ($result, $expected, $id) = @_;
- # An interesting dance follows where we try to make the following
- # IO layer stack setups to compare equal:
- #
- # PERLIO UNIX-like DOS-like
- #
- # unset / "" unix perlio / stdio [1] unix crlf
- # stdio unix perlio / stdio [1] stdio
- # perlio unix perlio unix perlio
- # mmap unix mmap unix mmap
- #
- # [1] "stdio" if Configure found out how to do "fast stdio" (depends
- # on the stdio implementation) and in Perl 5.8, otherwise "unix perlio"
- #
- if ($NONSTDIO) {
- # Get rid of "unix".
- shift @$result if $result->[0] eq "unix";
- # Change expectations.
- if ($FASTSTDIO) {
- $expected->[0] = $ENV{PERLIO};
- } else {
- $expected->[0] = $ENV{PERLIO} if $expected->[0] eq "stdio";
- }
- } elsif (!$FASTSTDIO && !$DOSISH) {
- splice(@$result, 0, 2, "stdio")
- if @$result >= 2 &&
- $result->[0] eq "unix" &&
- $result->[1] eq "perlio";
- } elsif ($DOSISH) {
- splice(@$result, 0, 2, "stdio")
- if @$result >= 2 &&
- $result->[0] eq "unix" &&
- $result->[1] eq "crlf";
- }
- if ($DOSISH && grep { $_ eq 'crlf' } @$expected) {
- # 5 tests potentially skipped because
- # DOSISH systems already have a CRLF layer
- # which will make new ones not stick.
- splice @$expected, 1, 1 if $expected->[1] eq 'crlf';
- }
- my $n = scalar @$expected;
- is(scalar @$result, $n, "$id - layers == $n");
- for (my $i = 0; $i < $n; $i++) {
- my $j = $expected->[$i];
- if (ref $j eq 'CODE') {
- ok($j->($result->[$i]), "$id - $i is ok");
- } else {
- is($result->[$i], $j,
- sprintf("$id - $i is %s",
- defined $j ? $j : "undef"));
- }
- }
- }
- check([ PerlIO::get_layers(STDIN) ],
- $UTF8_STDIN ? [ "stdio", "utf8" ] : [ "stdio" ],
- "STDIN");
- my $afile = tempfile();
- open(F, ">:crlf", $afile);
- check([ PerlIO::get_layers(F) ],
- [ qw(stdio crlf) ],
- "open :crlf");
- binmode(F, ":crlf");
- check([ PerlIO::get_layers(F) ],
- [ qw(stdio crlf) ],
- "binmode :crlf");
- binmode(F, ":encoding(cp1047)");
- check([ PerlIO::get_layers(F) ],
- [ qw[stdio crlf encoding(cp1047) utf8] ],
- ":encoding(cp1047)");
- binmode(F, ":crlf");
- check([ PerlIO::get_layers(F) ],
- [ qw[stdio crlf encoding(cp1047) utf8 crlf utf8] ],
- ":encoding(cp1047):crlf");
-
- binmode(F, ":pop:pop");
- check([ PerlIO::get_layers(F) ],
- [ qw(stdio crlf) ],
- ":pop");
- binmode(F, ":raw");
- check([ PerlIO::get_layers(F) ],
- [ "stdio" ],
- ":raw");
- binmode(F, ":utf8");
- check([ PerlIO::get_layers(F) ],
- [ qw(stdio utf8) ],
- ":utf8");
- binmode(F, ":bytes");
- check([ PerlIO::get_layers(F) ],
- [ "stdio" ],
- ":bytes");
- binmode(F, ":encoding(utf8)");
- check([ PerlIO::get_layers(F) ],
- [ qw[stdio encoding(utf8) utf8] ],
- ":encoding(utf8)");
- binmode(F, ":raw :crlf");
- check([ PerlIO::get_layers(F) ],
- [ qw(stdio crlf) ],
- ":raw:crlf");
- binmode(F, ":raw :encoding(latin1)"); # "latin1" will be canonized
- # 7 tests potentially skipped.
- unless ($DOSISH || !$FASTSTDIO) {
- my @results = PerlIO::get_layers(F, details => 1);
- # Get rid of the args and the flags.
- splice(@results, 1, 2) if $NONSTDIO;
- check([ @results ],
- [ "stdio", undef, sub { $_[0] > 0 },
- "encoding", "iso-8859-1", sub { $_[0] & PerlIO::F_UTF8() } ],
- ":raw:encoding(latin1)");
- }
- binmode(F);
- check([ PerlIO::get_layers(F) ],
- [ "stdio" ],
- "binmode");
- # RT78844
- {
- local $@ = "foo";
- binmode(F, ":encoding(utf8)");
- is( $@, "foo", '$@ not clobbered by binmode and :encoding');
- }
- close F;
- {
- use open(IN => ":crlf", OUT => ":encoding(cp1252)");
- open F, '<', $afile;
- open G, '>', $afile;
- diag ("perlcc issue 203"); # https://code.google.com/p/perl-compiler/issues/detail?id=203
- check([ PerlIO::get_layers(F, input => 1) ],
- [ qw(stdio crlf) ],
- "use open IN");
-
- check([ PerlIO::get_layers(G, output => 1) ],
- [ qw[stdio encoding(cp1252) utf8] ],
- "use open OUT");
- close F;
- close G;
- }
- # Check that PL_sigwarn's reference count is correct, and that
- # &PerlIO::Layer::NoWarnings isn't prematurely freed.
- fresh_perl_like (<<"EOT", qr/^CODE/);
- open(UTF, "<:raw:encoding(utf8)", '$afile') or die \$!;
- print ref *PerlIO::Layer::NoWarnings{CODE};
- EOT
- # TODO: not with 5.14
- # [perl #97956] Not calling FETCH all the time on tied variables
- my $f;
- sub TIESCALAR { bless [] }
- sub FETCH { ++$f; $_[0][0] = $_[1] }
- sub STORE { $_[0][0] }
- tie my $t, "";
- SKIP: {
- skip("requires 5.16", 3) if $] < 5.016;
- $t = *f;
- $f = 0; PerlIO::get_layers $t;
- is $f, 1, '1 fetch on tied glob';
- $t = \*f;
- $f = 0; PerlIO::get_layers $t;
- is $f, 1, '1 fetch on tied globref';
- $t = *f;
- $f = 0; PerlIO::get_layers \$t;
- is $f, 1, '1 fetch on referenced tied glob';
- }
- $t = '';
- $f = 0; PerlIO::get_layers $t;
- is $f, 1, '1 fetch on tied string';
- SKIP: {
- skip("requires 5.16", 3) if $] < 5.016;
- # No distinction between nums and strings
- open "12", "<:crlf", "t/test.pl" or die "$0 cannot open t/test.pl: $!";
- ok PerlIO::get_layers(12), 'str/num arguments are treated identically';
- }
- }
|