File Coverage

blib/lib/Encode/Locale.pm
Criterion Covered Total %
statement 57 106 53.7
branch 15 66 22.7
condition 8 22 36.3
subroutine 12 18 66.6
pod 3 3 100.0
total 95 215 44.1


line stmt bran cond sub pod time code
1             package Encode::Locale;
2              
3 5     5   84900 use strict;
  5         13  
  5         310  
4             our $VERSION = "1.05";
5              
6 5     5   28 use base 'Exporter';
  5         9  
  5         654  
7             our @EXPORT_OK = qw(
8             decode_argv env
9             $ENCODING_LOCALE $ENCODING_LOCALE_FS
10             $ENCODING_CONSOLE_IN $ENCODING_CONSOLE_OUT
11             );
12              
13 5     5   3408 use Encode ();
  5         50707  
  5         139  
14 5     5   40 use Encode::Alias ();
  5         8  
  5         3763  
15              
16             our $ENCODING_LOCALE;
17             our $ENCODING_LOCALE_FS;
18             our $ENCODING_CONSOLE_IN;
19             our $ENCODING_CONSOLE_OUT;
20              
21             sub DEBUG () { 0 }
22              
23             sub _init {
24 6 50   6   34 if ($^O eq "MSWin32") {
25 0 0       0 unless ($ENCODING_LOCALE) {
26             # Try to obtain what the Windows ANSI code page is
27 0         0 eval {
28 0 0       0 unless (defined &GetACP) {
29 0         0 require Win32;
30 0         0 eval { Win32::GetACP() };
  0         0  
31 0 0   0   0 *GetACP = sub { &Win32::GetACP } unless $@;
  0         0  
32             }
33 0 0       0 unless (defined &GetACP) {
34 0         0 require Win32::API;
35 0         0 Win32::API->Import('kernel32', 'int GetACP()');
36             }
37 0 0       0 if (defined &GetACP) {
38 0         0 my $cp = GetACP();
39 0 0       0 $ENCODING_LOCALE = "cp$cp" if $cp;
40             }
41             };
42             }
43              
44 0 0       0 unless ($ENCODING_CONSOLE_IN) {
45             # only test one since set together
46 0 0       0 unless (defined &GetInputCP) {
47 0         0 eval {
48 0         0 require Win32;
49 0         0 eval { Win32::GetConsoleCP() };
  0         0  
50             # manually "import" it since Win32->import refuses
51 0 0   0   0 *GetInputCP = sub { &Win32::GetConsoleCP } unless $@;
  0         0  
52 0 0   0   0 *GetOutputCP = sub { &Win32::GetConsoleOutputCP } unless $@;
  0         0  
53             };
54 0 0       0 unless (defined &GetInputCP) {
55 0         0 eval {
56             # try Win32::Console module for codepage to use
57 0         0 require Win32::Console;
58 0         0 eval { Win32::Console::InputCP() };
  0         0  
59 0     0   0 *GetInputCP = sub { &Win32::Console::InputCP }
60 0 0       0 unless $@;
61 0     0   0 *GetOutputCP = sub { &Win32::Console::OutputCP }
62 0 0       0 unless $@;
63             };
64             }
65 0 0       0 unless (defined &GetInputCP) {
66             # final fallback
67             *GetInputCP = *GetOutputCP = sub {
68             # another fallback that could work is:
69             # reg query HKLM\System\CurrentControlSet\Control\Nls\CodePage /v ACP
70 0 0 0 0   0 ((qx(chcp) || '') =~ /^Active code page: (\d+)/)
71             ? $1 : ();
72 0         0 };
73             }
74             }
75 0         0 my $cp = GetInputCP();
76 0 0       0 $ENCODING_CONSOLE_IN = "cp$cp" if $cp;
77 0         0 $cp = GetOutputCP();
78 0 0       0 $ENCODING_CONSOLE_OUT = "cp$cp" if $cp;
79             }
80             }
81              
82 6 100       16 unless ($ENCODING_LOCALE) {
83 5         7 eval {
84 5         2971 require I18N::Langinfo;
85 5         3639 $ENCODING_LOCALE = I18N::Langinfo::langinfo(I18N::Langinfo::CODESET());
86              
87             # Workaround of Encode < v2.25. The "646" encoding alias was
88             # introduced in Encode-2.25, but we don't want to require that version
89             # quite yet. Should avoid the CPAN testers failure reported from
90             # openbsd-4.7/perl-5.10.0 combo.
91 5 50       26 $ENCODING_LOCALE = "ascii" if $ENCODING_LOCALE eq "646";
92              
93             # https://rt.cpan.org/Ticket/Display.html?id=66373
94 5 50 33     27 $ENCODING_LOCALE = "hp-roman8" if $^O eq "hpux" && $ENCODING_LOCALE eq "roman8";
95             };
96 5   33     22 $ENCODING_LOCALE ||= $ENCODING_CONSOLE_IN;
97             }
98              
99 6 50       16 if ($^O eq "darwin") {
100 0   0     0 $ENCODING_LOCALE_FS ||= "UTF-8";
101             }
102              
103             # final fallback
104 6 0 33     18 $ENCODING_LOCALE ||= $^O eq "MSWin32" ? "cp1252" : "UTF-8";
105 6   33     36 $ENCODING_LOCALE_FS ||= $ENCODING_LOCALE;
106 6   66     47 $ENCODING_CONSOLE_IN ||= $ENCODING_LOCALE;
107 6   66     35 $ENCODING_CONSOLE_OUT ||= $ENCODING_CONSOLE_IN;
108              
109 6 50       25 unless (Encode::find_encoding($ENCODING_LOCALE)) {
110 0         0 my $foundit;
111 0 0       0 if (lc($ENCODING_LOCALE) eq "gb18030") {
112 0         0 eval {
113 0         0 require Encode::HanExtra;
114             };
115 0 0       0 if ($@) {
116 0         0 die "Need Encode::HanExtra to be installed to support locale codeset ($ENCODING_LOCALE), stopped";
117             }
118 0 0       0 $foundit++ if Encode::find_encoding($ENCODING_LOCALE);
119             }
120 0 0       0 die "The locale codeset ($ENCODING_LOCALE) isn't one that perl can decode, stopped"
121             unless $foundit;
122              
123             }
124              
125             # use Data::Dump; ddx $ENCODING_LOCALE, $ENCODING_LOCALE_FS, $ENCODING_CONSOLE_IN, $ENCODING_CONSOLE_OUT;
126             }
127              
128             _init();
129             Encode::Alias::define_alias(sub {
130 5     5   34 no strict 'refs';
  5         6  
  5         170  
131 5     5   22 no warnings 'once';
  5         7  
  5         387  
132             return ${"ENCODING_" . uc(shift)};
133             }, "locale");
134              
135             sub _flush_aliases {
136 5     5   25 no strict 'refs';
  5         6  
  5         1402  
137 1     1   3 for my $a (keys %Encode::Alias::Alias) {
138 4 100       5 if (defined ${"ENCODING_" . uc($a)}) {
  4         14  
139 1         3 delete $Encode::Alias::Alias{$a};
140 1         1 warn "Flushed alias cache for $a" if DEBUG;
141             }
142             }
143             }
144              
145             sub reinit {
146 1     1 1 710 $ENCODING_LOCALE = shift;
147 1         3 $ENCODING_LOCALE_FS = shift;
148 1         2 $ENCODING_CONSOLE_IN = $ENCODING_LOCALE;
149 1         2 $ENCODING_CONSOLE_OUT = $ENCODING_LOCALE;
150 1         26 _init();
151 1         2437 _flush_aliases();
152             }
153              
154             sub decode_argv {
155 1 50   1 1 497 die if defined wantarray;
156 1         3 for (@ARGV) {
157 4         99 $_ = Encode::decode(locale => $_, @_);
158             }
159             }
160              
161             sub env {
162 9     9 1 4360 my $k = Encode::encode(locale => shift);
163 9         280 my $old = $ENV{$k};
164 9 100       20 if (@_) {
165 4         6 my $v = shift;
166 4 100       11 if (defined $v) {
167 3         6 $ENV{$k} = Encode::encode(locale => $v);
168             }
169             else {
170 1         5 delete $ENV{$k};
171             }
172             }
173 9 50       92 return Encode::decode(locale => $old) if defined wantarray;
174             }
175              
176             1;
177              
178             __END__