Add a test for for PerlIO ":encoding(...)" layer.
[p5sagit/p5-mst-13.2.git] / lib / open.pm
CommitLineData
d1edabcf 1package open;
ac27b0f5 2use Carp;
16fe6d59 3$open::hint_bits = 0x20000;
4
0c4f7ff0 5our $VERSION = '1.01';
b75c8c73 6
58d53262 7my $locale_encoding;
8
9sub in_locale { $^H & $locale::hint_bits }
10
11sub _get_locale_encoding {
12 unless (defined $locale_encoding) {
13 eval { use I18N::Langinfo qw(langinfo CODESET) };
14 unless ($@) {
15 $locale_encoding = langinfo(CODESET);
16 }
11fc5dc3 17 my $country_language;
58d53262 18 if (not $locale_encoding && in_locale()) {
11fc5dc3 19 if ($ENV{LC_ALL} =~ /^([^.]+)\.([^.]+)$/) {
20 ($country_language, $locale_encoding) = ($1, $2);
21 } elsif ($ENV{LANG} =~ /^([^.]+)\.([^.]+)$/) {
22 ($country_language, $locale_encoding) = ($1, $2);
58d53262 23 }
24 } else {
25 # Could do heuristics based on the country and language
26 # parts of LC_ALL and LANG (the parts before the dot (if any)),
27 # since we have Locale::Country and Locale::Language available.
28 # TODO: get a database of Language -> Encoding mappings
29 # (the Estonian database would be excellent!)
30 # --jhi
31 }
11fc5dc3 32 if (defined $locale_encoding &&
33 $locale_encoding eq 'euc' &&
34 defined $country_language) {
35 if ($country_language =~ /^ja_JP|japan(?:ese)$/i) {
36 $locale_encoding = 'eucjp';
37 } elsif ($country_language =~ /^ko_KR|korea(?:n)$/i) {
38 $locale_encoding = 'euckr';
39 } elsif ($country_language =~ /^zh_TW|taiwan(?:ese)$/i) {
40 $locale_encoding = 'euctw';
41 }
42 croak "Locale encoding 'euc' too ambiguous"
43 if $locale_encoding eq 'euc';
44 }
58d53262 45 }
46}
47
16fe6d59 48sub import {
dfebf958 49 my ($class,@args) = @_;
50 croak("`use open' needs explicit list of disciplines") unless @args;
16fe6d59 51 $^H |= $open::hint_bits;
ac27b0f5 52 my ($in,$out) = split(/\0/,(${^OPEN} || '\0'));
53 my @in = split(/\s+/,$in);
54 my @out = split(/\s+/,$out);
dfebf958 55 while (@args) {
56 my $type = shift(@args);
57 my $discp = shift(@args);
ac27b0f5 58 my @val;
dfebf958 59 foreach my $layer (split(/\s+/,$discp)) {
60 $layer =~ s/^://;
58d53262 61 if ($layer eq 'locale') {
62 use Encode;
63 _get_locale_encoding()
64 unless defined $locale_encoding;
65 croak "Cannot figure out an encoding to use"
66 unless defined $locale_encoding;
11fc5dc3 67 if ($locale_encoding =~ /^utf-?8$/i) {
68 $layer = "utf8";
69 } else {
70 $layer = "encoding($locale_encoding)";
71 }
58d53262 72 }
0c4f7ff0 73 unless(PerlIO::Layer::->find($layer)) {
dfebf958 74 carp("Unknown discipline layer '$layer'");
ac27b0f5 75 }
76 push(@val,":$layer");
77 if ($layer =~ /^(crlf|raw)$/) {
78 $^H{"open_$type"} = $layer;
16fe6d59 79 }
ac27b0f5 80 }
81 if ($type eq 'IN') {
82 $in = join(' ',@val);
83 }
84 elsif ($type eq 'OUT') {
85 $out = join(' ',@val);
16fe6d59 86 }
f3b00462 87 elsif ($type eq 'INOUT') {
88 $in = $out = join(' ',@val);
89 }
16fe6d59 90 else {
ac27b0f5 91 croak "Unknown discipline class '$type'";
16fe6d59 92 }
93 }
ac27b0f5 94 ${^OPEN} = join('\0',$in,$out);
16fe6d59 95}
96
971;
98__END__
d1edabcf 99
100=head1 NAME
101
102open - perl pragma to set default disciplines for input and output
103
104=head1 SYNOPSIS
105
16fe6d59 106 use open IN => ":crlf", OUT => ":raw";
f3b00462 107 use open INOUT => ":utf8";
d1edabcf 108
109=head1 DESCRIPTION
110
d151aa0e 111Full-fledged support for I/O disciplines is now implemented provided
112Perl is configured to use PerlIO as its IO system (which is now the
113default).
16fe6d59 114
7d3b96bb 115The C<open> pragma serves as one of the interfaces to declare default
116"layers" (aka disciplines) for all I/O.
117
118The C<open> pragma is used to declare one or more default layers for
d151aa0e 119I/O operations. Any open(), readpipe() (aka qx//) and similar
120operators found within the lexical scope of this pragma will use the
121declared defaults.
7d3b96bb 122
d151aa0e 123When open() is given an explicit list of layers they are appended to
124the list declared using this pragma.
7d3b96bb 125
126Directory handles may also support disciplines in future.
127
128=head1 NONPERLIO FUNCTIONALITY
129
d151aa0e 130If Perl is not built to use PerlIO as its IO system then only the two
131pseudo-disciplines ":raw" and ":crlf" are available.
16fe6d59 132
133The ":raw" discipline corresponds to "binary mode" and the ":crlf"
134discipline corresponds to "text mode" on platforms that distinguish
135between the two modes when opening files (which is many DOS-like
d151aa0e 136platforms, including Windows). These two disciplines are no-ops on
137platforms where binmode() is a no-op, but perform their functions
138everywhere if PerlIO is enabled.
7d3b96bb 139
140=head1 IMPLEMENTATION DETAILS
d1edabcf 141
f3b00462 142There is a class method in C<PerlIO::Layer> C<find> which is
143implemented as XS code. It is called by C<import> to validate the
144layers:
0c4f7ff0 145
146 PerlIO::Layer::->find("perlio")
147
f3b00462 148The return value (if defined) is a Perl object, of class
149C<PerlIO::Layer> which is created by the C code in F<perlio.c>. As
150yet there is nothing useful you can do with the object at the perl
151level.
16fe6d59 152
d1edabcf 153=head1 SEE ALSO
154
7d3b96bb 155L<perlfunc/"binmode">, L<perlfunc/"open">, L<perlunicode>, L<PerlIO>
d1edabcf 156
157=cut