Commit | Line | Data |
7d59b7e4 |
1 | #!./perl |
2 | |
3 | BEGIN { |
4 | chdir 't' if -d 't'; |
5 | @INC = '../lib'; |
0c4f7ff0 |
6 | unless (find PerlIO::Layer 'perlio') { |
7d59b7e4 |
7 | print "1..0 # Skip: not perlio\n"; |
8 | exit 0; |
9 | } |
10 | } |
11 | |
169da838 |
12 | no utf8; # needed for use utf8 not griping about the raw octets |
3ba0e062 |
13 | |
bb4e15c8 |
14 | require "./test.pl"; |
15 | |
16 | plan(tests => 49); |
17 | |
7d59b7e4 |
18 | $| = 1; |
7d59b7e4 |
19 | |
20 | open(F,"+>:utf8",'a'); |
21 | print F chr(0x100).'£'; |
bb4e15c8 |
22 | ok( tell(F) == 4, tell(F) ); |
7d59b7e4 |
23 | print F "\n"; |
bb4e15c8 |
24 | ok( tell(F) >= 5, tell(F) ); |
7d59b7e4 |
25 | seek(F,0,0); |
bb4e15c8 |
26 | ok( getc(F) eq chr(0x100) ); |
27 | ok( getc(F) eq "£" ); |
28 | ok( getc(F) eq "\n" ); |
7d59b7e4 |
29 | seek(F,0,0); |
30 | binmode(F,":bytes"); |
d2f5bb60 |
31 | my $chr = chr(0xc4); |
32 | if (ord('A') == 193) { $chr = chr(0x8c); } # EBCDIC |
bb4e15c8 |
33 | ok( getc(F) eq $chr ); |
d2f5bb60 |
34 | $chr = chr(0x80); |
35 | if (ord('A') == 193) { $chr = chr(0x41); } # EBCDIC |
bb4e15c8 |
36 | ok( getc(F) eq $chr ); |
d2f5bb60 |
37 | $chr = chr(0xc2); |
38 | if (ord('A') == 193) { $chr = chr(0x80); } # EBCDIC |
bb4e15c8 |
39 | ok( getc(F) eq $chr ); |
d2f5bb60 |
40 | $chr = chr(0xa3); |
41 | if (ord('A') == 193) { $chr = chr(0x44); } # EBCDIC |
bb4e15c8 |
42 | ok( getc(F) eq $chr ); |
43 | ok( getc(F) eq "\n" ); |
7d59b7e4 |
44 | seek(F,0,0); |
45 | binmode(F,":utf8"); |
bb4e15c8 |
46 | ok( scalar(<F>) eq "\x{100}£\n" ); |
eb5c063a |
47 | seek(F,0,0); |
48 | $buf = chr(0x200); |
49 | $count = read(F,$buf,2,1); |
bb4e15c8 |
50 | ok( $count == 2 ); |
51 | ok( $buf eq "\x{200}\x{100}£" ); |
7d59b7e4 |
52 | close(F); |
53 | |
360eb788 |
54 | { |
7b89fb7c |
55 | $a = chr(300); # This *is* UTF-encoded |
56 | $b = chr(130); # This is not. |
6874a2de |
57 | |
7b89fb7c |
58 | open F, ">:utf8", 'a' or die $!; |
59 | print F $a,"\n"; |
60 | close F; |
6874a2de |
61 | |
7b89fb7c |
62 | open F, "<:utf8", 'a' or die $!; |
63 | $x = <F>; |
64 | chomp($x); |
bb4e15c8 |
65 | ok( $x eq chr(300) ); |
6874a2de |
66 | |
7b89fb7c |
67 | open F, "a" or die $!; # Not UTF |
68 | binmode(F, ":bytes"); |
69 | $x = <F>; |
70 | chomp($x); |
71 | $chr = chr(196).chr(172); |
72 | if (ord('A') == 193) { $chr = chr(141).chr(83); } # EBCDIC |
bb4e15c8 |
73 | ok( $x eq $chr ); |
7b89fb7c |
74 | close F; |
6874a2de |
75 | |
7b89fb7c |
76 | open F, ">:utf8", 'a' or die $!; |
77 | binmode(F); # we write a "\n" and then tell() - avoid CRLF issues. |
6874a2de |
78 | binmode(F,":utf8"); # turn UTF-8-ness back on |
7b89fb7c |
79 | print F $a; |
80 | my $y; |
81 | { my $x = tell(F); |
82 | { use bytes; $y = length($a);} |
bb4e15c8 |
83 | ok( $x == $y ); |
7b89fb7c |
84 | } |
6874a2de |
85 | |
7b89fb7c |
86 | { # Check byte length of $b |
87 | use bytes; my $y = length($b); |
bb4e15c8 |
88 | ok( $y == 1 ); |
7b89fb7c |
89 | } |
6874a2de |
90 | |
7b89fb7c |
91 | print F $b,"\n"; # Don't upgrades $b |
6874a2de |
92 | |
7b89fb7c |
93 | { # Check byte length of $b |
94 | use bytes; my $y = length($b); |
bb4e15c8 |
95 | ok( $y == 1 ); |
7b89fb7c |
96 | } |
6874a2de |
97 | |
7b89fb7c |
98 | { |
99 | my $x = tell(F); |
100 | { use bytes; if (ord('A')==193){$y += 2;}else{$y += 3;}} # EBCDIC ASCII |
bb4e15c8 |
101 | ok( $x == $y ); |
7b89fb7c |
102 | } |
6874a2de |
103 | |
7b89fb7c |
104 | close F; |
6874a2de |
105 | |
7b89fb7c |
106 | open F, "a" or die $!; # Not UTF |
107 | binmode(F, ":bytes"); |
108 | $x = <F>; |
109 | chomp($x); |
110 | $chr = v196.172.194.130; |
111 | if (ord('A') == 193) { $chr = v141.83.130; } # EBCDIC |
bb4e15c8 |
112 | ok( $x eq $chr, sprintf('(%vd)', $x) ); |
6874a2de |
113 | |
7b89fb7c |
114 | open F, "<:utf8", "a" or die $!; |
115 | $x = <F>; |
116 | chomp($x); |
117 | close F; |
bb4e15c8 |
118 | ok( $x eq chr(300).chr(130), sprintf('(%vd)', $x) ); |
6874a2de |
119 | |
3eb9224a |
120 | open F, ">", "a" or die $!; |
7b89fb7c |
121 | if (${^OPEN} =~ /:utf8/) { |
122 | binmode(F, ":bytes:"); |
123 | } |
124 | |
125 | # Now let's make it suffer. |
3eb9224a |
126 | my $w; |
127 | { |
128 | use warnings 'utf8'; |
129 | local $SIG{__WARN__} = sub { $w = $_[0] }; |
130 | print F $a; |
bb4e15c8 |
131 | ok( !($@ || $w !~ /Wide character in print/i) ); |
3eb9224a |
132 | } |
54d2e5f1 |
133 | } |
360eb788 |
134 | |
135 | # Hm. Time to get more evil. |
136 | open F, ">:utf8", "a" or die $!; |
137 | print F $a; |
138 | binmode(F, ":bytes"); |
139 | print F chr(130)."\n"; |
140 | close F; |
6874a2de |
141 | |
360eb788 |
142 | open F, "<", "a" or die $!; |
3eb9224a |
143 | binmode(F, ":bytes"); |
360eb788 |
144 | $x = <F>; chomp $x; |
d2f5bb60 |
145 | $chr = v196.172.130; |
146 | if (ord('A') == 193) { $chr = v141.83.130; } # EBCDIC |
bb4e15c8 |
147 | ok( $x eq $chr ); |
360eb788 |
148 | |
149 | # Right. |
150 | open F, ">:utf8", "a" or die $!; |
151 | print F $a; |
152 | close F; |
153 | open F, ">>", "a" or die $!; |
154 | print F chr(130)."\n"; |
155 | close F; |
156 | |
157 | open F, "<", "a" or die $!; |
158 | $x = <F>; chomp $x; |
bb4e15c8 |
159 | ok( $x eq $chr ); |
360eb788 |
160 | |
161 | # Now we have a deformed file. |
d0965105 |
162 | |
163 | if (ord('A') == 193) { |
bb4e15c8 |
164 | skip( "EBCDIC doesn't complain" ); |
d0965105 |
165 | } else { |
166 | open F, "<:utf8", "a" or die $!; |
167 | $x = <F>; chomp $x; |
bb4e15c8 |
168 | local $SIG{__WARN__} = sub { ok( 1 ) }; |
d0965105 |
169 | eval { sprintf "%vd\n", $x }; |
360eb788 |
170 | } |
171 | |
4f0c37ba |
172 | close F; |
360eb788 |
173 | unlink('a'); |
7d59b7e4 |
174 | |
62961d2e |
175 | open F, ">:utf8", "a"; |
d0965105 |
176 | @a = map { chr(1 << ($_ << 2)) } 0..5; # 0x1, 0x10, .., 0x100000 |
c36dfd09 |
177 | unshift @a, chr(0); # ... and a null byte in front just for fun |
d0965105 |
178 | print F @a; |
179 | close F; |
c36dfd09 |
180 | |
c88828dc |
181 | my $c; |
182 | |
183 | # read() should work on characters, not bytes |
d0965105 |
184 | open F, "<:utf8", "a"; |
185 | $a = 0; |
186 | for (@a) { |
c88828dc |
187 | unless (($c = read(F, $b, 1) == 1) && |
188 | length($b) == 1 && |
189 | ord($b) == ord($_) && |
190 | tell(F) == ($a += bytes::length($b))) { |
34fce102 |
191 | print '# ord($_) == ', ord($_), "\n"; |
192 | print '# ord($b) == ', ord($b), "\n"; |
193 | print '# length($b) == ', length($b), "\n"; |
194 | print '# bytes::length($b) == ', bytes::length($b), "\n"; |
195 | print '# tell(F) == ', tell(F), "\n"; |
196 | print '# $a == ', $a, "\n"; |
197 | print '# $c == ', $c, "\n"; |
d0965105 |
198 | print "not "; |
199 | last; |
200 | } |
201 | } |
c36dfd09 |
202 | close F; |
bb4e15c8 |
203 | ok( 1 ); |
d0965105 |
204 | |
62961d2e |
205 | { |
206 | # Check that warnings are on on I/O, and that they can be muffled. |
207 | |
208 | local $SIG{__WARN__} = sub { $@ = shift }; |
209 | |
210 | undef $@; |
211 | open F, ">a"; |
3eb9224a |
212 | binmode(F, ":bytes"); |
62961d2e |
213 | print F chr(0x100); |
214 | close(F); |
215 | |
bb4e15c8 |
216 | like( $@, 'Wide character in print' ); |
62961d2e |
217 | |
218 | undef $@; |
2b1ff55a |
219 | open F, ">:utf8", "a"; |
62961d2e |
220 | print F chr(0x100); |
221 | close(F); |
222 | |
bb4e15c8 |
223 | isnt( defined $@ ); |
62961d2e |
224 | |
225 | undef $@; |
226 | open F, ">a"; |
227 | binmode(F, ":utf8"); |
228 | print F chr(0x100); |
229 | close(F); |
230 | |
bb4e15c8 |
231 | isnt( defined $@ ); |
62961d2e |
232 | |
233 | no warnings 'utf8'; |
234 | |
235 | undef $@; |
236 | open F, ">a"; |
237 | print F chr(0x100); |
238 | close(F); |
239 | |
bb4e15c8 |
240 | isnt( defined $@ ); |
62961d2e |
241 | |
242 | use warnings 'utf8'; |
243 | |
244 | undef $@; |
245 | open F, ">a"; |
3eb9224a |
246 | binmode(F, ":bytes"); |
62961d2e |
247 | print F chr(0x100); |
248 | close(F); |
249 | |
bb4e15c8 |
250 | like( $@, 'Wide character in print' ); |
62961d2e |
251 | } |
252 | |
efd8b2ba |
253 | { |
254 | open F, ">:bytes","a"; print F "\xde"; close F; |
255 | |
256 | open F, "<:bytes", "a"; |
257 | my $b = chr 0x100; |
258 | $b .= <F>; |
bb4e15c8 |
259 | ok( $b eq chr(0x100).chr(0xde), "21395 '.= <>' utf8 vs. bytes" ); |
efd8b2ba |
260 | close F; |
261 | } |
262 | |
263 | { |
264 | open F, ">:utf8","a"; print F chr 0x100; close F; |
265 | |
266 | open F, "<:utf8", "a"; |
267 | my $b = "\xde"; |
268 | $b .= <F>; |
bb4e15c8 |
269 | ok( $b eq chr(0xde).chr(0x100), "21395 '.= <>' bytes vs. utf8" ); |
efd8b2ba |
270 | close F; |
271 | } |
272 | |
b5d30a84 |
273 | { |
274 | my @a = ( [ 0x007F, "bytes" ], |
275 | [ 0x0080, "bytes" ], |
276 | [ 0x0080, "utf8" ], |
277 | [ 0x0100, "utf8" ] ); |
278 | my $t = 34; |
279 | for my $u (@a) { |
280 | for my $v (@a) { |
281 | # print "# @$u - @$v\n"; |
282 | open F, ">a"; |
283 | binmode(F, ":" . $u->[1]); |
284 | print F chr($u->[0]); |
285 | close F; |
286 | |
287 | open F, "<a"; |
288 | binmode(F, ":" . $u->[1]); |
289 | |
290 | my $s = chr($v->[0]); |
291 | utf8::upgrade($s) if $v->[1] eq "utf8"; |
292 | |
293 | $s .= <F>; |
38295cca |
294 | ok( $s eq chr($v->[0]) . chr($u->[0]), 'rcatline utf8' ); |
b5d30a84 |
295 | close F; |
296 | $t++; |
297 | } |
298 | } |
11c2f0cf |
299 | # last test here 49 |
b5d30a84 |
300 | } |
301 | |
e111333b |
302 | # sysread() and syswrite() tested in lib/open.t since Fnctl is used |
c88828dc |
303 | |
304 | END { |
305 | 1 while unlink "a"; |
306 | 1 while unlink "b"; |
307 | } |
e111333b |
308 | |