File Coverage

lib/ExtUtils/MakeMaker/Locale.pm
Criterion Covered Total %
statement 51 108 47.2
branch 11 72 15.2
condition 10 28 35.7
subroutine 11 20 55.0
pod 3 3 100.0
total 86 231 37.2


line stmt bran cond sub pod time code
1             package ExtUtils::MakeMaker::Locale;
2              
3 53     53   559 use strict;
  53         107  
  53         2530  
4 53     53   324 use warnings;
  53         172  
  53         5748  
5             our $VERSION = "7.78";
6             $VERSION =~ tr/_//d;
7              
8 53     53   338 use base 'Exporter';
  53         109  
  53         13520  
9             our @EXPORT_OK = qw(
10             decode_argv env
11             $ENCODING_LOCALE $ENCODING_LOCALE_FS
12             $ENCODING_CONSOLE_IN $ENCODING_CONSOLE_OUT
13             );
14              
15 53     53   32594 use Encode ();
  53         1009309  
  53         2492  
16 53     53   443 use Encode::Alias ();
  53         199  
  53         53032  
17              
18             our $ENCODING_LOCALE;
19             our $ENCODING_LOCALE_FS;
20             our $ENCODING_CONSOLE_IN;
21             our $ENCODING_CONSOLE_OUT;
22              
23             sub DEBUG () { 0 }
24              
25             sub _init {
26 106 50   106   562 if ($^O eq "MSWin32") {
27 0 0       0 unless ($ENCODING_LOCALE) {
28             # Try to obtain what the Windows ANSI code page is
29 0         0 eval {
30 0 0       0 unless (defined &GetConsoleCP) {
31 0         0 require Win32;
32             # manually "import" it since Win32->import refuses
33 0 0   0   0 *GetConsoleCP = sub { &Win32::GetConsoleCP } if defined &Win32::GetConsoleCP;
  0         0  
34             }
35 0 0       0 unless (defined &GetConsoleCP) {
36 0         0 require Win32::API;
37 0         0 Win32::API->Import('kernel32', 'int GetConsoleCP()');
38             }
39 0 0       0 if (defined &GetConsoleCP) {
40 0         0 my $cp = GetConsoleCP();
41 0 0       0 $ENCODING_LOCALE = "cp$cp" if $cp;
42             }
43             };
44             }
45              
46 0 0       0 unless ($ENCODING_CONSOLE_IN) {
47             # only test one since set together
48 0 0       0 unless (defined &GetInputCP) {
49 0         0 eval {
50 0         0 require Win32;
51 0         0 eval {
52 0 0   0   0 local $SIG{__WARN__} = sub {} if ( "$]" < 5.014 ); # suppress deprecation warning for inherited AUTOLOAD of Win32::GetConsoleCP()
53 0         0 Win32::GetConsoleCP();
54             };
55             # manually "import" it since Win32->import refuses
56 0 0   0   0 *GetInputCP = sub { &Win32::GetConsoleCP } if defined &Win32::GetConsoleCP;
  0         0  
57 0 0   0   0 *GetOutputCP = sub { &Win32::GetConsoleOutputCP } if defined &Win32::GetConsoleOutputCP;
  0         0  
58             };
59 0 0       0 unless (defined &GetInputCP) {
60 0         0 eval {
61             # try Win32::Console module for codepage to use
62 0         0 require Win32::Console;
63 0     0   0 *GetInputCP = sub { &Win32::Console::InputCP }
64 0 0       0 if defined &Win32::Console::InputCP;
65 0     0   0 *GetOutputCP = sub { &Win32::Console::OutputCP }
66 0 0       0 if defined &Win32::Console::OutputCP;
67             };
68             }
69 0 0       0 unless (defined &GetInputCP) {
70             # final fallback
71             *GetInputCP = *GetOutputCP = sub {
72             # another fallback that could work is:
73             # reg query HKLM\System\CurrentControlSet\Control\Nls\CodePage /v ACP
74 0 0 0 0   0 ((qx(chcp) || '') =~ /^Active code page: (\d+)/)
75             ? $1 : ();
76 0         0 };
77             }
78             }
79 0         0 my $cp = GetInputCP();
80 0 0       0 $ENCODING_CONSOLE_IN = "cp$cp" if $cp;
81 0         0 $cp = GetOutputCP();
82 0 0       0 $ENCODING_CONSOLE_OUT = "cp$cp" if $cp;
83             }
84             }
85              
86 106 100       380 unless ($ENCODING_LOCALE) {
87 53         165 eval {
88 53         35029 require I18N::Langinfo;
89 53         58585 $ENCODING_LOCALE = I18N::Langinfo::langinfo(I18N::Langinfo::CODESET());
90              
91             # Workaround of Encode < v2.25. The "646" encoding alias was
92             # introduced in Encode-2.25, but we don't want to require that version
93             # quite yet. Should avoid the CPAN testers failure reported from
94             # openbsd-4.7/perl-5.10.0 combo.
95 53 50       383 $ENCODING_LOCALE = "ascii" if $ENCODING_LOCALE eq "646";
96              
97             # https://rt.cpan.org/Ticket/Display.html?id=66373
98 53 50 33     405 $ENCODING_LOCALE = "hp-roman8" if $^O eq "hpux" && $ENCODING_LOCALE eq "roman8";
99             };
100 53   33     267 $ENCODING_LOCALE ||= $ENCODING_CONSOLE_IN;
101             }
102              
103             # Workaround of Encode < v2.71 for "cp65000" and "cp65001"
104             # The "cp65000" and "cp65001" aliases were added in [Encode v2.71](https://github.com/dankogai/p5-encode/commit/7874bd95aa10967a3b5dbae333d16bcd703ac6c6)
105             # via commit .
106             # This will avoid test failures for Win32 machines using the UTF-7 or UTF-8 code pages.
107 106 50 33     711 $ENCODING_LOCALE = 'UTF-7' if $ENCODING_LOCALE && lc($ENCODING_LOCALE) eq "cp65000";
108 106 50 33     508 $ENCODING_LOCALE = 'utf-8-strict' if $ENCODING_LOCALE && lc($ENCODING_LOCALE) eq "cp65001";
109              
110 106 50       356 if ($^O eq "darwin") {
111 0   0     0 $ENCODING_LOCALE_FS ||= "UTF-8";
112             }
113              
114             # final fallback
115 106 0 33     323 $ENCODING_LOCALE ||= $^O eq "MSWin32" ? "cp1252" : "UTF-8";
116 106   33     691 $ENCODING_LOCALE_FS ||= $ENCODING_LOCALE;
117 106   66     490 $ENCODING_CONSOLE_IN ||= $ENCODING_LOCALE;
118 106   66     355 $ENCODING_CONSOLE_OUT ||= $ENCODING_CONSOLE_IN;
119              
120 106 50       430 unless (Encode::find_encoding($ENCODING_LOCALE)) {
121 0         0 my $foundit;
122 0 0       0 if (lc($ENCODING_LOCALE) eq "gb18030") {
123 0         0 eval {
124 0         0 require Encode::HanExtra;
125             };
126 0 0       0 if ($@) {
127 0         0 die "Need Encode::HanExtra to be installed to support locale codeset ($ENCODING_LOCALE), stopped";
128             }
129 0 0       0 $foundit++ if Encode::find_encoding($ENCODING_LOCALE);
130             }
131 0 0       0 die "The locale codeset ($ENCODING_LOCALE) isn't one that perl can decode, stopped"
132             unless $foundit;
133              
134             }
135              
136             # use Data::Dump; ddx $ENCODING_LOCALE, $ENCODING_LOCALE_FS, $ENCODING_CONSOLE_IN, $ENCODING_CONSOLE_OUT;
137             }
138              
139             _init();
140             Encode::Alias::define_alias(sub {
141 53     53   432 no strict 'refs';
  53         128  
  53         2581  
142 53     53   329 no warnings 'once';
  53         121  
  53         6053  
143             return ${"ENCODING_" . uc(shift)};
144             }, "locale");
145              
146             sub _flush_aliases {
147 53     53   337 no strict 'refs';
  53         115  
  53         21968  
148 53     53   361 for my $a (sort keys %Encode::Alias::Alias) {
149 212 100       342 if (defined ${"ENCODING_" . uc($a)}) {
  212         797  
150 53         138 delete $Encode::Alias::Alias{$a};
151 53         203 warn "Flushed alias cache for $a" if DEBUG;
152             }
153             }
154             }
155              
156             sub reinit {
157 53     53 1 177 $ENCODING_LOCALE = shift;
158 53         172 $ENCODING_LOCALE_FS = shift;
159 53         105 $ENCODING_CONSOLE_IN = $ENCODING_LOCALE;
160 53         165 $ENCODING_CONSOLE_OUT = $ENCODING_LOCALE;
161 53         203 _init();
162 53         7144 _flush_aliases();
163             }
164              
165             sub decode_argv {
166 0 0   0 1   die if defined wantarray;
167 0           for (@ARGV) {
168 0           $_ = Encode::decode(locale => $_, @_);
169             }
170             }
171              
172             sub env {
173 0     0 1   my $k = Encode::encode(locale => shift);
174 0           my $old = $ENV{$k};
175 0 0         if (@_) {
176 0           my $v = shift;
177 0 0         if (defined $v) {
178 0           $ENV{$k} = Encode::encode(locale => $v);
179             }
180             else {
181 0           delete $ENV{$k};
182             }
183             }
184 0 0         return Encode::decode(locale => $old) if defined wantarray;
185             }
186              
187             1;
188              
189             __END__