line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# $Id: encoding.pm,v 2.20 2017/06/10 17:23:50 dankogai Exp $ |
2
|
|
|
|
|
|
|
package encoding; |
3
|
|
|
|
|
|
|
our $VERSION = sprintf "%d.%02d", q$Revision: 2.20 $ =~ /(\d+)/g; |
4
|
|
|
|
|
|
|
|
5
|
7
|
|
|
7
|
|
82534
|
use Encode; |
|
7
|
|
|
|
|
39
|
|
|
7
|
|
|
|
|
827
|
|
6
|
7
|
|
|
7
|
|
68
|
use strict; |
|
7
|
|
|
|
|
21
|
|
|
7
|
|
|
|
|
211
|
|
7
|
7
|
|
|
7
|
|
49
|
use warnings; |
|
7
|
|
|
|
|
19
|
|
|
7
|
|
|
|
|
230
|
|
8
|
7
|
|
|
7
|
|
53
|
use Config; |
|
7
|
|
|
|
|
19
|
|
|
7
|
|
|
|
|
720
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
use constant { |
11
|
|
|
|
|
|
|
DEBUG => !!$ENV{PERL_ENCODE_DEBUG}, |
12
|
7
|
|
33
|
|
|
24
|
HAS_PERLIO => eval { require PerlIO::encoding; PerlIO::encoding->VERSION(0.02) }, |
|
7
|
|
|
|
|
4229
|
|
|
7
|
|
|
|
|
6537
|
|
13
|
|
|
|
|
|
|
PERL_5_21_7 => $^V && $^V ge v5.21.7, # lexically scoped |
14
|
7
|
|
|
7
|
|
56
|
}; |
|
7
|
|
|
|
|
20
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
sub _exception { |
17
|
8
|
|
|
8
|
|
27
|
my $name = shift; |
18
|
8
|
50
|
|
|
|
63
|
$] > 5.008 and return 0; # 5.8.1 or higher then no |
19
|
0
|
|
|
|
|
0
|
my %utfs = map { $_ => 1 } |
|
0
|
|
|
|
|
0
|
|
20
|
|
|
|
|
|
|
qw(utf8 UCS-2BE UCS-2LE UTF-16 UTF-16BE UTF-16LE |
21
|
|
|
|
|
|
|
UTF-32 UTF-32BE UTF-32LE); |
22
|
0
|
0
|
|
|
|
0
|
$utfs{$name} or return 0; # UTFs or no |
23
|
0
|
|
|
|
|
0
|
require Config; |
24
|
0
|
|
|
|
|
0
|
Config->import(); |
25
|
0
|
|
|
|
|
0
|
our %Config; |
26
|
0
|
0
|
|
|
|
0
|
return $Config{perl_patchlevel} ? 0 : 1 # maintperl then no |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
0
|
|
0
|
0
|
0
|
0
|
sub in_locale { $^H & ( $locale::hint_bits || 0 ) } |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub _get_locale_encoding { |
32
|
1
|
|
|
1
|
|
11
|
my $locale_encoding; |
33
|
|
|
|
|
|
|
|
34
|
1
|
50
|
|
|
|
8
|
if ($^O eq 'MSWin32') { |
35
|
0
|
|
|
|
|
0
|
my @tries = ( |
36
|
|
|
|
|
|
|
# First try to get the OutputCP. This will work only if we |
37
|
|
|
|
|
|
|
# are attached to a console |
38
|
|
|
|
|
|
|
'Win32.pm' => 'Win32::GetConsoleOutputCP', |
39
|
|
|
|
|
|
|
'Win32/Console.pm' => 'Win32::Console::OutputCP', |
40
|
|
|
|
|
|
|
# If above failed, this means that we are a GUI app |
41
|
|
|
|
|
|
|
# Let's assume that the ANSI codepage is what matters |
42
|
|
|
|
|
|
|
'Win32.pm' => 'Win32::GetACP', |
43
|
|
|
|
|
|
|
); |
44
|
0
|
|
|
|
|
0
|
while (@tries) { |
45
|
0
|
|
|
|
|
0
|
my $cp = eval { |
46
|
0
|
|
|
|
|
0
|
require $tries[0]; |
47
|
7
|
|
|
7
|
|
67
|
no strict 'refs'; |
|
7
|
|
|
|
|
20
|
|
|
7
|
|
|
|
|
4746
|
|
48
|
0
|
|
|
|
|
0
|
&{$tries[1]}() |
|
0
|
|
|
|
|
0
|
|
49
|
|
|
|
|
|
|
}; |
50
|
0
|
0
|
|
|
|
0
|
if ($cp) { |
51
|
0
|
0
|
|
|
|
0
|
if ($cp == 65001) { # Code page for UTF-8 |
52
|
0
|
|
|
|
|
0
|
$locale_encoding = 'UTF-8'; |
53
|
|
|
|
|
|
|
} else { |
54
|
0
|
|
|
|
|
0
|
$locale_encoding = 'cp' . $cp; |
55
|
|
|
|
|
|
|
} |
56
|
0
|
|
|
|
|
0
|
return $locale_encoding; |
57
|
|
|
|
|
|
|
} |
58
|
0
|
|
|
|
|
0
|
splice(@tries, 0, 2) |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# I18N::Langinfo isn't available everywhere |
63
|
1
|
|
|
|
|
3
|
$locale_encoding = eval { |
64
|
1
|
|
|
|
|
633
|
require I18N::Langinfo; |
65
|
1
|
|
|
|
|
757
|
find_encoding( |
66
|
|
|
|
|
|
|
I18N::Langinfo::langinfo( I18N::Langinfo::CODESET() ) |
67
|
|
|
|
|
|
|
)->name |
68
|
|
|
|
|
|
|
}; |
69
|
1
|
50
|
|
|
|
9
|
return $locale_encoding if defined $locale_encoding; |
70
|
|
|
|
|
|
|
|
71
|
0
|
|
|
|
|
0
|
eval { |
72
|
0
|
|
|
|
|
0
|
require POSIX; |
73
|
|
|
|
|
|
|
# Get the current locale |
74
|
|
|
|
|
|
|
# Remember that MSVCRT impl is quite different from Unixes |
75
|
0
|
|
|
|
|
0
|
my $locale = POSIX::setlocale(POSIX::LC_CTYPE()); |
76
|
0
|
0
|
|
|
|
0
|
if ( $locale =~ /^([^.]+)\.([^.@]+)(?:@.*)?$/ ) { |
77
|
0
|
|
|
|
|
0
|
my $country_language; |
78
|
0
|
|
|
|
|
0
|
( $country_language, $locale_encoding ) = ( $1, $2 ); |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# Could do more heuristics based on the country and language |
81
|
|
|
|
|
|
|
# since we have Locale::Country and Locale::Language available. |
82
|
|
|
|
|
|
|
# TODO: get a database of Language -> Encoding mappings |
83
|
|
|
|
|
|
|
# (the Estonian database at http://www.eki.ee/letter/ |
84
|
|
|
|
|
|
|
# would be excellent!) --jhi |
85
|
0
|
0
|
|
|
|
0
|
if (lc($locale_encoding) eq 'euc') { |
86
|
0
|
0
|
|
|
|
0
|
if ( $country_language =~ /^ja_JP|japan(?:ese)?$/i ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
87
|
0
|
|
|
|
|
0
|
$locale_encoding = 'euc-jp'; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
elsif ( $country_language =~ /^ko_KR|korean?$/i ) { |
90
|
0
|
|
|
|
|
0
|
$locale_encoding = 'euc-kr'; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
elsif ( $country_language =~ /^zh_CN|chin(?:a|ese)$/i ) { |
93
|
0
|
|
|
|
|
0
|
$locale_encoding = 'euc-cn'; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
elsif ( $country_language =~ /^zh_TW|taiwan(?:ese)?$/i ) { |
96
|
0
|
|
|
|
|
0
|
$locale_encoding = 'euc-tw'; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
else { |
99
|
0
|
|
|
|
|
0
|
require Carp; |
100
|
0
|
|
|
|
|
0
|
Carp::croak( |
101
|
|
|
|
|
|
|
"encoding: Locale encoding '$locale_encoding' too ambiguous" |
102
|
|
|
|
|
|
|
); |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
}; |
107
|
|
|
|
|
|
|
|
108
|
0
|
|
|
|
|
0
|
return $locale_encoding; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub import { |
112
|
|
|
|
|
|
|
|
113
|
9
|
|
|
9
|
|
220
|
if ( ord("A") == 193 ) { |
114
|
|
|
|
|
|
|
require Carp; |
115
|
|
|
|
|
|
|
Carp::croak("encoding: pragma does not support EBCDIC platforms"); |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
my $deprecate = |
119
|
|
|
|
|
|
|
($] >= 5.017 and !$Config{usecperl}) |
120
|
9
|
50
|
33
|
|
|
713
|
? "Use of the encoding pragma is deprecated" : 0; |
121
|
|
|
|
|
|
|
|
122
|
9
|
|
|
|
|
44
|
my $class = shift; |
123
|
9
|
|
|
|
|
27
|
my $name = shift; |
124
|
9
|
50
|
|
|
|
40
|
if (!$name){ |
125
|
0
|
|
|
|
|
0
|
require Carp; |
126
|
0
|
|
|
|
|
0
|
Carp::croak("encoding: no encoding specified."); |
127
|
|
|
|
|
|
|
} |
128
|
9
|
50
|
|
|
|
41
|
if ( $name eq ':_get_locale_encoding' ) { # used by lib/open.pm |
129
|
0
|
|
|
|
|
0
|
my $caller = caller(); |
130
|
|
|
|
|
|
|
{ |
131
|
7
|
|
|
7
|
|
69
|
no strict 'refs'; |
|
7
|
|
|
|
|
25
|
|
|
7
|
|
|
|
|
812
|
|
|
0
|
|
|
|
|
0
|
|
132
|
0
|
|
|
|
|
0
|
*{"${caller}::_get_locale_encoding"} = \&_get_locale_encoding; |
|
0
|
|
|
|
|
0
|
|
133
|
|
|
|
|
|
|
} |
134
|
0
|
|
|
|
|
0
|
return; |
135
|
|
|
|
|
|
|
} |
136
|
9
|
50
|
|
|
|
41
|
$name = _get_locale_encoding() if $name eq ':locale'; |
137
|
7
|
50
|
33
|
7
|
|
3770
|
BEGIN { strict->unimport('hashpairs') if $] >= 5.027 and $^V =~ /c$/; } |
138
|
9
|
|
|
|
|
35
|
my %arg = @_; |
139
|
9
|
50
|
|
|
|
35
|
$name = $ENV{PERL_ENCODING} unless defined $name; |
140
|
9
|
|
|
|
|
45
|
my $enc = find_encoding($name); |
141
|
9
|
50
|
|
|
|
44
|
unless ( defined $enc ) { |
142
|
0
|
|
|
|
|
0
|
require Carp; |
143
|
0
|
|
|
|
|
0
|
Carp::croak("encoding: Unknown encoding '$name'"); |
144
|
|
|
|
|
|
|
} |
145
|
9
|
|
|
|
|
104
|
$name = $enc->name; # canonize |
146
|
9
|
100
|
|
|
|
47
|
unless ( $arg{Filter} ) { |
147
|
8
|
50
|
33
|
|
|
50
|
if ($] >= 5.025003 and !$Config{usecperl}) { |
148
|
0
|
|
|
|
|
0
|
require Carp; |
149
|
0
|
|
|
|
|
0
|
Carp::croak("The encoding pragma is no longer supported. Check cperl"); |
150
|
|
|
|
|
|
|
} |
151
|
8
|
50
|
|
|
|
863
|
warnings::warnif("deprecated",$deprecate) if $deprecate; |
152
|
|
|
|
|
|
|
|
153
|
8
|
|
|
|
|
31
|
DEBUG and warn "_exception($name) = ", _exception($name); |
154
|
8
|
50
|
|
|
|
39
|
if (! _exception($name)) { |
155
|
8
|
|
|
|
|
23
|
if (!PERL_5_21_7) { |
156
|
|
|
|
|
|
|
${^ENCODING} = $enc; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
else { |
159
|
|
|
|
|
|
|
# Starting with 5.21.7, this pragma uses a shadow variable |
160
|
|
|
|
|
|
|
# designed explicitly for it, ${^E_NCODING}, to enforce |
161
|
|
|
|
|
|
|
# lexical scope; instead of ${^ENCODING}. |
162
|
8
|
|
|
|
|
48
|
$^H{'encoding'} = 1; |
163
|
8
|
|
|
|
|
41
|
${^E_NCODING} = $enc; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
} |
166
|
8
|
|
|
|
|
23
|
if (! HAS_PERLIO ) { |
167
|
|
|
|
|
|
|
return 1; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
else { |
171
|
1
|
50
|
|
|
|
52
|
warnings::warnif("deprecated",$deprecate) if $deprecate; |
172
|
|
|
|
|
|
|
|
173
|
1
|
50
|
|
|
|
5
|
defined( ${^ENCODING} ) and undef ${^ENCODING}; |
174
|
1
|
|
|
|
|
3
|
undef ${^E_NCODING} if PERL_5_21_7; |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
# implicitly 'use utf8' |
177
|
1
|
|
|
|
|
6
|
require utf8; # to fetch $utf8::hint_bits; |
178
|
1
|
|
|
|
|
3
|
$^H |= $utf8::hint_bits; |
179
|
1
|
50
|
50
|
|
|
2
|
eval { |
180
|
1
|
|
|
|
|
675
|
require Filter::Util::Call; |
181
|
1
|
|
|
|
|
898
|
Filter::Util::Call->import; |
182
|
|
|
|
|
|
|
filter_add( |
183
|
|
|
|
|
|
|
sub { |
184
|
11
|
|
|
11
|
|
60
|
my $status = filter_read(); |
185
|
11
|
50
|
|
|
|
26
|
if ( $status > 0 ) { |
186
|
11
|
|
|
|
|
40
|
$_ = $enc->decode( $_, 1 ); |
187
|
11
|
|
|
|
|
17
|
DEBUG and warn $_; |
188
|
|
|
|
|
|
|
} |
189
|
11
|
|
|
|
|
125
|
$status; |
190
|
|
|
|
|
|
|
} |
191
|
1
|
|
|
|
|
9
|
); |
192
|
1
|
|
|
|
|
20
|
1; |
193
|
|
|
|
|
|
|
} and DEBUG and warn "Filter installed"; |
194
|
|
|
|
|
|
|
} |
195
|
9
|
50
|
33
|
|
|
90
|
defined ${^UNICODE} and ${^UNICODE} != 0 and return 1; |
196
|
9
|
|
|
|
|
31
|
for my $h (qw(STDIN STDOUT)) { |
197
|
18
|
50
|
|
|
|
71
|
if ( $arg{$h} ) { |
198
|
0
|
0
|
|
|
|
0
|
unless ( defined find_encoding( $arg{$h} ) ) { |
199
|
0
|
|
|
|
|
0
|
require Carp; |
200
|
0
|
|
|
|
|
0
|
Carp::croak( |
201
|
|
|
|
|
|
|
"encoding: Unknown encoding for $h, '$arg{$h}'"); |
202
|
|
|
|
|
|
|
} |
203
|
0
|
|
|
|
|
0
|
eval { binmode( $h, ":raw :encoding($arg{$h})" ) }; |
|
0
|
|
|
|
|
0
|
|
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
else { |
206
|
18
|
50
|
|
|
|
68
|
unless ( exists $arg{$h} ) { |
207
|
18
|
|
|
|
|
46
|
eval { |
208
|
7
|
|
|
7
|
|
68
|
no warnings 'uninitialized'; |
|
7
|
|
|
|
|
24
|
|
|
7
|
|
|
|
|
1275
|
|
209
|
18
|
|
|
|
|
271
|
binmode( $h, ":raw :encoding($name)" ); |
210
|
|
|
|
|
|
|
}; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
} |
213
|
18
|
50
|
|
|
|
90
|
if ($@) { |
214
|
0
|
|
|
|
|
0
|
require Carp; |
215
|
0
|
|
|
|
|
0
|
Carp::croak($@); |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
} |
218
|
9
|
|
|
|
|
2021
|
return 1; # I doubt if we need it, though |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub unimport { |
222
|
7
|
|
|
7
|
|
64
|
no warnings; |
|
7
|
|
|
|
|
21
|
|
|
7
|
|
|
|
|
1071
|
|
223
|
3
|
|
|
3
|
|
148
|
undef ${^ENCODING}; |
224
|
3
|
|
|
|
|
8
|
undef ${^E_NCODING} if PERL_5_21_7; |
225
|
3
|
|
|
|
|
5
|
if (HAS_PERLIO) { |
226
|
3
|
|
|
|
|
13
|
binmode( STDIN, ":raw" ); |
227
|
3
|
|
|
|
|
9
|
binmode( STDOUT, ":raw" ); |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
else { |
230
|
|
|
|
|
|
|
binmode(STDIN); |
231
|
|
|
|
|
|
|
binmode(STDOUT); |
232
|
|
|
|
|
|
|
} |
233
|
3
|
100
|
|
|
|
85
|
if ( $INC{"Filter/Util/Call.pm"} ) { |
234
|
1
|
|
|
|
|
2
|
eval { filter_del() }; |
|
1
|
|
|
|
|
1046
|
|
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
1; |
239
|
|
|
|
|
|
|
__END__ |