File Coverage

blib/lib/Encode/Alias.pm
Criterion Covered Total %
statement 110 111 99.1
branch 28 32 87.5
condition 8 9 88.8
subroutine 9 9 100.0
pod 0 4 0.0
total 155 165 93.9


line stmt bran cond sub pod time code
1             package Encode::Alias;
2 35     35   484 use strict;
  35         67  
  35         899  
3 35     35   158 use warnings;
  35         58  
  35         2849  
4             our $VERSION = do { my @r = ( q$Revision: 2.23 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r };
5 35     35   294 use constant DEBUG => !!$ENV{PERL_ENCODE_DEBUG};
  35         82  
  35         2311  
6              
7 35     35   189 use Exporter 'import';
  35         68  
  35         22345  
8              
9             # Public, encouraged API is exported by default
10              
11             our @EXPORT =
12             qw (
13             define_alias
14             find_alias
15             );
16              
17             our @Alias; # ordered matching list
18             our %Alias; # cached known aliases
19              
20             sub find_alias {
21 3499     3499 0 6039 my $class = shift;
22 3499         4634 my $find = shift;
23 3499 100       7815 unless ( exists $Alias{$find} ) {
24 1274         2513 $Alias{$find} = undef; # Recursion guard
25 1274         2922 for ( my $i = 0 ; $i < @Alias ; $i += 2 ) {
26 44750         54393 my $alias = $Alias[$i];
27 44750         54782 my $val = $Alias[ $i + 1 ];
28 44750         45279 my $new;
29 44750 100 100     170691 if ( ref($alias) eq 'Regexp' && $find =~ $alias ) {
    100          
    100          
30 981         1406 DEBUG and warn "eval $val";
31 981         51509 $new = eval $val;
32 981         2749 DEBUG and $@ and warn "$val, $@";
33             }
34             elsif ( ref($alias) eq 'CODE' ) {
35 11         13 DEBUG and warn "$alias", "->", "($find)";
36 11         19 $new = $alias->($find);
37             }
38             elsif ( lc($find) eq lc($alias) ) {
39 30         62 $new = $val;
40             }
41 44750 100       92153 if ( defined($new) ) {
42 1022 100       2098 next if $new eq $find; # avoid (direct) recursion on bugs
43 886         936 DEBUG and warn "$alias, $new";
44 886 50       2618 my $enc =
45             ( ref($new) ) ? $new : Encode::find_encoding($new);
46 886 100       2327 if ($enc) {
47 840         1297 $Alias{$find} = $enc;
48 840         1472 last;
49             }
50             }
51             }
52              
53             # case insensitive search when canonical is not in all lowercase
54             # RT ticket #7835
55 1274 100       2509 unless ( $Alias{$find} ) {
56 434         678 my $lcfind = lc($find);
57 434         8988 for my $name ( keys %Encode::Encoding, keys %Encode::ExtModule )
58             {
59 95195 100       147117 $lcfind eq lc($name) or next;
60 60         211 $Alias{$find} = Encode::find_encoding($name);
61 60         150 DEBUG and warn "$find => $name";
62             }
63             }
64             }
65 3499         7537 if (DEBUG) {
66             my $name;
67             if ( my $e = $Alias{$find} ) {
68             $name = $e->name;
69             }
70             else {
71             $name = "";
72             }
73             warn "find_alias($class, $find)->name = $name";
74             }
75 3499         7817 return $Alias{$find};
76             }
77              
78             sub define_alias {
79 2026     2026 0 3825 while (@_) {
80 2354         3173 my $alias = shift;
81 2354         2849 my $name = shift;
82 2354 50       5334 unshift( @Alias, $alias => $name ) # newer one has precedence
83             if defined $alias;
84 2354 100       4165 if ( ref($alias) ) {
    50          
85              
86             # clear %Alias cache to allow overrides
87 1770         2739 my @a = keys %Alias;
88 1770         3799 for my $k (@a) {
89 2246 100 100     7934 if ( ref($alias) eq 'Regexp' && $k =~ $alias ) {
    100 66        
90 32         35 DEBUG and warn "delete \$Alias\{$k\}";
91 32         52 delete $Alias{$k};
92             }
93             elsif ( ref($alias) eq 'CODE' && $alias->($k) ) {
94 359         1977 DEBUG and warn "delete \$Alias\{$k\}";
95 359         508 delete $Alias{$k};
96             }
97             }
98             }
99             elsif (defined $alias) {
100 584         728 DEBUG and warn "delete \$Alias\{$alias\}";
101 584         1454 delete $Alias{$alias};
102             }
103 0         0 elsif (DEBUG) {
104             require Carp;
105             Carp::croak("undef \$alias");
106             }
107             }
108             }
109              
110             # HACK: Encode must be used after define_alias is declarated as Encode calls define_alias
111 35     35   554 use Encode ();
  35         75  
  35         39900  
112              
113             # Allow latin-1 style names as well
114             # 0 1 2 3 4 5 6 7 8 9 10
115             our @Latin2iso = ( 0, 1, 2, 3, 4, 9, 10, 13, 14, 15, 16 );
116              
117             # Allow winlatin1 style names as well
118             our %Winlatin2cp = (
119             'latin1' => 1252,
120             'latin2' => 1250,
121             'cyrillic' => 1251,
122             'greek' => 1253,
123             'turkish' => 1254,
124             'hebrew' => 1255,
125             'arabic' => 1256,
126             'baltic' => 1257,
127             'vietnamese' => 1258,
128             );
129              
130             init_aliases();
131              
132             sub undef_aliases {
133 37     37 0 555 @Alias = ();
134 37         157 %Alias = ();
135             }
136              
137             sub init_aliases {
138 36     36 0 372 undef_aliases();
139              
140             # Try all-lower-case version should all else fails
141 36         246 define_alias( qr/^(.*)$/ => '"\L$1"' );
142              
143             # UTF/UCS stuff
144 36         139 define_alias( qr/^(unicode-1-1-)?UTF-?7$/i => '"UTF-7"' );
145 36         192 define_alias( qr/^UCS-?2-?LE$/i => '"UCS-2LE"' );
146 36         210 define_alias(
147             qr/^UCS-?2-?(BE)?$/i => '"UCS-2BE"',
148             qr/^UCS-?4-?(BE|LE|)?$/i => 'uc("UTF-32$1")',
149             qr/^iso-10646-1$/i => '"UCS-2BE"'
150             );
151 36         189 define_alias(
152             qr/^UTF-?(16|32)-?BE$/i => '"UTF-$1BE"',
153             qr/^UTF-?(16|32)-?LE$/i => '"UTF-$1LE"',
154             qr/^UTF-?(16|32)$/i => '"UTF-$1"',
155             );
156              
157             # ASCII
158 36         140 define_alias( qr/^(?:US-?)ascii$/i => '"ascii"' );
159 36         108 define_alias( 'C' => 'ascii' );
160 36         127 define_alias( qr/\b(?:ISO[-_]?)?646(?:[-_]?US)?$/i => '"ascii"' );
161              
162             # Allow variants of iso-8859-1 etc.
163 36         126 define_alias( qr/\biso[-_]?(\d+)[-_](\d+)$/i => '"iso-$1-$2"' );
164              
165             # At least HP-UX has these.
166 36         125 define_alias( qr/\biso8859(\d+)$/i => '"iso-8859-$1"' );
167              
168             # More HP stuff.
169 36         156 define_alias(
170             qr/\b(?:hp-)?(arabic|greek|hebrew|kana|roman|thai|turkish)8$/i =>
171             '"${1}8"' );
172              
173             # The Official name of ASCII.
174 36         136 define_alias( qr/\bANSI[-_]?X3\.4[-_]?1968$/i => '"ascii"' );
175              
176             # This is a font issue, not an encoding issue.
177             # (The currency symbol of the Latin 1 upper half
178             # has been redefined as the euro symbol.)
179 36         125 define_alias( qr/^(.+)\@euro$/i => '"$1"' );
180              
181 36         514 define_alias( qr/\b(?:iso[-_]?)?latin[-_]?(\d+)$/i =>
182             'defined $Encode::Alias::Latin2iso[$1] ? "iso-8859-$Encode::Alias::Latin2iso[$1]" : undef'
183             );
184              
185 36         181 define_alias(
186             qr/\bwin(latin[12]|cyrillic|baltic|greek|turkish|
187             hebrew|arabic|baltic|vietnamese)$/ix =>
188             '"cp" . $Encode::Alias::Winlatin2cp{lc($1)}'
189             );
190              
191             # Common names for non-latin preferred MIME names
192 36         235 define_alias(
193             'ascii' => 'US-ascii',
194             'cyrillic' => 'iso-8859-5',
195             'arabic' => 'iso-8859-6',
196             'greek' => 'iso-8859-7',
197             'hebrew' => 'iso-8859-8',
198             'thai' => 'iso-8859-11',
199             );
200             # RT #20781
201 36         175 define_alias(qr/\btis-?620\b/i => '"iso-8859-11"');
202              
203             # At least AIX has IBM-NNN (surprisingly...) instead of cpNNN.
204             # And Microsoft has their own naming (again, surprisingly).
205             # And windows-* is registered in IANA!
206 36         145 define_alias(
207             qr/\b(?:cp|ibm|ms|windows)[-_ ]?(\d{2,4})$/i => '"cp$1"' );
208              
209             # Sometimes seen with a leading zero.
210             # define_alias( qr/\bcp037\b/i => '"cp37"');
211              
212             # Mac Mappings
213             # predefined in *.ucm; unneeded
214             # define_alias( qr/\bmacIcelandic$/i => '"macIceland"');
215 36         134 define_alias( qr/^(?:x[_-])?mac[_-](.*)$/i => '"mac$1"' );
216             # http://rt.cpan.org/Ticket/Display.html?id=36326
217 36         116 define_alias( qr/^macintosh$/i => '"MacRoman"' );
218             # https://rt.cpan.org/Ticket/Display.html?id=78125
219 36         154 define_alias( qr/^macce$/i => '"MacCentralEurRoman"' );
220             # Ououououou. gone. They are different!
221             # define_alias( qr/\bmacRomanian$/i => '"macRumanian"');
222              
223             # Standardize on the dashed versions.
224 36         171 define_alias( qr/\bkoi8[\s\-_]*([ru])$/i => '"koi8-$1"' );
225              
226 36 50       112 unless ($Encode::ON_EBCDIC) {
227              
228             # for Encode::CN
229 36         152 define_alias( qr/\beuc.*cn$/i => '"euc-cn"' );
230 36         137 define_alias( qr/\bcn.*euc$/i => '"euc-cn"' );
231              
232             # define_alias( qr/\bGB[- ]?(\d+)$/i => '"euc-cn"' )
233             # CP936 doesn't have vendor-addon for GBK, so they're identical.
234 36         133 define_alias( qr/^gbk$/i => '"cp936"' );
235              
236             # This fixes gb2312 vs. euc-cn confusion, practically
237 36         154 define_alias( qr/\bGB[-_ ]?2312(?!-?raw)/i => '"euc-cn"' );
238              
239             # for Encode::JP
240 36         142 define_alias( qr/\bjis$/i => '"7bit-jis"' );
241 36         139 define_alias( qr/\beuc.*jp$/i => '"euc-jp"' );
242 36         143 define_alias( qr/\bjp.*euc$/i => '"euc-jp"' );
243 36         149 define_alias( qr/\bujis$/i => '"euc-jp"' );
244 36         160 define_alias( qr/\bshift.*jis$/i => '"shiftjis"' );
245 36         155 define_alias( qr/\bsjis$/i => '"shiftjis"' );
246 36         153 define_alias( qr/\bwindows-31j$/i => '"cp932"' );
247              
248             # for Encode::KR
249 36         172 define_alias( qr/\beuc.*kr$/i => '"euc-kr"' );
250 36         233 define_alias( qr/\bkr.*euc$/i => '"euc-kr"' );
251              
252             # This fixes ksc5601 vs. euc-kr confusion, practically
253 36         191 define_alias( qr/(?:x-)?uhc$/i => '"cp949"' );
254 36         152 define_alias( qr/(?:x-)?windows-949$/i => '"cp949"' );
255 36         120 define_alias( qr/\bks_c_5601-1987$/i => '"cp949"' );
256              
257             # for Encode::TW
258 36         392 define_alias( qr/\bbig-?5$/i => '"big5-eten"' );
259 36         145 define_alias( qr/\bbig5-?et(?:en)?$/i => '"big5-eten"' );
260 36         152 define_alias( qr/\btca[-_]?big5$/i => '"big5-eten"' );
261 36         189 define_alias( qr/\bbig5-?hk(?:scs)?$/i => '"big5-hkscs"' );
262 36         135 define_alias( qr/\bhk(?:scs)?[-_]?big5$/i => '"big5-hkscs"' );
263             }
264              
265             # https://github.com/dankogai/p5-encode/issues/37
266 36         143 define_alias(qr/cp65000/i => '"UTF-7"');
267 36         139 define_alias(qr/cp65001/i => '"utf-8-strict"');
268              
269             # utf8 is blessed :)
270 36         130 define_alias( qr/\bUTF-8$/i => '"utf-8-strict"' );
271              
272             # At last, Map white space and _ to '-'
273 36         279 define_alias( qr/^(\S+)[\s_]+(.*)$/i => '"$1-$2"' );
274             }
275              
276             1;
277             __END__