0e733ad994c973f637f30b0d7bd945766b7199a6
[p5sagit/p5-mst-13.2.git] / t / io / layers.t
1 #!./perl
2
3 my $PERLIO;
4
5 BEGIN {
6     chdir 't' if -d 't';
7     @INC = '../lib';
8     require './test.pl';
9     unless (find PerlIO::Layer 'perlio') {
10         print "1..0 # Skip: not perlio\n";
11         exit 0;
12     }
13     # Makes testing easier.
14     $ENV{PERLIO} = 'stdio' if exists $ENV{PERLIO} && $ENV{PERLIO} eq '';
15     if (exists $ENV{PERLIO} && $ENV{PERLIO} !~ /^(stdio|perlio|mmap)$/) {
16         # We are not prepared for anything else.
17         print "1..0 # PERLIO='$ENV{PERLIO}' unknown\n";
18         exit 0;
19     }
20     $PERLIO = exists $ENV{PERLIO} ? $ENV{PERLIO} : "(undef)";
21 }
22
23 plan tests => 43;
24
25 use Config;
26
27 my $DOSISH    = $^O =~ /^(?:MSWin32|cygwin|os2|dos|NetWare|mint)$/ ? 1 : 0;
28 my $NONSTDIO  = exists $ENV{PERLIO} && $ENV{PERLIO} ne 'stdio' ? 1 : 0;
29 my $FASTSTDIO =
30     $Config{d_stdstdio} &&
31     $Config{d_stdio_ptr_lval} &&
32     ($Config{d_stdio_cnt_lval} ||
33      $Config{d_stdio_ptr_lval_sets_cnt}) ? 1 : 0;
34
35 print <<__EOH__;
36 # PERLIO    = $PERLIO
37 # DOSISH    = $DOSISH
38 # NONSTDIO  = $NONSTDIO
39 # FASTSTDIO = $FASTSTDIO
40 __EOH__
41
42 SKIP: {
43     skip("This perl does not have Encode", 43)
44         unless " $Config{extensions} " =~ / Encode /;
45
46     sub check {
47         my ($result, $expected, $id) = @_;
48         # An interesting dance follows where we try to make the following
49         # IO layer stack setups to compare equal:
50         #
51         # PERLIO     UNIX-like       DOS-like
52         #
53         # none or "" stdio [1]       unix crlf
54         # stdio      stdio [1]       stdio
55         # perlio     unix perlio     unix perlio
56         # mmap       unix mmap       unix mmap
57         #
58         # [1] If Configure found how to do "fast stdio",
59         # otherwise it will be "unix perlio".
60         #
61         if ($NONSTDIO) {
62             # Get rid of "unix".
63             shift @$result if $result->[0] eq "unix";
64             # Change expectations.
65             if ($FASTSTDIO) {
66                 $expected->[0] = $ENV{PERLIO};
67             } else {
68                 $expected->[0] = $ENV{PERLIO} if $expected->[0] eq "stdio";
69             }
70         } elsif (!$FASTSTDIO) {
71             splice(@$result, 0, 2, "stdio")
72                 if @$result >= 2 &&
73                    $result->[0] eq "unix" &&
74                    $result->[1] eq "perlio";
75         } elsif ($DOSISH) {
76             splice(@$result, 0, 2, "stdio")
77                 if @$result >= 2 &&
78                    $result->[0] eq "unix" &&
79                    $result->[1] eq "crlf";
80         }
81         my $n = scalar @$expected;
82         is($n, scalar @$expected, "$id - layers = $n");
83         for (my $i = 0; $i < $n; $i++) {
84             my $j = $expected->[$i];
85             if (ref $j eq 'CODE') {
86                 ok($j->($result->[$i]), "$id - $i is ok");
87             } else {
88                 is($result->[$i], $j,
89                    sprintf("$id - $i is %s",
90                            defined $j ? $j : "undef"));
91             }
92         }
93     }
94
95     check([ PerlIO::get_layers(STDIN) ],
96           [ "stdio" ],
97           "STDIN");
98
99     open(F, ">:crlf", "afile");
100
101     check([ PerlIO::get_layers(F) ],
102           [ qw(stdio crlf) ],
103           "open :crlf");
104
105     binmode(F, ":encoding(sjis)"); # "sjis" will be canonized to "shiftjis"
106
107     check([ PerlIO::get_layers(F) ],
108           [ qw[stdio crlf encoding(shiftjis) utf8] ],
109           ":encoding(sjis)");
110     
111     binmode(F, ":pop");
112
113     check([ PerlIO::get_layers(F) ],
114           [ qw(stdio crlf) ],
115           ":pop");
116
117     binmode(F, ":raw");
118
119     check([ PerlIO::get_layers(F) ],
120           [ "stdio" ],
121           ":raw");
122
123     binmode(F, ":pop") if $DOSISH; # Drop one extra :crlf.
124     binmode(F, ":utf8");
125
126     check([ PerlIO::get_layers(F) ],
127           [ qw(stdio utf8) ],
128           ":utf8");
129
130     binmode(F, ":bytes");
131
132     check([ PerlIO::get_layers(F) ],
133           [ "stdio" ],
134           ":bytes");
135
136     binmode(F, ":encoding(utf8)");
137
138     check([ PerlIO::get_layers(F) ],
139             [ qw[stdio encoding(utf8) utf8] ],
140             ":encoding(utf8)");
141
142     binmode(F, ":raw :crlf");
143
144     check([ PerlIO::get_layers(F) ],
145           [ qw(stdio crlf) ],
146           ":raw:crlf");
147
148     binmode(F, ":raw :encoding(latin1)"); # "latin1" will be canonized
149
150     SKIP: {
151         skip("too complex layer coreography", 7) if $DOSISH || !$FASTSTDIO;
152
153         my @results = PerlIO::get_layers(F, details => 1);
154
155         # Get rid of the args and the flags.
156         splice(@results, 1, 2) if $NONSTDIO;
157
158         check([ @results ],
159               [ "stdio",    undef,        sub { $_[0] > 0 },
160                 "encoding", "iso-8859-1", sub { $_[0] & PerlIO::F_UTF8() } ],
161               ":raw:encoding(latin1)");
162     }
163
164     binmode(F);
165
166     check([ PerlIO::get_layers(F) ],
167           [ "stdio" ],
168           "binmode");
169
170     close F;
171
172     {
173         use open(IN => ":crlf", OUT => ":encoding(cp1252)");
174
175         open F, "<afile";
176         open G, ">afile";
177
178         check([ PerlIO::get_layers(F, input  => 1) ],
179               [ qw(stdio crlf) ],
180               "use open IN");
181         
182         check([ PerlIO::get_layers(G, output => 1) ],
183               [ qw[stdio encoding(cp1252) utf8] ],
184               "use open OUT");
185
186         close F;
187         close G;
188     }
189
190     1 while unlink "afile";
191 }