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