File Coverage

blib/lib/Eutf2.pm
Criterion Covered Total %
statement 1045 3230 32.3
branch 1095 2772 39.5
condition 122 355 34.3
subroutine 55 110 50.0
pod 7 74 9.4
total 2324 6541 35.5


line stmt bran cond sub pod time code
1             package Eutf2;
2 306     306   2270 use strict;
  306         1549  
  306         9512  
3             ######################################################################
4             #
5             # Eutf2 - Run-time routines for UTF2.pm
6             #
7             # http://search.cpan.org/dist/Char-UTF2/
8             #
9             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
10             ######################################################################
11              
12 306     306   4825 use 5.00503; # Galapagos Consensus 1998 for primetools
  306         860  
13             # use 5.008001; # Lancaster Consensus 2013 for toolchains
14              
15             # 12.3. Delaying use Until Runtime
16             # in Chapter 12. Packages, Libraries, and Modules
17             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
18             # (and so on)
19              
20             # Version numbers should be boring
21             # http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
22             # For the impatient, the disinterested or those who just want to follow
23             # a recipe, my advice for all modules is this:
24             # our $VERSION = "0.001"; # or "0.001_001" for a dev release
25             # $VERSION = eval $VERSION; # No!! because '1.10' makes '1.1'
26              
27 306     306   1524 use vars qw($VERSION);
  306         644  
  306         43892  
28             $VERSION = '1.13';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 306 50   306   3299 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 306         580 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 306         45513 if (CORE::ord('A') != 0x41) {
39             die __FILE__, ": is not US-ASCII script (must be US-ASCII script).\n";
40             }
41             }
42              
43             BEGIN {
44              
45             # instead of utf8.pm
46 306     306   21871 CORE::eval q{
  306     306   1933  
  306     120   782  
  306         38062  
  0         0  
  0         0  
  0         0  
  0         0  
47             no warnings qw(redefine);
48             *utf8::upgrade = sub { CORE::length $_[0] };
49             *utf8::downgrade = sub { 1 };
50             *utf8::encode = sub { };
51             *utf8::decode = sub { 1 };
52             *utf8::is_utf8 = sub { };
53             *utf8::valid = sub { 1 };
54             };
55 306 50       138755 if ($@) {
56 0         0 *utf8::upgrade = sub { CORE::length $_[0] };
  0         0  
57 0         0 *utf8::downgrade = sub { 1 };
  0         0  
58 0         0 *utf8::encode = sub { };
59 0         0 *utf8::decode = sub { 1 };
  0         0  
60 0         0 *utf8::is_utf8 = sub { };
61 0         0 *utf8::valid = sub { 1 };
  0         0  
62             }
63             }
64              
65             # instead of Symbol.pm
66 0         0 BEGIN {
67             sub gensym () {
68 0 0   0 0 0 if ($] < 5.006) {
69 0         0 return \do { local *_ };
  0         0  
70             }
71             else {
72 0         0 return undef;
73             }
74             }
75              
76             sub qualify ($$) {
77 0     0 0 0 my($name) = @_;
78              
79 0 0       0 if (ref $name) {
    0          
    0          
    0          
    0          
    0          
    0          
80 0         0 return $name;
81             }
82             elsif (Eutf2::index($name,'::') >= 0) {
83 0         0 return $name;
84             }
85             elsif (Eutf2::index($name,"'") >= 0) {
86 0         0 return $name;
87             }
88              
89             # special character, "^xyz"
90             elsif ($name =~ /\A \^ [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+ \z/x) {
91              
92             # RGS 2001-11-05 : translate leading ^X to control-char
93 0         0 $name =~ s{\A \^ ([ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]) }{'qq(\c'.$1.')'}xee;
  0         0  
94 0         0 return 'main::' . $name;
95             }
96              
97             # Global names
98             elsif ($name =~ /\A (?: ARGV | ARGVOUT | ENV | INC | SIG | STDERR | STDIN | STDOUT ) \z/x) {
99 0         0 return 'main::' . $name;
100             }
101              
102             # or other
103             elsif ($name =~ /\A [^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz] \z/x) {
104 0         0 return 'main::' . $name;
105             }
106              
107             elsif (defined $_[1]) {
108 0         0 return $_[1] . '::' . $name;
109             }
110             else {
111 0         0 return (caller)[0] . '::' . $name;
112             }
113             }
114              
115             sub qualify_to_ref ($;$) {
116 0 0   0 0 0 if (defined $_[1]) {
117 306     306   2370 no strict qw(refs);
  306         565  
  306         20348  
118 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
119             }
120             else {
121 306     306   1994 no strict qw(refs);
  306     0   708  
  306         57562  
122 0         0 return \*{ qualify $_[0], (caller)[0] };
  0         0  
123             }
124             }
125             }
126              
127             # P.714 29.2.39. flock
128             # in Chapter 29: Functions
129             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
130              
131             # P.863 flock
132             # in Chapter 27: Functions
133             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
134              
135             sub LOCK_SH() {1}
136             sub LOCK_EX() {2}
137             sub LOCK_UN() {8}
138             sub LOCK_NB() {4}
139              
140             # instead of Carp.pm
141             sub carp;
142             sub croak;
143             sub cluck;
144             sub confess;
145              
146             # 6.18. Matching Multiple-Byte Characters
147             # in Chapter 6. Pattern Matching
148             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
149             # (and so on)
150              
151             # regexp of character
152             my $your_char = q{(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF]|[\x00-\x7F\xF5-\xFF]};
153 306     306   2115 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  306         621  
  306         38069  
154 306     306   1861 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  306         652  
  306         3963007  
155              
156             #
157             # UTF-8 character range per length
158             #
159             my %range_tr = ();
160              
161             #
162             # UTF-8 case conversion
163             #
164             my %lc = ();
165             @lc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
166             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
167             my %uc = ();
168             @uc{qw(a b c d e f g h i j k l m n o p q r s t u v w x y z)} =
169             qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
170             my %fc = ();
171             @fc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
172             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
173              
174             if (0) {
175             }
176              
177             elsif (__PACKAGE__ =~ / \b Eutf2 \z/oxms) {
178             %range_tr = (
179             1 => [ [0x00..0x7F],
180             [0xF5..0xFF], # malformed octet
181             ],
182             2 => [ [0xC2..0xDF],[0x80..0xBF],
183             ],
184             3 => [ [0xE0..0xE0],[0xA0..0xBF],[0x80..0xBF],
185             [0xE1..0xEC],[0x80..0xBF],[0x80..0xBF],
186             [0xED..0xED],[0x80..0x9F],[0x80..0xBF],
187             [0xEE..0xEF],[0x80..0xBF],[0x80..0xBF],
188             ],
189             4 => [ [0xF0..0xF0],[0x90..0xBF],[0x80..0xBF],[0x80..0xBF],
190             [0xF1..0xF3],[0x80..0xBF],[0x80..0xBF],[0x80..0xBF],
191             [0xF4..0xF4],[0x80..0x8F],[0x80..0xBF],[0x80..0xBF],
192             ],
193             );
194              
195             # CaseFolding-12.0.0.txt
196             # Date: 2019-01-22, 08:18:22 GMT
197             # c 2019 UnicodeR, Inc.
198             # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
199             # For terms of use, see http://www.unicode.org/terms_of_use.html
200             #
201             # Unicode Character Database
202             # For documentation, see http://www.unicode.org/reports/tr44/
203              
204             # you can use "make_CaseFolding.pl" to update this hash
205              
206             %fc = (
207             "\x41" => "\x61", # LATIN CAPITAL LETTER A
208             "\x42" => "\x62", # LATIN CAPITAL LETTER B
209             "\x43" => "\x63", # LATIN CAPITAL LETTER C
210             "\x44" => "\x64", # LATIN CAPITAL LETTER D
211             "\x45" => "\x65", # LATIN CAPITAL LETTER E
212             "\x46" => "\x66", # LATIN CAPITAL LETTER F
213             "\x47" => "\x67", # LATIN CAPITAL LETTER G
214             "\x48" => "\x68", # LATIN CAPITAL LETTER H
215             "\x49" => "\x69", # LATIN CAPITAL LETTER I
216             "\x4A" => "\x6A", # LATIN CAPITAL LETTER J
217             "\x4B" => "\x6B", # LATIN CAPITAL LETTER K
218             "\x4C" => "\x6C", # LATIN CAPITAL LETTER L
219             "\x4D" => "\x6D", # LATIN CAPITAL LETTER M
220             "\x4E" => "\x6E", # LATIN CAPITAL LETTER N
221             "\x4F" => "\x6F", # LATIN CAPITAL LETTER O
222             "\x50" => "\x70", # LATIN CAPITAL LETTER P
223             "\x51" => "\x71", # LATIN CAPITAL LETTER Q
224             "\x52" => "\x72", # LATIN CAPITAL LETTER R
225             "\x53" => "\x73", # LATIN CAPITAL LETTER S
226             "\x54" => "\x74", # LATIN CAPITAL LETTER T
227             "\x55" => "\x75", # LATIN CAPITAL LETTER U
228             "\x56" => "\x76", # LATIN CAPITAL LETTER V
229             "\x57" => "\x77", # LATIN CAPITAL LETTER W
230             "\x58" => "\x78", # LATIN CAPITAL LETTER X
231             "\x59" => "\x79", # LATIN CAPITAL LETTER Y
232             "\x5A" => "\x7A", # LATIN CAPITAL LETTER Z
233             "\xC2\xB5" => "\xCE\xBC", # MICRO SIGN
234             "\xC3\x80" => "\xC3\xA0", # LATIN CAPITAL LETTER A WITH GRAVE
235             "\xC3\x81" => "\xC3\xA1", # LATIN CAPITAL LETTER A WITH ACUTE
236             "\xC3\x82" => "\xC3\xA2", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
237             "\xC3\x83" => "\xC3\xA3", # LATIN CAPITAL LETTER A WITH TILDE
238             "\xC3\x84" => "\xC3\xA4", # LATIN CAPITAL LETTER A WITH DIAERESIS
239             "\xC3\x85" => "\xC3\xA5", # LATIN CAPITAL LETTER A WITH RING ABOVE
240             "\xC3\x86" => "\xC3\xA6", # LATIN CAPITAL LETTER AE
241             "\xC3\x87" => "\xC3\xA7", # LATIN CAPITAL LETTER C WITH CEDILLA
242             "\xC3\x88" => "\xC3\xA8", # LATIN CAPITAL LETTER E WITH GRAVE
243             "\xC3\x89" => "\xC3\xA9", # LATIN CAPITAL LETTER E WITH ACUTE
244             "\xC3\x8A" => "\xC3\xAA", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
245             "\xC3\x8B" => "\xC3\xAB", # LATIN CAPITAL LETTER E WITH DIAERESIS
246             "\xC3\x8C" => "\xC3\xAC", # LATIN CAPITAL LETTER I WITH GRAVE
247             "\xC3\x8D" => "\xC3\xAD", # LATIN CAPITAL LETTER I WITH ACUTE
248             "\xC3\x8E" => "\xC3\xAE", # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
249             "\xC3\x8F" => "\xC3\xAF", # LATIN CAPITAL LETTER I WITH DIAERESIS
250             "\xC3\x90" => "\xC3\xB0", # LATIN CAPITAL LETTER ETH
251             "\xC3\x91" => "\xC3\xB1", # LATIN CAPITAL LETTER N WITH TILDE
252             "\xC3\x92" => "\xC3\xB2", # LATIN CAPITAL LETTER O WITH GRAVE
253             "\xC3\x93" => "\xC3\xB3", # LATIN CAPITAL LETTER O WITH ACUTE
254             "\xC3\x94" => "\xC3\xB4", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
255             "\xC3\x95" => "\xC3\xB5", # LATIN CAPITAL LETTER O WITH TILDE
256             "\xC3\x96" => "\xC3\xB6", # LATIN CAPITAL LETTER O WITH DIAERESIS
257             "\xC3\x98" => "\xC3\xB8", # LATIN CAPITAL LETTER O WITH STROKE
258             "\xC3\x99" => "\xC3\xB9", # LATIN CAPITAL LETTER U WITH GRAVE
259             "\xC3\x9A" => "\xC3\xBA", # LATIN CAPITAL LETTER U WITH ACUTE
260             "\xC3\x9B" => "\xC3\xBB", # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
261             "\xC3\x9C" => "\xC3\xBC", # LATIN CAPITAL LETTER U WITH DIAERESIS
262             "\xC3\x9D" => "\xC3\xBD", # LATIN CAPITAL LETTER Y WITH ACUTE
263             "\xC3\x9E" => "\xC3\xBE", # LATIN CAPITAL LETTER THORN
264             "\xC3\x9F" => "\x73\x73", # LATIN SMALL LETTER SHARP S
265             "\xC4\x80" => "\xC4\x81", # LATIN CAPITAL LETTER A WITH MACRON
266             "\xC4\x82" => "\xC4\x83", # LATIN CAPITAL LETTER A WITH BREVE
267             "\xC4\x84" => "\xC4\x85", # LATIN CAPITAL LETTER A WITH OGONEK
268             "\xC4\x86" => "\xC4\x87", # LATIN CAPITAL LETTER C WITH ACUTE
269             "\xC4\x88" => "\xC4\x89", # LATIN CAPITAL LETTER C WITH CIRCUMFLEX
270             "\xC4\x8A" => "\xC4\x8B", # LATIN CAPITAL LETTER C WITH DOT ABOVE
271             "\xC4\x8C" => "\xC4\x8D", # LATIN CAPITAL LETTER C WITH CARON
272             "\xC4\x8E" => "\xC4\x8F", # LATIN CAPITAL LETTER D WITH CARON
273             "\xC4\x90" => "\xC4\x91", # LATIN CAPITAL LETTER D WITH STROKE
274             "\xC4\x92" => "\xC4\x93", # LATIN CAPITAL LETTER E WITH MACRON
275             "\xC4\x94" => "\xC4\x95", # LATIN CAPITAL LETTER E WITH BREVE
276             "\xC4\x96" => "\xC4\x97", # LATIN CAPITAL LETTER E WITH DOT ABOVE
277             "\xC4\x98" => "\xC4\x99", # LATIN CAPITAL LETTER E WITH OGONEK
278             "\xC4\x9A" => "\xC4\x9B", # LATIN CAPITAL LETTER E WITH CARON
279             "\xC4\x9C" => "\xC4\x9D", # LATIN CAPITAL LETTER G WITH CIRCUMFLEX
280             "\xC4\x9E" => "\xC4\x9F", # LATIN CAPITAL LETTER G WITH BREVE
281             "\xC4\xA0" => "\xC4\xA1", # LATIN CAPITAL LETTER G WITH DOT ABOVE
282             "\xC4\xA2" => "\xC4\xA3", # LATIN CAPITAL LETTER G WITH CEDILLA
283             "\xC4\xA4" => "\xC4\xA5", # LATIN CAPITAL LETTER H WITH CIRCUMFLEX
284             "\xC4\xA6" => "\xC4\xA7", # LATIN CAPITAL LETTER H WITH STROKE
285             "\xC4\xA8" => "\xC4\xA9", # LATIN CAPITAL LETTER I WITH TILDE
286             "\xC4\xAA" => "\xC4\xAB", # LATIN CAPITAL LETTER I WITH MACRON
287             "\xC4\xAC" => "\xC4\xAD", # LATIN CAPITAL LETTER I WITH BREVE
288             "\xC4\xAE" => "\xC4\xAF", # LATIN CAPITAL LETTER I WITH OGONEK
289             "\xC4\xB0" => "\x69\xCC\x87", # LATIN CAPITAL LETTER I WITH DOT ABOVE
290             "\xC4\xB2" => "\xC4\xB3", # LATIN CAPITAL LIGATURE IJ
291             "\xC4\xB4" => "\xC4\xB5", # LATIN CAPITAL LETTER J WITH CIRCUMFLEX
292             "\xC4\xB6" => "\xC4\xB7", # LATIN CAPITAL LETTER K WITH CEDILLA
293             "\xC4\xB9" => "\xC4\xBA", # LATIN CAPITAL LETTER L WITH ACUTE
294             "\xC4\xBB" => "\xC4\xBC", # LATIN CAPITAL LETTER L WITH CEDILLA
295             "\xC4\xBD" => "\xC4\xBE", # LATIN CAPITAL LETTER L WITH CARON
296             "\xC4\xBF" => "\xC5\x80", # LATIN CAPITAL LETTER L WITH MIDDLE DOT
297             "\xC5\x81" => "\xC5\x82", # LATIN CAPITAL LETTER L WITH STROKE
298             "\xC5\x83" => "\xC5\x84", # LATIN CAPITAL LETTER N WITH ACUTE
299             "\xC5\x85" => "\xC5\x86", # LATIN CAPITAL LETTER N WITH CEDILLA
300             "\xC5\x87" => "\xC5\x88", # LATIN CAPITAL LETTER N WITH CARON
301             "\xC5\x89" => "\xCA\xBC\x6E", # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
302             "\xC5\x8A" => "\xC5\x8B", # LATIN CAPITAL LETTER ENG
303             "\xC5\x8C" => "\xC5\x8D", # LATIN CAPITAL LETTER O WITH MACRON
304             "\xC5\x8E" => "\xC5\x8F", # LATIN CAPITAL LETTER O WITH BREVE
305             "\xC5\x90" => "\xC5\x91", # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
306             "\xC5\x92" => "\xC5\x93", # LATIN CAPITAL LIGATURE OE
307             "\xC5\x94" => "\xC5\x95", # LATIN CAPITAL LETTER R WITH ACUTE
308             "\xC5\x96" => "\xC5\x97", # LATIN CAPITAL LETTER R WITH CEDILLA
309             "\xC5\x98" => "\xC5\x99", # LATIN CAPITAL LETTER R WITH CARON
310             "\xC5\x9A" => "\xC5\x9B", # LATIN CAPITAL LETTER S WITH ACUTE
311             "\xC5\x9C" => "\xC5\x9D", # LATIN CAPITAL LETTER S WITH CIRCUMFLEX
312             "\xC5\x9E" => "\xC5\x9F", # LATIN CAPITAL LETTER S WITH CEDILLA
313             "\xC5\xA0" => "\xC5\xA1", # LATIN CAPITAL LETTER S WITH CARON
314             "\xC5\xA2" => "\xC5\xA3", # LATIN CAPITAL LETTER T WITH CEDILLA
315             "\xC5\xA4" => "\xC5\xA5", # LATIN CAPITAL LETTER T WITH CARON
316             "\xC5\xA6" => "\xC5\xA7", # LATIN CAPITAL LETTER T WITH STROKE
317             "\xC5\xA8" => "\xC5\xA9", # LATIN CAPITAL LETTER U WITH TILDE
318             "\xC5\xAA" => "\xC5\xAB", # LATIN CAPITAL LETTER U WITH MACRON
319             "\xC5\xAC" => "\xC5\xAD", # LATIN CAPITAL LETTER U WITH BREVE
320             "\xC5\xAE" => "\xC5\xAF", # LATIN CAPITAL LETTER U WITH RING ABOVE
321             "\xC5\xB0" => "\xC5\xB1", # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
322             "\xC5\xB2" => "\xC5\xB3", # LATIN CAPITAL LETTER U WITH OGONEK
323             "\xC5\xB4" => "\xC5\xB5", # LATIN CAPITAL LETTER W WITH CIRCUMFLEX
324             "\xC5\xB6" => "\xC5\xB7", # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
325             "\xC5\xB8" => "\xC3\xBF", # LATIN CAPITAL LETTER Y WITH DIAERESIS
326             "\xC5\xB9" => "\xC5\xBA", # LATIN CAPITAL LETTER Z WITH ACUTE
327             "\xC5\xBB" => "\xC5\xBC", # LATIN CAPITAL LETTER Z WITH DOT ABOVE
328             "\xC5\xBD" => "\xC5\xBE", # LATIN CAPITAL LETTER Z WITH CARON
329             "\xC5\xBF" => "\x73", # LATIN SMALL LETTER LONG S
330             "\xC6\x81" => "\xC9\x93", # LATIN CAPITAL LETTER B WITH HOOK
331             "\xC6\x82" => "\xC6\x83", # LATIN CAPITAL LETTER B WITH TOPBAR
332             "\xC6\x84" => "\xC6\x85", # LATIN CAPITAL LETTER TONE SIX
333             "\xC6\x86" => "\xC9\x94", # LATIN CAPITAL LETTER OPEN O
334             "\xC6\x87" => "\xC6\x88", # LATIN CAPITAL LETTER C WITH HOOK
335             "\xC6\x89" => "\xC9\x96", # LATIN CAPITAL LETTER AFRICAN D
336             "\xC6\x8A" => "\xC9\x97", # LATIN CAPITAL LETTER D WITH HOOK
337             "\xC6\x8B" => "\xC6\x8C", # LATIN CAPITAL LETTER D WITH TOPBAR
338             "\xC6\x8E" => "\xC7\x9D", # LATIN CAPITAL LETTER REVERSED E
339             "\xC6\x8F" => "\xC9\x99", # LATIN CAPITAL LETTER SCHWA
340             "\xC6\x90" => "\xC9\x9B", # LATIN CAPITAL LETTER OPEN E
341             "\xC6\x91" => "\xC6\x92", # LATIN CAPITAL LETTER F WITH HOOK
342             "\xC6\x93" => "\xC9\xA0", # LATIN CAPITAL LETTER G WITH HOOK
343             "\xC6\x94" => "\xC9\xA3", # LATIN CAPITAL LETTER GAMMA
344             "\xC6\x96" => "\xC9\xA9", # LATIN CAPITAL LETTER IOTA
345             "\xC6\x97" => "\xC9\xA8", # LATIN CAPITAL LETTER I WITH STROKE
346             "\xC6\x98" => "\xC6\x99", # LATIN CAPITAL LETTER K WITH HOOK
347             "\xC6\x9C" => "\xC9\xAF", # LATIN CAPITAL LETTER TURNED M
348             "\xC6\x9D" => "\xC9\xB2", # LATIN CAPITAL LETTER N WITH LEFT HOOK
349             "\xC6\x9F" => "\xC9\xB5", # LATIN CAPITAL LETTER O WITH MIDDLE TILDE
350             "\xC6\xA0" => "\xC6\xA1", # LATIN CAPITAL LETTER O WITH HORN
351             "\xC6\xA2" => "\xC6\xA3", # LATIN CAPITAL LETTER OI
352             "\xC6\xA4" => "\xC6\xA5", # LATIN CAPITAL LETTER P WITH HOOK
353             "\xC6\xA6" => "\xCA\x80", # LATIN LETTER YR
354             "\xC6\xA7" => "\xC6\xA8", # LATIN CAPITAL LETTER TONE TWO
355             "\xC6\xA9" => "\xCA\x83", # LATIN CAPITAL LETTER ESH
356             "\xC6\xAC" => "\xC6\xAD", # LATIN CAPITAL LETTER T WITH HOOK
357             "\xC6\xAE" => "\xCA\x88", # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
358             "\xC6\xAF" => "\xC6\xB0", # LATIN CAPITAL LETTER U WITH HORN
359             "\xC6\xB1" => "\xCA\x8A", # LATIN CAPITAL LETTER UPSILON
360             "\xC6\xB2" => "\xCA\x8B", # LATIN CAPITAL LETTER V WITH HOOK
361             "\xC6\xB3" => "\xC6\xB4", # LATIN CAPITAL LETTER Y WITH HOOK
362             "\xC6\xB5" => "\xC6\xB6", # LATIN CAPITAL LETTER Z WITH STROKE
363             "\xC6\xB7" => "\xCA\x92", # LATIN CAPITAL LETTER EZH
364             "\xC6\xB8" => "\xC6\xB9", # LATIN CAPITAL LETTER EZH REVERSED
365             "\xC6\xBC" => "\xC6\xBD", # LATIN CAPITAL LETTER TONE FIVE
366             "\xC7\x84" => "\xC7\x86", # LATIN CAPITAL LETTER DZ WITH CARON
367             "\xC7\x85" => "\xC7\x86", # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
368             "\xC7\x87" => "\xC7\x89", # LATIN CAPITAL LETTER LJ
369             "\xC7\x88" => "\xC7\x89", # LATIN CAPITAL LETTER L WITH SMALL LETTER J
370             "\xC7\x8A" => "\xC7\x8C", # LATIN CAPITAL LETTER NJ
371             "\xC7\x8B" => "\xC7\x8C", # LATIN CAPITAL LETTER N WITH SMALL LETTER J
372             "\xC7\x8D" => "\xC7\x8E", # LATIN CAPITAL LETTER A WITH CARON
373             "\xC7\x8F" => "\xC7\x90", # LATIN CAPITAL LETTER I WITH CARON
374             "\xC7\x91" => "\xC7\x92", # LATIN CAPITAL LETTER O WITH CARON
375             "\xC7\x93" => "\xC7\x94", # LATIN CAPITAL LETTER U WITH CARON
376             "\xC7\x95" => "\xC7\x96", # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
377             "\xC7\x97" => "\xC7\x98", # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
378             "\xC7\x99" => "\xC7\x9A", # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
379             "\xC7\x9B" => "\xC7\x9C", # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
380             "\xC7\x9E" => "\xC7\x9F", # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
381             "\xC7\xA0" => "\xC7\xA1", # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
382             "\xC7\xA2" => "\xC7\xA3", # LATIN CAPITAL LETTER AE WITH MACRON
383             "\xC7\xA4" => "\xC7\xA5", # LATIN CAPITAL LETTER G WITH STROKE
384             "\xC7\xA6" => "\xC7\xA7", # LATIN CAPITAL LETTER G WITH CARON
385             "\xC7\xA8" => "\xC7\xA9", # LATIN CAPITAL LETTER K WITH CARON
386             "\xC7\xAA" => "\xC7\xAB", # LATIN CAPITAL LETTER O WITH OGONEK
387             "\xC7\xAC" => "\xC7\xAD", # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
388             "\xC7\xAE" => "\xC7\xAF", # LATIN CAPITAL LETTER EZH WITH CARON
389             "\xC7\xB0" => "\x6A\xCC\x8C", # LATIN SMALL LETTER J WITH CARON
390             "\xC7\xB1" => "\xC7\xB3", # LATIN CAPITAL LETTER DZ
391             "\xC7\xB2" => "\xC7\xB3", # LATIN CAPITAL LETTER D WITH SMALL LETTER Z
392             "\xC7\xB4" => "\xC7\xB5", # LATIN CAPITAL LETTER G WITH ACUTE
393             "\xC7\xB6" => "\xC6\x95", # LATIN CAPITAL LETTER HWAIR
394             "\xC7\xB7" => "\xC6\xBF", # LATIN CAPITAL LETTER WYNN
395             "\xC7\xB8" => "\xC7\xB9", # LATIN CAPITAL LETTER N WITH GRAVE
396             "\xC7\xBA" => "\xC7\xBB", # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
397             "\xC7\xBC" => "\xC7\xBD", # LATIN CAPITAL LETTER AE WITH ACUTE
398             "\xC7\xBE" => "\xC7\xBF", # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
399             "\xC8\x80" => "\xC8\x81", # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
400             "\xC8\x82" => "\xC8\x83", # LATIN CAPITAL LETTER A WITH INVERTED BREVE
401             "\xC8\x84" => "\xC8\x85", # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
402             "\xC8\x86" => "\xC8\x87", # LATIN CAPITAL LETTER E WITH INVERTED BREVE
403             "\xC8\x88" => "\xC8\x89", # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
404             "\xC8\x8A" => "\xC8\x8B", # LATIN CAPITAL LETTER I WITH INVERTED BREVE
405             "\xC8\x8C" => "\xC8\x8D", # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
406             "\xC8\x8E" => "\xC8\x8F", # LATIN CAPITAL LETTER O WITH INVERTED BREVE
407             "\xC8\x90" => "\xC8\x91", # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
408             "\xC8\x92" => "\xC8\x93", # LATIN CAPITAL LETTER R WITH INVERTED BREVE
409             "\xC8\x94" => "\xC8\x95", # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
410             "\xC8\x96" => "\xC8\x97", # LATIN CAPITAL LETTER U WITH INVERTED BREVE
411             "\xC8\x98" => "\xC8\x99", # LATIN CAPITAL LETTER S WITH COMMA BELOW
412             "\xC8\x9A" => "\xC8\x9B", # LATIN CAPITAL LETTER T WITH COMMA BELOW
413             "\xC8\x9C" => "\xC8\x9D", # LATIN CAPITAL LETTER YOGH
414             "\xC8\x9E" => "\xC8\x9F", # LATIN CAPITAL LETTER H WITH CARON
415             "\xC8\xA0" => "\xC6\x9E", # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
416             "\xC8\xA2" => "\xC8\xA3", # LATIN CAPITAL LETTER OU
417             "\xC8\xA4" => "\xC8\xA5", # LATIN CAPITAL LETTER Z WITH HOOK
418             "\xC8\xA6" => "\xC8\xA7", # LATIN CAPITAL LETTER A WITH DOT ABOVE
419             "\xC8\xA8" => "\xC8\xA9", # LATIN CAPITAL LETTER E WITH CEDILLA
420             "\xC8\xAA" => "\xC8\xAB", # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
421             "\xC8\xAC" => "\xC8\xAD", # LATIN CAPITAL LETTER O WITH TILDE AND MACRON
422             "\xC8\xAE" => "\xC8\xAF", # LATIN CAPITAL LETTER O WITH DOT ABOVE
423             "\xC8\xB0" => "\xC8\xB1", # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
424             "\xC8\xB2" => "\xC8\xB3", # LATIN CAPITAL LETTER Y WITH MACRON
425             "\xC8\xBA" => "\xE2\xB1\xA5", # LATIN CAPITAL LETTER A WITH STROKE
426             "\xC8\xBB" => "\xC8\xBC", # LATIN CAPITAL LETTER C WITH STROKE
427             "\xC8\xBD" => "\xC6\x9A", # LATIN CAPITAL LETTER L WITH BAR
428             "\xC8\xBE" => "\xE2\xB1\xA6", # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
429             "\xC9\x81" => "\xC9\x82", # LATIN CAPITAL LETTER GLOTTAL STOP
430             "\xC9\x83" => "\xC6\x80", # LATIN CAPITAL LETTER B WITH STROKE
431             "\xC9\x84" => "\xCA\x89", # LATIN CAPITAL LETTER U BAR
432             "\xC9\x85" => "\xCA\x8C", # LATIN CAPITAL LETTER TURNED V
433             "\xC9\x86" => "\xC9\x87", # LATIN CAPITAL LETTER E WITH STROKE
434             "\xC9\x88" => "\xC9\x89", # LATIN CAPITAL LETTER J WITH STROKE
435             "\xC9\x8A" => "\xC9\x8B", # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
436             "\xC9\x8C" => "\xC9\x8D", # LATIN CAPITAL LETTER R WITH STROKE
437             "\xC9\x8E" => "\xC9\x8F", # LATIN CAPITAL LETTER Y WITH STROKE
438             "\xCD\x85" => "\xCE\xB9", # COMBINING GREEK YPOGEGRAMMENI
439             "\xCD\xB0" => "\xCD\xB1", # GREEK CAPITAL LETTER HETA
440             "\xCD\xB2" => "\xCD\xB3", # GREEK CAPITAL LETTER ARCHAIC SAMPI
441             "\xCD\xB6" => "\xCD\xB7", # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA
442             "\xCD\xBF" => "\xCF\xB3", # GREEK CAPITAL LETTER YOT
443             "\xCE\x86" => "\xCE\xAC", # GREEK CAPITAL LETTER ALPHA WITH TONOS
444             "\xCE\x88" => "\xCE\xAD", # GREEK CAPITAL LETTER EPSILON WITH TONOS
445             "\xCE\x89" => "\xCE\xAE", # GREEK CAPITAL LETTER ETA WITH TONOS
446             "\xCE\x8A" => "\xCE\xAF", # GREEK CAPITAL LETTER IOTA WITH TONOS
447             "\xCE\x8C" => "\xCF\x8C", # GREEK CAPITAL LETTER OMICRON WITH TONOS
448             "\xCE\x8E" => "\xCF\x8D", # GREEK CAPITAL LETTER UPSILON WITH TONOS
449             "\xCE\x8F" => "\xCF\x8E", # GREEK CAPITAL LETTER OMEGA WITH TONOS
450             "\xCE\x90" => "\xCE\xB9\xCC\x88\xCC\x81", # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
451             "\xCE\x91" => "\xCE\xB1", # GREEK CAPITAL LETTER ALPHA
452             "\xCE\x92" => "\xCE\xB2", # GREEK CAPITAL LETTER BETA
453             "\xCE\x93" => "\xCE\xB3", # GREEK CAPITAL LETTER GAMMA
454             "\xCE\x94" => "\xCE\xB4", # GREEK CAPITAL LETTER DELTA
455             "\xCE\x95" => "\xCE\xB5", # GREEK CAPITAL LETTER EPSILON
456             "\xCE\x96" => "\xCE\xB6", # GREEK CAPITAL LETTER ZETA
457             "\xCE\x97" => "\xCE\xB7", # GREEK CAPITAL LETTER ETA
458             "\xCE\x98" => "\xCE\xB8", # GREEK CAPITAL LETTER THETA
459             "\xCE\x99" => "\xCE\xB9", # GREEK CAPITAL LETTER IOTA
460             "\xCE\x9A" => "\xCE\xBA", # GREEK CAPITAL LETTER KAPPA
461             "\xCE\x9B" => "\xCE\xBB", # GREEK CAPITAL LETTER LAMDA
462             "\xCE\x9C" => "\xCE\xBC", # GREEK CAPITAL LETTER MU
463             "\xCE\x9D" => "\xCE\xBD", # GREEK CAPITAL LETTER NU
464             "\xCE\x9E" => "\xCE\xBE", # GREEK CAPITAL LETTER XI
465             "\xCE\x9F" => "\xCE\xBF", # GREEK CAPITAL LETTER OMICRON
466             "\xCE\xA0" => "\xCF\x80", # GREEK CAPITAL LETTER PI
467             "\xCE\xA1" => "\xCF\x81", # GREEK CAPITAL LETTER RHO
468             "\xCE\xA3" => "\xCF\x83", # GREEK CAPITAL LETTER SIGMA
469             "\xCE\xA4" => "\xCF\x84", # GREEK CAPITAL LETTER TAU
470             "\xCE\xA5" => "\xCF\x85", # GREEK CAPITAL LETTER UPSILON
471             "\xCE\xA6" => "\xCF\x86", # GREEK CAPITAL LETTER PHI
472             "\xCE\xA7" => "\xCF\x87", # GREEK CAPITAL LETTER CHI
473             "\xCE\xA8" => "\xCF\x88", # GREEK CAPITAL LETTER PSI
474             "\xCE\xA9" => "\xCF\x89", # GREEK CAPITAL LETTER OMEGA
475             "\xCE\xAA" => "\xCF\x8A", # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
476             "\xCE\xAB" => "\xCF\x8B", # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
477             "\xCE\xB0" => "\xCF\x85\xCC\x88\xCC\x81", # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
478             "\xCF\x82" => "\xCF\x83", # GREEK SMALL LETTER FINAL SIGMA
479             "\xCF\x8F" => "\xCF\x97", # GREEK CAPITAL KAI SYMBOL
480             "\xCF\x90" => "\xCE\xB2", # GREEK BETA SYMBOL
481             "\xCF\x91" => "\xCE\xB8", # GREEK THETA SYMBOL
482             "\xCF\x95" => "\xCF\x86", # GREEK PHI SYMBOL
483             "\xCF\x96" => "\xCF\x80", # GREEK PI SYMBOL
484             "\xCF\x98" => "\xCF\x99", # GREEK LETTER ARCHAIC KOPPA
485             "\xCF\x9A" => "\xCF\x9B", # GREEK LETTER STIGMA
486             "\xCF\x9C" => "\xCF\x9D", # GREEK LETTER DIGAMMA
487             "\xCF\x9E" => "\xCF\x9F", # GREEK LETTER KOPPA
488             "\xCF\xA0" => "\xCF\xA1", # GREEK LETTER SAMPI
489             "\xCF\xA2" => "\xCF\xA3", # COPTIC CAPITAL LETTER SHEI
490             "\xCF\xA4" => "\xCF\xA5", # COPTIC CAPITAL LETTER FEI
491             "\xCF\xA6" => "\xCF\xA7", # COPTIC CAPITAL LETTER KHEI
492             "\xCF\xA8" => "\xCF\xA9", # COPTIC CAPITAL LETTER HORI
493             "\xCF\xAA" => "\xCF\xAB", # COPTIC CAPITAL LETTER GANGIA
494             "\xCF\xAC" => "\xCF\xAD", # COPTIC CAPITAL LETTER SHIMA
495             "\xCF\xAE" => "\xCF\xAF", # COPTIC CAPITAL LETTER DEI
496             "\xCF\xB0" => "\xCE\xBA", # GREEK KAPPA SYMBOL
497             "\xCF\xB1" => "\xCF\x81", # GREEK RHO SYMBOL
498             "\xCF\xB4" => "\xCE\xB8", # GREEK CAPITAL THETA SYMBOL
499             "\xCF\xB5" => "\xCE\xB5", # GREEK LUNATE EPSILON SYMBOL
500             "\xCF\xB7" => "\xCF\xB8", # GREEK CAPITAL LETTER SHO
501             "\xCF\xB9" => "\xCF\xB2", # GREEK CAPITAL LUNATE SIGMA SYMBOL
502             "\xCF\xBA" => "\xCF\xBB", # GREEK CAPITAL LETTER SAN
503             "\xCF\xBD" => "\xCD\xBB", # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL
504             "\xCF\xBE" => "\xCD\xBC", # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL
505             "\xCF\xBF" => "\xCD\xBD", # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
506             "\xD0\x80" => "\xD1\x90", # CYRILLIC CAPITAL LETTER IE WITH GRAVE
507             "\xD0\x81" => "\xD1\x91", # CYRILLIC CAPITAL LETTER IO
508             "\xD0\x82" => "\xD1\x92", # CYRILLIC CAPITAL LETTER DJE
509             "\xD0\x83" => "\xD1\x93", # CYRILLIC CAPITAL LETTER GJE
510             "\xD0\x84" => "\xD1\x94", # CYRILLIC CAPITAL LETTER UKRAINIAN IE
511             "\xD0\x85" => "\xD1\x95", # CYRILLIC CAPITAL LETTER DZE
512             "\xD0\x86" => "\xD1\x96", # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
513             "\xD0\x87" => "\xD1\x97", # CYRILLIC CAPITAL LETTER YI
514             "\xD0\x88" => "\xD1\x98", # CYRILLIC CAPITAL LETTER JE
515             "\xD0\x89" => "\xD1\x99", # CYRILLIC CAPITAL LETTER LJE
516             "\xD0\x8A" => "\xD1\x9A", # CYRILLIC CAPITAL LETTER NJE
517             "\xD0\x8B" => "\xD1\x9B", # CYRILLIC CAPITAL LETTER TSHE
518             "\xD0\x8C" => "\xD1\x9C", # CYRILLIC CAPITAL LETTER KJE
519             "\xD0\x8D" => "\xD1\x9D", # CYRILLIC CAPITAL LETTER I WITH GRAVE
520             "\xD0\x8E" => "\xD1\x9E", # CYRILLIC CAPITAL LETTER SHORT U
521             "\xD0\x8F" => "\xD1\x9F", # CYRILLIC CAPITAL LETTER DZHE
522             "\xD0\x90" => "\xD0\xB0", # CYRILLIC CAPITAL LETTER A
523             "\xD0\x91" => "\xD0\xB1", # CYRILLIC CAPITAL LETTER BE
524             "\xD0\x92" => "\xD0\xB2", # CYRILLIC CAPITAL LETTER VE
525             "\xD0\x93" => "\xD0\xB3", # CYRILLIC CAPITAL LETTER GHE
526             "\xD0\x94" => "\xD0\xB4", # CYRILLIC CAPITAL LETTER DE
527             "\xD0\x95" => "\xD0\xB5", # CYRILLIC CAPITAL LETTER IE
528             "\xD0\x96" => "\xD0\xB6", # CYRILLIC CAPITAL LETTER ZHE
529             "\xD0\x97" => "\xD0\xB7", # CYRILLIC CAPITAL LETTER ZE
530             "\xD0\x98" => "\xD0\xB8", # CYRILLIC CAPITAL LETTER I
531             "\xD0\x99" => "\xD0\xB9", # CYRILLIC CAPITAL LETTER SHORT I
532             "\xD0\x9A" => "\xD0\xBA", # CYRILLIC CAPITAL LETTER KA
533             "\xD0\x9B" => "\xD0\xBB", # CYRILLIC CAPITAL LETTER EL
534             "\xD0\x9C" => "\xD0\xBC", # CYRILLIC CAPITAL LETTER EM
535             "\xD0\x9D" => "\xD0\xBD", # CYRILLIC CAPITAL LETTER EN
536             "\xD0\x9E" => "\xD0\xBE", # CYRILLIC CAPITAL LETTER O
537             "\xD0\x9F" => "\xD0\xBF", # CYRILLIC CAPITAL LETTER PE
538             "\xD0\xA0" => "\xD1\x80", # CYRILLIC CAPITAL LETTER ER
539             "\xD0\xA1" => "\xD1\x81", # CYRILLIC CAPITAL LETTER ES
540             "\xD0\xA2" => "\xD1\x82", # CYRILLIC CAPITAL LETTER TE
541             "\xD0\xA3" => "\xD1\x83", # CYRILLIC CAPITAL LETTER U
542             "\xD0\xA4" => "\xD1\x84", # CYRILLIC CAPITAL LETTER EF
543             "\xD0\xA5" => "\xD1\x85", # CYRILLIC CAPITAL LETTER HA
544             "\xD0\xA6" => "\xD1\x86", # CYRILLIC CAPITAL LETTER TSE
545             "\xD0\xA7" => "\xD1\x87", # CYRILLIC CAPITAL LETTER CHE
546             "\xD0\xA8" => "\xD1\x88", # CYRILLIC CAPITAL LETTER SHA
547             "\xD0\xA9" => "\xD1\x89", # CYRILLIC CAPITAL LETTER SHCHA
548             "\xD0\xAA" => "\xD1\x8A", # CYRILLIC CAPITAL LETTER HARD SIGN
549             "\xD0\xAB" => "\xD1\x8B", # CYRILLIC CAPITAL LETTER YERU
550             "\xD0\xAC" => "\xD1\x8C", # CYRILLIC CAPITAL LETTER SOFT SIGN
551             "\xD0\xAD" => "\xD1\x8D", # CYRILLIC CAPITAL LETTER E
552             "\xD0\xAE" => "\xD1\x8E", # CYRILLIC CAPITAL LETTER YU
553             "\xD0\xAF" => "\xD1\x8F", # CYRILLIC CAPITAL LETTER YA
554             "\xD1\xA0" => "\xD1\xA1", # CYRILLIC CAPITAL LETTER OMEGA
555             "\xD1\xA2" => "\xD1\xA3", # CYRILLIC CAPITAL LETTER YAT
556             "\xD1\xA4" => "\xD1\xA5", # CYRILLIC CAPITAL LETTER IOTIFIED E
557             "\xD1\xA6" => "\xD1\xA7", # CYRILLIC CAPITAL LETTER LITTLE YUS
558             "\xD1\xA8" => "\xD1\xA9", # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
559             "\xD1\xAA" => "\xD1\xAB", # CYRILLIC CAPITAL LETTER BIG YUS
560             "\xD1\xAC" => "\xD1\xAD", # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
561             "\xD1\xAE" => "\xD1\xAF", # CYRILLIC CAPITAL LETTER KSI
562             "\xD1\xB0" => "\xD1\xB1", # CYRILLIC CAPITAL LETTER PSI
563             "\xD1\xB2" => "\xD1\xB3", # CYRILLIC CAPITAL LETTER FITA
564             "\xD1\xB4" => "\xD1\xB5", # CYRILLIC CAPITAL LETTER IZHITSA
565             "\xD1\xB6" => "\xD1\xB7", # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
566             "\xD1\xB8" => "\xD1\xB9", # CYRILLIC CAPITAL LETTER UK
567             "\xD1\xBA" => "\xD1\xBB", # CYRILLIC CAPITAL LETTER ROUND OMEGA
568             "\xD1\xBC" => "\xD1\xBD", # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
569             "\xD1\xBE" => "\xD1\xBF", # CYRILLIC CAPITAL LETTER OT
570             "\xD2\x80" => "\xD2\x81", # CYRILLIC CAPITAL LETTER KOPPA
571             "\xD2\x8A" => "\xD2\x8B", # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
572             "\xD2\x8C" => "\xD2\x8D", # CYRILLIC CAPITAL LETTER SEMISOFT SIGN
573             "\xD2\x8E" => "\xD2\x8F", # CYRILLIC CAPITAL LETTER ER WITH TICK
574             "\xD2\x90" => "\xD2\x91", # CYRILLIC CAPITAL LETTER GHE WITH UPTURN
575             "\xD2\x92" => "\xD2\x93", # CYRILLIC CAPITAL LETTER GHE WITH STROKE
576             "\xD2\x94" => "\xD2\x95", # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
577             "\xD2\x96" => "\xD2\x97", # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
578             "\xD2\x98" => "\xD2\x99", # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
579             "\xD2\x9A" => "\xD2\x9B", # CYRILLIC CAPITAL LETTER KA WITH DESCENDER
580             "\xD2\x9C" => "\xD2\x9D", # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
581             "\xD2\x9E" => "\xD2\x9F", # CYRILLIC CAPITAL LETTER KA WITH STROKE
582             "\xD2\xA0" => "\xD2\xA1", # CYRILLIC CAPITAL LETTER BASHKIR KA
583             "\xD2\xA2" => "\xD2\xA3", # CYRILLIC CAPITAL LETTER EN WITH DESCENDER
584             "\xD2\xA4" => "\xD2\xA5", # CYRILLIC CAPITAL LIGATURE EN GHE
585             "\xD2\xA6" => "\xD2\xA7", # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
586             "\xD2\xA8" => "\xD2\xA9", # CYRILLIC CAPITAL LETTER ABKHASIAN HA
587             "\xD2\xAA" => "\xD2\xAB", # CYRILLIC CAPITAL LETTER ES WITH DESCENDER
588             "\xD2\xAC" => "\xD2\xAD", # CYRILLIC CAPITAL LETTER TE WITH DESCENDER
589             "\xD2\xAE" => "\xD2\xAF", # CYRILLIC CAPITAL LETTER STRAIGHT U
590             "\xD2\xB0" => "\xD2\xB1", # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
591             "\xD2\xB2" => "\xD2\xB3", # CYRILLIC CAPITAL LETTER HA WITH DESCENDER
592             "\xD2\xB4" => "\xD2\xB5", # CYRILLIC CAPITAL LIGATURE TE TSE
593             "\xD2\xB6" => "\xD2\xB7", # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
594             "\xD2\xB8" => "\xD2\xB9", # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
595             "\xD2\xBA" => "\xD2\xBB", # CYRILLIC CAPITAL LETTER SHHA
596             "\xD2\xBC" => "\xD2\xBD", # CYRILLIC CAPITAL LETTER ABKHASIAN CHE
597             "\xD2\xBE" => "\xD2\xBF", # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
598             "\xD3\x80" => "\xD3\x8F", # CYRILLIC LETTER PALOCHKA
599             "\xD3\x81" => "\xD3\x82", # CYRILLIC CAPITAL LETTER ZHE WITH BREVE
600             "\xD3\x83" => "\xD3\x84", # CYRILLIC CAPITAL LETTER KA WITH HOOK
601             "\xD3\x85" => "\xD3\x86", # CYRILLIC CAPITAL LETTER EL WITH TAIL
602             "\xD3\x87" => "\xD3\x88", # CYRILLIC CAPITAL LETTER EN WITH HOOK
603             "\xD3\x89" => "\xD3\x8A", # CYRILLIC CAPITAL LETTER EN WITH TAIL
604             "\xD3\x8B" => "\xD3\x8C", # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
605             "\xD3\x8D" => "\xD3\x8E", # CYRILLIC CAPITAL LETTER EM WITH TAIL
606             "\xD3\x90" => "\xD3\x91", # CYRILLIC CAPITAL LETTER A WITH BREVE
607             "\xD3\x92" => "\xD3\x93", # CYRILLIC CAPITAL LETTER A WITH DIAERESIS
608             "\xD3\x94" => "\xD3\x95", # CYRILLIC CAPITAL LIGATURE A IE
609             "\xD3\x96" => "\xD3\x97", # CYRILLIC CAPITAL LETTER IE WITH BREVE
610             "\xD3\x98" => "\xD3\x99", # CYRILLIC CAPITAL LETTER SCHWA
611             "\xD3\x9A" => "\xD3\x9B", # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
612             "\xD3\x9C" => "\xD3\x9D", # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
613             "\xD3\x9E" => "\xD3\x9F", # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
614             "\xD3\xA0" => "\xD3\xA1", # CYRILLIC CAPITAL LETTER ABKHASIAN DZE
615             "\xD3\xA2" => "\xD3\xA3", # CYRILLIC CAPITAL LETTER I WITH MACRON
616             "\xD3\xA4" => "\xD3\xA5", # CYRILLIC CAPITAL LETTER I WITH DIAERESIS
617             "\xD3\xA6" => "\xD3\xA7", # CYRILLIC CAPITAL LETTER O WITH DIAERESIS
618             "\xD3\xA8" => "\xD3\xA9", # CYRILLIC CAPITAL LETTER BARRED O
619             "\xD3\xAA" => "\xD3\xAB", # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
620             "\xD3\xAC" => "\xD3\xAD", # CYRILLIC CAPITAL LETTER E WITH DIAERESIS
621             "\xD3\xAE" => "\xD3\xAF", # CYRILLIC CAPITAL LETTER U WITH MACRON
622             "\xD3\xB0" => "\xD3\xB1", # CYRILLIC CAPITAL LETTER U WITH DIAERESIS
623             "\xD3\xB2" => "\xD3\xB3", # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
624             "\xD3\xB4" => "\xD3\xB5", # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
625             "\xD3\xB6" => "\xD3\xB7", # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
626             "\xD3\xB8" => "\xD3\xB9", # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
627             "\xD3\xBA" => "\xD3\xBB", # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
628             "\xD3\xBC" => "\xD3\xBD", # CYRILLIC CAPITAL LETTER HA WITH HOOK
629             "\xD3\xBE" => "\xD3\xBF", # CYRILLIC CAPITAL LETTER HA WITH STROKE
630             "\xD4\x80" => "\xD4\x81", # CYRILLIC CAPITAL LETTER KOMI DE
631             "\xD4\x82" => "\xD4\x83", # CYRILLIC CAPITAL LETTER KOMI DJE
632             "\xD4\x84" => "\xD4\x85", # CYRILLIC CAPITAL LETTER KOMI ZJE
633             "\xD4\x86" => "\xD4\x87", # CYRILLIC CAPITAL LETTER KOMI DZJE
634             "\xD4\x88" => "\xD4\x89", # CYRILLIC CAPITAL LETTER KOMI LJE
635             "\xD4\x8A" => "\xD4\x8B", # CYRILLIC CAPITAL LETTER KOMI NJE
636             "\xD4\x8C" => "\xD4\x8D", # CYRILLIC CAPITAL LETTER KOMI SJE
637             "\xD4\x8E" => "\xD4\x8F", # CYRILLIC CAPITAL LETTER KOMI TJE
638             "\xD4\x90" => "\xD4\x91", # CYRILLIC CAPITAL LETTER REVERSED ZE
639             "\xD4\x92" => "\xD4\x93", # CYRILLIC CAPITAL LETTER EL WITH HOOK
640             "\xD4\x94" => "\xD4\x95", # CYRILLIC CAPITAL LETTER LHA
641             "\xD4\x96" => "\xD4\x97", # CYRILLIC CAPITAL LETTER RHA
642             "\xD4\x98" => "\xD4\x99", # CYRILLIC CAPITAL LETTER YAE
643             "\xD4\x9A" => "\xD4\x9B", # CYRILLIC CAPITAL LETTER QA
644             "\xD4\x9C" => "\xD4\x9D", # CYRILLIC CAPITAL LETTER WE
645             "\xD4\x9E" => "\xD4\x9F", # CYRILLIC CAPITAL LETTER ALEUT KA
646             "\xD4\xA0" => "\xD4\xA1", # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK
647             "\xD4\xA2" => "\xD4\xA3", # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK
648             "\xD4\xA4" => "\xD4\xA5", # CYRILLIC CAPITAL LETTER PE WITH DESCENDER
649             "\xD4\xA6" => "\xD4\xA7", # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER
650             "\xD4\xA8" => "\xD4\xA9", # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK
651             "\xD4\xAA" => "\xD4\xAB", # CYRILLIC CAPITAL LETTER DZZHE
652             "\xD4\xAC" => "\xD4\xAD", # CYRILLIC CAPITAL LETTER DCHE
653             "\xD4\xAE" => "\xD4\xAF", # CYRILLIC CAPITAL LETTER EL WITH DESCENDER
654             "\xD4\xB1" => "\xD5\xA1", # ARMENIAN CAPITAL LETTER AYB
655             "\xD4\xB2" => "\xD5\xA2", # ARMENIAN CAPITAL LETTER BEN
656             "\xD4\xB3" => "\xD5\xA3", # ARMENIAN CAPITAL LETTER GIM
657             "\xD4\xB4" => "\xD5\xA4", # ARMENIAN CAPITAL LETTER DA
658             "\xD4\xB5" => "\xD5\xA5", # ARMENIAN CAPITAL LETTER ECH
659             "\xD4\xB6" => "\xD5\xA6", # ARMENIAN CAPITAL LETTER ZA
660             "\xD4\xB7" => "\xD5\xA7", # ARMENIAN CAPITAL LETTER EH
661             "\xD4\xB8" => "\xD5\xA8", # ARMENIAN CAPITAL LETTER ET
662             "\xD4\xB9" => "\xD5\xA9", # ARMENIAN CAPITAL LETTER TO
663             "\xD4\xBA" => "\xD5\xAA", # ARMENIAN CAPITAL LETTER ZHE
664             "\xD4\xBB" => "\xD5\xAB", # ARMENIAN CAPITAL LETTER INI
665             "\xD4\xBC" => "\xD5\xAC", # ARMENIAN CAPITAL LETTER LIWN
666             "\xD4\xBD" => "\xD5\xAD", # ARMENIAN CAPITAL LETTER XEH
667             "\xD4\xBE" => "\xD5\xAE", # ARMENIAN CAPITAL LETTER CA
668             "\xD4\xBF" => "\xD5\xAF", # ARMENIAN CAPITAL LETTER KEN
669             "\xD5\x80" => "\xD5\xB0", # ARMENIAN CAPITAL LETTER HO
670             "\xD5\x81" => "\xD5\xB1", # ARMENIAN CAPITAL LETTER JA
671             "\xD5\x82" => "\xD5\xB2", # ARMENIAN CAPITAL LETTER GHAD
672             "\xD5\x83" => "\xD5\xB3", # ARMENIAN CAPITAL LETTER CHEH
673             "\xD5\x84" => "\xD5\xB4", # ARMENIAN CAPITAL LETTER MEN
674             "\xD5\x85" => "\xD5\xB5", # ARMENIAN CAPITAL LETTER YI
675             "\xD5\x86" => "\xD5\xB6", # ARMENIAN CAPITAL LETTER NOW
676             "\xD5\x87" => "\xD5\xB7", # ARMENIAN CAPITAL LETTER SHA
677             "\xD5\x88" => "\xD5\xB8", # ARMENIAN CAPITAL LETTER VO
678             "\xD5\x89" => "\xD5\xB9", # ARMENIAN CAPITAL LETTER CHA
679             "\xD5\x8A" => "\xD5\xBA", # ARMENIAN CAPITAL LETTER PEH
680             "\xD5\x8B" => "\xD5\xBB", # ARMENIAN CAPITAL LETTER JHEH
681             "\xD5\x8C" => "\xD5\xBC", # ARMENIAN CAPITAL LETTER RA
682             "\xD5\x8D" => "\xD5\xBD", # ARMENIAN CAPITAL LETTER SEH
683             "\xD5\x8E" => "\xD5\xBE", # ARMENIAN CAPITAL LETTER VEW
684             "\xD5\x8F" => "\xD5\xBF", # ARMENIAN CAPITAL LETTER TIWN
685             "\xD5\x90" => "\xD6\x80", # ARMENIAN CAPITAL LETTER REH
686             "\xD5\x91" => "\xD6\x81", # ARMENIAN CAPITAL LETTER CO
687             "\xD5\x92" => "\xD6\x82", # ARMENIAN CAPITAL LETTER YIWN
688             "\xD5\x93" => "\xD6\x83", # ARMENIAN CAPITAL LETTER PIWR
689             "\xD5\x94" => "\xD6\x84", # ARMENIAN CAPITAL LETTER KEH
690             "\xD5\x95" => "\xD6\x85", # ARMENIAN CAPITAL LETTER OH
691             "\xD5\x96" => "\xD6\x86", # ARMENIAN CAPITAL LETTER FEH
692             "\xD6\x87" => "\xD5\xA5\xD6\x82", # ARMENIAN SMALL LIGATURE ECH YIWN
693             "\xE1\x82\xA0" => "\xE2\xB4\x80", # GEORGIAN CAPITAL LETTER AN
694             "\xE1\x82\xA1" => "\xE2\xB4\x81", # GEORGIAN CAPITAL LETTER BAN
695             "\xE1\x82\xA2" => "\xE2\xB4\x82", # GEORGIAN CAPITAL LETTER GAN
696             "\xE1\x82\xA3" => "\xE2\xB4\x83", # GEORGIAN CAPITAL LETTER DON
697             "\xE1\x82\xA4" => "\xE2\xB4\x84", # GEORGIAN CAPITAL LETTER EN
698             "\xE1\x82\xA5" => "\xE2\xB4\x85", # GEORGIAN CAPITAL LETTER VIN
699             "\xE1\x82\xA6" => "\xE2\xB4\x86", # GEORGIAN CAPITAL LETTER ZEN
700             "\xE1\x82\xA7" => "\xE2\xB4\x87", # GEORGIAN CAPITAL LETTER TAN
701             "\xE1\x82\xA8" => "\xE2\xB4\x88", # GEORGIAN CAPITAL LETTER IN
702             "\xE1\x82\xA9" => "\xE2\xB4\x89", # GEORGIAN CAPITAL LETTER KAN
703             "\xE1\x82\xAA" => "\xE2\xB4\x8A", # GEORGIAN CAPITAL LETTER LAS
704             "\xE1\x82\xAB" => "\xE2\xB4\x8B", # GEORGIAN CAPITAL LETTER MAN
705             "\xE1\x82\xAC" => "\xE2\xB4\x8C", # GEORGIAN CAPITAL LETTER NAR
706             "\xE1\x82\xAD" => "\xE2\xB4\x8D", # GEORGIAN CAPITAL LETTER ON
707             "\xE1\x82\xAE" => "\xE2\xB4\x8E", # GEORGIAN CAPITAL LETTER PAR
708             "\xE1\x82\xAF" => "\xE2\xB4\x8F", # GEORGIAN CAPITAL LETTER ZHAR
709             "\xE1\x82\xB0" => "\xE2\xB4\x90", # GEORGIAN CAPITAL LETTER RAE
710             "\xE1\x82\xB1" => "\xE2\xB4\x91", # GEORGIAN CAPITAL LETTER SAN
711             "\xE1\x82\xB2" => "\xE2\xB4\x92", # GEORGIAN CAPITAL LETTER TAR
712             "\xE1\x82\xB3" => "\xE2\xB4\x93", # GEORGIAN CAPITAL LETTER UN
713             "\xE1\x82\xB4" => "\xE2\xB4\x94", # GEORGIAN CAPITAL LETTER PHAR
714             "\xE1\x82\xB5" => "\xE2\xB4\x95", # GEORGIAN CAPITAL LETTER KHAR
715             "\xE1\x82\xB6" => "\xE2\xB4\x96", # GEORGIAN CAPITAL LETTER GHAN
716             "\xE1\x82\xB7" => "\xE2\xB4\x97", # GEORGIAN CAPITAL LETTER QAR
717             "\xE1\x82\xB8" => "\xE2\xB4\x98", # GEORGIAN CAPITAL LETTER SHIN
718             "\xE1\x82\xB9" => "\xE2\xB4\x99", # GEORGIAN CAPITAL LETTER CHIN
719             "\xE1\x82\xBA" => "\xE2\xB4\x9A", # GEORGIAN CAPITAL LETTER CAN
720             "\xE1\x82\xBB" => "\xE2\xB4\x9B", # GEORGIAN CAPITAL LETTER JIL
721             "\xE1\x82\xBC" => "\xE2\xB4\x9C", # GEORGIAN CAPITAL LETTER CIL
722             "\xE1\x82\xBD" => "\xE2\xB4\x9D", # GEORGIAN CAPITAL LETTER CHAR
723             "\xE1\x82\xBE" => "\xE2\xB4\x9E", # GEORGIAN CAPITAL LETTER XAN
724             "\xE1\x82\xBF" => "\xE2\xB4\x9F", # GEORGIAN CAPITAL LETTER JHAN
725             "\xE1\x83\x80" => "\xE2\xB4\xA0", # GEORGIAN CAPITAL LETTER HAE
726             "\xE1\x83\x81" => "\xE2\xB4\xA1", # GEORGIAN CAPITAL LETTER HE
727             "\xE1\x83\x82" => "\xE2\xB4\xA2", # GEORGIAN CAPITAL LETTER HIE
728             "\xE1\x83\x83" => "\xE2\xB4\xA3", # GEORGIAN CAPITAL LETTER WE
729             "\xE1\x83\x84" => "\xE2\xB4\xA4", # GEORGIAN CAPITAL LETTER HAR
730             "\xE1\x83\x85" => "\xE2\xB4\xA5", # GEORGIAN CAPITAL LETTER HOE
731             "\xE1\x83\x87" => "\xE2\xB4\xA7", # GEORGIAN CAPITAL LETTER YN
732             "\xE1\x83\x8D" => "\xE2\xB4\xAD", # GEORGIAN CAPITAL LETTER AEN
733             "\xE1\x8F\xB8" => "\xE1\x8F\xB0", # CHEROKEE SMALL LETTER YE
734             "\xE1\x8F\xB9" => "\xE1\x8F\xB1", # CHEROKEE SMALL LETTER YI
735             "\xE1\x8F\xBA" => "\xE1\x8F\xB2", # CHEROKEE SMALL LETTER YO
736             "\xE1\x8F\xBB" => "\xE1\x8F\xB3", # CHEROKEE SMALL LETTER YU
737             "\xE1\x8F\xBC" => "\xE1\x8F\xB4", # CHEROKEE SMALL LETTER YV
738             "\xE1\x8F\xBD" => "\xE1\x8F\xB5", # CHEROKEE SMALL LETTER MV
739             "\xE1\xB2\x80" => "\xD0\xB2", # CYRILLIC SMALL LETTER ROUNDED VE
740             "\xE1\xB2\x81" => "\xD0\xB4", # CYRILLIC SMALL LETTER LONG-LEGGED DE
741             "\xE1\xB2\x82" => "\xD0\xBE", # CYRILLIC SMALL LETTER NARROW O
742             "\xE1\xB2\x83" => "\xD1\x81", # CYRILLIC SMALL LETTER WIDE ES
743             "\xE1\xB2\x84" => "\xD1\x82", # CYRILLIC SMALL LETTER TALL TE
744             "\xE1\xB2\x85" => "\xD1\x82", # CYRILLIC SMALL LETTER THREE-LEGGED TE
745             "\xE1\xB2\x86" => "\xD1\x8A", # CYRILLIC SMALL LETTER TALL HARD SIGN
746             "\xE1\xB2\x87" => "\xD1\xA3", # CYRILLIC SMALL LETTER TALL YAT
747             "\xE1\xB2\x88" => "\xEA\x99\x8B", # CYRILLIC SMALL LETTER UNBLENDED UK
748             "\xE1\xB2\x90" => "\xE1\x83\x90", # GEORGIAN MTAVRULI CAPITAL LETTER AN
749             "\xE1\xB2\x91" => "\xE1\x83\x91", # GEORGIAN MTAVRULI CAPITAL LETTER BAN
750             "\xE1\xB2\x92" => "\xE1\x83\x92", # GEORGIAN MTAVRULI CAPITAL LETTER GAN
751             "\xE1\xB2\x93" => "\xE1\x83\x93", # GEORGIAN MTAVRULI CAPITAL LETTER DON
752             "\xE1\xB2\x94" => "\xE1\x83\x94", # GEORGIAN MTAVRULI CAPITAL LETTER EN
753             "\xE1\xB2\x95" => "\xE1\x83\x95", # GEORGIAN MTAVRULI CAPITAL LETTER VIN
754             "\xE1\xB2\x96" => "\xE1\x83\x96", # GEORGIAN MTAVRULI CAPITAL LETTER ZEN
755             "\xE1\xB2\x97" => "\xE1\x83\x97", # GEORGIAN MTAVRULI CAPITAL LETTER TAN
756             "\xE1\xB2\x98" => "\xE1\x83\x98", # GEORGIAN MTAVRULI CAPITAL LETTER IN
757             "\xE1\xB2\x99" => "\xE1\x83\x99", # GEORGIAN MTAVRULI CAPITAL LETTER KAN
758             "\xE1\xB2\x9A" => "\xE1\x83\x9A", # GEORGIAN MTAVRULI CAPITAL LETTER LAS
759             "\xE1\xB2\x9B" => "\xE1\x83\x9B", # GEORGIAN MTAVRULI CAPITAL LETTER MAN
760             "\xE1\xB2\x9C" => "\xE1\x83\x9C", # GEORGIAN MTAVRULI CAPITAL LETTER NAR
761             "\xE1\xB2\x9D" => "\xE1\x83\x9D", # GEORGIAN MTAVRULI CAPITAL LETTER ON
762             "\xE1\xB2\x9E" => "\xE1\x83\x9E", # GEORGIAN MTAVRULI CAPITAL LETTER PAR
763             "\xE1\xB2\x9F" => "\xE1\x83\x9F", # GEORGIAN MTAVRULI CAPITAL LETTER ZHAR
764             "\xE1\xB2\xA0" => "\xE1\x83\xA0", # GEORGIAN MTAVRULI CAPITAL LETTER RAE
765             "\xE1\xB2\xA1" => "\xE1\x83\xA1", # GEORGIAN MTAVRULI CAPITAL LETTER SAN
766             "\xE1\xB2\xA2" => "\xE1\x83\xA2", # GEORGIAN MTAVRULI CAPITAL LETTER TAR
767             "\xE1\xB2\xA3" => "\xE1\x83\xA3", # GEORGIAN MTAVRULI CAPITAL LETTER UN
768             "\xE1\xB2\xA4" => "\xE1\x83\xA4", # GEORGIAN MTAVRULI CAPITAL LETTER PHAR
769             "\xE1\xB2\xA5" => "\xE1\x83\xA5", # GEORGIAN MTAVRULI CAPITAL LETTER KHAR
770             "\xE1\xB2\xA6" => "\xE1\x83\xA6", # GEORGIAN MTAVRULI CAPITAL LETTER GHAN
771             "\xE1\xB2\xA7" => "\xE1\x83\xA7", # GEORGIAN MTAVRULI CAPITAL LETTER QAR
772             "\xE1\xB2\xA8" => "\xE1\x83\xA8", # GEORGIAN MTAVRULI CAPITAL LETTER SHIN
773             "\xE1\xB2\xA9" => "\xE1\x83\xA9", # GEORGIAN MTAVRULI CAPITAL LETTER CHIN
774             "\xE1\xB2\xAA" => "\xE1\x83\xAA", # GEORGIAN MTAVRULI CAPITAL LETTER CAN
775             "\xE1\xB2\xAB" => "\xE1\x83\xAB", # GEORGIAN MTAVRULI CAPITAL LETTER JIL
776             "\xE1\xB2\xAC" => "\xE1\x83\xAC", # GEORGIAN MTAVRULI CAPITAL LETTER CIL
777             "\xE1\xB2\xAD" => "\xE1\x83\xAD", # GEORGIAN MTAVRULI CAPITAL LETTER CHAR
778             "\xE1\xB2\xAE" => "\xE1\x83\xAE", # GEORGIAN MTAVRULI CAPITAL LETTER XAN
779             "\xE1\xB2\xAF" => "\xE1\x83\xAF", # GEORGIAN MTAVRULI CAPITAL LETTER JHAN
780             "\xE1\xB2\xB0" => "\xE1\x83\xB0", # GEORGIAN MTAVRULI CAPITAL LETTER HAE
781             "\xE1\xB2\xB1" => "\xE1\x83\xB1", # GEORGIAN MTAVRULI CAPITAL LETTER HE
782             "\xE1\xB2\xB2" => "\xE1\x83\xB2", # GEORGIAN MTAVRULI CAPITAL LETTER HIE
783             "\xE1\xB2\xB3" => "\xE1\x83\xB3", # GEORGIAN MTAVRULI CAPITAL LETTER WE
784             "\xE1\xB2\xB4" => "\xE1\x83\xB4", # GEORGIAN MTAVRULI CAPITAL LETTER HAR
785             "\xE1\xB2\xB5" => "\xE1\x83\xB5", # GEORGIAN MTAVRULI CAPITAL LETTER HOE
786             "\xE1\xB2\xB6" => "\xE1\x83\xB6", # GEORGIAN MTAVRULI CAPITAL LETTER FI
787             "\xE1\xB2\xB7" => "\xE1\x83\xB7", # GEORGIAN MTAVRULI CAPITAL LETTER YN
788             "\xE1\xB2\xB8" => "\xE1\x83\xB8", # GEORGIAN MTAVRULI CAPITAL LETTER ELIFI
789             "\xE1\xB2\xB9" => "\xE1\x83\xB9", # GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN
790             "\xE1\xB2\xBA" => "\xE1\x83\xBA", # GEORGIAN MTAVRULI CAPITAL LETTER AIN
791             "\xE1\xB2\xBD" => "\xE1\x83\xBD", # GEORGIAN MTAVRULI CAPITAL LETTER AEN
792             "\xE1\xB2\xBE" => "\xE1\x83\xBE", # GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN
793             "\xE1\xB2\xBF" => "\xE1\x83\xBF", # GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN
794             "\xE1\xB8\x80" => "\xE1\xB8\x81", # LATIN CAPITAL LETTER A WITH RING BELOW
795             "\xE1\xB8\x82" => "\xE1\xB8\x83", # LATIN CAPITAL LETTER B WITH DOT ABOVE
796             "\xE1\xB8\x84" => "\xE1\xB8\x85", # LATIN CAPITAL LETTER B WITH DOT BELOW
797             "\xE1\xB8\x86" => "\xE1\xB8\x87", # LATIN CAPITAL LETTER B WITH LINE BELOW
798             "\xE1\xB8\x88" => "\xE1\xB8\x89", # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
799             "\xE1\xB8\x8A" => "\xE1\xB8\x8B", # LATIN CAPITAL LETTER D WITH DOT ABOVE
800             "\xE1\xB8\x8C" => "\xE1\xB8\x8D", # LATIN CAPITAL LETTER D WITH DOT BELOW
801             "\xE1\xB8\x8E" => "\xE1\xB8\x8F", # LATIN CAPITAL LETTER D WITH LINE BELOW
802             "\xE1\xB8\x90" => "\xE1\xB8\x91", # LATIN CAPITAL LETTER D WITH CEDILLA
803             "\xE1\xB8\x92" => "\xE1\xB8\x93", # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
804             "\xE1\xB8\x94" => "\xE1\xB8\x95", # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
805             "\xE1\xB8\x96" => "\xE1\xB8\x97", # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
806             "\xE1\xB8\x98" => "\xE1\xB8\x99", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
807             "\xE1\xB8\x9A" => "\xE1\xB8\x9B", # LATIN CAPITAL LETTER E WITH TILDE BELOW
808             "\xE1\xB8\x9C" => "\xE1\xB8\x9D", # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
809             "\xE1\xB8\x9E" => "\xE1\xB8\x9F", # LATIN CAPITAL LETTER F WITH DOT ABOVE
810             "\xE1\xB8\xA0" => "\xE1\xB8\xA1", # LATIN CAPITAL LETTER G WITH MACRON
811             "\xE1\xB8\xA2" => "\xE1\xB8\xA3", # LATIN CAPITAL LETTER H WITH DOT ABOVE
812             "\xE1\xB8\xA4" => "\xE1\xB8\xA5", # LATIN CAPITAL LETTER H WITH DOT BELOW
813             "\xE1\xB8\xA6" => "\xE1\xB8\xA7", # LATIN CAPITAL LETTER H WITH DIAERESIS
814             "\xE1\xB8\xA8" => "\xE1\xB8\xA9", # LATIN CAPITAL LETTER H WITH CEDILLA
815             "\xE1\xB8\xAA" => "\xE1\xB8\xAB", # LATIN CAPITAL LETTER H WITH BREVE BELOW
816             "\xE1\xB8\xAC" => "\xE1\xB8\xAD", # LATIN CAPITAL LETTER I WITH TILDE BELOW
817             "\xE1\xB8\xAE" => "\xE1\xB8\xAF", # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
818             "\xE1\xB8\xB0" => "\xE1\xB8\xB1", # LATIN CAPITAL LETTER K WITH ACUTE
819             "\xE1\xB8\xB2" => "\xE1\xB8\xB3", # LATIN CAPITAL LETTER K WITH DOT BELOW
820             "\xE1\xB8\xB4" => "\xE1\xB8\xB5", # LATIN CAPITAL LETTER K WITH LINE BELOW
821             "\xE1\xB8\xB6" => "\xE1\xB8\xB7", # LATIN CAPITAL LETTER L WITH DOT BELOW
822             "\xE1\xB8\xB8" => "\xE1\xB8\xB9", # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
823             "\xE1\xB8\xBA" => "\xE1\xB8\xBB", # LATIN CAPITAL LETTER L WITH LINE BELOW
824             "\xE1\xB8\xBC" => "\xE1\xB8\xBD", # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
825             "\xE1\xB8\xBE" => "\xE1\xB8\xBF", # LATIN CAPITAL LETTER M WITH ACUTE
826             "\xE1\xB9\x80" => "\xE1\xB9\x81", # LATIN CAPITAL LETTER M WITH DOT ABOVE
827             "\xE1\xB9\x82" => "\xE1\xB9\x83", # LATIN CAPITAL LETTER M WITH DOT BELOW
828             "\xE1\xB9\x84" => "\xE1\xB9\x85", # LATIN CAPITAL LETTER N WITH DOT ABOVE
829             "\xE1\xB9\x86" => "\xE1\xB9\x87", # LATIN CAPITAL LETTER N WITH DOT BELOW
830             "\xE1\xB9\x88" => "\xE1\xB9\x89", # LATIN CAPITAL LETTER N WITH LINE BELOW
831             "\xE1\xB9\x8A" => "\xE1\xB9\x8B", # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
832             "\xE1\xB9\x8C" => "\xE1\xB9\x8D", # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
833             "\xE1\xB9\x8E" => "\xE1\xB9\x8F", # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
834             "\xE1\xB9\x90" => "\xE1\xB9\x91", # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
835             "\xE1\xB9\x92" => "\xE1\xB9\x93", # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
836             "\xE1\xB9\x94" => "\xE1\xB9\x95", # LATIN CAPITAL LETTER P WITH ACUTE
837             "\xE1\xB9\x96" => "\xE1\xB9\x97", # LATIN CAPITAL LETTER P WITH DOT ABOVE
838             "\xE1\xB9\x98" => "\xE1\xB9\x99", # LATIN CAPITAL LETTER R WITH DOT ABOVE
839             "\xE1\xB9\x9A" => "\xE1\xB9\x9B", # LATIN CAPITAL LETTER R WITH DOT BELOW
840             "\xE1\xB9\x9C" => "\xE1\xB9\x9D", # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
841             "\xE1\xB9\x9E" => "\xE1\xB9\x9F", # LATIN CAPITAL LETTER R WITH LINE BELOW
842             "\xE1\xB9\xA0" => "\xE1\xB9\xA1", # LATIN CAPITAL LETTER S WITH DOT ABOVE
843             "\xE1\xB9\xA2" => "\xE1\xB9\xA3", # LATIN CAPITAL LETTER S WITH DOT BELOW
844             "\xE1\xB9\xA4" => "\xE1\xB9\xA5", # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
845             "\xE1\xB9\xA6" => "\xE1\xB9\xA7", # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
846             "\xE1\xB9\xA8" => "\xE1\xB9\xA9", # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
847             "\xE1\xB9\xAA" => "\xE1\xB9\xAB", # LATIN CAPITAL LETTER T WITH DOT ABOVE
848             "\xE1\xB9\xAC" => "\xE1\xB9\xAD", # LATIN CAPITAL LETTER T WITH DOT BELOW
849             "\xE1\xB9\xAE" => "\xE1\xB9\xAF", # LATIN CAPITAL LETTER T WITH LINE BELOW
850             "\xE1\xB9\xB0" => "\xE1\xB9\xB1", # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
851             "\xE1\xB9\xB2" => "\xE1\xB9\xB3", # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
852             "\xE1\xB9\xB4" => "\xE1\xB9\xB5", # LATIN CAPITAL LETTER U WITH TILDE BELOW
853             "\xE1\xB9\xB6" => "\xE1\xB9\xB7", # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
854             "\xE1\xB9\xB8" => "\xE1\xB9\xB9", # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
855             "\xE1\xB9\xBA" => "\xE1\xB9\xBB", # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
856             "\xE1\xB9\xBC" => "\xE1\xB9\xBD", # LATIN CAPITAL LETTER V WITH TILDE
857             "\xE1\xB9\xBE" => "\xE1\xB9\xBF", # LATIN CAPITAL LETTER V WITH DOT BELOW
858             "\xE1\xBA\x80" => "\xE1\xBA\x81", # LATIN CAPITAL LETTER W WITH GRAVE
859             "\xE1\xBA\x82" => "\xE1\xBA\x83", # LATIN CAPITAL LETTER W WITH ACUTE
860             "\xE1\xBA\x84" => "\xE1\xBA\x85", # LATIN CAPITAL LETTER W WITH DIAERESIS
861             "\xE1\xBA\x86" => "\xE1\xBA\x87", # LATIN CAPITAL LETTER W WITH DOT ABOVE
862             "\xE1\xBA\x88" => "\xE1\xBA\x89", # LATIN CAPITAL LETTER W WITH DOT BELOW
863             "\xE1\xBA\x8A" => "\xE1\xBA\x8B", # LATIN CAPITAL LETTER X WITH DOT ABOVE
864             "\xE1\xBA\x8C" => "\xE1\xBA\x8D", # LATIN CAPITAL LETTER X WITH DIAERESIS
865             "\xE1\xBA\x8E" => "\xE1\xBA\x8F", # LATIN CAPITAL LETTER Y WITH DOT ABOVE
866             "\xE1\xBA\x90" => "\xE1\xBA\x91", # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
867             "\xE1\xBA\x92" => "\xE1\xBA\x93", # LATIN CAPITAL LETTER Z WITH DOT BELOW
868             "\xE1\xBA\x94" => "\xE1\xBA\x95", # LATIN CAPITAL LETTER Z WITH LINE BELOW
869             "\xE1\xBA\x96" => "\x68\xCC\xB1", # LATIN SMALL LETTER H WITH LINE BELOW
870             "\xE1\xBA\x97" => "\x74\xCC\x88", # LATIN SMALL LETTER T WITH DIAERESIS
871             "\xE1\xBA\x98" => "\x77\xCC\x8A", # LATIN SMALL LETTER W WITH RING ABOVE
872             "\xE1\xBA\x99" => "\x79\xCC\x8A", # LATIN SMALL LETTER Y WITH RING ABOVE
873             "\xE1\xBA\x9A" => "\x61\xCA\xBE", # LATIN SMALL LETTER A WITH RIGHT HALF RING
874             "\xE1\xBA\x9B" => "\xE1\xB9\xA1", # LATIN SMALL LETTER LONG S WITH DOT ABOVE
875             "\xE1\xBA\x9E" => "\x73\x73", # LATIN CAPITAL LETTER SHARP S
876             "\xE1\xBA\xA0" => "\xE1\xBA\xA1", # LATIN CAPITAL LETTER A WITH DOT BELOW
877             "\xE1\xBA\xA2" => "\xE1\xBA\xA3", # LATIN CAPITAL LETTER A WITH HOOK ABOVE
878             "\xE1\xBA\xA4" => "\xE1\xBA\xA5", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
879             "\xE1\xBA\xA6" => "\xE1\xBA\xA7", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
880             "\xE1\xBA\xA8" => "\xE1\xBA\xA9", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
881             "\xE1\xBA\xAA" => "\xE1\xBA\xAB", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
882             "\xE1\xBA\xAC" => "\xE1\xBA\xAD", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
883             "\xE1\xBA\xAE" => "\xE1\xBA\xAF", # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
884             "\xE1\xBA\xB0" => "\xE1\xBA\xB1", # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
885             "\xE1\xBA\xB2" => "\xE1\xBA\xB3", # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
886             "\xE1\xBA\xB4" => "\xE1\xBA\xB5", # LATIN CAPITAL LETTER A WITH BREVE AND TILDE
887             "\xE1\xBA\xB6" => "\xE1\xBA\xB7", # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
888             "\xE1\xBA\xB8" => "\xE1\xBA\xB9", # LATIN CAPITAL LETTER E WITH DOT BELOW
889             "\xE1\xBA\xBA" => "\xE1\xBA\xBB", # LATIN CAPITAL LETTER E WITH HOOK ABOVE
890             "\xE1\xBA\xBC" => "\xE1\xBA\xBD", # LATIN CAPITAL LETTER E WITH TILDE
891             "\xE1\xBA\xBE" => "\xE1\xBA\xBF", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
892             "\xE1\xBB\x80" => "\xE1\xBB\x81", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
893             "\xE1\xBB\x82" => "\xE1\xBB\x83", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
894             "\xE1\xBB\x84" => "\xE1\xBB\x85", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
895             "\xE1\xBB\x86" => "\xE1\xBB\x87", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
896             "\xE1\xBB\x88" => "\xE1\xBB\x89", # LATIN CAPITAL LETTER I WITH HOOK ABOVE
897             "\xE1\xBB\x8A" => "\xE1\xBB\x8B", # LATIN CAPITAL LETTER I WITH DOT BELOW
898             "\xE1\xBB\x8C" => "\xE1\xBB\x8D", # LATIN CAPITAL LETTER O WITH DOT BELOW
899             "\xE1\xBB\x8E" => "\xE1\xBB\x8F", # LATIN CAPITAL LETTER O WITH HOOK ABOVE
900             "\xE1\xBB\x90" => "\xE1\xBB\x91", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
901             "\xE1\xBB\x92" => "\xE1\xBB\x93", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
902             "\xE1\xBB\x94" => "\xE1\xBB\x95", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
903             "\xE1\xBB\x96" => "\xE1\xBB\x97", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
904             "\xE1\xBB\x98" => "\xE1\xBB\x99", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
905             "\xE1\xBB\x9A" => "\xE1\xBB\x9B", # LATIN CAPITAL LETTER O WITH HORN AND ACUTE
906             "\xE1\xBB\x9C" => "\xE1\xBB\x9D", # LATIN CAPITAL LETTER O WITH HORN AND GRAVE
907             "\xE1\xBB\x9E" => "\xE1\xBB\x9F", # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
908             "\xE1\xBB\xA0" => "\xE1\xBB\xA1", # LATIN CAPITAL LETTER O WITH HORN AND TILDE
909             "\xE1\xBB\xA2" => "\xE1\xBB\xA3", # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
910             "\xE1\xBB\xA4" => "\xE1\xBB\xA5", # LATIN CAPITAL LETTER U WITH DOT BELOW
911             "\xE1\xBB\xA6" => "\xE1\xBB\xA7", # LATIN CAPITAL LETTER U WITH HOOK ABOVE
912             "\xE1\xBB\xA8" => "\xE1\xBB\xA9", # LATIN CAPITAL LETTER U WITH HORN AND ACUTE
913             "\xE1\xBB\xAA" => "\xE1\xBB\xAB", # LATIN CAPITAL LETTER U WITH HORN AND GRAVE
914             "\xE1\xBB\xAC" => "\xE1\xBB\xAD", # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
915             "\xE1\xBB\xAE" => "\xE1\xBB\xAF", # LATIN CAPITAL LETTER U WITH HORN AND TILDE
916             "\xE1\xBB\xB0" => "\xE1\xBB\xB1", # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
917             "\xE1\xBB\xB2" => "\xE1\xBB\xB3", # LATIN CAPITAL LETTER Y WITH GRAVE
918             "\xE1\xBB\xB4" => "\xE1\xBB\xB5", # LATIN CAPITAL LETTER Y WITH DOT BELOW
919             "\xE1\xBB\xB6" => "\xE1\xBB\xB7", # LATIN CAPITAL LETTER Y WITH HOOK ABOVE
920             "\xE1\xBB\xB8" => "\xE1\xBB\xB9", # LATIN CAPITAL LETTER Y WITH TILDE
921             "\xE1\xBB\xBA" => "\xE1\xBB\xBB", # LATIN CAPITAL LETTER MIDDLE-WELSH LL
922             "\xE1\xBB\xBC" => "\xE1\xBB\xBD", # LATIN CAPITAL LETTER MIDDLE-WELSH V
923             "\xE1\xBB\xBE" => "\xE1\xBB\xBF", # LATIN CAPITAL LETTER Y WITH LOOP
924             "\xE1\xBC\x88" => "\xE1\xBC\x80", # GREEK CAPITAL LETTER ALPHA WITH PSILI
925             "\xE1\xBC\x89" => "\xE1\xBC\x81", # GREEK CAPITAL LETTER ALPHA WITH DASIA
926             "\xE1\xBC\x8A" => "\xE1\xBC\x82", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
927             "\xE1\xBC\x8B" => "\xE1\xBC\x83", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
928             "\xE1\xBC\x8C" => "\xE1\xBC\x84", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
929             "\xE1\xBC\x8D" => "\xE1\xBC\x85", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
930             "\xE1\xBC\x8E" => "\xE1\xBC\x86", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
931             "\xE1\xBC\x8F" => "\xE1\xBC\x87", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
932             "\xE1\xBC\x98" => "\xE1\xBC\x90", # GREEK CAPITAL LETTER EPSILON WITH PSILI
933             "\xE1\xBC\x99" => "\xE1\xBC\x91", # GREEK CAPITAL LETTER EPSILON WITH DASIA
934             "\xE1\xBC\x9A" => "\xE1\xBC\x92", # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
935             "\xE1\xBC\x9B" => "\xE1\xBC\x93", # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
936             "\xE1\xBC\x9C" => "\xE1\xBC\x94", # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
937             "\xE1\xBC\x9D" => "\xE1\xBC\x95", # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
938             "\xE1\xBC\xA8" => "\xE1\xBC\xA0", # GREEK CAPITAL LETTER ETA WITH PSILI
939             "\xE1\xBC\xA9" => "\xE1\xBC\xA1", # GREEK CAPITAL LETTER ETA WITH DASIA
940             "\xE1\xBC\xAA" => "\xE1\xBC\xA2", # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
941             "\xE1\xBC\xAB" => "\xE1\xBC\xA3", # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
942             "\xE1\xBC\xAC" => "\xE1\xBC\xA4", # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
943             "\xE1\xBC\xAD" => "\xE1\xBC\xA5", # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
944             "\xE1\xBC\xAE" => "\xE1\xBC\xA6", # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
945             "\xE1\xBC\xAF" => "\xE1\xBC\xA7", # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
946             "\xE1\xBC\xB8" => "\xE1\xBC\xB0", # GREEK CAPITAL LETTER IOTA WITH PSILI
947             "\xE1\xBC\xB9" => "\xE1\xBC\xB1", # GREEK CAPITAL LETTER IOTA WITH DASIA
948             "\xE1\xBC\xBA" => "\xE1\xBC\xB2", # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
949             "\xE1\xBC\xBB" => "\xE1\xBC\xB3", # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
950             "\xE1\xBC\xBC" => "\xE1\xBC\xB4", # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
951             "\xE1\xBC\xBD" => "\xE1\xBC\xB5", # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
952             "\xE1\xBC\xBE" => "\xE1\xBC\xB6", # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
953             "\xE1\xBC\xBF" => "\xE1\xBC\xB7", # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
954             "\xE1\xBD\x88" => "\xE1\xBD\x80", # GREEK CAPITAL LETTER OMICRON WITH PSILI
955             "\xE1\xBD\x89" => "\xE1\xBD\x81", # GREEK CAPITAL LETTER OMICRON WITH DASIA
956             "\xE1\xBD\x8A" => "\xE1\xBD\x82", # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
957             "\xE1\xBD\x8B" => "\xE1\xBD\x83", # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
958             "\xE1\xBD\x8C" => "\xE1\xBD\x84", # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
959             "\xE1\xBD\x8D" => "\xE1\xBD\x85", # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
960             "\xE1\xBD\x90" => "\xCF\x85\xCC\x93", # GREEK SMALL LETTER UPSILON WITH PSILI
961             "\xE1\xBD\x92" => "\xCF\x85\xCC\x93\xCC\x80", # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
962             "\xE1\xBD\x94" => "\xCF\x85\xCC\x93\xCC\x81", # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
963             "\xE1\xBD\x96" => "\xCF\x85\xCC\x93\xCD\x82", # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
964             "\xE1\xBD\x99" => "\xE1\xBD\x91", # GREEK CAPITAL LETTER UPSILON WITH DASIA
965             "\xE1\xBD\x9B" => "\xE1\xBD\x93", # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
966             "\xE1\xBD\x9D" => "\xE1\xBD\x95", # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
967             "\xE1\xBD\x9F" => "\xE1\xBD\x97", # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
968             "\xE1\xBD\xA8" => "\xE1\xBD\xA0", # GREEK CAPITAL LETTER OMEGA WITH PSILI
969             "\xE1\xBD\xA9" => "\xE1\xBD\xA1", # GREEK CAPITAL LETTER OMEGA WITH DASIA
970             "\xE1\xBD\xAA" => "\xE1\xBD\xA2", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
971             "\xE1\xBD\xAB" => "\xE1\xBD\xA3", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
972             "\xE1\xBD\xAC" => "\xE1\xBD\xA4", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
973             "\xE1\xBD\xAD" => "\xE1\xBD\xA5", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
974             "\xE1\xBD\xAE" => "\xE1\xBD\xA6", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
975             "\xE1\xBD\xAF" => "\xE1\xBD\xA7", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
976             "\xE1\xBE\x80" => "\xE1\xBC\x80\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
977             "\xE1\xBE\x81" => "\xE1\xBC\x81\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
978             "\xE1\xBE\x82" => "\xE1\xBC\x82\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
979             "\xE1\xBE\x83" => "\xE1\xBC\x83\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
980             "\xE1\xBE\x84" => "\xE1\xBC\x84\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
981             "\xE1\xBE\x85" => "\xE1\xBC\x85\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
982             "\xE1\xBE\x86" => "\xE1\xBC\x86\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
983             "\xE1\xBE\x87" => "\xE1\xBC\x87\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
984             "\xE1\xBE\x88" => "\xE1\xBC\x80\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
985             "\xE1\xBE\x89" => "\xE1\xBC\x81\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
986             "\xE1\xBE\x8A" => "\xE1\xBC\x82\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
987             "\xE1\xBE\x8B" => "\xE1\xBC\x83\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
988             "\xE1\xBE\x8C" => "\xE1\xBC\x84\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
989             "\xE1\xBE\x8D" => "\xE1\xBC\x85\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
990             "\xE1\xBE\x8E" => "\xE1\xBC\x86\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
991             "\xE1\xBE\x8F" => "\xE1\xBC\x87\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
992             "\xE1\xBE\x90" => "\xE1\xBC\xA0\xCE\xB9", # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
993             "\xE1\xBE\x91" => "\xE1\xBC\xA1\xCE\xB9", # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
994             "\xE1\xBE\x92" => "\xE1\xBC\xA2\xCE\xB9", # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
995             "\xE1\xBE\x93" => "\xE1\xBC\xA3\xCE\xB9", # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
996             "\xE1\xBE\x94" => "\xE1\xBC\xA4\xCE\xB9", # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
997             "\xE1\xBE\x95" => "\xE1\xBC\xA5\xCE\xB9", # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
998             "\xE1\xBE\x96" => "\xE1\xBC\xA6\xCE\xB9", # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
999             "\xE1\xBE\x97" => "\xE1\xBC\xA7\xCE\xB9", # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1000             "\xE1\xBE\x98" => "\xE1\xBC\xA0\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
1001             "\xE1\xBE\x99" => "\xE1\xBC\xA1\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
1002             "\xE1\xBE\x9A" => "\xE1\xBC\xA2\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1003             "\xE1\xBE\x9B" => "\xE1\xBC\xA3\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1004             "\xE1\xBE\x9C" => "\xE1\xBC\xA4\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1005             "\xE1\xBE\x9D" => "\xE1\xBC\xA5\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1006             "\xE1\xBE\x9E" => "\xE1\xBC\xA6\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1007             "\xE1\xBE\x9F" => "\xE1\xBC\xA7\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1008             "\xE1\xBE\xA0" => "\xE1\xBD\xA0\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
1009             "\xE1\xBE\xA1" => "\xE1\xBD\xA1\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
1010             "\xE1\xBE\xA2" => "\xE1\xBD\xA2\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1011             "\xE1\xBE\xA3" => "\xE1\xBD\xA3\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1012             "\xE1\xBE\xA4" => "\xE1\xBD\xA4\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1013             "\xE1\xBE\xA5" => "\xE1\xBD\xA5\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1014             "\xE1\xBE\xA6" => "\xE1\xBD\xA6\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1015             "\xE1\xBE\xA7" => "\xE1\xBD\xA7\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1016             "\xE1\xBE\xA8" => "\xE1\xBD\xA0\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
1017             "\xE1\xBE\xA9" => "\xE1\xBD\xA1\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
1018             "\xE1\xBE\xAA" => "\xE1\xBD\xA2\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1019             "\xE1\xBE\xAB" => "\xE1\xBD\xA3\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1020             "\xE1\xBE\xAC" => "\xE1\xBD\xA4\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1021             "\xE1\xBE\xAD" => "\xE1\xBD\xA5\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1022             "\xE1\xBE\xAE" => "\xE1\xBD\xA6\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1023             "\xE1\xBE\xAF" => "\xE1\xBD\xA7\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1024             "\xE1\xBE\xB2" => "\xE1\xBD\xB0\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
1025             "\xE1\xBE\xB3" => "\xCE\xB1\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
1026             "\xE1\xBE\xB4" => "\xCE\xAC\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
1027             "\xE1\xBE\xB6" => "\xCE\xB1\xCD\x82", # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
1028             "\xE1\xBE\xB7" => "\xCE\xB1\xCD\x82\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
1029             "\xE1\xBE\xB8" => "\xE1\xBE\xB0", # GREEK CAPITAL LETTER ALPHA WITH VRACHY
1030             "\xE1\xBE\xB9" => "\xE1\xBE\xB1", # GREEK CAPITAL LETTER ALPHA WITH MACRON
1031             "\xE1\xBE\xBA" => "\xE1\xBD\xB0", # GREEK CAPITAL LETTER ALPHA WITH VARIA
1032             "\xE1\xBE\xBB" => "\xE1\xBD\xB1", # GREEK CAPITAL LETTER ALPHA WITH OXIA
1033             "\xE1\xBE\xBC" => "\xCE\xB1\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
1034             "\xE1\xBE\xBE" => "\xCE\xB9", # GREEK PROSGEGRAMMENI
1035             "\xE1\xBF\x82" => "\xE1\xBD\xB4\xCE\xB9", # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
1036             "\xE1\xBF\x83" => "\xCE\xB7\xCE\xB9", # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
1037             "\xE1\xBF\x84" => "\xCE\xAE\xCE\xB9", # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
1038             "\xE1\xBF\x86" => "\xCE\xB7\xCD\x82", # GREEK SMALL LETTER ETA WITH PERISPOMENI
1039             "\xE1\xBF\x87" => "\xCE\xB7\xCD\x82\xCE\xB9", # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
1040             "\xE1\xBF\x88" => "\xE1\xBD\xB2", # GREEK CAPITAL LETTER EPSILON WITH VARIA
1041             "\xE1\xBF\x89" => "\xE1\xBD\xB3", # GREEK CAPITAL LETTER EPSILON WITH OXIA
1042             "\xE1\xBF\x8A" => "\xE1\xBD\xB4", # GREEK CAPITAL LETTER ETA WITH VARIA
1043             "\xE1\xBF\x8B" => "\xE1\xBD\xB5", # GREEK CAPITAL LETTER ETA WITH OXIA
1044             "\xE1\xBF\x8C" => "\xCE\xB7\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
1045             "\xE1\xBF\x92" => "\xCE\xB9\xCC\x88\xCC\x80", # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
1046             "\xE1\xBF\x93" => "\xCE\xB9\xCC\x88\xCC\x81", # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
1047             "\xE1\xBF\x96" => "\xCE\xB9\xCD\x82", # GREEK SMALL LETTER IOTA WITH PERISPOMENI
1048             "\xE1\xBF\x97" => "\xCE\xB9\xCC\x88\xCD\x82", # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
1049             "\xE1\xBF\x98" => "\xE1\xBF\x90", # GREEK CAPITAL LETTER IOTA WITH VRACHY
1050             "\xE1\xBF\x99" => "\xE1\xBF\x91", # GREEK CAPITAL LETTER IOTA WITH MACRON
1051             "\xE1\xBF\x9A" => "\xE1\xBD\xB6", # GREEK CAPITAL LETTER IOTA WITH VARIA
1052             "\xE1\xBF\x9B" => "\xE1\xBD\xB7", # GREEK CAPITAL LETTER IOTA WITH OXIA
1053             "\xE1\xBF\xA2" => "\xCF\x85\xCC\x88\xCC\x80", # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
1054             "\xE1\xBF\xA3" => "\xCF\x85\xCC\x88\xCC\x81", # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
1055             "\xE1\xBF\xA4" => "\xCF\x81\xCC\x93", # GREEK SMALL LETTER RHO WITH PSILI
1056             "\xE1\xBF\xA6" => "\xCF\x85\xCD\x82", # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
1057             "\xE1\xBF\xA7" => "\xCF\x85\xCC\x88\xCD\x82", # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
1058             "\xE1\xBF\xA8" => "\xE1\xBF\xA0", # GREEK CAPITAL LETTER UPSILON WITH VRACHY
1059             "\xE1\xBF\xA9" => "\xE1\xBF\xA1", # GREEK CAPITAL LETTER UPSILON WITH MACRON
1060             "\xE1\xBF\xAA" => "\xE1\xBD\xBA", # GREEK CAPITAL LETTER UPSILON WITH VARIA
1061             "\xE1\xBF\xAB" => "\xE1\xBD\xBB", # GREEK CAPITAL LETTER UPSILON WITH OXIA
1062             "\xE1\xBF\xAC" => "\xE1\xBF\xA5", # GREEK CAPITAL LETTER RHO WITH DASIA
1063             "\xE1\xBF\xB2" => "\xE1\xBD\xBC\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
1064             "\xE1\xBF\xB3" => "\xCF\x89\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
1065             "\xE1\xBF\xB4" => "\xCF\x8E\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
1066             "\xE1\xBF\xB6" => "\xCF\x89\xCD\x82", # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
1067             "\xE1\xBF\xB7" => "\xCF\x89\xCD\x82\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
1068             "\xE1\xBF\xB8" => "\xE1\xBD\xB8", # GREEK CAPITAL LETTER OMICRON WITH VARIA
1069             "\xE1\xBF\xB9" => "\xE1\xBD\xB9", # GREEK CAPITAL LETTER OMICRON WITH OXIA
1070             "\xE1\xBF\xBA" => "\xE1\xBD\xBC", # GREEK CAPITAL LETTER OMEGA WITH VARIA
1071             "\xE1\xBF\xBB" => "\xE1\xBD\xBD", # GREEK CAPITAL LETTER OMEGA WITH OXIA
1072             "\xE1\xBF\xBC" => "\xCF\x89\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
1073             "\xE2\x84\xA6" => "\xCF\x89", # OHM SIGN
1074             "\xE2\x84\xAA" => "\x6B", # KELVIN SIGN
1075             "\xE2\x84\xAB" => "\xC3\xA5", # ANGSTROM SIGN
1076             "\xE2\x84\xB2" => "\xE2\x85\x8E", # TURNED CAPITAL F
1077             "\xE2\x85\xA0" => "\xE2\x85\xB0", # ROMAN NUMERAL ONE
1078             "\xE2\x85\xA1" => "\xE2\x85\xB1", # ROMAN NUMERAL TWO
1079             "\xE2\x85\xA2" => "\xE2\x85\xB2", # ROMAN NUMERAL THREE
1080             "\xE2\x85\xA3" => "\xE2\x85\xB3", # ROMAN NUMERAL FOUR
1081             "\xE2\x85\xA4" => "\xE2\x85\xB4", # ROMAN NUMERAL FIVE
1082             "\xE2\x85\xA5" => "\xE2\x85\xB5", # ROMAN NUMERAL SIX
1083             "\xE2\x85\xA6" => "\xE2\x85\xB6", # ROMAN NUMERAL SEVEN
1084             "\xE2\x85\xA7" => "\xE2\x85\xB7", # ROMAN NUMERAL EIGHT
1085             "\xE2\x85\xA8" => "\xE2\x85\xB8", # ROMAN NUMERAL NINE
1086             "\xE2\x85\xA9" => "\xE2\x85\xB9", # ROMAN NUMERAL TEN
1087             "\xE2\x85\xAA" => "\xE2\x85\xBA", # ROMAN NUMERAL ELEVEN
1088             "\xE2\x85\xAB" => "\xE2\x85\xBB", # ROMAN NUMERAL TWELVE
1089             "\xE2\x85\xAC" => "\xE2\x85\xBC", # ROMAN NUMERAL FIFTY
1090             "\xE2\x85\xAD" => "\xE2\x85\xBD", # ROMAN NUMERAL ONE HUNDRED
1091             "\xE2\x85\xAE" => "\xE2\x85\xBE", # ROMAN NUMERAL FIVE HUNDRED
1092             "\xE2\x85\xAF" => "\xE2\x85\xBF", # ROMAN NUMERAL ONE THOUSAND
1093             "\xE2\x86\x83" => "\xE2\x86\x84", # ROMAN NUMERAL REVERSED ONE HUNDRED
1094             "\xE2\x92\xB6" => "\xE2\x93\x90", # CIRCLED LATIN CAPITAL LETTER A
1095             "\xE2\x92\xB7" => "\xE2\x93\x91", # CIRCLED LATIN CAPITAL LETTER B
1096             "\xE2\x92\xB8" => "\xE2\x93\x92", # CIRCLED LATIN CAPITAL LETTER C
1097             "\xE2\x92\xB9" => "\xE2\x93\x93", # CIRCLED LATIN CAPITAL LETTER D
1098             "\xE2\x92\xBA" => "\xE2\x93\x94", # CIRCLED LATIN CAPITAL LETTER E
1099             "\xE2\x92\xBB" => "\xE2\x93\x95", # CIRCLED LATIN CAPITAL LETTER F
1100             "\xE2\x92\xBC" => "\xE2\x93\x96", # CIRCLED LATIN CAPITAL LETTER G
1101             "\xE2\x92\xBD" => "\xE2\x93\x97", # CIRCLED LATIN CAPITAL LETTER H
1102             "\xE2\x92\xBE" => "\xE2\x93\x98", # CIRCLED LATIN CAPITAL LETTER I
1103             "\xE2\x92\xBF" => "\xE2\x93\x99", # CIRCLED LATIN CAPITAL LETTER J
1104             "\xE2\x93\x80" => "\xE2\x93\x9A", # CIRCLED LATIN CAPITAL LETTER K
1105             "\xE2\x93\x81" => "\xE2\x93\x9B", # CIRCLED LATIN CAPITAL LETTER L
1106             "\xE2\x93\x82" => "\xE2\x93\x9C", # CIRCLED LATIN CAPITAL LETTER M
1107             "\xE2\x93\x83" => "\xE2\x93\x9D", # CIRCLED LATIN CAPITAL LETTER N
1108             "\xE2\x93\x84" => "\xE2\x93\x9E", # CIRCLED LATIN CAPITAL LETTER O
1109             "\xE2\x93\x85" => "\xE2\x93\x9F", # CIRCLED LATIN CAPITAL LETTER P
1110             "\xE2\x93\x86" => "\xE2\x93\xA0", # CIRCLED LATIN CAPITAL LETTER Q
1111             "\xE2\x93\x87" => "\xE2\x93\xA1", # CIRCLED LATIN CAPITAL LETTER R
1112             "\xE2\x93\x88" => "\xE2\x93\xA2", # CIRCLED LATIN CAPITAL LETTER S
1113             "\xE2\x93\x89" => "\xE2\x93\xA3", # CIRCLED LATIN CAPITAL LETTER T
1114             "\xE2\x93\x8A" => "\xE2\x93\xA4", # CIRCLED LATIN CAPITAL LETTER U
1115             "\xE2\x93\x8B" => "\xE2\x93\xA5", # CIRCLED LATIN CAPITAL LETTER V
1116             "\xE2\x93\x8C" => "\xE2\x93\xA6", # CIRCLED LATIN CAPITAL LETTER W
1117             "\xE2\x93\x8D" => "\xE2\x93\xA7", # CIRCLED LATIN CAPITAL LETTER X
1118             "\xE2\x93\x8E" => "\xE2\x93\xA8", # CIRCLED LATIN CAPITAL LETTER Y
1119             "\xE2\x93\x8F" => "\xE2\x93\xA9", # CIRCLED LATIN CAPITAL LETTER Z
1120             "\xE2\xB0\x80" => "\xE2\xB0\xB0", # GLAGOLITIC CAPITAL LETTER AZU
1121             "\xE2\xB0\x81" => "\xE2\xB0\xB1", # GLAGOLITIC CAPITAL LETTER BUKY
1122             "\xE2\xB0\x82" => "\xE2\xB0\xB2", # GLAGOLITIC CAPITAL LETTER VEDE
1123             "\xE2\xB0\x83" => "\xE2\xB0\xB3", # GLAGOLITIC CAPITAL LETTER GLAGOLI
1124             "\xE2\xB0\x84" => "\xE2\xB0\xB4", # GLAGOLITIC CAPITAL LETTER DOBRO
1125             "\xE2\xB0\x85" => "\xE2\xB0\xB5", # GLAGOLITIC CAPITAL LETTER YESTU
1126             "\xE2\xB0\x86" => "\xE2\xB0\xB6", # GLAGOLITIC CAPITAL LETTER ZHIVETE
1127             "\xE2\xB0\x87" => "\xE2\xB0\xB7", # GLAGOLITIC CAPITAL LETTER DZELO
1128             "\xE2\xB0\x88" => "\xE2\xB0\xB8", # GLAGOLITIC CAPITAL LETTER ZEMLJA
1129             "\xE2\xB0\x89" => "\xE2\xB0\xB9", # GLAGOLITIC CAPITAL LETTER IZHE
1130             "\xE2\xB0\x8A" => "\xE2\xB0\xBA", # GLAGOLITIC CAPITAL LETTER INITIAL IZHE
1131             "\xE2\xB0\x8B" => "\xE2\xB0\xBB", # GLAGOLITIC CAPITAL LETTER I
1132             "\xE2\xB0\x8C" => "\xE2\xB0\xBC", # GLAGOLITIC CAPITAL LETTER DJERVI
1133             "\xE2\xB0\x8D" => "\xE2\xB0\xBD", # GLAGOLITIC CAPITAL LETTER KAKO
1134             "\xE2\xB0\x8E" => "\xE2\xB0\xBE", # GLAGOLITIC CAPITAL LETTER LJUDIJE
1135             "\xE2\xB0\x8F" => "\xE2\xB0\xBF", # GLAGOLITIC CAPITAL LETTER MYSLITE
1136             "\xE2\xB0\x90" => "\xE2\xB1\x80", # GLAGOLITIC CAPITAL LETTER NASHI
1137             "\xE2\xB0\x91" => "\xE2\xB1\x81", # GLAGOLITIC CAPITAL LETTER ONU
1138             "\xE2\xB0\x92" => "\xE2\xB1\x82", # GLAGOLITIC CAPITAL LETTER POKOJI
1139             "\xE2\xB0\x93" => "\xE2\xB1\x83", # GLAGOLITIC CAPITAL LETTER RITSI
1140             "\xE2\xB0\x94" => "\xE2\xB1\x84", # GLAGOLITIC CAPITAL LETTER SLOVO
1141             "\xE2\xB0\x95" => "\xE2\xB1\x85", # GLAGOLITIC CAPITAL LETTER TVRIDO
1142             "\xE2\xB0\x96" => "\xE2\xB1\x86", # GLAGOLITIC CAPITAL LETTER UKU
1143             "\xE2\xB0\x97" => "\xE2\xB1\x87", # GLAGOLITIC CAPITAL LETTER FRITU
1144             "\xE2\xB0\x98" => "\xE2\xB1\x88", # GLAGOLITIC CAPITAL LETTER HERU
1145             "\xE2\xB0\x99" => "\xE2\xB1\x89", # GLAGOLITIC CAPITAL LETTER OTU
1146             "\xE2\xB0\x9A" => "\xE2\xB1\x8A", # GLAGOLITIC CAPITAL LETTER PE
1147             "\xE2\xB0\x9B" => "\xE2\xB1\x8B", # GLAGOLITIC CAPITAL LETTER SHTA
1148             "\xE2\xB0\x9C" => "\xE2\xB1\x8C", # GLAGOLITIC CAPITAL LETTER TSI
1149             "\xE2\xB0\x9D" => "\xE2\xB1\x8D", # GLAGOLITIC CAPITAL LETTER CHRIVI
1150             "\xE2\xB0\x9E" => "\xE2\xB1\x8E", # GLAGOLITIC CAPITAL LETTER SHA
1151             "\xE2\xB0\x9F" => "\xE2\xB1\x8F", # GLAGOLITIC CAPITAL LETTER YERU
1152             "\xE2\xB0\xA0" => "\xE2\xB1\x90", # GLAGOLITIC CAPITAL LETTER YERI
1153             "\xE2\xB0\xA1" => "\xE2\xB1\x91", # GLAGOLITIC CAPITAL LETTER YATI
1154             "\xE2\xB0\xA2" => "\xE2\xB1\x92", # GLAGOLITIC CAPITAL LETTER SPIDERY HA
1155             "\xE2\xB0\xA3" => "\xE2\xB1\x93", # GLAGOLITIC CAPITAL LETTER YU
1156             "\xE2\xB0\xA4" => "\xE2\xB1\x94", # GLAGOLITIC CAPITAL LETTER SMALL YUS
1157             "\xE2\xB0\xA5" => "\xE2\xB1\x95", # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
1158             "\xE2\xB0\xA6" => "\xE2\xB1\x96", # GLAGOLITIC CAPITAL LETTER YO
1159             "\xE2\xB0\xA7" => "\xE2\xB1\x97", # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
1160             "\xE2\xB0\xA8" => "\xE2\xB1\x98", # GLAGOLITIC CAPITAL LETTER BIG YUS
1161             "\xE2\xB0\xA9" => "\xE2\xB1\x99", # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
1162             "\xE2\xB0\xAA" => "\xE2\xB1\x9A", # GLAGOLITIC CAPITAL LETTER FITA
1163             "\xE2\xB0\xAB" => "\xE2\xB1\x9B", # GLAGOLITIC CAPITAL LETTER IZHITSA
1164             "\xE2\xB0\xAC" => "\xE2\xB1\x9C", # GLAGOLITIC CAPITAL LETTER SHTAPIC
1165             "\xE2\xB0\xAD" => "\xE2\xB1\x9D", # GLAGOLITIC CAPITAL LETTER TROKUTASTI A
1166             "\xE2\xB0\xAE" => "\xE2\xB1\x9E", # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
1167             "\xE2\xB1\xA0" => "\xE2\xB1\xA1", # LATIN CAPITAL LETTER L WITH DOUBLE BAR
1168             "\xE2\xB1\xA2" => "\xC9\xAB", # LATIN CAPITAL LETTER L WITH MIDDLE TILDE
1169             "\xE2\xB1\xA3" => "\xE1\xB5\xBD", # LATIN CAPITAL LETTER P WITH STROKE
1170             "\xE2\xB1\xA4" => "\xC9\xBD", # LATIN CAPITAL LETTER R WITH TAIL
1171             "\xE2\xB1\xA7" => "\xE2\xB1\xA8", # LATIN CAPITAL LETTER H WITH DESCENDER
1172             "\xE2\xB1\xA9" => "\xE2\xB1\xAA", # LATIN CAPITAL LETTER K WITH DESCENDER
1173             "\xE2\xB1\xAB" => "\xE2\xB1\xAC", # LATIN CAPITAL LETTER Z WITH DESCENDER
1174             "\xE2\xB1\xAD" => "\xC9\x91", # LATIN CAPITAL LETTER ALPHA
1175             "\xE2\xB1\xAE" => "\xC9\xB1", # LATIN CAPITAL LETTER M WITH HOOK
1176             "\xE2\xB1\xAF" => "\xC9\x90", # LATIN CAPITAL LETTER TURNED A
1177             "\xE2\xB1\xB0" => "\xC9\x92", # LATIN CAPITAL LETTER TURNED ALPHA
1178             "\xE2\xB1\xB2" => "\xE2\xB1\xB3", # LATIN CAPITAL LETTER W WITH HOOK
1179             "\xE2\xB1\xB5" => "\xE2\xB1\xB6", # LATIN CAPITAL LETTER HALF H
1180             "\xE2\xB1\xBE" => "\xC8\xBF", # LATIN CAPITAL LETTER S WITH SWASH TAIL
1181             "\xE2\xB1\xBF" => "\xC9\x80", # LATIN CAPITAL LETTER Z WITH SWASH TAIL
1182             "\xE2\xB2\x80" => "\xE2\xB2\x81", # COPTIC CAPITAL LETTER ALFA
1183             "\xE2\xB2\x82" => "\xE2\xB2\x83", # COPTIC CAPITAL LETTER VIDA
1184             "\xE2\xB2\x84" => "\xE2\xB2\x85", # COPTIC CAPITAL LETTER GAMMA
1185             "\xE2\xB2\x86" => "\xE2\xB2\x87", # COPTIC CAPITAL LETTER DALDA
1186             "\xE2\xB2\x88" => "\xE2\xB2\x89", # COPTIC CAPITAL LETTER EIE
1187             "\xE2\xB2\x8A" => "\xE2\xB2\x8B", # COPTIC CAPITAL LETTER SOU
1188             "\xE2\xB2\x8C" => "\xE2\xB2\x8D", # COPTIC CAPITAL LETTER ZATA
1189             "\xE2\xB2\x8E" => "\xE2\xB2\x8F", # COPTIC CAPITAL LETTER HATE
1190             "\xE2\xB2\x90" => "\xE2\xB2\x91", # COPTIC CAPITAL LETTER THETHE
1191             "\xE2\xB2\x92" => "\xE2\xB2\x93", # COPTIC CAPITAL LETTER IAUDA
1192             "\xE2\xB2\x94" => "\xE2\xB2\x95", # COPTIC CAPITAL LETTER KAPA
1193             "\xE2\xB2\x96" => "\xE2\xB2\x97", # COPTIC CAPITAL LETTER LAULA
1194             "\xE2\xB2\x98" => "\xE2\xB2\x99", # COPTIC CAPITAL LETTER MI
1195             "\xE2\xB2\x9A" => "\xE2\xB2\x9B", # COPTIC CAPITAL LETTER NI
1196             "\xE2\xB2\x9C" => "\xE2\xB2\x9D", # COPTIC CAPITAL LETTER KSI
1197             "\xE2\xB2\x9E" => "\xE2\xB2\x9F", # COPTIC CAPITAL LETTER O
1198             "\xE2\xB2\xA0" => "\xE2\xB2\xA1", # COPTIC CAPITAL LETTER PI
1199             "\xE2\xB2\xA2" => "\xE2\xB2\xA3", # COPTIC CAPITAL LETTER RO
1200             "\xE2\xB2\xA4" => "\xE2\xB2\xA5", # COPTIC CAPITAL LETTER SIMA
1201             "\xE2\xB2\xA6" => "\xE2\xB2\xA7", # COPTIC CAPITAL LETTER TAU
1202             "\xE2\xB2\xA8" => "\xE2\xB2\xA9", # COPTIC CAPITAL LETTER UA
1203             "\xE2\xB2\xAA" => "\xE2\xB2\xAB", # COPTIC CAPITAL LETTER FI
1204             "\xE2\xB2\xAC" => "\xE2\xB2\xAD", # COPTIC CAPITAL LETTER KHI
1205             "\xE2\xB2\xAE" => "\xE2\xB2\xAF", # COPTIC CAPITAL LETTER PSI
1206             "\xE2\xB2\xB0" => "\xE2\xB2\xB1", # COPTIC CAPITAL LETTER OOU
1207             "\xE2\xB2\xB2" => "\xE2\xB2\xB3", # COPTIC CAPITAL LETTER DIALECT-P ALEF
1208             "\xE2\xB2\xB4" => "\xE2\xB2\xB5", # COPTIC CAPITAL LETTER OLD COPTIC AIN
1209             "\xE2\xB2\xB6" => "\xE2\xB2\xB7", # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
1210             "\xE2\xB2\xB8" => "\xE2\xB2\xB9", # COPTIC CAPITAL LETTER DIALECT-P KAPA
1211             "\xE2\xB2\xBA" => "\xE2\xB2\xBB", # COPTIC CAPITAL LETTER DIALECT-P NI
1212             "\xE2\xB2\xBC" => "\xE2\xB2\xBD", # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
1213             "\xE2\xB2\xBE" => "\xE2\xB2\xBF", # COPTIC CAPITAL LETTER OLD COPTIC OOU
1214             "\xE2\xB3\x80" => "\xE2\xB3\x81", # COPTIC CAPITAL LETTER SAMPI
1215             "\xE2\xB3\x82" => "\xE2\xB3\x83", # COPTIC CAPITAL LETTER CROSSED SHEI
1216             "\xE2\xB3\x84" => "\xE2\xB3\x85", # COPTIC CAPITAL LETTER OLD COPTIC SHEI
1217             "\xE2\xB3\x86" => "\xE2\xB3\x87", # COPTIC CAPITAL LETTER OLD COPTIC ESH
1218             "\xE2\xB3\x88" => "\xE2\xB3\x89", # COPTIC CAPITAL LETTER AKHMIMIC KHEI
1219             "\xE2\xB3\x8A" => "\xE2\xB3\x8B", # COPTIC CAPITAL LETTER DIALECT-P HORI
1220             "\xE2\xB3\x8C" => "\xE2\xB3\x8D", # COPTIC CAPITAL LETTER OLD COPTIC HORI
1221             "\xE2\xB3\x8E" => "\xE2\xB3\x8F", # COPTIC CAPITAL LETTER OLD COPTIC HA
1222             "\xE2\xB3\x90" => "\xE2\xB3\x91", # COPTIC CAPITAL LETTER L-SHAPED HA
1223             "\xE2\xB3\x92" => "\xE2\xB3\x93", # COPTIC CAPITAL LETTER OLD COPTIC HEI
1224             "\xE2\xB3\x94" => "\xE2\xB3\x95", # COPTIC CAPITAL LETTER OLD COPTIC HAT
1225             "\xE2\xB3\x96" => "\xE2\xB3\x97", # COPTIC CAPITAL LETTER OLD COPTIC GANGIA
1226             "\xE2\xB3\x98" => "\xE2\xB3\x99", # COPTIC CAPITAL LETTER OLD COPTIC DJA
1227             "\xE2\xB3\x9A" => "\xE2\xB3\x9B", # COPTIC CAPITAL LETTER OLD COPTIC SHIMA
1228             "\xE2\xB3\x9C" => "\xE2\xB3\x9D", # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
1229             "\xE2\xB3\x9E" => "\xE2\xB3\x9F", # COPTIC CAPITAL LETTER OLD NUBIAN NGI
1230             "\xE2\xB3\xA0" => "\xE2\xB3\xA1", # COPTIC CAPITAL LETTER OLD NUBIAN NYI
1231             "\xE2\xB3\xA2" => "\xE2\xB3\xA3", # COPTIC CAPITAL LETTER OLD NUBIAN WAU
1232             "\xE2\xB3\xAB" => "\xE2\xB3\xAC", # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI
1233             "\xE2\xB3\xAD" => "\xE2\xB3\xAE", # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA
1234             "\xE2\xB3\xB2" => "\xE2\xB3\xB3", # COPTIC CAPITAL LETTER BOHAIRIC KHEI
1235             "\xEA\x99\x80" => "\xEA\x99\x81", # CYRILLIC CAPITAL LETTER ZEMLYA
1236             "\xEA\x99\x82" => "\xEA\x99\x83", # CYRILLIC CAPITAL LETTER DZELO
1237             "\xEA\x99\x84" => "\xEA\x99\x85", # CYRILLIC CAPITAL LETTER REVERSED DZE
1238             "\xEA\x99\x86" => "\xEA\x99\x87", # CYRILLIC CAPITAL LETTER IOTA
1239             "\xEA\x99\x88" => "\xEA\x99\x89", # CYRILLIC CAPITAL LETTER DJERV
1240             "\xEA\x99\x8A" => "\xEA\x99\x8B", # CYRILLIC CAPITAL LETTER MONOGRAPH UK
1241             "\xEA\x99\x8C" => "\xEA\x99\x8D", # CYRILLIC CAPITAL LETTER BROAD OMEGA
1242             "\xEA\x99\x8E" => "\xEA\x99\x8F", # CYRILLIC CAPITAL LETTER NEUTRAL YER
1243             "\xEA\x99\x90" => "\xEA\x99\x91", # CYRILLIC CAPITAL LETTER YERU WITH BACK YER
1244             "\xEA\x99\x92" => "\xEA\x99\x93", # CYRILLIC CAPITAL LETTER IOTIFIED YAT
1245             "\xEA\x99\x94" => "\xEA\x99\x95", # CYRILLIC CAPITAL LETTER REVERSED YU
1246             "\xEA\x99\x96" => "\xEA\x99\x97", # CYRILLIC CAPITAL LETTER IOTIFIED A
1247             "\xEA\x99\x98" => "\xEA\x99\x99", # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS
1248             "\xEA\x99\x9A" => "\xEA\x99\x9B", # CYRILLIC CAPITAL LETTER BLENDED YUS
1249             "\xEA\x99\x9C" => "\xEA\x99\x9D", # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS
1250             "\xEA\x99\x9E" => "\xEA\x99\x9F", # CYRILLIC CAPITAL LETTER YN
1251             "\xEA\x99\xA0" => "\xEA\x99\xA1", # CYRILLIC CAPITAL LETTER REVERSED TSE
1252             "\xEA\x99\xA2" => "\xEA\x99\xA3", # CYRILLIC CAPITAL LETTER SOFT DE
1253             "\xEA\x99\xA4" => "\xEA\x99\xA5", # CYRILLIC CAPITAL LETTER SOFT EL
1254             "\xEA\x99\xA6" => "\xEA\x99\xA7", # CYRILLIC CAPITAL LETTER SOFT EM
1255             "\xEA\x99\xA8" => "\xEA\x99\xA9", # CYRILLIC CAPITAL LETTER MONOCULAR O
1256             "\xEA\x99\xAA" => "\xEA\x99\xAB", # CYRILLIC CAPITAL LETTER BINOCULAR O
1257             "\xEA\x99\xAC" => "\xEA\x99\xAD", # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O
1258             "\xEA\x9A\x80" => "\xEA\x9A\x81", # CYRILLIC CAPITAL LETTER DWE
1259             "\xEA\x9A\x82" => "\xEA\x9A\x83", # CYRILLIC CAPITAL LETTER DZWE
1260             "\xEA\x9A\x84" => "\xEA\x9A\x85", # CYRILLIC CAPITAL LETTER ZHWE
1261             "\xEA\x9A\x86" => "\xEA\x9A\x87", # CYRILLIC CAPITAL LETTER CCHE
1262             "\xEA\x9A\x88" => "\xEA\x9A\x89", # CYRILLIC CAPITAL LETTER DZZE
1263             "\xEA\x9A\x8A" => "\xEA\x9A\x8B", # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK
1264             "\xEA\x9A\x8C" => "\xEA\x9A\x8D", # CYRILLIC CAPITAL LETTER TWE
1265             "\xEA\x9A\x8E" => "\xEA\x9A\x8F", # CYRILLIC CAPITAL LETTER TSWE
1266             "\xEA\x9A\x90" => "\xEA\x9A\x91", # CYRILLIC CAPITAL LETTER TSSE
1267             "\xEA\x9A\x92" => "\xEA\x9A\x93", # CYRILLIC CAPITAL LETTER TCHE
1268             "\xEA\x9A\x94" => "\xEA\x9A\x95", # CYRILLIC CAPITAL LETTER HWE
1269             "\xEA\x9A\x96" => "\xEA\x9A\x97", # CYRILLIC CAPITAL LETTER SHWE
1270             "\xEA\x9A\x98" => "\xEA\x9A\x99", # CYRILLIC CAPITAL LETTER DOUBLE O
1271             "\xEA\x9A\x9A" => "\xEA\x9A\x9B", # CYRILLIC CAPITAL LETTER CROSSED O
1272             "\xEA\x9C\xA2" => "\xEA\x9C\xA3", # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF
1273             "\xEA\x9C\xA4" => "\xEA\x9C\xA5", # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN
1274             "\xEA\x9C\xA6" => "\xEA\x9C\xA7", # LATIN CAPITAL LETTER HENG
1275             "\xEA\x9C\xA8" => "\xEA\x9C\xA9", # LATIN CAPITAL LETTER TZ
1276             "\xEA\x9C\xAA" => "\xEA\x9C\xAB", # LATIN CAPITAL LETTER TRESILLO
1277             "\xEA\x9C\xAC" => "\xEA\x9C\xAD", # LATIN CAPITAL LETTER CUATRILLO
1278             "\xEA\x9C\xAE" => "\xEA\x9C\xAF", # LATIN CAPITAL LETTER CUATRILLO WITH COMMA
1279             "\xEA\x9C\xB2" => "\xEA\x9C\xB3", # LATIN CAPITAL LETTER AA
1280             "\xEA\x9C\xB4" => "\xEA\x9C\xB5", # LATIN CAPITAL LETTER AO
1281             "\xEA\x9C\xB6" => "\xEA\x9C\xB7", # LATIN CAPITAL LETTER AU
1282             "\xEA\x9C\xB8" => "\xEA\x9C\xB9", # LATIN CAPITAL LETTER AV
1283             "\xEA\x9C\xBA" => "\xEA\x9C\xBB", # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR
1284             "\xEA\x9C\xBC" => "\xEA\x9C\xBD", # LATIN CAPITAL LETTER AY
1285             "\xEA\x9C\xBE" => "\xEA\x9C\xBF", # LATIN CAPITAL LETTER REVERSED C WITH DOT
1286             "\xEA\x9D\x80" => "\xEA\x9D\x81", # LATIN CAPITAL LETTER K WITH STROKE
1287             "\xEA\x9D\x82" => "\xEA\x9D\x83", # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE
1288             "\xEA\x9D\x84" => "\xEA\x9D\x85", # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE
1289             "\xEA\x9D\x86" => "\xEA\x9D\x87", # LATIN CAPITAL LETTER BROKEN L
1290             "\xEA\x9D\x88" => "\xEA\x9D\x89", # LATIN CAPITAL LETTER L WITH HIGH STROKE
1291             "\xEA\x9D\x8A" => "\xEA\x9D\x8B", # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY
1292             "\xEA\x9D\x8C" => "\xEA\x9D\x8D", # LATIN CAPITAL LETTER O WITH LOOP
1293             "\xEA\x9D\x8E" => "\xEA\x9D\x8F", # LATIN CAPITAL LETTER OO
1294             "\xEA\x9D\x90" => "\xEA\x9D\x91", # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER
1295             "\xEA\x9D\x92" => "\xEA\x9D\x93", # LATIN CAPITAL LETTER P WITH FLOURISH
1296             "\xEA\x9D\x94" => "\xEA\x9D\x95", # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL
1297             "\xEA\x9D\x96" => "\xEA\x9D\x97", # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER
1298             "\xEA\x9D\x98" => "\xEA\x9D\x99", # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE
1299             "\xEA\x9D\x9A" => "\xEA\x9D\x9B", # LATIN CAPITAL LETTER R ROTUNDA
1300             "\xEA\x9D\x9C" => "\xEA\x9D\x9D", # LATIN CAPITAL LETTER RUM ROTUNDA
1301             "\xEA\x9D\x9E" => "\xEA\x9D\x9F", # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE
1302             "\xEA\x9D\xA0" => "\xEA\x9D\xA1", # LATIN CAPITAL LETTER VY
1303             "\xEA\x9D\xA2" => "\xEA\x9D\xA3", # LATIN CAPITAL LETTER VISIGOTHIC Z
1304             "\xEA\x9D\xA4" => "\xEA\x9D\xA5", # LATIN CAPITAL LETTER THORN WITH STROKE
1305             "\xEA\x9D\xA6" => "\xEA\x9D\xA7", # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER
1306             "\xEA\x9D\xA8" => "\xEA\x9D\xA9", # LATIN CAPITAL LETTER VEND
1307             "\xEA\x9D\xAA" => "\xEA\x9D\xAB", # LATIN CAPITAL LETTER ET
1308             "\xEA\x9D\xAC" => "\xEA\x9D\xAD", # LATIN CAPITAL LETTER IS
1309             "\xEA\x9D\xAE" => "\xEA\x9D\xAF", # LATIN CAPITAL LETTER CON
1310             "\xEA\x9D\xB9" => "\xEA\x9D\xBA", # LATIN CAPITAL LETTER INSULAR D
1311             "\xEA\x9D\xBB" => "\xEA\x9D\xBC", # LATIN CAPITAL LETTER INSULAR F
1312             "\xEA\x9D\xBD" => "\xE1\xB5\xB9", # LATIN CAPITAL LETTER INSULAR G
1313             "\xEA\x9D\xBE" => "\xEA\x9D\xBF", # LATIN CAPITAL LETTER TURNED INSULAR G
1314             "\xEA\x9E\x80" => "\xEA\x9E\x81", # LATIN CAPITAL LETTER TURNED L
1315             "\xEA\x9E\x82" => "\xEA\x9E\x83", # LATIN CAPITAL LETTER INSULAR R
1316             "\xEA\x9E\x84" => "\xEA\x9E\x85", # LATIN CAPITAL LETTER INSULAR S
1317             "\xEA\x9E\x86" => "\xEA\x9E\x87", # LATIN CAPITAL LETTER INSULAR T
1318             "\xEA\x9E\x8B" => "\xEA\x9E\x8C", # LATIN CAPITAL LETTER SALTILLO
1319             "\xEA\x9E\x8D" => "\xC9\xA5", # LATIN CAPITAL LETTER TURNED H
1320             "\xEA\x9E\x90" => "\xEA\x9E\x91", # LATIN CAPITAL LETTER N WITH DESCENDER
1321             "\xEA\x9E\x92" => "\xEA\x9E\x93", # LATIN CAPITAL LETTER C WITH BAR
1322             "\xEA\x9E\x96" => "\xEA\x9E\x97", # LATIN CAPITAL LETTER B WITH FLOURISH
1323             "\xEA\x9E\x98" => "\xEA\x9E\x99", # LATIN CAPITAL LETTER F WITH STROKE
1324             "\xEA\x9E\x9A" => "\xEA\x9E\x9B", # LATIN CAPITAL LETTER VOLAPUK AE
1325             "\xEA\x9E\x9C" => "\xEA\x9E\x9D", # LATIN CAPITAL LETTER VOLAPUK OE
1326             "\xEA\x9E\x9E" => "\xEA\x9E\x9F", # LATIN CAPITAL LETTER VOLAPUK UE
1327             "\xEA\x9E\xA0" => "\xEA\x9E\xA1", # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE
1328             "\xEA\x9E\xA2" => "\xEA\x9E\xA3", # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE
1329             "\xEA\x9E\xA4" => "\xEA\x9E\xA5", # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE
1330             "\xEA\x9E\xA6" => "\xEA\x9E\xA7", # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE
1331             "\xEA\x9E\xA8" => "\xEA\x9E\xA9", # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE
1332             "\xEA\x9E\xAA" => "\xC9\xA6", # LATIN CAPITAL LETTER H WITH HOOK
1333             "\xEA\x9E\xAB" => "\xC9\x9C", # LATIN CAPITAL LETTER REVERSED OPEN E
1334             "\xEA\x9E\xAC" => "\xC9\xA1", # LATIN CAPITAL LETTER SCRIPT G
1335             "\xEA\x9E\xAD" => "\xC9\xAC", # LATIN CAPITAL LETTER L WITH BELT
1336             "\xEA\x9E\xAE" => "\xC9\xAA", # LATIN CAPITAL LETTER SMALL CAPITAL I
1337             "\xEA\x9E\xB0" => "\xCA\x9E", # LATIN CAPITAL LETTER TURNED K
1338             "\xEA\x9E\xB1" => "\xCA\x87", # LATIN CAPITAL LETTER TURNED T
1339             "\xEA\x9E\xB2" => "\xCA\x9D", # LATIN CAPITAL LETTER J WITH CROSSED-TAIL
1340             "\xEA\x9E\xB3" => "\xEA\xAD\x93", # LATIN CAPITAL LETTER CHI
1341             "\xEA\x9E\xB4" => "\xEA\x9E\xB5", # LATIN CAPITAL LETTER BETA
1342             "\xEA\x9E\xB6" => "\xEA\x9E\xB7", # LATIN CAPITAL LETTER OMEGA
1343             "\xEA\x9E\xB8" => "\xEA\x9E\xB9", # LATIN CAPITAL LETTER U WITH STROKE
1344             "\xEA\x9E\xBA" => "\xEA\x9E\xBB", # LATIN CAPITAL LETTER GLOTTAL A
1345             "\xEA\x9E\xBC" => "\xEA\x9E\xBD", # LATIN CAPITAL LETTER GLOTTAL I
1346             "\xEA\x9E\xBE" => "\xEA\x9E\xBF", # LATIN CAPITAL LETTER GLOTTAL U
1347             "\xEA\x9F\x82" => "\xEA\x9F\x83", # LATIN CAPITAL LETTER ANGLICANA W
1348             "\xEA\x9F\x84" => "\xEA\x9E\x94", # LATIN CAPITAL LETTER C WITH PALATAL HOOK
1349             "\xEA\x9F\x85" => "\xCA\x82", # LATIN CAPITAL LETTER S WITH HOOK
1350             "\xEA\x9F\x86" => "\xE1\xB6\x8E", # LATIN CAPITAL LETTER Z WITH PALATAL HOOK
1351             "\xEA\xAD\xB0" => "\xE1\x8E\xA0", # CHEROKEE SMALL LETTER A
1352             "\xEA\xAD\xB1" => "\xE1\x8E\xA1", # CHEROKEE SMALL LETTER E
1353             "\xEA\xAD\xB2" => "\xE1\x8E\xA2", # CHEROKEE SMALL LETTER I
1354             "\xEA\xAD\xB3" => "\xE1\x8E\xA3", # CHEROKEE SMALL LETTER O
1355             "\xEA\xAD\xB4" => "\xE1\x8E\xA4", # CHEROKEE SMALL LETTER U
1356             "\xEA\xAD\xB5" => "\xE1\x8E\xA5", # CHEROKEE SMALL LETTER V
1357             "\xEA\xAD\xB6" => "\xE1\x8E\xA6", # CHEROKEE SMALL LETTER GA
1358             "\xEA\xAD\xB7" => "\xE1\x8E\xA7", # CHEROKEE SMALL LETTER KA
1359             "\xEA\xAD\xB8" => "\xE1\x8E\xA8", # CHEROKEE SMALL LETTER GE
1360             "\xEA\xAD\xB9" => "\xE1\x8E\xA9", # CHEROKEE SMALL LETTER GI
1361             "\xEA\xAD\xBA" => "\xE1\x8E\xAA", # CHEROKEE SMALL LETTER GO
1362             "\xEA\xAD\xBB" => "\xE1\x8E\xAB", # CHEROKEE SMALL LETTER GU
1363             "\xEA\xAD\xBC" => "\xE1\x8E\xAC", # CHEROKEE SMALL LETTER GV
1364             "\xEA\xAD\xBD" => "\xE1\x8E\xAD", # CHEROKEE SMALL LETTER HA
1365             "\xEA\xAD\xBE" => "\xE1\x8E\xAE", # CHEROKEE SMALL LETTER HE
1366             "\xEA\xAD\xBF" => "\xE1\x8E\xAF", # CHEROKEE SMALL LETTER HI
1367             "\xEA\xAE\x80" => "\xE1\x8E\xB0", # CHEROKEE SMALL LETTER HO
1368             "\xEA\xAE\x81" => "\xE1\x8E\xB1", # CHEROKEE SMALL LETTER HU
1369             "\xEA\xAE\x82" => "\xE1\x8E\xB2", # CHEROKEE SMALL LETTER HV
1370             "\xEA\xAE\x83" => "\xE1\x8E\xB3", # CHEROKEE SMALL LETTER LA
1371             "\xEA\xAE\x84" => "\xE1\x8E\xB4", # CHEROKEE SMALL LETTER LE
1372             "\xEA\xAE\x85" => "\xE1\x8E\xB5", # CHEROKEE SMALL LETTER LI
1373             "\xEA\xAE\x86" => "\xE1\x8E\xB6", # CHEROKEE SMALL LETTER LO
1374             "\xEA\xAE\x87" => "\xE1\x8E\xB7", # CHEROKEE SMALL LETTER LU
1375             "\xEA\xAE\x88" => "\xE1\x8E\xB8", # CHEROKEE SMALL LETTER LV
1376             "\xEA\xAE\x89" => "\xE1\x8E\xB9", # CHEROKEE SMALL LETTER MA
1377             "\xEA\xAE\x8A" => "\xE1\x8E\xBA", # CHEROKEE SMALL LETTER ME
1378             "\xEA\xAE\x8B" => "\xE1\x8E\xBB", # CHEROKEE SMALL LETTER MI
1379             "\xEA\xAE\x8C" => "\xE1\x8E\xBC", # CHEROKEE SMALL LETTER MO
1380             "\xEA\xAE\x8D" => "\xE1\x8E\xBD", # CHEROKEE SMALL LETTER MU
1381             "\xEA\xAE\x8E" => "\xE1\x8E\xBE", # CHEROKEE SMALL LETTER NA
1382             "\xEA\xAE\x8F" => "\xE1\x8E\xBF", # CHEROKEE SMALL LETTER HNA
1383             "\xEA\xAE\x90" => "\xE1\x8F\x80", # CHEROKEE SMALL LETTER NAH
1384             "\xEA\xAE\x91" => "\xE1\x8F\x81", # CHEROKEE SMALL LETTER NE
1385             "\xEA\xAE\x92" => "\xE1\x8F\x82", # CHEROKEE SMALL LETTER NI
1386             "\xEA\xAE\x93" => "\xE1\x8F\x83", # CHEROKEE SMALL LETTER NO
1387             "\xEA\xAE\x94" => "\xE1\x8F\x84", # CHEROKEE SMALL LETTER NU
1388             "\xEA\xAE\x95" => "\xE1\x8F\x85", # CHEROKEE SMALL LETTER NV
1389             "\xEA\xAE\x96" => "\xE1\x8F\x86", # CHEROKEE SMALL LETTER QUA
1390             "\xEA\xAE\x97" => "\xE1\x8F\x87", # CHEROKEE SMALL LETTER QUE
1391             "\xEA\xAE\x98" => "\xE1\x8F\x88", # CHEROKEE SMALL LETTER QUI
1392             "\xEA\xAE\x99" => "\xE1\x8F\x89", # CHEROKEE SMALL LETTER QUO
1393             "\xEA\xAE\x9A" => "\xE1\x8F\x8A", # CHEROKEE SMALL LETTER QUU
1394             "\xEA\xAE\x9B" => "\xE1\x8F\x8B", # CHEROKEE SMALL LETTER QUV
1395             "\xEA\xAE\x9C" => "\xE1\x8F\x8C", # CHEROKEE SMALL LETTER SA
1396             "\xEA\xAE\x9D" => "\xE1\x8F\x8D", # CHEROKEE SMALL LETTER S
1397             "\xEA\xAE\x9E" => "\xE1\x8F\x8E", # CHEROKEE SMALL LETTER SE
1398             "\xEA\xAE\x9F" => "\xE1\x8F\x8F", # CHEROKEE SMALL LETTER SI
1399             "\xEA\xAE\xA0" => "\xE1\x8F\x90", # CHEROKEE SMALL LETTER SO
1400             "\xEA\xAE\xA1" => "\xE1\x8F\x91", # CHEROKEE SMALL LETTER SU
1401             "\xEA\xAE\xA2" => "\xE1\x8F\x92", # CHEROKEE SMALL LETTER SV
1402             "\xEA\xAE\xA3" => "\xE1\x8F\x93", # CHEROKEE SMALL LETTER DA
1403             "\xEA\xAE\xA4" => "\xE1\x8F\x94", # CHEROKEE SMALL LETTER TA
1404             "\xEA\xAE\xA5" => "\xE1\x8F\x95", # CHEROKEE SMALL LETTER DE
1405             "\xEA\xAE\xA6" => "\xE1\x8F\x96", # CHEROKEE SMALL LETTER TE
1406             "\xEA\xAE\xA7" => "\xE1\x8F\x97", # CHEROKEE SMALL LETTER DI
1407             "\xEA\xAE\xA8" => "\xE1\x8F\x98", # CHEROKEE SMALL LETTER TI
1408             "\xEA\xAE\xA9" => "\xE1\x8F\x99", # CHEROKEE SMALL LETTER DO
1409             "\xEA\xAE\xAA" => "\xE1\x8F\x9A", # CHEROKEE SMALL LETTER DU
1410             "\xEA\xAE\xAB" => "\xE1\x8F\x9B", # CHEROKEE SMALL LETTER DV
1411             "\xEA\xAE\xAC" => "\xE1\x8F\x9C", # CHEROKEE SMALL LETTER DLA
1412             "\xEA\xAE\xAD" => "\xE1\x8F\x9D", # CHEROKEE SMALL LETTER TLA
1413             "\xEA\xAE\xAE" => "\xE1\x8F\x9E", # CHEROKEE SMALL LETTER TLE
1414             "\xEA\xAE\xAF" => "\xE1\x8F\x9F", # CHEROKEE SMALL LETTER TLI
1415             "\xEA\xAE\xB0" => "\xE1\x8F\xA0", # CHEROKEE SMALL LETTER TLO
1416             "\xEA\xAE\xB1" => "\xE1\x8F\xA1", # CHEROKEE SMALL LETTER TLU
1417             "\xEA\xAE\xB2" => "\xE1\x8F\xA2", # CHEROKEE SMALL LETTER TLV
1418             "\xEA\xAE\xB3" => "\xE1\x8F\xA3", # CHEROKEE SMALL LETTER TSA
1419             "\xEA\xAE\xB4" => "\xE1\x8F\xA4", # CHEROKEE SMALL LETTER TSE
1420             "\xEA\xAE\xB5" => "\xE1\x8F\xA5", # CHEROKEE SMALL LETTER TSI
1421             "\xEA\xAE\xB6" => "\xE1\x8F\xA6", # CHEROKEE SMALL LETTER TSO
1422             "\xEA\xAE\xB7" => "\xE1\x8F\xA7", # CHEROKEE SMALL LETTER TSU
1423             "\xEA\xAE\xB8" => "\xE1\x8F\xA8", # CHEROKEE SMALL LETTER TSV
1424             "\xEA\xAE\xB9" => "\xE1\x8F\xA9", # CHEROKEE SMALL LETTER WA
1425             "\xEA\xAE\xBA" => "\xE1\x8F\xAA", # CHEROKEE SMALL LETTER WE
1426             "\xEA\xAE\xBB" => "\xE1\x8F\xAB", # CHEROKEE SMALL LETTER WI
1427             "\xEA\xAE\xBC" => "\xE1\x8F\xAC", # CHEROKEE SMALL LETTER WO
1428             "\xEA\xAE\xBD" => "\xE1\x8F\xAD", # CHEROKEE SMALL LETTER WU
1429             "\xEA\xAE\xBE" => "\xE1\x8F\xAE", # CHEROKEE SMALL LETTER WV
1430             "\xEA\xAE\xBF" => "\xE1\x8F\xAF", # CHEROKEE SMALL LETTER YA
1431             "\xEF\xAC\x80" => "\x66\x66", # LATIN SMALL LIGATURE FF
1432             "\xEF\xAC\x81" => "\x66\x69", # LATIN SMALL LIGATURE FI
1433             "\xEF\xAC\x82" => "\x66\x6C", # LATIN SMALL LIGATURE FL
1434             "\xEF\xAC\x83" => "\x66\x66\x69", # LATIN SMALL LIGATURE FFI
1435             "\xEF\xAC\x84" => "\x66\x66\x6C", # LATIN SMALL LIGATURE FFL
1436             "\xEF\xAC\x85" => "\x73\x74", # LATIN SMALL LIGATURE LONG S T
1437             "\xEF\xAC\x86" => "\x73\x74", # LATIN SMALL LIGATURE ST
1438             "\xEF\xAC\x93" => "\xD5\xB4\xD5\xB6", # ARMENIAN SMALL LIGATURE MEN NOW
1439             "\xEF\xAC\x94" => "\xD5\xB4\xD5\xA5", # ARMENIAN SMALL LIGATURE MEN ECH
1440             "\xEF\xAC\x95" => "\xD5\xB4\xD5\xAB", # ARMENIAN SMALL LIGATURE MEN INI
1441             "\xEF\xAC\x96" => "\xD5\xBE\xD5\xB6", # ARMENIAN SMALL LIGATURE VEW NOW
1442             "\xEF\xAC\x97" => "\xD5\xB4\xD5\xAD", # ARMENIAN SMALL LIGATURE MEN XEH
1443             "\xEF\xBC\xA1" => "\xEF\xBD\x81", # FULLWIDTH LATIN CAPITAL LETTER A
1444             "\xEF\xBC\xA2" => "\xEF\xBD\x82", # FULLWIDTH LATIN CAPITAL LETTER B
1445             "\xEF\xBC\xA3" => "\xEF\xBD\x83", # FULLWIDTH LATIN CAPITAL LETTER C
1446             "\xEF\xBC\xA4" => "\xEF\xBD\x84", # FULLWIDTH LATIN CAPITAL LETTER D
1447             "\xEF\xBC\xA5" => "\xEF\xBD\x85", # FULLWIDTH LATIN CAPITAL LETTER E
1448             "\xEF\xBC\xA6" => "\xEF\xBD\x86", # FULLWIDTH LATIN CAPITAL LETTER F
1449             "\xEF\xBC\xA7" => "\xEF\xBD\x87", # FULLWIDTH LATIN CAPITAL LETTER G
1450             "\xEF\xBC\xA8" => "\xEF\xBD\x88", # FULLWIDTH LATIN CAPITAL LETTER H
1451             "\xEF\xBC\xA9" => "\xEF\xBD\x89", # FULLWIDTH LATIN CAPITAL LETTER I
1452             "\xEF\xBC\xAA" => "\xEF\xBD\x8A", # FULLWIDTH LATIN CAPITAL LETTER J
1453             "\xEF\xBC\xAB" => "\xEF\xBD\x8B", # FULLWIDTH LATIN CAPITAL LETTER K
1454             "\xEF\xBC\xAC" => "\xEF\xBD\x8C", # FULLWIDTH LATIN CAPITAL LETTER L
1455             "\xEF\xBC\xAD" => "\xEF\xBD\x8D", # FULLWIDTH LATIN CAPITAL LETTER M
1456             "\xEF\xBC\xAE" => "\xEF\xBD\x8E", # FULLWIDTH LATIN CAPITAL LETTER N
1457             "\xEF\xBC\xAF" => "\xEF\xBD\x8F", # FULLWIDTH LATIN CAPITAL LETTER O
1458             "\xEF\xBC\xB0" => "\xEF\xBD\x90", # FULLWIDTH LATIN CAPITAL LETTER P
1459             "\xEF\xBC\xB1" => "\xEF\xBD\x91", # FULLWIDTH LATIN CAPITAL LETTER Q
1460             "\xEF\xBC\xB2" => "\xEF\xBD\x92", # FULLWIDTH LATIN CAPITAL LETTER R
1461             "\xEF\xBC\xB3" => "\xEF\xBD\x93", # FULLWIDTH LATIN CAPITAL LETTER S
1462             "\xEF\xBC\xB4" => "\xEF\xBD\x94", # FULLWIDTH LATIN CAPITAL LETTER T
1463             "\xEF\xBC\xB5" => "\xEF\xBD\x95", # FULLWIDTH LATIN CAPITAL LETTER U
1464             "\xEF\xBC\xB6" => "\xEF\xBD\x96", # FULLWIDTH LATIN CAPITAL LETTER V
1465             "\xEF\xBC\xB7" => "\xEF\xBD\x97", # FULLWIDTH LATIN CAPITAL LETTER W
1466             "\xEF\xBC\xB8" => "\xEF\xBD\x98", # FULLWIDTH LATIN CAPITAL LETTER X
1467             "\xEF\xBC\xB9" => "\xEF\xBD\x99", # FULLWIDTH LATIN CAPITAL LETTER Y
1468             "\xEF\xBC\xBA" => "\xEF\xBD\x9A", # FULLWIDTH LATIN CAPITAL LETTER Z
1469             "\xF0\x90\x90\x80" => "\xF0\x90\x90\xA8", # DESERET CAPITAL LETTER LONG I
1470             "\xF0\x90\x90\x81" => "\xF0\x90\x90\xA9", # DESERET CAPITAL LETTER LONG E
1471             "\xF0\x90\x90\x82" => "\xF0\x90\x90\xAA", # DESERET CAPITAL LETTER LONG A
1472             "\xF0\x90\x90\x83" => "\xF0\x90\x90\xAB", # DESERET CAPITAL LETTER LONG AH
1473             "\xF0\x90\x90\x84" => "\xF0\x90\x90\xAC", # DESERET CAPITAL LETTER LONG O
1474             "\xF0\x90\x90\x85" => "\xF0\x90\x90\xAD", # DESERET CAPITAL LETTER LONG OO
1475             "\xF0\x90\x90\x86" => "\xF0\x90\x90\xAE", # DESERET CAPITAL LETTER SHORT I
1476             "\xF0\x90\x90\x87" => "\xF0\x90\x90\xAF", # DESERET CAPITAL LETTER SHORT E
1477             "\xF0\x90\x90\x88" => "\xF0\x90\x90\xB0", # DESERET CAPITAL LETTER SHORT A
1478             "\xF0\x90\x90\x89" => "\xF0\x90\x90\xB1", # DESERET CAPITAL LETTER SHORT AH
1479             "\xF0\x90\x90\x8A" => "\xF0\x90\x90\xB2", # DESERET CAPITAL LETTER SHORT O
1480             "\xF0\x90\x90\x8B" => "\xF0\x90\x90\xB3", # DESERET CAPITAL LETTER SHORT OO
1481             "\xF0\x90\x90\x8C" => "\xF0\x90\x90\xB4", # DESERET CAPITAL LETTER AY
1482             "\xF0\x90\x90\x8D" => "\xF0\x90\x90\xB5", # DESERET CAPITAL LETTER OW
1483             "\xF0\x90\x90\x8E" => "\xF0\x90\x90\xB6", # DESERET CAPITAL LETTER WU
1484             "\xF0\x90\x90\x8F" => "\xF0\x90\x90\xB7", # DESERET CAPITAL LETTER YEE
1485             "\xF0\x90\x90\x90" => "\xF0\x90\x90\xB8", # DESERET CAPITAL LETTER H
1486             "\xF0\x90\x90\x91" => "\xF0\x90\x90\xB9", # DESERET CAPITAL LETTER PEE
1487             "\xF0\x90\x90\x92" => "\xF0\x90\x90\xBA", # DESERET CAPITAL LETTER BEE
1488             "\xF0\x90\x90\x93" => "\xF0\x90\x90\xBB", # DESERET CAPITAL LETTER TEE
1489             "\xF0\x90\x90\x94" => "\xF0\x90\x90\xBC", # DESERET CAPITAL LETTER DEE
1490             "\xF0\x90\x90\x95" => "\xF0\x90\x90\xBD", # DESERET CAPITAL LETTER CHEE
1491             "\xF0\x90\x90\x96" => "\xF0\x90\x90\xBE", # DESERET CAPITAL LETTER JEE
1492             "\xF0\x90\x90\x97" => "\xF0\x90\x90\xBF", # DESERET CAPITAL LETTER KAY
1493             "\xF0\x90\x90\x98" => "\xF0\x90\x91\x80", # DESERET CAPITAL LETTER GAY
1494             "\xF0\x90\x90\x99" => "\xF0\x90\x91\x81", # DESERET CAPITAL LETTER EF
1495             "\xF0\x90\x90\x9A" => "\xF0\x90\x91\x82", # DESERET CAPITAL LETTER VEE
1496             "\xF0\x90\x90\x9B" => "\xF0\x90\x91\x83", # DESERET CAPITAL LETTER ETH
1497             "\xF0\x90\x90\x9C" => "\xF0\x90\x91\x84", # DESERET CAPITAL LETTER THEE
1498             "\xF0\x90\x90\x9D" => "\xF0\x90\x91\x85", # DESERET CAPITAL LETTER ES
1499             "\xF0\x90\x90\x9E" => "\xF0\x90\x91\x86", # DESERET CAPITAL LETTER ZEE
1500             "\xF0\x90\x90\x9F" => "\xF0\x90\x91\x87", # DESERET CAPITAL LETTER ESH
1501             "\xF0\x90\x90\xA0" => "\xF0\x90\x91\x88", # DESERET CAPITAL LETTER ZHEE
1502             "\xF0\x90\x90\xA1" => "\xF0\x90\x91\x89", # DESERET CAPITAL LETTER ER
1503             "\xF0\x90\x90\xA2" => "\xF0\x90\x91\x8A", # DESERET CAPITAL LETTER EL
1504             "\xF0\x90\x90\xA3" => "\xF0\x90\x91\x8B", # DESERET CAPITAL LETTER EM
1505             "\xF0\x90\x90\xA4" => "\xF0\x90\x91\x8C", # DESERET CAPITAL LETTER EN
1506             "\xF0\x90\x90\xA5" => "\xF0\x90\x91\x8D", # DESERET CAPITAL LETTER ENG
1507             "\xF0\x90\x90\xA6" => "\xF0\x90\x91\x8E", # DESERET CAPITAL LETTER OI
1508             "\xF0\x90\x90\xA7" => "\xF0\x90\x91\x8F", # DESERET CAPITAL LETTER EW
1509             "\xF0\x90\x92\xB0" => "\xF0\x90\x93\x98", # OSAGE CAPITAL LETTER A
1510             "\xF0\x90\x92\xB1" => "\xF0\x90\x93\x99", # OSAGE CAPITAL LETTER AI
1511             "\xF0\x90\x92\xB2" => "\xF0\x90\x93\x9A", # OSAGE CAPITAL LETTER AIN
1512             "\xF0\x90\x92\xB3" => "\xF0\x90\x93\x9B", # OSAGE CAPITAL LETTER AH
1513             "\xF0\x90\x92\xB4" => "\xF0\x90\x93\x9C", # OSAGE CAPITAL LETTER BRA
1514             "\xF0\x90\x92\xB5" => "\xF0\x90\x93\x9D", # OSAGE CAPITAL LETTER CHA
1515             "\xF0\x90\x92\xB6" => "\xF0\x90\x93\x9E", # OSAGE CAPITAL LETTER EHCHA
1516             "\xF0\x90\x92\xB7" => "\xF0\x90\x93\x9F", # OSAGE CAPITAL LETTER E
1517             "\xF0\x90\x92\xB8" => "\xF0\x90\x93\xA0", # OSAGE CAPITAL LETTER EIN
1518             "\xF0\x90\x92\xB9" => "\xF0\x90\x93\xA1", # OSAGE CAPITAL LETTER HA
1519             "\xF0\x90\x92\xBA" => "\xF0\x90\x93\xA2", # OSAGE CAPITAL LETTER HYA
1520             "\xF0\x90\x92\xBB" => "\xF0\x90\x93\xA3", # OSAGE CAPITAL LETTER I
1521             "\xF0\x90\x92\xBC" => "\xF0\x90\x93\xA4", # OSAGE CAPITAL LETTER KA
1522             "\xF0\x90\x92\xBD" => "\xF0\x90\x93\xA5", # OSAGE CAPITAL LETTER EHKA
1523             "\xF0\x90\x92\xBE" => "\xF0\x90\x93\xA6", # OSAGE CAPITAL LETTER KYA
1524             "\xF0\x90\x92\xBF" => "\xF0\x90\x93\xA7", # OSAGE CAPITAL LETTER LA
1525             "\xF0\x90\x93\x80" => "\xF0\x90\x93\xA8", # OSAGE CAPITAL LETTER MA
1526             "\xF0\x90\x93\x81" => "\xF0\x90\x93\xA9", # OSAGE CAPITAL LETTER NA
1527             "\xF0\x90\x93\x82" => "\xF0\x90\x93\xAA", # OSAGE CAPITAL LETTER O
1528             "\xF0\x90\x93\x83" => "\xF0\x90\x93\xAB", # OSAGE CAPITAL LETTER OIN
1529             "\xF0\x90\x93\x84" => "\xF0\x90\x93\xAC", # OSAGE CAPITAL LETTER PA
1530             "\xF0\x90\x93\x85" => "\xF0\x90\x93\xAD", # OSAGE CAPITAL LETTER EHPA
1531             "\xF0\x90\x93\x86" => "\xF0\x90\x93\xAE", # OSAGE CAPITAL LETTER SA
1532             "\xF0\x90\x93\x87" => "\xF0\x90\x93\xAF", # OSAGE CAPITAL LETTER SHA
1533             "\xF0\x90\x93\x88" => "\xF0\x90\x93\xB0", # OSAGE CAPITAL LETTER TA
1534             "\xF0\x90\x93\x89" => "\xF0\x90\x93\xB1", # OSAGE CAPITAL LETTER EHTA
1535             "\xF0\x90\x93\x8A" => "\xF0\x90\x93\xB2", # OSAGE CAPITAL LETTER TSA
1536             "\xF0\x90\x93\x8B" => "\xF0\x90\x93\xB3", # OSAGE CAPITAL LETTER EHTSA
1537             "\xF0\x90\x93\x8C" => "\xF0\x90\x93\xB4", # OSAGE CAPITAL LETTER TSHA
1538             "\xF0\x90\x93\x8D" => "\xF0\x90\x93\xB5", # OSAGE CAPITAL LETTER DHA
1539             "\xF0\x90\x93\x8E" => "\xF0\x90\x93\xB6", # OSAGE CAPITAL LETTER U
1540             "\xF0\x90\x93\x8F" => "\xF0\x90\x93\xB7", # OSAGE CAPITAL LETTER WA
1541             "\xF0\x90\x93\x90" => "\xF0\x90\x93\xB8", # OSAGE CAPITAL LETTER KHA
1542             "\xF0\x90\x93\x91" => "\xF0\x90\x93\xB9", # OSAGE CAPITAL LETTER GHA
1543             "\xF0\x90\x93\x92" => "\xF0\x90\x93\xBA", # OSAGE CAPITAL LETTER ZA
1544             "\xF0\x90\x93\x93" => "\xF0\x90\x93\xBB", # OSAGE CAPITAL LETTER ZHA
1545             "\xF0\x90\xB2\x80" => "\xF0\x90\xB3\x80", # OLD HUNGARIAN CAPITAL LETTER A
1546             "\xF0\x90\xB2\x81" => "\xF0\x90\xB3\x81", # OLD HUNGARIAN CAPITAL LETTER AA
1547             "\xF0\x90\xB2\x82" => "\xF0\x90\xB3\x82", # OLD HUNGARIAN CAPITAL LETTER EB
1548             "\xF0\x90\xB2\x83" => "\xF0\x90\xB3\x83", # OLD HUNGARIAN CAPITAL LETTER AMB
1549             "\xF0\x90\xB2\x84" => "\xF0\x90\xB3\x84", # OLD HUNGARIAN CAPITAL LETTER EC
1550             "\xF0\x90\xB2\x85" => "\xF0\x90\xB3\x85", # OLD HUNGARIAN CAPITAL LETTER ENC
1551             "\xF0\x90\xB2\x86" => "\xF0\x90\xB3\x86", # OLD HUNGARIAN CAPITAL LETTER ECS
1552             "\xF0\x90\xB2\x87" => "\xF0\x90\xB3\x87", # OLD HUNGARIAN CAPITAL LETTER ED
1553             "\xF0\x90\xB2\x88" => "\xF0\x90\xB3\x88", # OLD HUNGARIAN CAPITAL LETTER AND
1554             "\xF0\x90\xB2\x89" => "\xF0\x90\xB3\x89", # OLD HUNGARIAN CAPITAL LETTER E
1555             "\xF0\x90\xB2\x8A" => "\xF0\x90\xB3\x8A", # OLD HUNGARIAN CAPITAL LETTER CLOSE E
1556             "\xF0\x90\xB2\x8B" => "\xF0\x90\xB3\x8B", # OLD HUNGARIAN CAPITAL LETTER EE
1557             "\xF0\x90\xB2\x8C" => "\xF0\x90\xB3\x8C", # OLD HUNGARIAN CAPITAL LETTER EF
1558             "\xF0\x90\xB2\x8D" => "\xF0\x90\xB3\x8D", # OLD HUNGARIAN CAPITAL LETTER EG
1559             "\xF0\x90\xB2\x8E" => "\xF0\x90\xB3\x8E", # OLD HUNGARIAN CAPITAL LETTER EGY
1560             "\xF0\x90\xB2\x8F" => "\xF0\x90\xB3\x8F", # OLD HUNGARIAN CAPITAL LETTER EH
1561             "\xF0\x90\xB2\x90" => "\xF0\x90\xB3\x90", # OLD HUNGARIAN CAPITAL LETTER I
1562             "\xF0\x90\xB2\x91" => "\xF0\x90\xB3\x91", # OLD HUNGARIAN CAPITAL LETTER II
1563             "\xF0\x90\xB2\x92" => "\xF0\x90\xB3\x92", # OLD HUNGARIAN CAPITAL LETTER EJ
1564             "\xF0\x90\xB2\x93" => "\xF0\x90\xB3\x93", # OLD HUNGARIAN CAPITAL LETTER EK
1565             "\xF0\x90\xB2\x94" => "\xF0\x90\xB3\x94", # OLD HUNGARIAN CAPITAL LETTER AK
1566             "\xF0\x90\xB2\x95" => "\xF0\x90\xB3\x95", # OLD HUNGARIAN CAPITAL LETTER UNK
1567             "\xF0\x90\xB2\x96" => "\xF0\x90\xB3\x96", # OLD HUNGARIAN CAPITAL LETTER EL
1568             "\xF0\x90\xB2\x97" => "\xF0\x90\xB3\x97", # OLD HUNGARIAN CAPITAL LETTER ELY
1569             "\xF0\x90\xB2\x98" => "\xF0\x90\xB3\x98", # OLD HUNGARIAN CAPITAL LETTER EM
1570             "\xF0\x90\xB2\x99" => "\xF0\x90\xB3\x99", # OLD HUNGARIAN CAPITAL LETTER EN
1571             "\xF0\x90\xB2\x9A" => "\xF0\x90\xB3\x9A", # OLD HUNGARIAN CAPITAL LETTER ENY
1572             "\xF0\x90\xB2\x9B" => "\xF0\x90\xB3\x9B", # OLD HUNGARIAN CAPITAL LETTER O
1573             "\xF0\x90\xB2\x9C" => "\xF0\x90\xB3\x9C", # OLD HUNGARIAN CAPITAL LETTER OO
1574             "\xF0\x90\xB2\x9D" => "\xF0\x90\xB3\x9D", # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE
1575             "\xF0\x90\xB2\x9E" => "\xF0\x90\xB3\x9E", # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE
1576             "\xF0\x90\xB2\x9F" => "\xF0\x90\xB3\x9F", # OLD HUNGARIAN CAPITAL LETTER OEE
1577             "\xF0\x90\xB2\xA0" => "\xF0\x90\xB3\xA0", # OLD HUNGARIAN CAPITAL LETTER EP
1578             "\xF0\x90\xB2\xA1" => "\xF0\x90\xB3\xA1", # OLD HUNGARIAN CAPITAL LETTER EMP
1579             "\xF0\x90\xB2\xA2" => "\xF0\x90\xB3\xA2", # OLD HUNGARIAN CAPITAL LETTER ER
1580             "\xF0\x90\xB2\xA3" => "\xF0\x90\xB3\xA3", # OLD HUNGARIAN CAPITAL LETTER SHORT ER
1581             "\xF0\x90\xB2\xA4" => "\xF0\x90\xB3\xA4", # OLD HUNGARIAN CAPITAL LETTER ES
1582             "\xF0\x90\xB2\xA5" => "\xF0\x90\xB3\xA5", # OLD HUNGARIAN CAPITAL LETTER ESZ
1583             "\xF0\x90\xB2\xA6" => "\xF0\x90\xB3\xA6", # OLD HUNGARIAN CAPITAL LETTER ET
1584             "\xF0\x90\xB2\xA7" => "\xF0\x90\xB3\xA7", # OLD HUNGARIAN CAPITAL LETTER ENT
1585             "\xF0\x90\xB2\xA8" => "\xF0\x90\xB3\xA8", # OLD HUNGARIAN CAPITAL LETTER ETY
1586             "\xF0\x90\xB2\xA9" => "\xF0\x90\xB3\xA9", # OLD HUNGARIAN CAPITAL LETTER ECH
1587             "\xF0\x90\xB2\xAA" => "\xF0\x90\xB3\xAA", # OLD HUNGARIAN CAPITAL LETTER U
1588             "\xF0\x90\xB2\xAB" => "\xF0\x90\xB3\xAB", # OLD HUNGARIAN CAPITAL LETTER UU
1589             "\xF0\x90\xB2\xAC" => "\xF0\x90\xB3\xAC", # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE
1590             "\xF0\x90\xB2\xAD" => "\xF0\x90\xB3\xAD", # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE
1591             "\xF0\x90\xB2\xAE" => "\xF0\x90\xB3\xAE", # OLD HUNGARIAN CAPITAL LETTER EV
1592             "\xF0\x90\xB2\xAF" => "\xF0\x90\xB3\xAF", # OLD HUNGARIAN CAPITAL LETTER EZ
1593             "\xF0\x90\xB2\xB0" => "\xF0\x90\xB3\xB0", # OLD HUNGARIAN CAPITAL LETTER EZS
1594             "\xF0\x90\xB2\xB1" => "\xF0\x90\xB3\xB1", # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN
1595             "\xF0\x90\xB2\xB2" => "\xF0\x90\xB3\xB2", # OLD HUNGARIAN CAPITAL LETTER US
1596             "\xF0\x91\xA2\xA0" => "\xF0\x91\xA3\x80", # WARANG CITI CAPITAL LETTER NGAA
1597             "\xF0\x91\xA2\xA1" => "\xF0\x91\xA3\x81", # WARANG CITI CAPITAL LETTER A
1598             "\xF0\x91\xA2\xA2" => "\xF0\x91\xA3\x82", # WARANG CITI CAPITAL LETTER WI
1599             "\xF0\x91\xA2\xA3" => "\xF0\x91\xA3\x83", # WARANG CITI CAPITAL LETTER YU
1600             "\xF0\x91\xA2\xA4" => "\xF0\x91\xA3\x84", # WARANG CITI CAPITAL LETTER YA
1601             "\xF0\x91\xA2\xA5" => "\xF0\x91\xA3\x85", # WARANG CITI CAPITAL LETTER YO
1602             "\xF0\x91\xA2\xA6" => "\xF0\x91\xA3\x86", # WARANG CITI CAPITAL LETTER II
1603             "\xF0\x91\xA2\xA7" => "\xF0\x91\xA3\x87", # WARANG CITI CAPITAL LETTER UU
1604             "\xF0\x91\xA2\xA8" => "\xF0\x91\xA3\x88", # WARANG CITI CAPITAL LETTER E
1605             "\xF0\x91\xA2\xA9" => "\xF0\x91\xA3\x89", # WARANG CITI CAPITAL LETTER O
1606             "\xF0\x91\xA2\xAA" => "\xF0\x91\xA3\x8A", # WARANG CITI CAPITAL LETTER ANG
1607             "\xF0\x91\xA2\xAB" => "\xF0\x91\xA3\x8B", # WARANG CITI CAPITAL LETTER GA
1608             "\xF0\x91\xA2\xAC" => "\xF0\x91\xA3\x8C", # WARANG CITI CAPITAL LETTER KO
1609             "\xF0\x91\xA2\xAD" => "\xF0\x91\xA3\x8D", # WARANG CITI CAPITAL LETTER ENY
1610             "\xF0\x91\xA2\xAE" => "\xF0\x91\xA3\x8E", # WARANG CITI CAPITAL LETTER YUJ
1611             "\xF0\x91\xA2\xAF" => "\xF0\x91\xA3\x8F", # WARANG CITI CAPITAL LETTER UC
1612             "\xF0\x91\xA2\xB0" => "\xF0\x91\xA3\x90", # WARANG CITI CAPITAL LETTER ENN
1613             "\xF0\x91\xA2\xB1" => "\xF0\x91\xA3\x91", # WARANG CITI CAPITAL LETTER ODD
1614             "\xF0\x91\xA2\xB2" => "\xF0\x91\xA3\x92", # WARANG CITI CAPITAL LETTER TTE
1615             "\xF0\x91\xA2\xB3" => "\xF0\x91\xA3\x93", # WARANG CITI CAPITAL LETTER NUNG
1616             "\xF0\x91\xA2\xB4" => "\xF0\x91\xA3\x94", # WARANG CITI CAPITAL LETTER DA
1617             "\xF0\x91\xA2\xB5" => "\xF0\x91\xA3\x95", # WARANG CITI CAPITAL LETTER AT
1618             "\xF0\x91\xA2\xB6" => "\xF0\x91\xA3\x96", # WARANG CITI CAPITAL LETTER AM
1619             "\xF0\x91\xA2\xB7" => "\xF0\x91\xA3\x97", # WARANG CITI CAPITAL LETTER BU
1620             "\xF0\x91\xA2\xB8" => "\xF0\x91\xA3\x98", # WARANG CITI CAPITAL LETTER PU
1621             "\xF0\x91\xA2\xB9" => "\xF0\x91\xA3\x99", # WARANG CITI CAPITAL LETTER HIYO
1622             "\xF0\x91\xA2\xBA" => "\xF0\x91\xA3\x9A", # WARANG CITI CAPITAL LETTER HOLO
1623             "\xF0\x91\xA2\xBB" => "\xF0\x91\xA3\x9B", # WARANG CITI CAPITAL LETTER HORR
1624             "\xF0\x91\xA2\xBC" => "\xF0\x91\xA3\x9C", # WARANG CITI CAPITAL LETTER HAR
1625             "\xF0\x91\xA2\xBD" => "\xF0\x91\xA3\x9D", # WARANG CITI CAPITAL LETTER SSUU
1626             "\xF0\x91\xA2\xBE" => "\xF0\x91\xA3\x9E", # WARANG CITI CAPITAL LETTER SII
1627             "\xF0\x91\xA2\xBF" => "\xF0\x91\xA3\x9F", # WARANG CITI CAPITAL LETTER VIYO
1628             "\xF0\x96\xB9\x80" => "\xF0\x96\xB9\xA0", # MEDEFAIDRIN CAPITAL LETTER M
1629             "\xF0\x96\xB9\x81" => "\xF0\x96\xB9\xA1", # MEDEFAIDRIN CAPITAL LETTER S
1630             "\xF0\x96\xB9\x82" => "\xF0\x96\xB9\xA2", # MEDEFAIDRIN CAPITAL LETTER V
1631             "\xF0\x96\xB9\x83" => "\xF0\x96\xB9\xA3", # MEDEFAIDRIN CAPITAL LETTER W
1632             "\xF0\x96\xB9\x84" => "\xF0\x96\xB9\xA4", # MEDEFAIDRIN CAPITAL LETTER ATIU
1633             "\xF0\x96\xB9\x85" => "\xF0\x96\xB9\xA5", # MEDEFAIDRIN CAPITAL LETTER Z
1634             "\xF0\x96\xB9\x86" => "\xF0\x96\xB9\xA6", # MEDEFAIDRIN CAPITAL LETTER KP
1635             "\xF0\x96\xB9\x87" => "\xF0\x96\xB9\xA7", # MEDEFAIDRIN CAPITAL LETTER P
1636             "\xF0\x96\xB9\x88" => "\xF0\x96\xB9\xA8", # MEDEFAIDRIN CAPITAL LETTER T
1637             "\xF0\x96\xB9\x89" => "\xF0\x96\xB9\xA9", # MEDEFAIDRIN CAPITAL LETTER G
1638             "\xF0\x96\xB9\x8A" => "\xF0\x96\xB9\xAA", # MEDEFAIDRIN CAPITAL LETTER F
1639             "\xF0\x96\xB9\x8B" => "\xF0\x96\xB9\xAB", # MEDEFAIDRIN CAPITAL LETTER I
1640             "\xF0\x96\xB9\x8C" => "\xF0\x96\xB9\xAC", # MEDEFAIDRIN CAPITAL LETTER K
1641             "\xF0\x96\xB9\x8D" => "\xF0\x96\xB9\xAD", # MEDEFAIDRIN CAPITAL LETTER A
1642             "\xF0\x96\xB9\x8E" => "\xF0\x96\xB9\xAE", # MEDEFAIDRIN CAPITAL LETTER J
1643             "\xF0\x96\xB9\x8F" => "\xF0\x96\xB9\xAF", # MEDEFAIDRIN CAPITAL LETTER E
1644             "\xF0\x96\xB9\x90" => "\xF0\x96\xB9\xB0", # MEDEFAIDRIN CAPITAL LETTER B
1645             "\xF0\x96\xB9\x91" => "\xF0\x96\xB9\xB1", # MEDEFAIDRIN CAPITAL LETTER C
1646             "\xF0\x96\xB9\x92" => "\xF0\x96\xB9\xB2", # MEDEFAIDRIN CAPITAL LETTER U
1647             "\xF0\x96\xB9\x93" => "\xF0\x96\xB9\xB3", # MEDEFAIDRIN CAPITAL LETTER YU
1648             "\xF0\x96\xB9\x94" => "\xF0\x96\xB9\xB4", # MEDEFAIDRIN CAPITAL LETTER L
1649             "\xF0\x96\xB9\x95" => "\xF0\x96\xB9\xB5", # MEDEFAIDRIN CAPITAL LETTER Q
1650             "\xF0\x96\xB9\x96" => "\xF0\x96\xB9\xB6", # MEDEFAIDRIN CAPITAL LETTER HP
1651             "\xF0\x96\xB9\x97" => "\xF0\x96\xB9\xB7", # MEDEFAIDRIN CAPITAL LETTER NY
1652             "\xF0\x96\xB9\x98" => "\xF0\x96\xB9\xB8", # MEDEFAIDRIN CAPITAL LETTER X
1653             "\xF0\x96\xB9\x99" => "\xF0\x96\xB9\xB9", # MEDEFAIDRIN CAPITAL LETTER D
1654             "\xF0\x96\xB9\x9A" => "\xF0\x96\xB9\xBA", # MEDEFAIDRIN CAPITAL LETTER OE
1655             "\xF0\x96\xB9\x9B" => "\xF0\x96\xB9\xBB", # MEDEFAIDRIN CAPITAL LETTER N
1656             "\xF0\x96\xB9\x9C" => "\xF0\x96\xB9\xBC", # MEDEFAIDRIN CAPITAL LETTER R
1657             "\xF0\x96\xB9\x9D" => "\xF0\x96\xB9\xBD", # MEDEFAIDRIN CAPITAL LETTER O
1658             "\xF0\x96\xB9\x9E" => "\xF0\x96\xB9\xBE", # MEDEFAIDRIN CAPITAL LETTER AI
1659             "\xF0\x96\xB9\x9F" => "\xF0\x96\xB9\xBF", # MEDEFAIDRIN CAPITAL LETTER Y
1660             "\xF0\x9E\xA4\x80" => "\xF0\x9E\xA4\xA2", # ADLAM CAPITAL LETTER ALIF
1661             "\xF0\x9E\xA4\x81" => "\xF0\x9E\xA4\xA3", # ADLAM CAPITAL LETTER DAALI
1662             "\xF0\x9E\xA4\x82" => "\xF0\x9E\xA4\xA4", # ADLAM CAPITAL LETTER LAAM
1663             "\xF0\x9E\xA4\x83" => "\xF0\x9E\xA4\xA5", # ADLAM CAPITAL LETTER MIIM
1664             "\xF0\x9E\xA4\x84" => "\xF0\x9E\xA4\xA6", # ADLAM CAPITAL LETTER BA
1665             "\xF0\x9E\xA4\x85" => "\xF0\x9E\xA4\xA7", # ADLAM CAPITAL LETTER SINNYIIYHE
1666             "\xF0\x9E\xA4\x86" => "\xF0\x9E\xA4\xA8", # ADLAM CAPITAL LETTER PE
1667             "\xF0\x9E\xA4\x87" => "\xF0\x9E\xA4\xA9", # ADLAM CAPITAL LETTER BHE
1668             "\xF0\x9E\xA4\x88" => "\xF0\x9E\xA4\xAA", # ADLAM CAPITAL LETTER RA
1669             "\xF0\x9E\xA4\x89" => "\xF0\x9E\xA4\xAB", # ADLAM CAPITAL LETTER E
1670             "\xF0\x9E\xA4\x8A" => "\xF0\x9E\xA4\xAC", # ADLAM CAPITAL LETTER FA
1671             "\xF0\x9E\xA4\x8B" => "\xF0\x9E\xA4\xAD", # ADLAM CAPITAL LETTER I
1672             "\xF0\x9E\xA4\x8C" => "\xF0\x9E\xA4\xAE", # ADLAM CAPITAL LETTER O
1673             "\xF0\x9E\xA4\x8D" => "\xF0\x9E\xA4\xAF", # ADLAM CAPITAL LETTER DHA
1674             "\xF0\x9E\xA4\x8E" => "\xF0\x9E\xA4\xB0", # ADLAM CAPITAL LETTER YHE
1675             "\xF0\x9E\xA4\x8F" => "\xF0\x9E\xA4\xB1", # ADLAM CAPITAL LETTER WAW
1676             "\xF0\x9E\xA4\x90" => "\xF0\x9E\xA4\xB2", # ADLAM CAPITAL LETTER NUN
1677             "\xF0\x9E\xA4\x91" => "\xF0\x9E\xA4\xB3", # ADLAM CAPITAL LETTER KAF
1678             "\xF0\x9E\xA4\x92" => "\xF0\x9E\xA4\xB4", # ADLAM CAPITAL LETTER YA
1679             "\xF0\x9E\xA4\x93" => "\xF0\x9E\xA4\xB5", # ADLAM CAPITAL LETTER U
1680             "\xF0\x9E\xA4\x94" => "\xF0\x9E\xA4\xB6", # ADLAM CAPITAL LETTER JIIM
1681             "\xF0\x9E\xA4\x95" => "\xF0\x9E\xA4\xB7", # ADLAM CAPITAL LETTER CHI
1682             "\xF0\x9E\xA4\x96" => "\xF0\x9E\xA4\xB8", # ADLAM CAPITAL LETTER HA
1683             "\xF0\x9E\xA4\x97" => "\xF0\x9E\xA4\xB9", # ADLAM CAPITAL LETTER QAAF
1684             "\xF0\x9E\xA4\x98" => "\xF0\x9E\xA4\xBA", # ADLAM CAPITAL LETTER GA
1685             "\xF0\x9E\xA4\x99" => "\xF0\x9E\xA4\xBB", # ADLAM CAPITAL LETTER NYA
1686             "\xF0\x9E\xA4\x9A" => "\xF0\x9E\xA4\xBC", # ADLAM CAPITAL LETTER TU
1687             "\xF0\x9E\xA4\x9B" => "\xF0\x9E\xA4\xBD", # ADLAM CAPITAL LETTER NHA
1688             "\xF0\x9E\xA4\x9C" => "\xF0\x9E\xA4\xBE", # ADLAM CAPITAL LETTER VA
1689             "\xF0\x9E\xA4\x9D" => "\xF0\x9E\xA4\xBF", # ADLAM CAPITAL LETTER KHA
1690             "\xF0\x9E\xA4\x9E" => "\xF0\x9E\xA5\x80", # ADLAM CAPITAL LETTER GBE
1691             "\xF0\x9E\xA4\x9F" => "\xF0\x9E\xA5\x81", # ADLAM CAPITAL LETTER ZAL
1692             "\xF0\x9E\xA4\xA0" => "\xF0\x9E\xA5\x82", # ADLAM CAPITAL LETTER KPO
1693             "\xF0\x9E\xA4\xA1" => "\xF0\x9E\xA5\x83", # ADLAM CAPITAL LETTER SHA
1694             );
1695             }
1696              
1697             else {
1698             croak "Don't know my package name '@{[__PACKAGE__]}'";
1699             }
1700              
1701             #
1702             # @ARGV wildcard globbing
1703             #
1704             sub import {
1705              
1706 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
1707 0         0 my @argv = ();
1708 0         0 for (@ARGV) {
1709              
1710             # has space
1711 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
1712 0 0       0 if (my @glob = Eutf2::glob(qq{"$_"})) {
1713 0         0 push @argv, @glob;
1714             }
1715             else {
1716 0         0 push @argv, $_;
1717             }
1718             }
1719              
1720             # has wildcard metachar
1721             elsif (/\A (?:$q_char)*? [*?] /oxms) {
1722 0 0       0 if (my @glob = Eutf2::glob($_)) {
1723 0         0 push @argv, @glob;
1724             }
1725             else {
1726 0         0 push @argv, $_;
1727             }
1728             }
1729              
1730             # no wildcard globbing
1731             else {
1732 0         0 push @argv, $_;
1733             }
1734             }
1735 0         0 @ARGV = @argv;
1736             }
1737              
1738 0         0 *Char::ord = \&UTF2::ord;
1739 0         0 *Char::ord_ = \&UTF2::ord_;
1740 0         0 *Char::reverse = \&UTF2::reverse;
1741 0         0 *Char::getc = \&UTF2::getc;
1742 0         0 *Char::length = \&UTF2::length;
1743 0         0 *Char::substr = \&UTF2::substr;
1744 0         0 *Char::index = \&UTF2::index;
1745 0         0 *Char::rindex = \&UTF2::rindex;
1746 0         0 *Char::eval = \&UTF2::eval;
1747 0         0 *Char::escape = \&UTF2::escape;
1748 0         0 *Char::escape_token = \&UTF2::escape_token;
1749 0         0 *Char::escape_script = \&UTF2::escape_script;
1750             }
1751              
1752             # P.230 Care with Prototypes
1753             # in Chapter 6: Subroutines
1754             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1755             #
1756             # If you aren't careful, you can get yourself into trouble with prototypes.
1757             # But if you are careful, you can do a lot of neat things with them. This is
1758             # all very powerful, of course, and should only be used in moderation to make
1759             # the world a better place.
1760              
1761             # P.332 Care with Prototypes
1762             # in Chapter 7: Subroutines
1763             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1764             #
1765             # If you aren't careful, you can get yourself into trouble with prototypes.
1766             # But if you are careful, you can do a lot of neat things with them. This is
1767             # all very powerful, of course, and should only be used in moderation to make
1768             # the world a better place.
1769              
1770             #
1771             # Prototypes of subroutines
1772             #
1773       0     sub unimport {}
1774             sub Eutf2::split(;$$$);
1775             sub Eutf2::tr($$$$;$);
1776             sub Eutf2::chop(@);
1777             sub Eutf2::index($$;$);
1778             sub Eutf2::rindex($$;$);
1779             sub Eutf2::lcfirst(@);
1780             sub Eutf2::lcfirst_();
1781             sub Eutf2::lc(@);
1782             sub Eutf2::lc_();
1783             sub Eutf2::ucfirst(@);
1784             sub Eutf2::ucfirst_();
1785             sub Eutf2::uc(@);
1786             sub Eutf2::uc_();
1787             sub Eutf2::fc(@);
1788             sub Eutf2::fc_();
1789             sub Eutf2::ignorecase;
1790             sub Eutf2::classic_character_class;
1791             sub Eutf2::capture;
1792             sub Eutf2::chr(;$);
1793             sub Eutf2::chr_();
1794             sub Eutf2::glob($);
1795             sub Eutf2::glob_();
1796              
1797             sub UTF2::ord(;$);
1798             sub UTF2::ord_();
1799             sub UTF2::reverse(@);
1800             sub UTF2::getc(;*@);
1801             sub UTF2::length(;$);
1802             sub UTF2::substr($$;$$);
1803             sub UTF2::index($$;$);
1804             sub UTF2::rindex($$;$);
1805             sub UTF2::escape(;$);
1806              
1807             #
1808             # Regexp work
1809             #
1810 306         28695 use vars qw(
1811             $re_a
1812             $re_t
1813             $re_n
1814             $re_r
1815 306     306   3211 );
  306         654  
1816              
1817             #
1818             # Character class
1819             #
1820 306         4682169 use vars qw(
1821             $dot
1822             $dot_s
1823             $eD
1824             $eS
1825             $eW
1826             $eH
1827             $eV
1828             $eR
1829             $eN
1830             $not_alnum
1831             $not_alpha
1832             $not_ascii
1833             $not_blank
1834             $not_cntrl
1835             $not_digit
1836             $not_graph
1837             $not_lower
1838             $not_lower_i
1839             $not_print
1840             $not_punct
1841             $not_space
1842             $not_upper
1843             $not_upper_i
1844             $not_word
1845             $not_xdigit
1846             $eb
1847             $eB
1848 306     306   1896 );
  306         595  
1849              
1850             ${Eutf2::dot} = qr{(?>[^\x80-\xFF\x0A]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1851             ${Eutf2::dot_s} = qr{(?>[^\x80-\xFF]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1852             ${Eutf2::eD} = qr{(?>[^\x80-\xFF0-9]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1853              
1854             # Vertical tabs are now whitespace
1855             # \s in a regex now matches a vertical tab in all circumstances.
1856             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1857             # ${Eutf2::eS} = qr{(?>[^\x80-\xFF\x09\x0A \x0C\x0D\x20]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1858             # ${Eutf2::eS} = qr{(?>[^\x80-\xFF\x09\x0A\x0B\x0C\x0D\x20]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1859             ${Eutf2::eS} = qr{(?>[^\x80-\xFF\s]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1860              
1861             ${Eutf2::eW} = qr{(?>[^\x80-\xFF0-9A-Z_a-z]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1862             ${Eutf2::eH} = qr{(?>[^\x80-\xFF\x09\x20]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1863             ${Eutf2::eV} = qr{(?>[^\x80-\xFF\x0A\x0B\x0C\x0D]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1864             ${Eutf2::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
1865             ${Eutf2::eN} = qr{(?>[^\x80-\xFF\x0A]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1866             ${Eutf2::not_alnum} = qr{(?>[^\x80-\xFF\x30-\x39\x41-\x5A\x61-\x7A]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1867             ${Eutf2::not_alpha} = qr{(?>[^\x80-\xFF\x41-\x5A\x61-\x7A]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1868             ${Eutf2::not_ascii} = qr{(?>[^\x80-\xFF\x00-\x7F]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1869             ${Eutf2::not_blank} = qr{(?>[^\x80-\xFF\x09\x20]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1870             ${Eutf2::not_cntrl} = qr{(?>[^\x80-\xFF\x00-\x1F\x7F]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1871             ${Eutf2::not_digit} = qr{(?>[^\x80-\xFF\x30-\x39]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1872             ${Eutf2::not_graph} = qr{(?>[^\x80-\xFF\x21-\x7F]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1873             ${Eutf2::not_lower} = qr{(?>[^\x80-\xFF\x61-\x7A]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1874             ${Eutf2::not_lower_i} = qr{(?>[^\x80-\xFF\x41-\x5A\x61-\x7A]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])}; # Perl 5.16 compatible
1875             # ${Eutf2::not_lower_i} = qr{(?>[^\x80-\xFF]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])}; # older Perl compatible
1876             ${Eutf2::not_print} = qr{(?>[^\x80-\xFF\x20-\x7F]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1877             ${Eutf2::not_punct} = qr{(?>[^\x80-\xFF\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1878             ${Eutf2::not_space} = qr{(?>[^\x80-\xFF\s\x0B]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1879             ${Eutf2::not_upper} = qr{(?>[^\x80-\xFF\x41-\x5A]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1880             ${Eutf2::not_upper_i} = qr{(?>[^\x80-\xFF\x41-\x5A\x61-\x7A]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])}; # Perl 5.16 compatible
1881             # ${Eutf2::not_upper_i} = qr{(?>[^\x80-\xFF]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])}; # older Perl compatible
1882             ${Eutf2::not_word} = qr{(?>[^\x80-\xFF\x30-\x39\x41-\x5A\x5F\x61-\x7A]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1883             ${Eutf2::not_xdigit} = qr{(?>[^\x80-\xFF\x30-\x39\x41-\x46\x61-\x66]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])};
1884             ${Eutf2::eb} = qr{(?:\A(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[0-9A-Z_a-z])|(?<=[0-9A-Z_a-z])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]|\z))};
1885             ${Eutf2::eB} = qr{(?:(?<=[0-9A-Z_a-z])(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]))};
1886              
1887             # avoid: Name "Eutf2::foo" used only once: possible typo at here.
1888             ${Eutf2::dot} = ${Eutf2::dot};
1889             ${Eutf2::dot_s} = ${Eutf2::dot_s};
1890             ${Eutf2::eD} = ${Eutf2::eD};
1891             ${Eutf2::eS} = ${Eutf2::eS};
1892             ${Eutf2::eW} = ${Eutf2::eW};
1893             ${Eutf2::eH} = ${Eutf2::eH};
1894             ${Eutf2::eV} = ${Eutf2::eV};
1895             ${Eutf2::eR} = ${Eutf2::eR};
1896             ${Eutf2::eN} = ${Eutf2::eN};
1897             ${Eutf2::not_alnum} = ${Eutf2::not_alnum};
1898             ${Eutf2::not_alpha} = ${Eutf2::not_alpha};
1899             ${Eutf2::not_ascii} = ${Eutf2::not_ascii};
1900             ${Eutf2::not_blank} = ${Eutf2::not_blank};
1901             ${Eutf2::not_cntrl} = ${Eutf2::not_cntrl};
1902             ${Eutf2::not_digit} = ${Eutf2::not_digit};
1903             ${Eutf2::not_graph} = ${Eutf2::not_graph};
1904             ${Eutf2::not_lower} = ${Eutf2::not_lower};
1905             ${Eutf2::not_lower_i} = ${Eutf2::not_lower_i};
1906             ${Eutf2::not_print} = ${Eutf2::not_print};
1907             ${Eutf2::not_punct} = ${Eutf2::not_punct};
1908             ${Eutf2::not_space} = ${Eutf2::not_space};
1909             ${Eutf2::not_upper} = ${Eutf2::not_upper};
1910             ${Eutf2::not_upper_i} = ${Eutf2::not_upper_i};
1911             ${Eutf2::not_word} = ${Eutf2::not_word};
1912             ${Eutf2::not_xdigit} = ${Eutf2::not_xdigit};
1913             ${Eutf2::eb} = ${Eutf2::eb};
1914             ${Eutf2::eB} = ${Eutf2::eB};
1915              
1916             #
1917             # UTF-8 split
1918             #
1919             sub Eutf2::split(;$$$) {
1920              
1921             # P.794 29.2.161. split
1922             # in Chapter 29: Functions
1923             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1924              
1925             # P.951 split
1926             # in Chapter 27: Functions
1927             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1928              
1929 0     0 0 0 my $pattern = $_[0];
1930 0         0 my $string = $_[1];
1931 0         0 my $limit = $_[2];
1932              
1933             # if $pattern is also omitted or is the literal space, " "
1934 0 0       0 if (not defined $pattern) {
1935 0         0 $pattern = ' ';
1936             }
1937              
1938             # if $string is omitted, the function splits the $_ string
1939 0 0       0 if (not defined $string) {
1940 0 0       0 if (defined $_) {
1941 0         0 $string = $_;
1942             }
1943             else {
1944 0         0 $string = '';
1945             }
1946             }
1947              
1948 0         0 my @split = ();
1949              
1950             # when string is empty
1951 0 0       0 if ($string eq '') {
    0          
1952              
1953             # resulting list value in list context
1954 0 0       0 if (wantarray) {
1955 0         0 return @split;
1956             }
1957              
1958             # count of substrings in scalar context
1959             else {
1960 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
1961 0         0 @_ = @split;
1962 0         0 return scalar @_;
1963             }
1964             }
1965              
1966             # split's first argument is more consistently interpreted
1967             #
1968             # After some changes earlier in v5.17, split's behavior has been simplified:
1969             # if the PATTERN argument evaluates to a string containing one space, it is
1970             # treated the way that a literal string containing one space once was.
1971             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
1972              
1973             # if $pattern is also omitted or is the literal space, " ", the function splits
1974             # on whitespace, /\s+/, after skipping any leading whitespace
1975             # (and so on)
1976              
1977             elsif ($pattern eq ' ') {
1978 0 0       0 if (not defined $limit) {
1979 0         0 return CORE::split(' ', $string);
1980             }
1981             else {
1982 0         0 return CORE::split(' ', $string, $limit);
1983             }
1984             }
1985              
1986             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
1987 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
1988              
1989             # a pattern capable of matching either the null string or something longer than the
1990             # null string will split the value of $string into separate characters wherever it
1991             # matches the null string between characters
1992             # (and so on)
1993              
1994 0 0       0 if ('' =~ / \A $pattern \z /xms) {
1995 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
1996 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
1997              
1998             # P.1024 Appendix W.10 Multibyte Processing
1999             # of ISBN 1-56592-224-7 CJKV Information Processing
2000             # (and so on)
2001              
2002             # the //m modifier is assumed when you split on the pattern /^/
2003             # (and so on)
2004              
2005             # V
2006 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
2007              
2008             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
2009             # is included in the resulting list, interspersed with the fields that are ordinarily returned
2010             # (and so on)
2011              
2012 0         0 local $@;
2013 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
2014 0         0 push @split, CORE::eval('$' . $digit);
2015             }
2016             }
2017             }
2018              
2019             else {
2020 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
2021              
2022             # V
2023 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
2024 0         0 local $@;
2025 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
2026 0         0 push @split, CORE::eval('$' . $digit);
2027             }
2028             }
2029             }
2030             }
2031              
2032             elsif ($limit > 0) {
2033 0 0       0 if ('' =~ / \A $pattern \z /xms) {
2034 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
2035 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
2036              
2037             # V
2038 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
2039 0         0 local $@;
2040 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
2041 0         0 push @split, CORE::eval('$' . $digit);
2042             }
2043             }
2044             }
2045             }
2046             else {
2047 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
2048 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
2049              
2050             # V
2051 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
2052 0         0 local $@;
2053 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
2054 0         0 push @split, CORE::eval('$' . $digit);
2055             }
2056             }
2057             }
2058             }
2059             }
2060              
2061 0 0       0 if (CORE::length($string) > 0) {
2062 0         0 push @split, $string;
2063             }
2064              
2065             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
2066 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
2067 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
2068 0         0 pop @split;
2069             }
2070             }
2071              
2072             # resulting list value in list context
2073 0 0       0 if (wantarray) {
2074 0         0 return @split;
2075             }
2076              
2077             # count of substrings in scalar context
2078             else {
2079 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
2080 0         0 @_ = @split;
2081 0         0 return scalar @_;
2082             }
2083             }
2084              
2085             #
2086             # get last subexpression offsets
2087             #
2088             sub _last_subexpression_offsets {
2089 0     0   0 my $pattern = $_[0];
2090              
2091             # remove comment
2092 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
2093              
2094 0         0 my $modifier = '';
2095 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
2096 0         0 $modifier = $1;
2097 0         0 $modifier =~ s/-[A-Za-z]*//;
2098             }
2099              
2100             # with /x modifier
2101 0         0 my @char = ();
2102 0 0       0 if ($modifier =~ /x/oxms) {
2103 0         0 @char = $pattern =~ /\G((?>
2104             [^\x80-\xFF\\\#\[\(]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
2105             \\ $q_char |
2106             \# (?>[^\n]*) $ |
2107             \[ (?>(?:[^\x80-\xFF\\\]]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF]|\\\\|\\\]|$q_char)+) \] |
2108             \(\? |
2109             $q_char
2110             ))/oxmsg;
2111             }
2112              
2113             # without /x modifier
2114             else {
2115 0         0 @char = $pattern =~ /\G((?>
2116             [^\x80-\xFF\\\[\(]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
2117             \\ $q_char |
2118             \[ (?>(?:[^\x80-\xFF\\\]]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF]|\\\\|\\\]|$q_char)+) \] |
2119             \(\? |
2120             $q_char
2121             ))/oxmsg;
2122             }
2123              
2124 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
2125             }
2126              
2127             #
2128             # UTF-8 transliteration (tr///)
2129             #
2130             sub Eutf2::tr($$$$;$) {
2131              
2132 0     0 0 0 my $bind_operator = $_[1];
2133 0         0 my $searchlist = $_[2];
2134 0         0 my $replacementlist = $_[3];
2135 0   0     0 my $modifier = $_[4] || '';
2136              
2137 0 0       0 if ($modifier =~ /r/oxms) {
2138 0 0       0 if ($bind_operator =~ / !~ /oxms) {
2139 0         0 croak "Using !~ with tr///r doesn't make sense";
2140             }
2141             }
2142              
2143 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2144 0         0 my @searchlist = _charlist_tr($searchlist);
2145 0         0 my @replacementlist = _charlist_tr($replacementlist);
2146              
2147 0         0 my %tr = ();
2148 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
2149 0 0       0 if (not exists $tr{$searchlist[$i]}) {
2150 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
2151 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
2152             }
2153             elsif ($modifier =~ /d/oxms) {
2154 0         0 $tr{$searchlist[$i]} = '';
2155             }
2156             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
2157 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
2158             }
2159             else {
2160 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
2161             }
2162             }
2163             }
2164              
2165 0         0 my $tr = 0;
2166 0         0 my $replaced = '';
2167 0 0       0 if ($modifier =~ /c/oxms) {
2168 0         0 while (defined(my $char = shift @char)) {
2169 0 0       0 if (not exists $tr{$char}) {
2170 0 0       0 if (defined $replacementlist[0]) {
2171 0         0 $replaced .= $replacementlist[0];
2172             }
2173 0         0 $tr++;
2174 0 0       0 if ($modifier =~ /s/oxms) {
2175 0   0     0 while (@char and (not exists $tr{$char[0]})) {
2176 0         0 shift @char;
2177 0         0 $tr++;
2178             }
2179             }
2180             }
2181             else {
2182 0         0 $replaced .= $char;
2183             }
2184             }
2185             }
2186             else {
2187 0         0 while (defined(my $char = shift @char)) {
2188 0 0       0 if (exists $tr{$char}) {
2189 0         0 $replaced .= $tr{$char};
2190 0         0 $tr++;
2191 0 0       0 if ($modifier =~ /s/oxms) {
2192 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
2193 0         0 shift @char;
2194 0         0 $tr++;
2195             }
2196             }
2197             }
2198             else {
2199 0         0 $replaced .= $char;
2200             }
2201             }
2202             }
2203              
2204 0 0       0 if ($modifier =~ /r/oxms) {
2205 0         0 return $replaced;
2206             }
2207             else {
2208 0         0 $_[0] = $replaced;
2209 0 0       0 if ($bind_operator =~ / !~ /oxms) {
2210 0         0 return not $tr;
2211             }
2212             else {
2213 0         0 return $tr;
2214             }
2215             }
2216             }
2217              
2218             #
2219             # UTF-8 chop
2220             #
2221             sub Eutf2::chop(@) {
2222              
2223 0     0 0 0 my $chop;
2224 0 0       0 if (@_ == 0) {
2225 0         0 my @char = /\G (?>$q_char) /oxmsg;
2226 0         0 $chop = pop @char;
2227 0         0 $_ = join '', @char;
2228             }
2229             else {
2230 0         0 for (@_) {
2231 0         0 my @char = /\G (?>$q_char) /oxmsg;
2232 0         0 $chop = pop @char;
2233 0         0 $_ = join '', @char;
2234             }
2235             }
2236 0         0 return $chop;
2237             }
2238              
2239             #
2240             # UTF-8 index by octet
2241             #
2242             sub Eutf2::index($$;$) {
2243              
2244 0     0 1 0 my($str,$substr,$position) = @_;
2245 0   0     0 $position ||= 0;
2246 0         0 my $pos = 0;
2247              
2248 0         0 while ($pos < CORE::length($str)) {
2249 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
2250 0 0       0 if ($pos >= $position) {
2251 0         0 return $pos;
2252             }
2253             }
2254 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
2255 0         0 $pos += CORE::length($1);
2256             }
2257             else {
2258 0         0 $pos += 1;
2259             }
2260             }
2261 0         0 return -1;
2262             }
2263              
2264             #
2265             # UTF-8 reverse index
2266             #
2267             sub Eutf2::rindex($$;$) {
2268              
2269 0     0 0 0 my($str,$substr,$position) = @_;
2270 0   0     0 $position ||= CORE::length($str) - 1;
2271 0         0 my $pos = 0;
2272 0         0 my $rindex = -1;
2273              
2274 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
2275 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
2276 0         0 $rindex = $pos;
2277             }
2278 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
2279 0         0 $pos += CORE::length($1);
2280             }
2281             else {
2282 0         0 $pos += 1;
2283             }
2284             }
2285 0         0 return $rindex;
2286             }
2287              
2288             #
2289             # UTF-8 lower case first with parameter
2290             #
2291             sub Eutf2::lcfirst(@) {
2292 0 0   0 0 0 if (@_) {
2293 0         0 my $s = shift @_;
2294 0 0 0     0 if (@_ and wantarray) {
2295 0         0 return Eutf2::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
2296             }
2297             else {
2298 0         0 return Eutf2::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
2299             }
2300             }
2301             else {
2302 0         0 return Eutf2::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
2303             }
2304             }
2305              
2306             #
2307             # UTF-8 lower case first without parameter
2308             #
2309             sub Eutf2::lcfirst_() {
2310 0     0 0 0 return Eutf2::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
2311             }
2312              
2313             #
2314             # UTF-8 lower case with parameter
2315             #
2316             sub Eutf2::lc(@) {
2317 0 0   0 0 0 if (@_) {
2318 0         0 my $s = shift @_;
2319 0 0 0     0 if (@_ and wantarray) {
2320 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
2321             }
2322             else {
2323 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
2324             }
2325             }
2326             else {
2327 0         0 return Eutf2::lc_();
2328             }
2329             }
2330              
2331             #
2332             # UTF-8 lower case without parameter
2333             #
2334             sub Eutf2::lc_() {
2335 0     0 0 0 my $s = $_;
2336 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
2337             }
2338              
2339             #
2340             # UTF-8 upper case first with parameter
2341             #
2342             sub Eutf2::ucfirst(@) {
2343 0 0   0 0 0 if (@_) {
2344 0         0 my $s = shift @_;
2345 0 0 0     0 if (@_ and wantarray) {
2346 0         0 return Eutf2::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
2347             }
2348             else {
2349 0         0 return Eutf2::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
2350             }
2351             }
2352             else {
2353 0         0 return Eutf2::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
2354             }
2355             }
2356              
2357             #
2358             # UTF-8 upper case first without parameter
2359             #
2360             sub Eutf2::ucfirst_() {
2361 0     0 0 0 return Eutf2::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
2362             }
2363              
2364             #
2365             # UTF-8 upper case with parameter
2366             #
2367             sub Eutf2::uc(@) {
2368 0 50   2478 0 0 if (@_) {
2369 2478         3230 my $s = shift @_;
2370 2478 50 33     2720 if (@_ and wantarray) {
2371 2478 0       3878 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
2372             }
2373             else {
2374 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  2478         6804  
2375             }
2376             }
2377             else {
2378 2478         7126 return Eutf2::uc_();
2379             }
2380             }
2381              
2382             #
2383             # UTF-8 upper case without parameter
2384             #
2385             sub Eutf2::uc_() {
2386 0     0 0 0 my $s = $_;
2387 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
2388             }
2389              
2390             #
2391             # UTF-8 fold case with parameter
2392             #
2393             sub Eutf2::fc(@) {
2394 0 50   2525 0 0 if (@_) {
2395 2525         3143 my $s = shift @_;
2396 2525 50 33     2692 if (@_ and wantarray) {
2397 2525 0       3951 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
2398             }
2399             else {
2400 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  2525         6508  
2401             }
2402             }
2403             else {
2404 2525         7674 return Eutf2::fc_();
2405             }
2406             }
2407              
2408             #
2409             # UTF-8 fold case without parameter
2410             #
2411             sub Eutf2::fc_() {
2412 0     0 0 0 my $s = $_;
2413 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
2414             }
2415              
2416             #
2417             # UTF-8 regexp capture
2418             #
2419             {
2420             sub Eutf2::capture {
2421 0     0 1 0 return $_[0];
2422             }
2423             }
2424              
2425             #
2426             # UTF-8 regexp ignore case modifier
2427             #
2428             sub Eutf2::ignorecase {
2429              
2430 0     0 0 0 my @string = @_;
2431 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
2432              
2433             # ignore case of $scalar or @array
2434 0         0 for my $string (@string) {
2435              
2436             # split regexp
2437 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
2438              
2439             # unescape character
2440 0         0 for (my $i=0; $i <= $#char; $i++) {
2441 0 0       0 next if not defined $char[$i];
2442              
2443             # open character class [...]
2444 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
2445 0         0 my $left = $i;
2446              
2447             # [] make die "unmatched [] in regexp ...\n"
2448              
2449 0 0       0 if ($char[$i+1] eq ']') {
2450 0         0 $i++;
2451             }
2452              
2453 0         0 while (1) {
2454 0 0       0 if (++$i > $#char) {
2455 0         0 croak "Unmatched [] in regexp";
2456             }
2457 0 0       0 if ($char[$i] eq ']') {
2458 0         0 my $right = $i;
2459 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
2460              
2461             # escape character
2462 0         0 for my $char (@charlist) {
2463 0 0       0 if (0) {
2464             }
2465              
2466 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
2467 0         0 $char = '\\' . $char;
2468             }
2469             }
2470              
2471             # [...]
2472 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
2473              
2474 0         0 $i = $left;
2475 0         0 last;
2476             }
2477             }
2478             }
2479              
2480             # open character class [^...]
2481             elsif ($char[$i] eq '[^') {
2482 0         0 my $left = $i;
2483              
2484             # [^] make die "unmatched [] in regexp ...\n"
2485              
2486 0 0       0 if ($char[$i+1] eq ']') {
2487 0         0 $i++;
2488             }
2489              
2490 0         0 while (1) {
2491 0 0       0 if (++$i > $#char) {
2492 0         0 croak "Unmatched [] in regexp";
2493             }
2494 0 0       0 if ($char[$i] eq ']') {
2495 0         0 my $right = $i;
2496 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
2497              
2498             # escape character
2499 0         0 for my $char (@charlist) {
2500 0 0       0 if (0) {
2501             }
2502              
2503 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
2504 0         0 $char = '\\' . $char;
2505             }
2506             }
2507              
2508             # [^...]
2509 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
2510              
2511 0         0 $i = $left;
2512 0         0 last;
2513             }
2514             }
2515             }
2516              
2517             # rewrite classic character class or escape character
2518             elsif (my $char = classic_character_class($char[$i])) {
2519 0         0 $char[$i] = $char;
2520             }
2521              
2522             # with /i modifier
2523             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
2524 0         0 my $uc = Eutf2::uc($char[$i]);
2525 0         0 my $fc = Eutf2::fc($char[$i]);
2526 0 0       0 if ($uc ne $fc) {
2527 0 0       0 if (CORE::length($fc) == 1) {
2528 0         0 $char[$i] = '[' . $uc . $fc . ']';
2529             }
2530             else {
2531 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
2532             }
2533             }
2534             }
2535             }
2536              
2537             # characterize
2538 0         0 for (my $i=0; $i <= $#char; $i++) {
2539 0 0       0 next if not defined $char[$i];
2540              
2541 0 0       0 if (0) {
2542             }
2543              
2544             # quote character before ? + * {
2545 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
2546 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
2547 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
2548             }
2549             }
2550             }
2551              
2552 0         0 $string = join '', @char;
2553             }
2554              
2555             # make regexp string
2556 0         0 return @string;
2557             }
2558              
2559             #
2560             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
2561             #
2562             sub Eutf2::classic_character_class {
2563 0     2820 0 0 my($char) = @_;
2564              
2565             return {
2566             '\D' => '${Eutf2::eD}',
2567             '\S' => '${Eutf2::eS}',
2568             '\W' => '${Eutf2::eW}',
2569             '\d' => '[0-9]',
2570              
2571             # Before Perl 5.6, \s only matched the five whitespace characters
2572             # tab, newline, form-feed, carriage return, and the space character
2573             # itself, which, taken together, is the character class [\t\n\f\r ].
2574              
2575             # Vertical tabs are now whitespace
2576             # \s in a regex now matches a vertical tab in all circumstances.
2577             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
2578             # \t \n \v \f \r space
2579             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
2580             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
2581             '\s' => '\s',
2582              
2583             '\w' => '[0-9A-Z_a-z]',
2584             '\C' => '[\x00-\xFF]',
2585             '\X' => 'X',
2586              
2587             # \h \v \H \V
2588              
2589             # P.114 Character Class Shortcuts
2590             # in Chapter 7: In the World of Regular Expressions
2591             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
2592              
2593             # P.357 13.2.3 Whitespace
2594             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
2595             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
2596             #
2597             # 0x00009 CHARACTER TABULATION h s
2598             # 0x0000a LINE FEED (LF) vs
2599             # 0x0000b LINE TABULATION v
2600             # 0x0000c FORM FEED (FF) vs
2601             # 0x0000d CARRIAGE RETURN (CR) vs
2602             # 0x00020 SPACE h s
2603              
2604             # P.196 Table 5-9. Alphanumeric regex metasymbols
2605             # in Chapter 5. Pattern Matching
2606             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2607              
2608             # (and so on)
2609              
2610             '\H' => '${Eutf2::eH}',
2611             '\V' => '${Eutf2::eV}',
2612             '\h' => '[\x09\x20]',
2613             '\v' => '[\x0A\x0B\x0C\x0D]',
2614             '\R' => '${Eutf2::eR}',
2615              
2616             # \N
2617             #
2618             # http://perldoc.perl.org/perlre.html
2619             # Character Classes and other Special Escapes
2620             # Any character but \n (experimental). Not affected by /s modifier
2621              
2622             '\N' => '${Eutf2::eN}',
2623              
2624             # \b \B
2625              
2626             # P.180 Boundaries: The \b and \B Assertions
2627             # in Chapter 5: Pattern Matching
2628             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2629              
2630             # P.219 Boundaries: The \b and \B Assertions
2631             # in Chapter 5: Pattern Matching
2632             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2633              
2634             # \b really means (?:(?<=\w)(?!\w)|(?
2635             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
2636             '\b' => '${Eutf2::eb}',
2637              
2638             # \B really means (?:(?<=\w)(?=\w)|(?
2639             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
2640             '\B' => '${Eutf2::eB}',
2641              
2642 2820   100     3972 }->{$char} || '';
2643             }
2644              
2645             #
2646             # prepare UTF-8 characters per length
2647             #
2648              
2649             # 1 octet characters
2650             my @chars1 = ();
2651             sub chars1 {
2652 2820 0   0 0 127452 if (@chars1) {
2653 0         0 return @chars1;
2654             }
2655 0 0       0 if (exists $range_tr{1}) {
2656 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
2657 0         0 while (my @range = splice(@ranges,0,1)) {
2658 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
2659 0         0 push @chars1, pack 'C', $oct0;
2660             }
2661             }
2662             }
2663 0         0 return @chars1;
2664             }
2665              
2666             # 2 octets characters
2667             my @chars2 = ();
2668             sub chars2 {
2669 0 0   0 0 0 if (@chars2) {
2670 0         0 return @chars2;
2671             }
2672 0 0       0 if (exists $range_tr{2}) {
2673 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
2674 0         0 while (my @range = splice(@ranges,0,2)) {
2675 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
2676 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
2677 0         0 push @chars2, pack 'CC', $oct0,$oct1;
2678             }
2679             }
2680             }
2681             }
2682 0         0 return @chars2;
2683             }
2684              
2685             # 3 octets characters
2686             my @chars3 = ();
2687             sub chars3 {
2688 0 0   0 0 0 if (@chars3) {
2689 0         0 return @chars3;
2690             }
2691 0 0       0 if (exists $range_tr{3}) {
2692 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
2693 0         0 while (my @range = splice(@ranges,0,3)) {
2694 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
2695 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
2696 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
2697 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
2698             }
2699             }
2700             }
2701             }
2702             }
2703 0         0 return @chars3;
2704             }
2705              
2706             # 4 octets characters
2707             my @chars4 = ();
2708             sub chars4 {
2709 0 0   0 0 0 if (@chars4) {
2710 0         0 return @chars4;
2711             }
2712 0 0       0 if (exists $range_tr{4}) {
2713 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
2714 0         0 while (my @range = splice(@ranges,0,4)) {
2715 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
2716 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
2717 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
2718 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
2719 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
2720             }
2721             }
2722             }
2723             }
2724             }
2725             }
2726 0         0 return @chars4;
2727             }
2728              
2729             #
2730             # UTF-8 open character list for tr
2731             #
2732             sub _charlist_tr {
2733              
2734 0     0   0 local $_ = shift @_;
2735              
2736             # unescape character
2737 0         0 my @char = ();
2738 0         0 while (not /\G \z/oxmsgc) {
2739 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
2740 0         0 push @char, '\-';
2741             }
2742             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
2743 0         0 push @char, CORE::chr(oct $1);
2744             }
2745             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
2746 0         0 push @char, CORE::chr(hex $1);
2747             }
2748             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
2749 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
2750             }
2751             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
2752             push @char, {
2753             '\0' => "\0",
2754             '\n' => "\n",
2755             '\r' => "\r",
2756             '\t' => "\t",
2757             '\f' => "\f",
2758             '\b' => "\x08", # \b means backspace in character class
2759             '\a' => "\a",
2760             '\e' => "\e",
2761 0         0 }->{$1};
2762             }
2763             elsif (/\G \\ ($q_char) /oxmsgc) {
2764 0         0 push @char, $1;
2765             }
2766             elsif (/\G ($q_char) /oxmsgc) {
2767 0         0 push @char, $1;
2768             }
2769             }
2770              
2771             # join separated multiple-octet
2772 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
2773              
2774             # unescape '-'
2775 0         0 my @i = ();
2776 0         0 for my $i (0 .. $#char) {
2777 0 0       0 if ($char[$i] eq '\-') {
    0          
2778 0         0 $char[$i] = '-';
2779             }
2780             elsif ($char[$i] eq '-') {
2781 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
2782 0         0 push @i, $i;
2783             }
2784             }
2785             }
2786              
2787             # open character list (reverse for splice)
2788 0         0 for my $i (CORE::reverse @i) {
2789 0         0 my @range = ();
2790              
2791             # range error
2792 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
2793 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2794             }
2795              
2796             # range of multiple-octet code
2797 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
2798 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
2799 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
2800             }
2801             elsif (CORE::length($char[$i+1]) == 2) {
2802 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
2803 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
2804             }
2805             elsif (CORE::length($char[$i+1]) == 3) {
2806 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
2807 0         0 push @range, chars2();
2808 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
2809             }
2810             elsif (CORE::length($char[$i+1]) == 4) {
2811 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
2812 0         0 push @range, chars2();
2813 0         0 push @range, chars3();
2814 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
2815             }
2816             else {
2817 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2818             }
2819             }
2820             elsif (CORE::length($char[$i-1]) == 2) {
2821 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
2822 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
2823             }
2824             elsif (CORE::length($char[$i+1]) == 3) {
2825 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
2826 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
2827             }
2828             elsif (CORE::length($char[$i+1]) == 4) {
2829 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
2830 0         0 push @range, chars3();
2831 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
2832             }
2833             else {
2834 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2835             }
2836             }
2837             elsif (CORE::length($char[$i-1]) == 3) {
2838 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
2839 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
2840             }
2841             elsif (CORE::length($char[$i+1]) == 4) {
2842 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
2843 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
2844             }
2845             else {
2846 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2847             }
2848             }
2849             elsif (CORE::length($char[$i-1]) == 4) {
2850 0 0       0 if (CORE::length($char[$i+1]) == 4) {
2851 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
2852             }
2853             else {
2854 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2855             }
2856             }
2857             else {
2858 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2859             }
2860              
2861 0         0 splice @char, $i-1, 3, @range;
2862             }
2863              
2864 0         0 return @char;
2865             }
2866              
2867             #
2868             # UTF-8 open character class
2869             #
2870             sub _cc {
2871 0 50   933   0 if (scalar(@_) == 0) {
    100          
    50          
2872 933         1701 die __FILE__, ": subroutine cc got no parameter.\n";
2873             }
2874             elsif (scalar(@_) == 1) {
2875 0         0 return sprintf('\x%02X',$_[0]);
2876             }
2877             elsif (scalar(@_) == 2) {
2878 482 50       1243 if ($_[0] > $_[1]) {
    100          
    50          
2879 451         872 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
2880             }
2881             elsif ($_[0] == $_[1]) {
2882 0         0 return sprintf('\x%02X',$_[0]);
2883             }
2884             elsif (($_[0]+1) == $_[1]) {
2885 40         85 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
2886             }
2887             else {
2888 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
2889             }
2890             }
2891             else {
2892 411         1548 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
2893             }
2894             }
2895              
2896             #
2897             # UTF-8 octet range
2898             #
2899             sub _octets {
2900 0     577   0 my $length = shift @_;
2901              
2902 577 100       888 if ($length == 1) {
    100          
    50          
    0          
2903 577         1212 my($a1) = unpack 'C', $_[0];
2904 406         893 my($z1) = unpack 'C', $_[1];
2905              
2906 406 50       628 if ($a1 > $z1) {
2907 406         744 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
2908             }
2909              
2910 0 50       0 if ($a1 == $z1) {
    50          
2911 406         837 return sprintf('\x%02X',$a1);
2912             }
2913             elsif (($a1+1) == $z1) {
2914 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
2915             }
2916             else {
2917 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
2918             }
2919             }
2920             elsif ($length == 2) {
2921 406         2243 my($a1,$a2) = unpack 'CC', $_[0];
2922 20         42 my($z1,$z2) = unpack 'CC', $_[1];
2923 20         35 my($A1,$A2) = unpack 'CC', $_[2];
2924 20         41 my($Z1,$Z2) = unpack 'CC', $_[3];
2925              
2926 20 50       33 if ($a1 == $z1) {
    50          
2927             return (
2928             # 11111111 222222222222
2929             # A A Z
2930 20         45 _cc($a1) . _cc($a2,$z2), # a2-z2
2931             );
2932             }
2933             elsif (($a1+1) == $z1) {
2934             return (
2935             # 11111111111 222222222222
2936             # A Z A Z
2937 0         0 _cc($a1) . _cc($a2,$Z2), # a2-
2938             _cc( $z1) . _cc($A2,$z2), # -z2
2939             );
2940             }
2941             else {
2942             return (
2943             # 1111111111111111 222222222222
2944             # A Z A Z
2945 0         0 _cc($a1) . _cc($a2,$Z2), # a2-
2946             _cc($a1+1,$z1-1) . _cc($A2,$Z2), # -
2947             _cc( $z1) . _cc($A2,$z2), # -z2
2948             );
2949             }
2950             }
2951             elsif ($length == 3) {
2952 20         37 my($a1,$a2,$a3) = unpack 'CCC', $_[0];
2953 151         403 my($z1,$z2,$z3) = unpack 'CCC', $_[1];
2954 151         289 my($A1,$A2,$A3) = unpack 'CCC', $_[2];
2955 151         264 my($Z1,$Z2,$Z3) = unpack 'CCC', $_[3];
2956              
2957 151 100       271 if ($a1 == $z1) {
    50          
2958 151 100       277 if ($a2 == $z2) {
    50          
2959             return (
2960             # 11111111 22222222 333333333333
2961             # A A A Z
2962 131         258 _cc($a1) . _cc($a2) . _cc($a3,$z3), # a3-z3
2963             );
2964             }
2965             elsif (($a2+1) == $z2) {
2966             return (
2967             # 11111111 22222222222 333333333333
2968             # A A Z A Z
2969 111         214 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
2970             _cc($a1) . _cc( $z2) . _cc($A3,$z3), # -z3
2971             );
2972             }
2973             else {
2974             return (
2975             # 11111111 2222222222222222 333333333333
2976             # A A Z A Z
2977 0         0 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
2978             _cc($a1) . _cc($a2+1,$z2-1) . _cc($A3,$Z3), # -
2979             _cc($a1) . _cc( $z2) . _cc($A3,$z3), # -z3
2980             );
2981             }
2982             }
2983             elsif (($a1+1) == $z1) {
2984             return (
2985             # 11111111111 22222222222222 333333333333
2986             # A Z A Z A Z
2987 20         28 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
2988             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3), # -
2989             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3), # -
2990             _cc( $z1) . _cc( $z2) . _cc($A3,$z3), # -z3
2991             );
2992             }
2993             else {
2994             return (
2995             # 1111111111111111 22222222222222 333333333333
2996             # A Z A Z A Z
2997 0         0 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
2998             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3), # -
2999             _cc($a1+1,$z1-1) . _cc($A2,$Z2) . _cc($A3,$Z3), # -
3000             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3), # -
3001             _cc( $z1) . _cc( $z2) . _cc($A3,$z3), # -z3
3002             );
3003             }
3004             }
3005             elsif ($length == 4) {
3006 20         32 my($a1,$a2,$a3,$a4) = unpack 'CCCC', $_[0];
3007 0         0 my($z1,$z2,$z3,$z4) = unpack 'CCCC', $_[1];
3008 0         0 my($A1,$A2,$A3,$A4) = unpack 'CCCC', $_[0];
3009 0         0 my($Z1,$Z2,$Z3,$Z4) = unpack 'CCCC', $_[1];
3010              
3011 0 0       0 if ($a1 == $z1) {
    0          
3012 0 0       0 if ($a2 == $z2) {
    0          
3013 0 0       0 if ($a3 == $z3) {
    0          
3014             return (
3015             # 11111111 22222222 33333333 444444444444
3016             # A A A A Z
3017 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$z4), # a4-z4
3018             );
3019             }
3020             elsif (($a3+1) == $z3) {
3021             return (
3022             # 11111111 22222222 33333333333 444444444444
3023             # A A A Z A Z
3024 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3025             _cc($a1) . _cc($a2) . _cc( $z3) . _cc($A4,$z4), # -z4
3026             );
3027             }
3028             else {
3029             return (
3030             # 11111111 22222222 3333333333333333 444444444444
3031             # A A A Z A Z
3032 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3033             _cc($a1) . _cc($a2) . _cc($a3+1,$z3-1) . _cc($A4,$Z4), # -
3034             _cc($a1) . _cc($a2) . _cc( $z3) . _cc($A4,$z4), # -z4
3035             );
3036             }
3037             }
3038             elsif (($a2+1) == $z2) {
3039             return (
3040             # 11111111 22222222222 33333333333333 444444444444
3041             # A A Z A Z A Z
3042 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3043             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
3044             _cc($a1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
3045             _cc($a1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
3046             );
3047             }
3048             else {
3049             return (
3050             # 11111111 2222222222222222 33333333333333 444444444444
3051             # A A Z A Z A Z
3052 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3053             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
3054             _cc($a1) . _cc($a2+1,$z2-1) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3055             _cc($a1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
3056             _cc($a1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
3057             );
3058             }
3059             }
3060             elsif (($a1+1) == $z1) {
3061             return (
3062             # 11111111111 22222222222222 33333333333333 444444444444
3063             # A Z A Z A Z A Z
3064 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3065             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
3066             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3067             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3068             _cc( $z1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
3069             _cc( $z1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
3070             );
3071             }
3072             else {
3073             return (
3074             # 1111111111111111 22222222222222 33333333333333 444444444444
3075             # A Z A Z A Z A Z
3076 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3077             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
3078             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3079             _cc($a1+1,$z1-1) . _cc($A2,$Z2) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3080             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3081             _cc( $z1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
3082             _cc( $z1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
3083             );
3084             }
3085             }
3086             else {
3087 0         0 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
3088             }
3089             }
3090              
3091             #
3092             # UTF-8 range regexp
3093             #
3094             sub _range_regexp {
3095 0     537   0 my($length,$first,$last) = @_;
3096              
3097 537         1001 my @range_regexp = ();
3098 537 50       650 if (not exists $range_tr{$length}) {
3099 537         1222 return @range_regexp;
3100             }
3101              
3102 0         0 my @ranges = @{ $range_tr{$length} };
  537         683  
3103 537         1191 while (my @range = splice(@ranges,0,$length)) {
3104 537         1368 my $min = '';
3105 1316         1642 my $max = '';
3106 1316         1363 for (my $i=0; $i < $length; $i++) {
3107 1316         2148 $min .= pack 'C', $range[$i][0];
3108 2384         3851 $max .= pack 'C', $range[$i][-1];
3109             }
3110              
3111             # min___max
3112             # FIRST_____________LAST
3113             # (nothing)
3114              
3115 2384 100 66     3905 if ($max lt $first) {
    100 100        
    50 33        
    100 100        
    100 66        
    100 66        
    50 66        
3116             }
3117              
3118             # **********
3119             # min_________max
3120             # FIRST_____________LAST
3121             # **********
3122              
3123             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
3124 1316         9617 push @range_regexp, _octets($length,$first,$max,$min,$max);
3125             }
3126              
3127             # **********************
3128             # min________________max
3129             # FIRST_____________LAST
3130             # **********************
3131              
3132             elsif (($min eq $first) and ($max eq $last)) {
3133 28         64 push @range_regexp, _octets($length,$first,$last,$min,$max);
3134             }
3135              
3136             # *********
3137             # min___max
3138             # FIRST_____________LAST
3139             # *********
3140              
3141             elsif (($first le $min) and ($max le $last)) {
3142 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
3143             }
3144              
3145             # **********************
3146             # min__________________________max
3147             # FIRST_____________LAST
3148             # **********************
3149              
3150             elsif (($min le $first) and ($last le $max)) {
3151 60         88 push @range_regexp, _octets($length,$first,$last,$min,$max);
3152             }
3153              
3154             # *********
3155             # min________max
3156             # FIRST_____________LAST
3157             # *********
3158              
3159             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
3160 469         974 push @range_regexp, _octets($length,$min,$last,$min,$max);
3161             }
3162              
3163             # min___max
3164             # FIRST_____________LAST
3165             # (nothing)
3166              
3167             elsif ($last lt $min) {
3168             }
3169              
3170             else {
3171 20         38 die __FILE__, ": subroutine _range_regexp panic.\n";
3172             }
3173             }
3174              
3175 0         0 return @range_regexp;
3176             }
3177              
3178             #
3179             # UTF-8 open character list for qr and not qr
3180             #
3181             sub _charlist {
3182              
3183 537     770   1127 my $modifier = pop @_;
3184 770         1127 my @char = @_;
3185              
3186 770 100       1468 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
3187              
3188             # unescape character
3189 770         1660 for (my $i=0; $i <= $#char; $i++) {
3190              
3191             # escape - to ...
3192 770 100 100     2288 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
3193 2660 100 100     18279 if ((0 < $i) and ($i < $#char)) {
3194 522         1604 $char[$i] = '...';
3195             }
3196             }
3197              
3198             # octal escape sequence
3199             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
3200 497         961 $char[$i] = octchr($1);
3201             }
3202              
3203             # hexadecimal escape sequence
3204             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
3205 0         0 $char[$i] = hexchr($1);
3206             }
3207              
3208             # \b{...} --> b\{...}
3209             # \B{...} --> B\{...}
3210             # \N{CHARNAME} --> N\{CHARNAME}
3211             # \p{PROPERTY} --> p\{PROPERTY}
3212             # \P{PROPERTY} --> P\{PROPERTY}
3213             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
3214 0         0 $char[$i] = $1 . '\\' . $2;
3215             }
3216              
3217             # \p, \P, \X --> p, P, X
3218             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
3219 0         0 $char[$i] = $1;
3220             }
3221              
3222             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
3223 0         0 $char[$i] = CORE::chr oct $1;
3224             }
3225             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
3226 0         0 $char[$i] = CORE::chr hex $1;
3227             }
3228             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
3229 206         668 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
3230             }
3231             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
3232             $char[$i] = {
3233             '\0' => "\0",
3234             '\n' => "\n",
3235             '\r' => "\r",
3236             '\t' => "\t",
3237             '\f' => "\f",
3238             '\b' => "\x08", # \b means backspace in character class
3239             '\a' => "\a",
3240             '\e' => "\e",
3241             '\d' => '[0-9]',
3242              
3243             # Vertical tabs are now whitespace
3244             # \s in a regex now matches a vertical tab in all circumstances.
3245             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
3246             # \t \n \v \f \r space
3247             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
3248             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
3249             '\s' => '\s',
3250              
3251             '\w' => '[0-9A-Z_a-z]',
3252             '\D' => '${Eutf2::eD}',
3253             '\S' => '${Eutf2::eS}',
3254             '\W' => '${Eutf2::eW}',
3255              
3256             '\H' => '${Eutf2::eH}',
3257             '\V' => '${Eutf2::eV}',
3258             '\h' => '[\x09\x20]',
3259             '\v' => '[\x0A\x0B\x0C\x0D]',
3260             '\R' => '${Eutf2::eR}',
3261              
3262 0         0 }->{$1};
3263             }
3264              
3265             # POSIX-style character classes
3266             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
3267             $char[$i] = {
3268              
3269             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
3270             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
3271             '[:^lower:]' => '${Eutf2::not_lower_i}',
3272             '[:^upper:]' => '${Eutf2::not_upper_i}',
3273              
3274 33         473 }->{$1};
3275             }
3276             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
3277             $char[$i] = {
3278              
3279             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
3280             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
3281             '[:ascii:]' => '[\x00-\x7F]',
3282             '[:blank:]' => '[\x09\x20]',
3283             '[:cntrl:]' => '[\x00-\x1F\x7F]',
3284             '[:digit:]' => '[\x30-\x39]',
3285             '[:graph:]' => '[\x21-\x7F]',
3286             '[:lower:]' => '[\x61-\x7A]',
3287             '[:print:]' => '[\x20-\x7F]',
3288             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
3289              
3290             # P.174 POSIX-Style Character Classes
3291             # in Chapter 5: Pattern Matching
3292             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
3293              
3294             # P.311 11.2.4 Character Classes and other Special Escapes
3295             # in Chapter 11: perlre: Perl regular expressions
3296             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
3297              
3298             # P.210 POSIX-Style Character Classes
3299             # in Chapter 5: Pattern Matching
3300             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3301              
3302             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
3303              
3304             '[:upper:]' => '[\x41-\x5A]',
3305             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
3306             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
3307             '[:^alnum:]' => '${Eutf2::not_alnum}',
3308             '[:^alpha:]' => '${Eutf2::not_alpha}',
3309             '[:^ascii:]' => '${Eutf2::not_ascii}',
3310             '[:^blank:]' => '${Eutf2::not_blank}',
3311             '[:^cntrl:]' => '${Eutf2::not_cntrl}',
3312             '[:^digit:]' => '${Eutf2::not_digit}',
3313             '[:^graph:]' => '${Eutf2::not_graph}',
3314             '[:^lower:]' => '${Eutf2::not_lower}',
3315             '[:^print:]' => '${Eutf2::not_print}',
3316             '[:^punct:]' => '${Eutf2::not_punct}',
3317             '[:^space:]' => '${Eutf2::not_space}',
3318             '[:^upper:]' => '${Eutf2::not_upper}',
3319             '[:^word:]' => '${Eutf2::not_word}',
3320             '[:^xdigit:]' => '${Eutf2::not_xdigit}',
3321              
3322 8         57 }->{$1};
3323             }
3324             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
3325 70         1188 $char[$i] = $1;
3326             }
3327             }
3328              
3329             # open character list
3330 7         34 my @singleoctet = ();
3331 770         1170 my @multipleoctet = ();
3332 770         943 for (my $i=0; $i <= $#char; ) {
3333              
3334             # escaped -
3335 770 100 100     1478 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
3336 2163         8290 $i += 1;
3337 497         592 next;
3338             }
3339              
3340             # make range regexp
3341             elsif ($char[$i] eq '...') {
3342              
3343             # range error
3344 497 50       839 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    100          
3345 497         1582 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
3346             }
3347             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
3348 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
3349 477         1027 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
3350             }
3351             }
3352              
3353             # make range regexp per length
3354 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
3355 497         1273 my @regexp = ();
3356              
3357             # is first and last
3358 537 100 100     664 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    100 66        
    100          
    50          
3359 537         1864 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
3360             }
3361              
3362             # is first
3363             elsif ($length == CORE::length($char[$i-1])) {
3364 477         1120 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
3365             }
3366              
3367             # is inside in first and last
3368             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
3369 20         65 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
3370             }
3371              
3372             # is last
3373             elsif ($length == CORE::length($char[$i+1])) {
3374 20         52 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
3375             }
3376              
3377             else {
3378 20         50 die __FILE__, ": subroutine make_regexp panic.\n";
3379             }
3380              
3381 0 100       0 if ($length == 1) {
3382 537         868 push @singleoctet, @regexp;
3383             }
3384             else {
3385 386         794 push @multipleoctet, @regexp;
3386             }
3387             }
3388              
3389 151         342 $i += 2;
3390             }
3391              
3392             # with /i modifier
3393             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
3394 497 100       956 if ($modifier =~ /i/oxms) {
3395 764         1177 my $uc = Eutf2::uc($char[$i]);
3396 192         315 my $fc = Eutf2::fc($char[$i]);
3397 192 50       333 if ($uc ne $fc) {
3398 192 50       332 if (CORE::length($fc) == 1) {
3399 192         251 push @singleoctet, $uc, $fc;
3400             }
3401             else {
3402 192         319 push @singleoctet, $uc;
3403 0         0 push @multipleoctet, $fc;
3404             }
3405             }
3406             else {
3407 0         0 push @singleoctet, $char[$i];
3408             }
3409             }
3410             else {
3411 0         0 push @singleoctet, $char[$i];
3412             }
3413 572         872 $i += 1;
3414             }
3415              
3416             # single character of single octet code
3417             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
3418 764         1427 push @singleoctet, "\t", "\x20";
3419 0         0 $i += 1;
3420             }
3421             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
3422 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
3423 0         0 $i += 1;
3424             }
3425             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
3426 0         0 push @singleoctet, $char[$i];
3427 2         6 $i += 1;
3428             }
3429              
3430             # single character of multiple-octet code
3431             else {
3432 2         5 push @multipleoctet, $char[$i];
3433 403         677 $i += 1;
3434             }
3435             }
3436              
3437             # quote metachar
3438 403         651 for (@singleoctet) {
3439 770 50       1347 if ($_ eq '...') {
    100          
    100          
    100          
    100          
3440 1364         5179 $_ = '-';
3441             }
3442             elsif (/\A \n \z/oxms) {
3443 0         0 $_ = '\n';
3444             }
3445             elsif (/\A \r \z/oxms) {
3446 8         33 $_ = '\r';
3447             }
3448             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
3449 8         17 $_ = sprintf('\x%02X', CORE::ord $1);
3450             }
3451             elsif (/\A [\x00-\xFF] \z/oxms) {
3452 1         5 $_ = quotemeta $_;
3453             }
3454             }
3455              
3456             # return character list
3457 939         1380 return \@singleoctet, \@multipleoctet;
3458             }
3459              
3460             #
3461             # UTF-8 octal escape sequence
3462             #
3463             sub octchr {
3464 770     5 0 2389 my($octdigit) = @_;
3465              
3466 5         15 my @binary = ();
3467 5         8 for my $octal (split(//,$octdigit)) {
3468             push @binary, {
3469             '0' => '000',
3470             '1' => '001',
3471             '2' => '010',
3472             '3' => '011',
3473             '4' => '100',
3474             '5' => '101',
3475             '6' => '110',
3476             '7' => '111',
3477 5         45 }->{$octal};
3478             }
3479 50         180 my $binary = join '', @binary;
3480              
3481             my $octchr = {
3482             # 1234567
3483             1 => pack('B*', "0000000$binary"),
3484             2 => pack('B*', "000000$binary"),
3485             3 => pack('B*', "00000$binary"),
3486             4 => pack('B*', "0000$binary"),
3487             5 => pack('B*', "000$binary"),
3488             6 => pack('B*', "00$binary"),
3489             7 => pack('B*', "0$binary"),
3490             0 => pack('B*', "$binary"),
3491              
3492 5         14 }->{CORE::length($binary) % 8};
3493              
3494 5         57 return $octchr;
3495             }
3496              
3497             #
3498             # UTF-8 hexadecimal escape sequence
3499             #
3500             sub hexchr {
3501 5     5 0 19 my($hexdigit) = @_;
3502              
3503             my $hexchr = {
3504             1 => pack('H*', "0$hexdigit"),
3505             0 => pack('H*', "$hexdigit"),
3506              
3507 5         14 }->{CORE::length($_[0]) % 2};
3508              
3509 5         37 return $hexchr;
3510             }
3511              
3512             #
3513             # UTF-8 open character list for qr
3514             #
3515             sub charlist_qr {
3516              
3517 5     531 0 19 my $modifier = pop @_;
3518 531         938 my @char = @_;
3519              
3520 531         1222 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
3521 531         1394 my @singleoctet = @$singleoctet;
3522 531         1087 my @multipleoctet = @$multipleoctet;
3523              
3524             # return character list
3525 531 100       760 if (scalar(@singleoctet) >= 1) {
3526              
3527             # with /i modifier
3528 531 100       1230 if ($modifier =~ m/i/oxms) {
3529 384         753 my %singleoctet_ignorecase = ();
3530 107         176 for (@singleoctet) {
3531 107   66     158 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
3532 272         793 for my $ord (hex($1) .. hex($2)) {
3533 80         261 my $char = CORE::chr($ord);
3534 1091         1485 my $uc = Eutf2::uc($char);
3535 1091         1405 my $fc = Eutf2::fc($char);
3536 1091 100       1564 if ($uc eq $fc) {
3537 1091         1576 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
3538             }
3539             else {
3540 502 50       1115 if (CORE::length($fc) == 1) {
3541 589         707 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
3542 589         1069 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
3543             }
3544             else {
3545 589         1314 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
3546 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
3547             }
3548             }
3549             }
3550             }
3551 0 100       0 if ($_ ne '') {
3552 272         417 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
3553             }
3554             }
3555 192         417 my $i = 0;
3556 107         134 my @singleoctet_ignorecase = ();
3557 107         133 for my $ord (0 .. 255) {
3558 107 100       154 if (exists $singleoctet_ignorecase{$ord}) {
3559 27392         30225 push @{$singleoctet_ignorecase[$i]}, $ord;
  1622         1437  
3560             }
3561             else {
3562 1622         2268 $i++;
3563             }
3564             }
3565 25770         24782 @singleoctet = ();
3566 107         154 for my $range (@singleoctet_ignorecase) {
3567 107 100       213 if (ref $range) {
3568 11367 50       16738 if (scalar(@{$range}) == 1) {
  214 50       201  
3569 214         306 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
3570             }
3571 0         0 elsif (scalar(@{$range}) == 2) {
3572 214         297 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
3573             }
3574             else {
3575 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  214         226  
  214         240  
3576             }
3577             }
3578             }
3579             }
3580              
3581 214         900 my $not_anchor = '';
3582 384         530 $not_anchor = '(?!(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF]))';
3583              
3584 384         489 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
3585             }
3586 384 100       982 if (scalar(@multipleoctet) >= 2) {
3587 531         1025 return '(?:' . join('|', @multipleoctet) . ')';
3588             }
3589             else {
3590 102         689 return $multipleoctet[0];
3591             }
3592             }
3593              
3594             #
3595             # UTF-8 open character list for not qr
3596             #
3597             sub charlist_not_qr {
3598              
3599 429     239 0 1785 my $modifier = pop @_;
3600 239         485 my @char = @_;
3601              
3602 239         541 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
3603 239         477 my @singleoctet = @$singleoctet;
3604 239         470 my @multipleoctet = @$multipleoctet;
3605              
3606             # with /i modifier
3607 239 100       340 if ($modifier =~ m/i/oxms) {
3608 239         536 my %singleoctet_ignorecase = ();
3609 128         187 for (@singleoctet) {
3610 128   66     172 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
3611 272         795 for my $ord (hex($1) .. hex($2)) {
3612 80         259 my $char = CORE::chr($ord);
3613 1091         1419 my $uc = Eutf2::uc($char);
3614 1091         1337 my $fc = Eutf2::fc($char);
3615 1091 100       1513 if ($uc eq $fc) {
3616 1091         1600 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
3617             }
3618             else {
3619 502 50       1136 if (CORE::length($fc) == 1) {
3620 589         726 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
3621 589         1063 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
3622             }
3623             else {
3624 589         1374 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
3625 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
3626             }
3627             }
3628             }
3629             }
3630 0 100       0 if ($_ ne '') {
3631 272         417 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
3632             }
3633             }
3634 192         420 my $i = 0;
3635 128         147 my @singleoctet_ignorecase = ();
3636 128         150 for my $ord (0 .. 255) {
3637 128 100       196 if (exists $singleoctet_ignorecase{$ord}) {
3638 32768         35966 push @{$singleoctet_ignorecase[$i]}, $ord;
  1622         1412  
3639             }
3640             else {
3641 1622         2331 $i++;
3642             }
3643             }
3644 31146         30102 @singleoctet = ();
3645 128         179 for my $range (@singleoctet_ignorecase) {
3646 128 100       258 if (ref $range) {
3647 11367 50       16967 if (scalar(@{$range}) == 1) {
  214 50       194  
3648 214         303 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
3649             }
3650 0         0 elsif (scalar(@{$range}) == 2) {
3651 214         293 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
3652             }
3653             else {
3654 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  214         230  
  214         244  
3655             }
3656             }
3657             }
3658             }
3659              
3660             # return character list
3661 214 100       931 if (scalar(@multipleoctet) >= 1) {
3662 239 100       434 if (scalar(@singleoctet) >= 1) {
3663              
3664             # any character other than multiple-octet and single octet character class
3665 114         188 return '(?!' . join('|', @multipleoctet) . ')(?:[^\x80-\xFF' . join('', @singleoctet) . ']|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])';
3666             }
3667             else {
3668              
3669             # any character other than multiple-octet character class
3670 70         467 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
3671             }
3672             }
3673             else {
3674 44 50       255 if (scalar(@singleoctet) >= 1) {
3675              
3676             # any character other than single octet character class
3677 125         226 return '(?:[^\x80-\xFF' . join('', @singleoctet) . ']|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])';
3678             }
3679             else {
3680              
3681             # any character
3682 125         763 return "(?:$your_char)";
3683             }
3684             }
3685             }
3686              
3687             #
3688             # open file in read mode
3689             #
3690             sub _open_r {
3691 0     612   0 my(undef,$file) = @_;
3692 306     306   4818 use Fcntl qw(O_RDONLY);
  306         843  
  306         58731  
3693 612         1856 return CORE::sysopen($_[0], $file, &O_RDONLY);
3694             }
3695              
3696             #
3697             # open file in append mode
3698             #
3699             sub _open_a {
3700 612     306   28437 my(undef,$file) = @_;
3701 306     306   2465 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  306         6019  
  306         1474862  
3702 306         1016 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
3703             }
3704              
3705             #
3706             # safe system
3707             #
3708             sub _systemx {
3709              
3710             # P.707 29.2.33. exec
3711             # in Chapter 29: Functions
3712             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
3713             #
3714             # Be aware that in older releases of Perl, exec (and system) did not flush
3715             # your output buffer, so you needed to enable command buffering by setting $|
3716             # on one or more filehandles to avoid lost output in the case of exec, or
3717             # misordererd output in the case of system. This situation was largely remedied
3718             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
3719              
3720             # P.855 exec
3721             # in Chapter 27: Functions
3722             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3723             #
3724             # In very old release of Perl (before v5.6), exec (and system) did not flush
3725             # your output buffer, so you needed to enable command buffering by setting $|
3726             # on one or more filehandles to avoid lost output with exec or misordered
3727             # output with system.
3728              
3729 306     306   70080 $| = 1;
3730              
3731             # P.565 23.1.2. Cleaning Up Your Environment
3732             # in Chapter 23: Security
3733             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
3734              
3735             # P.656 Cleaning Up Your Environment
3736             # in Chapter 20: Security
3737             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3738              
3739             # local $ENV{'PATH'} = '.';
3740 306         1491 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
3741              
3742             # P.707 29.2.33. exec
3743             # in Chapter 29: Functions
3744             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
3745             #
3746             # As we mentioned earlier, exec treats a discrete list of arguments as an
3747             # indication that it should bypass shell processing. However, there is one
3748             # place where you might still get tripped up. The exec call (and system, too)
3749             # will not distinguish between a single scalar argument and an array containing
3750             # only one element.
3751             #
3752             # @args = ("echo surprise"); # just one element in list
3753             # exec @args # still subject to shell escapes
3754             # or die "exec: $!"; # because @args == 1
3755             #
3756             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
3757             # first argument as the pathname, which forces the rest of the arguments to be
3758             # interpreted as a list, even if there is only one of them:
3759             #
3760             # exec { $args[0] } @args # safe even with one-argument list
3761             # or die "can't exec @args: $!";
3762              
3763             # P.855 exec
3764             # in Chapter 27: Functions
3765             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3766             #
3767             # As we mentioned earlier, exec treats a discrete list of arguments as a
3768             # directive to bypass shell processing. However, there is one place where
3769             # you might still get tripped up. The exec call (and system, too) cannot
3770             # distinguish between a single scalar argument and an array containing
3771             # only one element.
3772             #
3773             # @args = ("echo surprise"); # just one element in list
3774             # exec @args # still subject to shell escapes
3775             # || die "exec: $!"; # because @args == 1
3776             #
3777             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
3778             # argument as the pathname, which forces the rest of the arguments to be
3779             # interpreted as a list, even if there is only one of them:
3780             #
3781             # exec { $args[0] } @args # safe even with one-argument list
3782             # || die "can't exec @args: $!";
3783              
3784 306         2910 return CORE::system { $_[0] } @_; # safe even with one-argument list
  306         635  
3785             }
3786              
3787             #
3788             # UTF-8 order to character (with parameter)
3789             #
3790             sub Eutf2::chr(;$) {
3791              
3792 306 0   0 0 39957014 my $c = @_ ? $_[0] : $_;
3793              
3794 0 0       0 if ($c == 0x00) {
3795 0         0 return "\x00";
3796             }
3797             else {
3798 0         0 my @chr = ();
3799 0         0 while ($c > 0) {
3800 0         0 unshift @chr, ($c % 0x100);
3801 0         0 $c = int($c / 0x100);
3802             }
3803 0         0 return pack 'C*', @chr;
3804             }
3805             }
3806              
3807             #
3808             # UTF-8 order to character (without parameter)
3809             #
3810             sub Eutf2::chr_() {
3811              
3812 0     0 0 0 my $c = $_;
3813              
3814 0 0       0 if ($c == 0x00) {
3815 0         0 return "\x00";
3816             }
3817             else {
3818 0         0 my @chr = ();
3819 0         0 while ($c > 0) {
3820 0         0 unshift @chr, ($c % 0x100);
3821 0         0 $c = int($c / 0x100);
3822             }
3823 0         0 return pack 'C*', @chr;
3824             }
3825             }
3826              
3827             #
3828             # UTF-8 path globbing (with parameter)
3829             #
3830             sub Eutf2::glob($) {
3831              
3832 0 0   0 0 0 if (wantarray) {
3833 0         0 my @glob = _DOS_like_glob(@_);
3834 0         0 for my $glob (@glob) {
3835 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
3836             }
3837 0         0 return @glob;
3838             }
3839             else {
3840 0         0 my $glob = _DOS_like_glob(@_);
3841 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
3842 0         0 return $glob;
3843             }
3844             }
3845              
3846             #
3847             # UTF-8 path globbing (without parameter)
3848             #
3849             sub Eutf2::glob_() {
3850              
3851 0 0   0 0 0 if (wantarray) {
3852 0         0 my @glob = _DOS_like_glob();
3853 0         0 for my $glob (@glob) {
3854 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
3855             }
3856 0         0 return @glob;
3857             }
3858             else {
3859 0         0 my $glob = _DOS_like_glob();
3860 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
3861 0         0 return $glob;
3862             }
3863             }
3864              
3865             #
3866             # UTF-8 path globbing via File::DosGlob 1.10
3867             #
3868             # Often I confuse "_dosglob" and "_doglob".
3869             # So, I renamed "_dosglob" to "_DOS_like_glob".
3870             #
3871             my %iter;
3872             my %entries;
3873             sub _DOS_like_glob {
3874              
3875             # context (keyed by second cxix argument provided by core)
3876 0     0   0 my($expr,$cxix) = @_;
3877              
3878             # glob without args defaults to $_
3879 0 0       0 $expr = $_ if not defined $expr;
3880              
3881             # represents the current user's home directory
3882             #
3883             # 7.3. Expanding Tildes in Filenames
3884             # in Chapter 7. File Access
3885             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3886             #
3887             # and File::HomeDir, File::HomeDir::Windows module
3888              
3889             # DOS-like system
3890 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
3891 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
3892             { my_home_MSWin32() }oxmse;
3893             }
3894              
3895             # UNIX-like system
3896 0 0 0     0 else {
  0         0  
3897             $expr =~ s{ \A ~ ( (?:[^\x80-\xFF/]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])* ) }
3898             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
3899             }
3900 0 0       0  
3901 0 0       0 # assume global context if not provided one
3902             $cxix = '_G_' if not defined $cxix;
3903             $iter{$cxix} = 0 if not exists $iter{$cxix};
3904 0 0       0  
3905 0         0 # if we're just beginning, do it all first
3906             if ($iter{$cxix} == 0) {
3907             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
3908             }
3909 0 0       0  
3910 0         0 # chuck it all out, quick or slow
3911 0         0 if (wantarray) {
  0         0  
3912             delete $iter{$cxix};
3913             return @{delete $entries{$cxix}};
3914 0 0       0 }
  0         0  
3915 0         0 else {
  0         0  
3916             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
3917             return shift @{$entries{$cxix}};
3918             }
3919 0         0 else {
3920 0         0 # return undef for EOL
3921 0         0 delete $iter{$cxix};
3922             delete $entries{$cxix};
3923             return undef;
3924             }
3925             }
3926             }
3927              
3928             #
3929             # UTF-8 path globbing subroutine
3930             #
3931 0     0   0 sub _do_glob {
3932 0         0  
3933 0         0 my($cond,@expr) = @_;
3934             my @glob = ();
3935             my $fix_drive_relative_paths = 0;
3936 0         0  
3937 0 0       0 OUTER:
3938 0 0       0 for my $expr (@expr) {
3939             next OUTER if not defined $expr;
3940 0         0 next OUTER if $expr eq '';
3941 0         0  
3942 0         0 my @matched = ();
3943 0         0 my @globdir = ();
3944 0         0 my $head = '.';
3945             my $pathsep = '/';
3946             my $tail;
3947 0 0       0  
3948 0         0 # if argument is within quotes strip em and do no globbing
3949 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
3950 0 0       0 $expr = $1;
3951 0         0 if ($cond eq 'd') {
3952             if (-d $expr) {
3953             push @glob, $expr;
3954             }
3955 0 0       0 }
3956 0         0 else {
3957             if (-e $expr) {
3958             push @glob, $expr;
3959 0         0 }
3960             }
3961             next OUTER;
3962             }
3963              
3964 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
3965 0 0       0 # to h:./*.pm to expand correctly
3966 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
3967             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^\x80-\xFF/\\]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF]) #$1./$2#oxms) {
3968             $fix_drive_relative_paths = 1;
3969             }
3970 0 0       0 }
3971 0 0       0  
3972 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
3973 0         0 if ($tail eq '') {
3974             push @glob, $expr;
3975 0 0       0 next OUTER;
3976 0 0       0 }
3977 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
3978 0         0 if (@globdir = _do_glob('d', $head)) {
3979             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
3980             next OUTER;
3981 0 0 0     0 }
3982 0         0 }
3983             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
3984 0         0 $head .= $pathsep;
3985             }
3986             $expr = $tail;
3987             }
3988 0 0       0  
3989 0 0       0 # If file component has no wildcards, we can avoid opendir
3990 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
3991             if ($head eq '.') {
3992 0 0 0     0 $head = '';
3993 0         0 }
3994             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
3995 0         0 $head .= $pathsep;
3996 0 0       0 }
3997 0 0       0 $head .= $expr;
3998 0         0 if ($cond eq 'd') {
3999             if (-d $head) {
4000             push @glob, $head;
4001             }
4002 0 0       0 }
4003 0         0 else {
4004             if (-e $head) {
4005             push @glob, $head;
4006 0         0 }
4007             }
4008 0 0       0 next OUTER;
4009 0         0 }
4010 0         0 opendir(*DIR, $head) or next OUTER;
4011             my @leaf = readdir DIR;
4012 0 0       0 closedir DIR;
4013 0         0  
4014             if ($head eq '.') {
4015 0 0 0     0 $head = '';
4016 0         0 }
4017             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
4018             $head .= $pathsep;
4019 0         0 }
4020 0         0  
4021 0         0 my $pattern = '';
4022             while ($expr =~ / \G ($q_char) /oxgc) {
4023             my $char = $1;
4024              
4025             # 6.9. Matching Shell Globs as Regular Expressions
4026             # in Chapter 6. Pattern Matching
4027             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
4028 0 0       0 # (and so on)
    0          
    0          
4029 0         0  
4030             if ($char eq '*') {
4031             $pattern .= "(?:$your_char)*",
4032 0         0 }
4033             elsif ($char eq '?') {
4034             $pattern .= "(?:$your_char)?", # DOS style
4035             # $pattern .= "(?:$your_char)", # UNIX style
4036 0         0 }
4037             elsif ((my $fc = Eutf2::fc($char)) ne $char) {
4038             $pattern .= $fc;
4039 0         0 }
4040             else {
4041             $pattern .= quotemeta $char;
4042 0     0   0 }
  0         0  
4043             }
4044             my $matchsub = sub { Eutf2::fc($_[0]) =~ /\A $pattern \z/xms };
4045              
4046             # if ($@) {
4047             # print STDERR "$0: $@\n";
4048             # next OUTER;
4049             # }
4050 0         0  
4051 0 0 0     0 INNER:
4052 0         0 for my $leaf (@leaf) {
4053             if ($leaf eq '.' or $leaf eq '..') {
4054 0 0 0     0 next INNER;
4055 0         0 }
4056             if ($cond eq 'd' and not -d "$head$leaf") {
4057             next INNER;
4058 0 0       0 }
4059 0         0  
4060 0         0 if (&$matchsub($leaf)) {
4061             push @matched, "$head$leaf";
4062             next INNER;
4063             }
4064              
4065             # [DOS compatibility special case]
4066 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
4067              
4068             if (Eutf2::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
4069             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
4070 0 0       0 Eutf2::index($pattern,'\\.') != -1 # pattern has a dot.
4071 0         0 ) {
4072 0         0 if (&$matchsub("$leaf.")) {
4073             push @matched, "$head$leaf";
4074             next INNER;
4075             }
4076 0 0       0 }
4077 0         0 }
4078             if (@matched) {
4079             push @glob, @matched;
4080 0 0       0 }
4081 0         0 }
4082 0         0 if ($fix_drive_relative_paths) {
4083             for my $glob (@glob) {
4084             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
4085 0         0 }
4086             }
4087             return @glob;
4088             }
4089              
4090             #
4091             # UTF-8 parse line
4092             #
4093 0     0   0 sub _parse_line {
4094              
4095 0         0 my($line) = @_;
4096 0         0  
4097 0         0 $line .= ' ';
4098             my @piece = ();
4099             while ($line =~ /
4100             " ( (?>(?: [^\x80-\xFF"] |(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] )* ) ) " (?>\s+) |
4101             ( (?>(?: [^\x80-\xFF"\s]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] )* ) ) (?>\s+)
4102 0 0       0 /oxmsg
4103             ) {
4104 0         0 push @piece, defined($1) ? $1 : $2;
4105             }
4106             return @piece;
4107             }
4108              
4109             #
4110             # UTF-8 parse path
4111             #
4112 0     0   0 sub _parse_path {
4113              
4114 0         0 my($path,$pathsep) = @_;
4115 0         0  
4116 0         0 $path .= '/';
4117             my @subpath = ();
4118             while ($path =~ /
4119             ((?: [^\x80-\xFF\/\\]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] )+?) [\/\\]
4120 0         0 /oxmsg
4121             ) {
4122             push @subpath, $1;
4123 0         0 }
4124 0         0  
4125 0         0 my $tail = pop @subpath;
4126             my $head = join $pathsep, @subpath;
4127             return $head, $tail;
4128             }
4129              
4130             #
4131             # via File::HomeDir::Windows 1.00
4132             #
4133             sub my_home_MSWin32 {
4134              
4135             # A lot of unix people and unix-derived tools rely on
4136 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
4137 0         0 # so that they can replace raw HOME calls with File::HomeDir.
4138             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
4139             return $ENV{'HOME'};
4140             }
4141              
4142 0         0 # Do we have a user profile?
4143             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
4144             return $ENV{'USERPROFILE'};
4145             }
4146              
4147 0         0 # Some Windows use something like $ENV{'HOME'}
4148             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
4149             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
4150 0         0 }
4151              
4152             return undef;
4153             }
4154              
4155             #
4156             # via File::HomeDir::Unix 1.00
4157 0     0 0 0 #
4158             sub my_home {
4159 0 0 0     0 my $home;
    0 0        
4160 0         0  
4161             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
4162             $home = $ENV{'HOME'};
4163             }
4164              
4165             # This is from the original code, but I'm guessing
4166 0         0 # it means "login directory" and exists on some Unixes.
4167             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
4168             $home = $ENV{'LOGDIR'};
4169             }
4170              
4171             ### More-desperate methods
4172              
4173 0         0 # Light desperation on any (Unixish) platform
4174             else {
4175             $home = CORE::eval q{ (getpwuid($<))[7] };
4176             }
4177              
4178 0 0 0     0 # On Unix in general, a non-existant home means "no home"
4179 0         0 # For example, "nobody"-like users might use /nonexistant
4180             if (defined $home and ! -d($home)) {
4181 0         0 $home = undef;
4182             }
4183             return $home;
4184             }
4185              
4186             #
4187             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
4188 0     0 0 0 #
4189             sub Eutf2::PREMATCH {
4190             return $`;
4191             }
4192              
4193             #
4194             # ${^MATCH}, $MATCH, $& the string that matched
4195 0     0 0 0 #
4196             sub Eutf2::MATCH {
4197             return $&;
4198             }
4199              
4200             #
4201             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
4202 0     0 0 0 #
4203             sub Eutf2::POSTMATCH {
4204             return $';
4205             }
4206              
4207             #
4208             # UTF-8 character to order (with parameter)
4209             #
4210 0 0   0 1 0 sub UTF2::ord(;$) {
4211              
4212 0 0       0 local $_ = shift if @_;
4213 0         0  
4214 0         0 if (/\A ($q_char) /oxms) {
4215 0         0 my @ord = unpack 'C*', $1;
4216 0         0 my $ord = 0;
4217             while (my $o = shift @ord) {
4218 0         0 $ord = $ord * 0x100 + $o;
4219             }
4220             return $ord;
4221 0         0 }
4222             else {
4223             return CORE::ord $_;
4224             }
4225             }
4226              
4227             #
4228             # UTF-8 character to order (without parameter)
4229             #
4230 0 0   0 0 0 sub UTF2::ord_() {
4231 0         0  
4232 0         0 if (/\A ($q_char) /oxms) {
4233 0         0 my @ord = unpack 'C*', $1;
4234 0         0 my $ord = 0;
4235             while (my $o = shift @ord) {
4236 0         0 $ord = $ord * 0x100 + $o;
4237             }
4238             return $ord;
4239 0         0 }
4240             else {
4241             return CORE::ord $_;
4242             }
4243             }
4244              
4245             #
4246             # UTF-8 reverse
4247             #
4248 0 0   0 0 0 sub UTF2::reverse(@) {
4249 0         0  
4250             if (wantarray) {
4251             return CORE::reverse @_;
4252             }
4253             else {
4254              
4255             # One of us once cornered Larry in an elevator and asked him what
4256             # problem he was solving with this, but he looked as far off into
4257             # the distance as he could in an elevator and said, "It seemed like
4258 0         0 # a good idea at the time."
4259              
4260             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
4261             }
4262             }
4263              
4264             #
4265             # UTF-8 getc (with parameter, without parameter)
4266             #
4267 0     0 0 0 sub UTF2::getc(;*@) {
4268 0 0       0  
4269 0 0 0     0 my($package) = caller;
4270             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
4271 0         0 croak 'Too many arguments for UTF2::getc' if @_ and not wantarray;
  0         0  
4272 0         0  
4273 0         0 my @length = sort { $a <=> $b } keys %range_tr;
4274 0         0 my $getc = '';
4275 0 0       0 for my $length ($length[0] .. $length[-1]) {
4276 0 0       0 $getc .= CORE::getc($fh);
4277 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
4278             if ($getc =~ /\A ${Eutf2::dot_s} \z/oxms) {
4279             return wantarray ? ($getc,@_) : $getc;
4280             }
4281 0 0       0 }
4282             }
4283             return wantarray ? ($getc,@_) : $getc;
4284             }
4285              
4286             #
4287             # UTF-8 length by character
4288             #
4289 0 0   0 1 0 sub UTF2::length(;$) {
4290              
4291 0         0 local $_ = shift if @_;
4292 0         0  
4293             local @_ = /\G ($q_char) /oxmsg;
4294             return scalar @_;
4295             }
4296              
4297             #
4298             # UTF-8 substr by character
4299             #
4300             BEGIN {
4301              
4302             # P.232 The lvalue Attribute
4303             # in Chapter 6: Subroutines
4304             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4305              
4306             # P.336 The lvalue Attribute
4307             # in Chapter 7: Subroutines
4308             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4309              
4310             # P.144 8.4 Lvalue subroutines
4311             # in Chapter 8: perlsub: Perl subroutines
4312 306 50 0 306 1 272167 # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
  0 0   0   0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
4313              
4314             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
4315             # vv----------------------*******
4316             sub UTF2::substr($$;$$) %s {
4317              
4318             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
4319              
4320             # If the substring is beyond either end of the string, substr() returns the undefined
4321             # value and produces a warning. When used as an lvalue, specifying a substring that
4322             # is entirely outside the string raises an exception.
4323             # http://perldoc.perl.org/functions/substr.html
4324              
4325             # A return with no argument returns the scalar value undef in scalar context,
4326             # an empty list () in list context, and (naturally) nothing at all in void
4327             # context.
4328              
4329             my $offset = $_[1];
4330             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
4331             return;
4332             }
4333              
4334             # substr($string,$offset,$length,$replacement)
4335             if (@_ == 4) {
4336             my(undef,undef,$length,$replacement) = @_;
4337             my $substr = join '', splice(@char, $offset, $length, $replacement);
4338             $_[0] = join '', @char;
4339              
4340             # return $substr; this doesn't work, don't say "return"
4341             $substr;
4342             }
4343              
4344             # substr($string,$offset,$length)
4345             elsif (@_ == 3) {
4346             my(undef,undef,$length) = @_;
4347             my $octet_offset = 0;
4348             my $octet_length = 0;
4349             if ($offset == 0) {
4350             $octet_offset = 0;
4351             }
4352             elsif ($offset > 0) {
4353             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
4354             }
4355             else {
4356             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
4357             }
4358             if ($length == 0) {
4359             $octet_length = 0;
4360             }
4361             elsif ($length > 0) {
4362             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
4363             }
4364             else {
4365             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
4366             }
4367             CORE::substr($_[0], $octet_offset, $octet_length);
4368             }
4369              
4370             # substr($string,$offset)
4371             else {
4372             my $octet_offset = 0;
4373             if ($offset == 0) {
4374             $octet_offset = 0;
4375             }
4376             elsif ($offset > 0) {
4377             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
4378             }
4379             else {
4380             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
4381             }
4382             CORE::substr($_[0], $octet_offset);
4383             }
4384             }
4385             END
4386             }
4387              
4388             #
4389             # UTF-8 index by character
4390             #
4391 0     0 1 0 sub UTF2::index($$;$) {
4392 0 0       0  
4393 0         0 my $index;
4394             if (@_ == 3) {
4395             $index = Eutf2::index($_[0], $_[1], CORE::length(UTF2::substr($_[0], 0, $_[2])));
4396 0         0 }
4397             else {
4398             $index = Eutf2::index($_[0], $_[1]);
4399 0 0       0 }
4400 0         0  
4401             if ($index == -1) {
4402             return -1;
4403 0         0 }
4404             else {
4405             return UTF2::length(CORE::substr $_[0], 0, $index);
4406             }
4407             }
4408              
4409             #
4410             # UTF-8 rindex by character
4411             #
4412 0     0 1 0 sub UTF2::rindex($$;$) {
4413 0 0       0  
4414 0         0 my $rindex;
4415             if (@_ == 3) {
4416             $rindex = Eutf2::rindex($_[0], $_[1], CORE::length(UTF2::substr($_[0], 0, $_[2])));
4417 0         0 }
4418             else {
4419             $rindex = Eutf2::rindex($_[0], $_[1]);
4420 0 0       0 }
4421 0         0  
4422             if ($rindex == -1) {
4423             return -1;
4424 0         0 }
4425             else {
4426             return UTF2::length(CORE::substr $_[0], 0, $rindex);
4427             }
4428             }
4429              
4430 306     306   4645 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  306         677  
  306         46471  
4431             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
4432             use vars qw($slash); $slash = 'm//';
4433              
4434             # ord() to ord() or UTF2::ord()
4435             my $function_ord = 'ord';
4436              
4437             # ord to ord or UTF2::ord_
4438             my $function_ord_ = 'ord';
4439              
4440             # reverse to reverse or UTF2::reverse
4441             my $function_reverse = 'reverse';
4442              
4443             # getc to getc or UTF2::getc
4444             my $function_getc = 'getc';
4445              
4446             # P.1023 Appendix W.9 Multibyte Anchoring
4447             # of ISBN 1-56592-224-7 CJKV Information Processing
4448              
4449 306     306   4137 my $anchor = '';
  306     0   2042  
  306         19228917  
4450              
4451             use vars qw($nest);
4452              
4453             # regexp of nested parens in qqXX
4454              
4455             # P.340 Matching Nested Constructs with Embedded Code
4456             # in Chapter 7: Perl
4457             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
4458              
4459             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
4460             [^\x80-\xFF\\()] |
4461             \( (?{$nest++}) |
4462             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4463             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4464             \\ [^\x80-\xFFc] |
4465             \\c[\x40-\x5F] |
4466             \\ (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4467             [\x00-\xFF]
4468             }xms;
4469              
4470             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
4471             [^\x80-\xFF\\{}] |
4472             \{ (?{$nest++}) |
4473             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4474             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4475             \\ [^\x80-\xFFc] |
4476             \\c[\x40-\x5F] |
4477             \\ (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4478             [\x00-\xFF]
4479             }xms;
4480              
4481             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
4482             [^\x80-\xFF\\\[\]] |
4483             \[ (?{$nest++}) |
4484             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4485             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4486             \\ [^\x80-\xFFc] |
4487             \\c[\x40-\x5F] |
4488             \\ (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4489             [\x00-\xFF]
4490             }xms;
4491              
4492             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
4493             [^\x80-\xFF\\<>] |
4494             \< (?{$nest++}) |
4495             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4496             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4497             \\ [^\x80-\xFFc] |
4498             \\c[\x40-\x5F] |
4499             \\ (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4500             [\x00-\xFF]
4501             }xms;
4502              
4503             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
4504             (?: ::)? (?:
4505             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
4506             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
4507             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
4508             ))
4509             }xms;
4510              
4511             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
4512             (?: ::)? (?:
4513             (?>[0-9]+) |
4514             [^\x80-\xFFa-zA-Z_0-9\[\]] |
4515             ^[A-Z] |
4516             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
4517             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
4518             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
4519             ))
4520             }xms;
4521              
4522             my $qq_substr = qr{(?> Char::substr | UTF2::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
4523             }xms;
4524              
4525             # regexp of nested parens in qXX
4526             my $q_paren = qr{(?{local $nest=0}) (?>(?:
4527             [^\x80-\xFF()] |
4528             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4529             \( (?{$nest++}) |
4530             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4531             [\x00-\xFF]
4532             }xms;
4533              
4534             my $q_brace = qr{(?{local $nest=0}) (?>(?:
4535             [^\x80-\xFF\{\}] |
4536             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4537             \{ (?{$nest++}) |
4538             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4539             [\x00-\xFF]
4540             }xms;
4541              
4542             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
4543             [^\x80-\xFF\[\]] |
4544             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4545             \[ (?{$nest++}) |
4546             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4547             [\x00-\xFF]
4548             }xms;
4549              
4550             my $q_angle = qr{(?{local $nest=0}) (?>(?:
4551             [^\x80-\xFF<>] |
4552             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
4553             \< (?{$nest++}) |
4554             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4555             [\x00-\xFF]
4556             }xms;
4557              
4558             my $matched = '';
4559             my $s_matched = '';
4560              
4561             my $tr_variable = ''; # variable of tr///
4562             my $sub_variable = ''; # variable of s///
4563             my $bind_operator = ''; # =~ or !~
4564              
4565             my @heredoc = (); # here document
4566             my @heredoc_delimiter = ();
4567             my $here_script = ''; # here script
4568              
4569             #
4570             # escape UTF-8 script
4571 0 50   306 0 0 #
4572             sub UTF2::escape(;$) {
4573             local($_) = $_[0] if @_;
4574              
4575             # P.359 The Study Function
4576             # in Chapter 7: Perl
4577 306         1123 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
4578              
4579             study $_; # Yes, I studied study yesterday.
4580              
4581             # while all script
4582              
4583             # 6.14. Matching from Where the Last Pattern Left Off
4584             # in Chapter 6. Pattern Matching
4585             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
4586             # (and so on)
4587              
4588             # one member of Tag-team
4589             #
4590             # P.128 Start of match (or end of previous match): \G
4591             # P.130 Advanced Use of \G with Perl
4592             # in Chapter 3: Overview of Regular Expression Features and Flavors
4593             # P.255 Use leading anchors
4594             # P.256 Expose ^ and \G at the front expressions
4595             # in Chapter 6: Crafting an Efficient Expression
4596             # P.315 "Tag-team" matching with /gc
4597             # in Chapter 7: Perl
4598 306         670 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
4599 306         565  
4600 306         1158 my $e_script = '';
4601             while (not /\G \z/oxgc) { # member
4602             $e_script .= UTF2::escape_token();
4603 135221         203103 }
4604              
4605             return $e_script;
4606             }
4607              
4608             #
4609             # escape UTF-8 token of script
4610             #
4611             sub UTF2::escape_token {
4612              
4613 306     135221 0 4512 # \n output here document
4614              
4615             my $ignore_modules = join('|', qw(
4616             utf8
4617             bytes
4618             charnames
4619             I18N::Japanese
4620             I18N::Collate
4621             I18N::JExt
4622             File::DosGlob
4623             Wild
4624             Wildcard
4625             Japanese
4626             ));
4627              
4628             # another member of Tag-team
4629             #
4630             # P.315 "Tag-team" matching with /gc
4631             # in Chapter 7: Perl
4632 135221 100 100     165820 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
    100 100        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    100          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
4633 135221         6501167  
4634 22128 100       26326 if (/\G ( \n ) /oxgc) { # another member (and so on)
4635 22128         37352 my $heredoc = '';
4636             if (scalar(@heredoc_delimiter) >= 1) {
4637 191         240 $slash = 'm//';
4638 191         405  
4639             $heredoc = join '', @heredoc;
4640             @heredoc = ();
4641 191         325  
4642 191         343 # skip here document
4643             for my $heredoc_delimiter (@heredoc_delimiter) {
4644 199         1215 /\G .*? \n $heredoc_delimiter \n/xmsgc;
4645             }
4646 191         370 @heredoc_delimiter = ();
4647              
4648 191         272 $here_script = '';
4649             }
4650             return "\n" . $heredoc;
4651             }
4652 22128         63365  
4653             # ignore space, comment
4654             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
4655              
4656             # if (, elsif (, unless (, while (, until (, given (, and when (
4657              
4658             # given, when
4659              
4660             # P.225 The given Statement
4661             # in Chapter 15: Smart Matching and given-when
4662             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4663              
4664             # P.133 The given Statement
4665             # in Chapter 4: Statements and Declarations
4666             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4667 36018         106745  
4668 2398         3509 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
4669             $slash = 'm//';
4670             return $1;
4671             }
4672              
4673             # scalar variable ($scalar = ...) =~ tr///;
4674             # scalar variable ($scalar = ...) =~ s///;
4675              
4676             # state
4677              
4678             # P.68 Persistent, Private Variables
4679             # in Chapter 4: Subroutines
4680             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4681              
4682             # P.160 Persistent Lexically Scoped Variables: state
4683             # in Chapter 4: Statements and Declarations
4684             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4685              
4686             # (and so on)
4687 2398         7032  
4688             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
4689 139 50       334 my $e_string = e_string($1);
    50          
4690 139         7212  
4691 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
4692 0         0 $tr_variable = $e_string . e_string($1);
4693 0         0 $bind_operator = $2;
4694             $slash = 'm//';
4695             return '';
4696 0         0 }
4697 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
4698 0         0 $sub_variable = $e_string . e_string($1);
4699 0         0 $bind_operator = $2;
4700             $slash = 'm//';
4701             return '';
4702 0         0 }
4703 139         328 else {
4704             $slash = 'div';
4705             return $e_string;
4706             }
4707             }
4708              
4709 139         578 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eutf2::PREMATCH()
4710 4         9 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4711             $slash = 'div';
4712             return q{Eutf2::PREMATCH()};
4713             }
4714              
4715 4         12 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eutf2::MATCH()
4716 28         115 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4717             $slash = 'div';
4718             return q{Eutf2::MATCH()};
4719             }
4720              
4721 28         81 # $', ${'} --> $', ${'}
4722 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
4723             $slash = 'div';
4724             return $1;
4725             }
4726              
4727 1         4 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eutf2::POSTMATCH()
4728 3         8 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4729             $slash = 'div';
4730             return q{Eutf2::POSTMATCH()};
4731             }
4732              
4733             # scalar variable $scalar =~ tr///;
4734             # scalar variable $scalar =~ s///;
4735             # substr() =~ tr///;
4736 3         10 # substr() =~ s///;
4737             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
4738 2318 100       4916 my $scalar = e_string($1);
    100          
4739 2318         8824  
4740 9         16 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
4741 9         17 $tr_variable = $scalar;
4742 9         15 $bind_operator = $1;
4743             $slash = 'm//';
4744             return '';
4745 9         25 }
4746 95         186 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
4747 95         189 $sub_variable = $scalar;
4748 95         144 $bind_operator = $1;
4749             $slash = 'm//';
4750             return '';
4751 95         310 }
4752 2214         3288 else {
4753             $slash = 'div';
4754             return $scalar;
4755             }
4756             }
4757              
4758 2214         5707 # end of statement
4759             elsif (/\G ( [,;] ) /oxgc) {
4760             $slash = 'm//';
4761 9208         13852  
4762             # clear tr/// variable
4763             $tr_variable = '';
4764 9208         10409  
4765             # clear s/// variable
4766 9208         9840 $sub_variable = '';
4767              
4768 9208         10154 $bind_operator = '';
4769              
4770             return $1;
4771             }
4772              
4773 9208         30005 # bareword
4774             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4775             return $1;
4776             }
4777              
4778 0         0 # $0 --> $0
4779 2         6 elsif (/\G ( \$ 0 ) /oxmsgc) {
4780             $slash = 'div';
4781             return $1;
4782 2         8 }
4783 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4784             $slash = 'div';
4785             return $1;
4786             }
4787              
4788 0         0 # $$ --> $$
4789 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4790             $slash = 'div';
4791             return $1;
4792             }
4793              
4794             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4795 1         5 # $1, $2, $3 --> $1, $2, $3 otherwise
4796 57         139 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4797             $slash = 'div';
4798             return e_capture($1);
4799 57         233 }
4800 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4801             $slash = 'div';
4802             return e_capture($1);
4803             }
4804              
4805 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4806 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4807             $slash = 'div';
4808             return e_capture($1.'->'.$2);
4809             }
4810              
4811 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4812 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4813             $slash = 'div';
4814             return e_capture($1.'->'.$2);
4815             }
4816              
4817 0         0 # $$foo
4818 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4819             $slash = 'div';
4820             return e_capture($1);
4821             }
4822              
4823 0         0 # ${ foo }
4824 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
4825             $slash = 'div';
4826             return '${' . $1 . '}';
4827             }
4828              
4829 0         0 # ${ ... }
4830 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4831             $slash = 'div';
4832             return e_capture($1);
4833             }
4834              
4835             # variable or function
4836 0         0 # $ @ % & * $ #
4837 27         41 elsif (/\G ( (?: [\$\@\%\&\*] | \$\# | -> | \b sub \b) (?>\s*) (?: split | chop | index | rindex | lc | uc | fc | chr | ord | reverse | getc | tr | y | q | qq | qx | qw | m | s | qr | glob | lstat | opendir | stat | unlink | chdir ) ) \b /oxmsgc) {
4838             $slash = 'div';
4839             return $1;
4840             }
4841             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4842 27         86 # $ @ # \ ' " / ? ( ) [ ] < >
4843 90         182 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4844             $slash = 'div';
4845             return $1;
4846             }
4847              
4848 90         380 # while ()
4849             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
4850             return $1;
4851             }
4852              
4853             # while () --- glob
4854              
4855             # avoid "Error: Runtime exception" of perl version 5.005_03
4856 0         0  
4857             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^\x80-\xFF>\0\a\e\f\n\r\t]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])+?) > (?>\s*) \) \b /oxgc) {
4858             return 'while ($_ = Eutf2::glob("' . $1 . '"))';
4859             }
4860              
4861 0         0 # while (glob)
4862             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
4863             return 'while ($_ = Eutf2::glob_)';
4864             }
4865              
4866 0         0 # while (glob(WILDCARD))
4867             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
4868             return 'while ($_ = Eutf2::glob';
4869             }
4870 0         0  
  401         857  
4871             # doit if, doit unless, doit while, doit until, doit for, doit when
4872             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
4873 401         1553  
  19         31  
4874 19         65 # subroutines of package Eutf2
  0         0  
4875 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         26  
4876 13         39 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
4877 0         0 elsif (/\G \b UTF2::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         205  
4878 114         360 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         5  
4879 2         5 elsif (/\G \b UTF2::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval UTF2::escape'; }
  2         3  
4880 2         6 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         5  
4881 2         6 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::chop'; }
  0         0  
4882 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  2         5  
4883 2         6 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  2         3  
4884 2         7 elsif (/\G \b UTF2::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'UTF2::index'; }
  2         3  
4885 2         7 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::index'; }
  0         0  
4886 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  2         4  
4887 2         5 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  2         3  
4888 2         6 elsif (/\G \b UTF2::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'UTF2::rindex'; }
  1         2  
4889 1         3 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::rindex'; }
  0         0  
4890 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eutf2::lc'; }
  0         0  
4891 0         0 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eutf2::lcfirst'; }
  0         0  
4892 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eutf2::uc'; }
  7         11  
4893             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eutf2::ucfirst'; }
4894             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eutf2::fc'; }
4895 7         22  
  0         0  
4896 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4897 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
4898 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
4899 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
4900 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
4901 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
4902             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
4903 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
4904 0         0  
  0         0  
4905 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
4906 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
4907 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
4908 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
4909 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
4910             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
4911             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
4912 0         0  
  0         0  
4913 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
4914 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
4915 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
4916             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
4917 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         3  
4918 2         7  
  2         3  
4919 2         7 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         61  
4920 36         106 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         4  
4921 2         7 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eutf2::chr'; }
  2         5  
4922 2         7 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
4923 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
4924 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eutf2::glob'; }
  0         0  
4925 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::lc_'; }
  0         0  
4926 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::lcfirst_'; }
  0         0  
4927 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::uc_'; }
  0         0  
4928 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::ucfirst_'; }
  0         0  
4929             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::fc_'; }
4930 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
4931 0         0  
  0         0  
4932 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
4933 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
4934 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::chr_'; }
  2         6  
4935 2         7 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
4936 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  4         8  
4937 4         14 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eutf2::glob_'; }
  8         17  
4938             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
4939             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
4940 8         27 # split
4941             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4942 120         236 $slash = 'm//';
4943 120         179  
4944 120         417 my $e = '';
4945             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4946             $e .= $1;
4947             }
4948 117 100       416  
  120 100       14057  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
4949             # end of split
4950             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Eutf2::split' . $e; }
4951 3         13  
4952             # split scalar value
4953             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Eutf2::split' . $e . e_string($1); }
4954 1         6  
4955 0         0 # split literal space
4956 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Eutf2::split' . $e . qq {qq$1 $2}; }
4957 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Eutf2::split' . $e . qq{$1qq$2 $3}; }
4958 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Eutf2::split' . $e . qq{$1qq$2 $3}; }
4959 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Eutf2::split' . $e . qq{$1qq$2 $3}; }
4960 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Eutf2::split' . $e . qq{$1qq$2 $3}; }
4961 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Eutf2::split' . $e . qq{$1qq$2 $3}; }
4962 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Eutf2::split' . $e . qq {q$1 $2}; }
4963 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Eutf2::split' . $e . qq {$1q$2 $3}; }
4964 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Eutf2::split' . $e . qq {$1q$2 $3}; }
4965 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Eutf2::split' . $e . qq {$1q$2 $3}; }
4966 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Eutf2::split' . $e . qq {$1q$2 $3}; }
4967 13         78 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Eutf2::split' . $e . qq {$1q$2 $3}; }
4968             elsif (/\G ' [ ] ' /oxgc) { return 'Eutf2::split' . $e . qq {' '}; }
4969             elsif (/\G " [ ] " /oxgc) { return 'Eutf2::split' . $e . qq {" "}; }
4970              
4971 2 0       9 # split qq//
  0         0  
4972             elsif (/\G \b (qq) \b /oxgc) {
4973 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
4974 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4975 0         0 while (not /\G \z/oxgc) {
4976 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
4977 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
4978 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
4979 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
4980 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
4981             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
4982 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
4983             }
4984             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4985             }
4986             }
4987              
4988 0 50       0 # split qr//
  12         766  
4989             elsif (/\G \b (qr) \b /oxgc) {
4990 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
4991 12 50       60 else {
  12 50       6383  
    50          
    50          
    50          
    50          
    50          
    50          
4992 0         0 while (not /\G \z/oxgc) {
4993 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
4994 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
4995 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
4996 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
4997 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
4998 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
4999             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
5000 12         79 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
5001             }
5002             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5003             }
5004             }
5005              
5006 0 0       0 # split q//
  0         0  
5007             elsif (/\G \b (q) \b /oxgc) {
5008 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
5009 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
5010 0         0 while (not /\G \z/oxgc) {
5011 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5012 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
5013 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
5014 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
5015 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
5016             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
5017 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
5018             }
5019             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5020             }
5021             }
5022              
5023 0 50       0 # split m//
  24         904  
5024             elsif (/\G \b (m) \b /oxgc) {
5025 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
5026 24 50       95 else {
  24 50       7663  
    50          
    50          
    50          
    50          
    50          
    50          
5027 0         0 while (not /\G \z/oxgc) {
5028 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5029 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
5030 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
5031 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
5032 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
5033 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
5034             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
5035 24         139 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
5036             }
5037             die __FILE__, ": Search pattern not terminated\n";
5038             }
5039             }
5040              
5041 0         0 # split ''
5042 0         0 elsif (/\G (\') /oxgc) {
5043 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
5044 0         0 while (not /\G \z/oxgc) {
5045 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5046 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
5047             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
5048 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5049             }
5050             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5051             }
5052              
5053 0         0 # split ""
5054 0         0 elsif (/\G (\") /oxgc) {
5055 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
5056 0         0 while (not /\G \z/oxgc) {
5057 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
5058 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
5059             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
5060 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
5061             }
5062             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5063             }
5064              
5065 0         0 # split //
5066 65         168 elsif (/\G (\/) /oxgc) {
5067 65 50       218 my $regexp = '';
  434 50       2804  
    100          
    50          
5068 0         0 while (not /\G \z/oxgc) {
5069 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
5070 65         269 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
5071             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
5072 369         832 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
5073             }
5074             die __FILE__, ": Search pattern not terminated\n";
5075             }
5076             }
5077              
5078             # tr/// or y///
5079              
5080             # about [cdsrbB]* (/B modifier)
5081             #
5082             # P.559 appendix C
5083             # of ISBN 4-89052-384-7 Programming perl
5084             # (Japanese title is: Perl puroguramingu)
5085 0         0  
5086             elsif (/\G \b ( tr | y ) \b /oxgc) {
5087             my $ope = $1;
5088 11 50       28  
5089 11         283 # $1 $2 $3 $4 $5 $6
5090 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
5091             my @tr = ($tr_variable,$2);
5092             return e_tr(@tr,'',$4,$6);
5093 0         0 }
5094 11         19 else {
5095 11 50       30 my $e = '';
  11 50       1592  
    50          
    50          
    50          
    50          
5096             while (not /\G \z/oxgc) {
5097 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5098 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
5099 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
5100 0         0 while (not /\G \z/oxgc) {
5101 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5102 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
5103 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
5104 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
5105             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
5106 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
5107             }
5108             die __FILE__, ": Transliteration replacement not terminated\n";
5109 0         0 }
5110 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
5111 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
5112 0         0 while (not /\G \z/oxgc) {
5113 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5114 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
5115 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
5116 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
5117             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
5118 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
5119             }
5120             die __FILE__, ": Transliteration replacement not terminated\n";
5121 0         0 }
5122 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
5123 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
5124 0         0 while (not /\G \z/oxgc) {
5125 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5126 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
5127 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
5128 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
5129             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
5130 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
5131             }
5132             die __FILE__, ": Transliteration replacement not terminated\n";
5133 0         0 }
5134 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
5135 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
5136 0         0 while (not /\G \z/oxgc) {
5137 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5138 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
5139 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
5140 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
5141             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
5142 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
5143             }
5144             die __FILE__, ": Transliteration replacement not terminated\n";
5145             }
5146 0         0 # $1 $2 $3 $4 $5 $6
5147 11         47 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
5148             my @tr = ($tr_variable,$2);
5149             return e_tr(@tr,'',$4,$6);
5150 11         33 }
5151             }
5152             die __FILE__, ": Transliteration pattern not terminated\n";
5153             }
5154             }
5155              
5156 0         0 # qq//
5157             elsif (/\G \b (qq) \b /oxgc) {
5158             my $ope = $1;
5159 3822 100       15347  
5160 3822         7310 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
5161 40         52 if (/\G (\#) /oxgc) { # qq# #
5162 40 100       85 my $qq_string = '';
  1948 50       6855  
    100          
    50          
5163 80         148 while (not /\G \z/oxgc) {
5164 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
5165 40         81 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
5166             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
5167 1828         3713 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5168             }
5169             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5170             }
5171 0         0  
5172 3782         4739 else {
5173 3782 50       8720 my $e = '';
  3782 50       13130  
    100          
    50          
    100          
    50          
5174             while (not /\G \z/oxgc) {
5175             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5176              
5177 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
5178 0         0 elsif (/\G (\() /oxgc) { # qq ( )
5179 0         0 my $qq_string = '';
5180 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
5181 0         0 while (not /\G \z/oxgc) {
5182 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
5183             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
5184 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
5185 0         0 elsif (/\G (\)) /oxgc) {
5186             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
5187 0         0 else { $qq_string .= $1; }
5188             }
5189 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5190             }
5191             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5192             }
5193              
5194 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
5195 3724         4857 elsif (/\G (\{) /oxgc) { # qq { }
5196 3724         4985 my $qq_string = '';
5197 3724 100       7288 local $nest = 1;
  155735 50       526713  
    100          
    100          
    50          
5198 792         1504 while (not /\G \z/oxgc) {
5199 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1384         1847  
5200             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
5201 1384 100       2422 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  5108         7390  
5202 3724         7075 elsif (/\G (\}) /oxgc) {
5203             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
5204 1384         2740 else { $qq_string .= $1; }
5205             }
5206 148451         278966 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5207             }
5208             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5209             }
5210              
5211 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
5212 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
5213 0         0 my $qq_string = '';
5214 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
5215 0         0 while (not /\G \z/oxgc) {
5216 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
5217             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
5218 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
5219 0         0 elsif (/\G (\]) /oxgc) {
5220             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
5221 0         0 else { $qq_string .= $1; }
5222             }
5223 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5224             }
5225             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5226             }
5227              
5228 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
5229 38         60 elsif (/\G (\<) /oxgc) { # qq < >
5230 38         72 my $qq_string = '';
5231 38 100       156 local $nest = 1;
  1418 50       7588  
    50          
    100          
    50          
5232 22         52 while (not /\G \z/oxgc) {
5233 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
5234             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
5235 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  38         92  
5236 38         102 elsif (/\G (\>) /oxgc) {
5237             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
5238 0         0 else { $qq_string .= $1; }
5239             }
5240 1358         2927 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5241             }
5242             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5243             }
5244              
5245 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
5246 20         30 elsif (/\G (\S) /oxgc) { # qq * *
5247 20         21 my $delimiter = $1;
5248 20 50       41 my $qq_string = '';
  840 50       2610  
    100          
    50          
5249 0         0 while (not /\G \z/oxgc) {
5250 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
5251 20         38 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
5252             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
5253 820         1527 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5254             }
5255             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5256 0         0 }
5257             }
5258             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5259             }
5260             }
5261              
5262 0         0 # qr//
5263 36 50       84 elsif (/\G \b (qr) \b /oxgc) {
5264 36         444 my $ope = $1;
5265             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
5266             return e_qr($ope,$1,$3,$2,$4);
5267 0         0 }
5268 36         61 else {
5269 36 50       99 my $e = '';
  36 50       17246  
    100          
    50          
    50          
    100          
    50          
    50          
5270 0         0 while (not /\G \z/oxgc) {
5271 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5272 1         7 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
5273 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
5274 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
5275 2         13 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
5276 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
5277             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
5278 33         132 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
5279             }
5280             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5281             }
5282             }
5283              
5284 0         0 # qw//
5285 34 50       88 elsif (/\G \b (qw) \b /oxgc) {
5286 34         401 my $ope = $1;
5287             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
5288             return e_qw($ope,$1,$3,$2);
5289 0         0 }
5290 34         65 else {
5291 34 50       102 my $e = '';
  34 50       190  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5292             while (not /\G \z/oxgc) {
5293 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5294 34         141  
5295             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
5296 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
5297 0         0  
5298             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
5299 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
5300 0         0  
5301             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
5302 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
5303 0         0  
5304             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
5305 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
5306 0         0  
5307             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
5308 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
5309             }
5310             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5311             }
5312             }
5313              
5314 0         0 # qx//
5315 2 50       7 elsif (/\G \b (qx) \b /oxgc) {
5316 2         75 my $ope = $1;
5317             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
5318             return e_qq($ope,$1,$3,$2);
5319 0         0 }
5320 2         7 else {
5321 2 50       9 my $e = '';
  2 50       223  
    50          
    0          
    0          
    0          
    0          
5322 0         0 while (not /\G \z/oxgc) {
5323 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5324 2         9 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
5325 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
5326 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
5327 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
5328             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
5329 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
5330             }
5331             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5332             }
5333             }
5334              
5335 0         0 # q//
5336             elsif (/\G \b (q) \b /oxgc) {
5337             my $ope = $1;
5338              
5339             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
5340              
5341             # avoid "Error: Runtime exception" of perl version 5.005_03
5342 527 50       1702 # (and so on)
5343 527         1494  
5344 0         0 if (/\G (\#) /oxgc) { # q# #
5345 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
5346 0         0 while (not /\G \z/oxgc) {
5347 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5348 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
5349             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
5350 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5351             }
5352             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5353             }
5354 0         0  
5355 527         937 else {
5356 527 50       1659 my $e = '';
  527 50       2922  
    100          
    50          
    100          
    50          
5357             while (not /\G \z/oxgc) {
5358             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5359              
5360 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
5361 0         0 elsif (/\G (\() /oxgc) { # q ( )
5362 0         0 my $q_string = '';
5363 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
5364 0         0 while (not /\G \z/oxgc) {
5365 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5366 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
5367             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
5368 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
5369 0         0 elsif (/\G (\)) /oxgc) {
5370             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
5371 0         0 else { $q_string .= $1; }
5372             }
5373 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5374             }
5375             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5376             }
5377              
5378 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
5379 521         891 elsif (/\G (\{) /oxgc) { # q { }
5380 521         976 my $q_string = '';
5381 521 50       1436 local $nest = 1;
  8128 50       43547  
    50          
    100          
    100          
    50          
5382 0         0 while (not /\G \z/oxgc) {
5383 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5384 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  114         181  
5385             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
5386 114 100       223 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  635         1346  
5387 521         1582 elsif (/\G (\}) /oxgc) {
5388             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
5389 114         230 else { $q_string .= $1; }
5390             }
5391 7379         16515 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5392             }
5393             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5394             }
5395              
5396 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
5397 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
5398 0         0 my $q_string = '';
5399 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
5400 0         0 while (not /\G \z/oxgc) {
5401 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5402 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
5403             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
5404 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
5405 0         0 elsif (/\G (\]) /oxgc) {
5406             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
5407 0         0 else { $q_string .= $1; }
5408             }
5409 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5410             }
5411             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5412             }
5413              
5414 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
5415 5         14 elsif (/\G (\<) /oxgc) { # q < >
5416 5         11 my $q_string = '';
5417 5 50       19 local $nest = 1;
  82 50       549  
    50          
    50          
    100          
    50          
5418 0         0 while (not /\G \z/oxgc) {
5419 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5420 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
5421             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
5422 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         17  
5423 5         20 elsif (/\G (\>) /oxgc) {
5424             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
5425 0         0 else { $q_string .= $1; }
5426             }
5427 77         162 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5428             }
5429             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5430             }
5431              
5432 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
5433 1         3 elsif (/\G (\S) /oxgc) { # q * *
5434 1         1 my $delimiter = $1;
5435 1 50       3 my $q_string = '';
  14 50       97  
    100          
    50          
5436 0         0 while (not /\G \z/oxgc) {
5437 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5438 1         3 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
5439             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
5440 13         26 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5441             }
5442             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5443 0         0 }
5444             }
5445             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5446             }
5447             }
5448              
5449 0         0 # m//
5450 269 50       658 elsif (/\G \b (m) \b /oxgc) {
5451 269         2902 my $ope = $1;
5452             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
5453             return e_qr($ope,$1,$3,$2,$4);
5454 0         0 }
5455 269         424 else {
5456 269 50       687 my $e = '';
  269 50       25885  
    50          
    50          
    50          
    100          
    100          
    50          
    50          
5457 0         0 while (not /\G \z/oxgc) {
5458 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5459 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
5460 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
5461 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
5462 18         93 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
5463 13         48 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
5464 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
5465             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
5466 238         767 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
5467             }
5468             die __FILE__, ": Search pattern not terminated\n";
5469             }
5470             }
5471              
5472             # s///
5473              
5474             # about [cegimosxpradlunbB]* (/cg modifier)
5475             #
5476             # P.67 Pattern-Matching Operators
5477             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
5478 0         0  
5479             elsif (/\G \b (s) \b /oxgc) {
5480             my $ope = $1;
5481 132 100       371  
5482 132         6361 # $1 $2 $3 $4 $5 $6
5483             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
5484             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
5485 1         5 }
5486 131         273 else {
5487 131 50       556 my $e = '';
  131 50       50560  
    50          
    50          
    50          
    100          
    100          
    50          
    50          
5488             while (not /\G \z/oxgc) {
5489 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5490 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
5491 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5492             while (not /\G \z/oxgc) {
5493 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5494 0         0 # $1 $2 $3 $4
5495 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5496 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5497 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5498 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5499 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5500 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5501 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5502             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5503 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5504             }
5505             die __FILE__, ": Substitution replacement not terminated\n";
5506 0         0 }
5507 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
5508 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5509             while (not /\G \z/oxgc) {
5510 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5511 0         0 # $1 $2 $3 $4
5512 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5513 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5514 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5515 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5516 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5517 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5518 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5519             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5520 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5521             }
5522             die __FILE__, ": Substitution replacement not terminated\n";
5523 0         0 }
5524 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
5525 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
5526             while (not /\G \z/oxgc) {
5527 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5528 0         0 # $1 $2 $3 $4
5529 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5530 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5531 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5532 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5533 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5534             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5535 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5536             }
5537             die __FILE__, ": Substitution replacement not terminated\n";
5538 0         0 }
5539 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
5540 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5541             while (not /\G \z/oxgc) {
5542 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5543 0         0 # $1 $2 $3 $4
5544 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5545 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5546 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5547 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5548 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5549 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5550 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5551             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5552 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5553             }
5554             die __FILE__, ": Substitution replacement not terminated\n";
5555             }
5556 0         0 # $1 $2 $3 $4 $5 $6
5557             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
5558             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
5559             }
5560 22         66 # $1 $2 $3 $4 $5 $6
5561             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
5562             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
5563             }
5564 2         14 # $1 $2 $3 $4 $5 $6
5565             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
5566             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
5567             }
5568 0         0 # $1 $2 $3 $4 $5 $6
5569             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
5570             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
5571 107         541 }
5572             }
5573             die __FILE__, ": Substitution pattern not terminated\n";
5574             }
5575             }
5576 0         0  
5577 0         0 # require ignore module
5578 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
5579             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^\x80-\xFF#]) /oxmsgc) { return "# require$1\n$2"; }
5580             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
5581 0         0  
5582 43         356 # use strict; --> use strict; no strict qw(refs);
5583 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
5584             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^\x80-\xFF#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
5585             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
5586              
5587 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
5588 3         43 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
5589             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
5590             return "use $1; no strict qw(refs);";
5591 0         0 }
5592             else {
5593             return "use $1;";
5594             }
5595 3 0 0     20 }
      0        
5596 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
5597             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
5598             return "use $1; no strict qw(refs);";
5599 0         0 }
5600             else {
5601             return "use $1;";
5602             }
5603             }
5604 0         0  
5605 2         16 # ignore use module
5606 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
5607             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^\x80-\xFF#]) /oxmsgc) { return "# use$1\n$2"; }
5608             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
5609 0         0  
5610 0         0 # ignore no module
5611 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
5612             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^\x80-\xFF#]) /oxmsgc) { return "# no$1\n$2"; }
5613             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
5614 0         0  
5615             # use else
5616             elsif (/\G \b use \b /oxmsgc) { return "use"; }
5617 0         0  
5618             # use else
5619             elsif (/\G \b no \b /oxmsgc) { return "no"; }
5620              
5621 2         14 # ''
5622 1589         3019 elsif (/\G (?
5623 1589 100       3769 my $q_string = '';
  10558 100       41380  
    100          
    50          
5624 4         11 while (not /\G \z/oxgc) {
5625 48         95 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5626 1589         3378 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
5627             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
5628 8917         19388 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5629             }
5630             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5631             }
5632              
5633 0         0 # ""
5634 5587         10252 elsif (/\G (\") /oxgc) {
5635 5587 100       15810 my $qq_string = '';
  86921 100       275887  
    100          
    50          
5636 109         230 while (not /\G \z/oxgc) {
5637 12         21 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
5638 5587         11791 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
5639             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
5640 81213         157922 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
5641             }
5642             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5643             }
5644              
5645 0         0 # ``
5646 1         3 elsif (/\G (\`) /oxgc) {
5647 1 50       4 my $qx_string = '';
  19 50       105  
    100          
    50          
5648 0         0 while (not /\G \z/oxgc) {
5649 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
5650 1         3 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
5651             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
5652 18         38 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
5653             }
5654             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5655             }
5656              
5657 0         0 # // --- not divide operator (num / num), not defined-or
5658 1069         2079 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
5659 1069 100       2841 my $regexp = '';
  10235 50       53735  
    100          
    50          
5660 1         4 while (not /\G \z/oxgc) {
5661 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
5662 1069         2633 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
5663             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
5664 9165         19198 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
5665             }
5666             die __FILE__, ": Search pattern not terminated\n";
5667             }
5668              
5669 0         0 # ?? --- not conditional operator (condition ? then : else)
5670 18         35 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
5671 18 50       51 my $regexp = '';
  82 50       423  
    100          
    50          
5672 0         0 while (not /\G \z/oxgc) {
5673 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
5674 18         45 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
5675             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
5676 64         142 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
5677             }
5678             die __FILE__, ": Search pattern not terminated\n";
5679             }
5680 0         0  
  0         0  
5681             # <<>> (a safer ARGV)
5682             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
5683 0         0  
  0         0  
5684             # << (bit shift) --- not here document
5685             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
5686              
5687 0         0 # <<~'HEREDOC'
5688 6         12 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
5689 6         12 $slash = 'm//';
5690             my $here_quote = $1;
5691             my $delimiter = $2;
5692 6 50       10  
5693 6         23 # get here document
5694 6         26 if ($here_script eq '') {
5695             $here_script = CORE::substr $_, pos $_;
5696 6 50       32 $here_script =~ s/.*?\n//oxm;
5697 6         60 }
5698 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5699 6         7 my $heredoc = $1;
5700 6         43 my $indent = $2;
5701 6         16 $heredoc =~ s{^$indent}{}msg; # no /ox
5702             push @heredoc, $heredoc . qq{\n$delimiter\n};
5703             push @heredoc_delimiter, qq{\\s*$delimiter};
5704 6         10 }
5705             else {
5706 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5707             }
5708             return qq{<<'$delimiter'};
5709             }
5710              
5711             # <<~\HEREDOC
5712              
5713             # P.66 2.6.6. "Here" Documents
5714             # in Chapter 2: Bits and Pieces
5715             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5716              
5717             # P.73 "Here" Documents
5718             # in Chapter 2: Bits and Pieces
5719             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5720 6         26  
5721 3         5 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
5722 3         7 $slash = 'm//';
5723             my $here_quote = $1;
5724             my $delimiter = $2;
5725 3 50       5  
5726 3         7 # get here document
5727 3         12 if ($here_script eq '') {
5728             $here_script = CORE::substr $_, pos $_;
5729 3 50       15 $here_script =~ s/.*?\n//oxm;
5730 3         34 }
5731 3         6 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5732 3         5 my $heredoc = $1;
5733 3         32 my $indent = $2;
5734 3         9 $heredoc =~ s{^$indent}{}msg; # no /ox
5735             push @heredoc, $heredoc . qq{\n$delimiter\n};
5736             push @heredoc_delimiter, qq{\\s*$delimiter};
5737 3         6 }
5738             else {
5739 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5740             }
5741             return qq{<<\\$delimiter};
5742             }
5743              
5744 3         12 # <<~"HEREDOC"
5745 6         11 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
5746 6         11 $slash = 'm//';
5747             my $here_quote = $1;
5748             my $delimiter = $2;
5749 6 50       9  
5750 6         12 # get here document
5751 6         29 if ($here_script eq '') {
5752             $here_script = CORE::substr $_, pos $_;
5753 6 50       29 $here_script =~ s/.*?\n//oxm;
5754 6         53 }
5755 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5756 6         9 my $heredoc = $1;
5757 6         43 my $indent = $2;
5758 6         22 $heredoc =~ s{^$indent}{}msg; # no /ox
5759             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5760             push @heredoc_delimiter, qq{\\s*$delimiter};
5761 6         14 }
5762             else {
5763 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5764             }
5765             return qq{<<"$delimiter"};
5766             }
5767              
5768 6         20 # <<~HEREDOC
5769 3         6 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
5770 3         7 $slash = 'm//';
5771             my $here_quote = $1;
5772             my $delimiter = $2;
5773 3 50       7  
5774 3         8 # get here document
5775 3         14 if ($here_script eq '') {
5776             $here_script = CORE::substr $_, pos $_;
5777 3 50       15 $here_script =~ s/.*?\n//oxm;
5778 3         37 }
5779 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5780 3         5 my $heredoc = $1;
5781 3         36 my $indent = $2;
5782 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
5783             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5784             push @heredoc_delimiter, qq{\\s*$delimiter};
5785 3         8 }
5786             else {
5787 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5788             }
5789             return qq{<<$delimiter};
5790             }
5791              
5792 3         12 # <<~`HEREDOC`
5793 6         11 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
5794 6         20 $slash = 'm//';
5795             my $here_quote = $1;
5796             my $delimiter = $2;
5797 6 50       10  
5798 6         16 # get here document
5799 6         22 if ($here_script eq '') {
5800             $here_script = CORE::substr $_, pos $_;
5801 6 50       29 $here_script =~ s/.*?\n//oxm;
5802 6         50 }
5803 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5804 6         7 my $heredoc = $1;
5805 6         45 my $indent = $2;
5806 6         14 $heredoc =~ s{^$indent}{}msg; # no /ox
5807             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5808             push @heredoc_delimiter, qq{\\s*$delimiter};
5809 6         13 }
5810             else {
5811 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5812             }
5813             return qq{<<`$delimiter`};
5814             }
5815              
5816 6         23 # <<'HEREDOC'
5817 80         167 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
5818 80         160 $slash = 'm//';
5819             my $here_quote = $1;
5820             my $delimiter = $2;
5821 80 100       134  
5822 80         155 # get here document
5823 77         389 if ($here_script eq '') {
5824             $here_script = CORE::substr $_, pos $_;
5825 77 50       422 $here_script =~ s/.*?\n//oxm;
5826 80         655 }
5827 80         272 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5828             push @heredoc, $1 . qq{\n$delimiter\n};
5829             push @heredoc_delimiter, $delimiter;
5830 80         147 }
5831             else {
5832 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5833             }
5834             return $here_quote;
5835             }
5836              
5837             # <<\HEREDOC
5838              
5839             # P.66 2.6.6. "Here" Documents
5840             # in Chapter 2: Bits and Pieces
5841             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5842              
5843             # P.73 "Here" Documents
5844             # in Chapter 2: Bits and Pieces
5845             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5846 80         331  
5847 2         5 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5848 2         5 $slash = 'm//';
5849             my $here_quote = $1;
5850             my $delimiter = $2;
5851 2 100       3  
5852 2         6 # get here document
5853 1         6 if ($here_script eq '') {
5854             $here_script = CORE::substr $_, pos $_;
5855 1 50       6 $here_script =~ s/.*?\n//oxm;
5856 2         35 }
5857 2         8 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5858             push @heredoc, $1 . qq{\n$delimiter\n};
5859             push @heredoc_delimiter, $delimiter;
5860 2         6 }
5861             else {
5862 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5863             }
5864             return $here_quote;
5865             }
5866              
5867 2         9 # <<"HEREDOC"
5868 39         101 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5869 39         94 $slash = 'm//';
5870             my $here_quote = $1;
5871             my $delimiter = $2;
5872 39 100       74  
5873 39         104 # get here document
5874 38         210 if ($here_script eq '') {
5875             $here_script = CORE::substr $_, pos $_;
5876 38 50       220 $here_script =~ s/.*?\n//oxm;
5877 39         454 }
5878 39         123 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5879             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5880             push @heredoc_delimiter, $delimiter;
5881 39         96 }
5882             else {
5883 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5884             }
5885             return $here_quote;
5886             }
5887              
5888 39         169 # <
5889 54         126 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5890 54         124 $slash = 'm//';
5891             my $here_quote = $1;
5892             my $delimiter = $2;
5893 54 100       92  
5894 54         150 # get here document
5895 51         320 if ($here_script eq '') {
5896             $here_script = CORE::substr $_, pos $_;
5897 51 50       379 $here_script =~ s/.*?\n//oxm;
5898 54         1059 }
5899 54         176 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5900             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5901             push @heredoc_delimiter, $delimiter;
5902 54         127 }
5903             else {
5904 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5905             }
5906             return $here_quote;
5907             }
5908              
5909 54         228 # <<`HEREDOC`
5910 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5911 0         0 $slash = 'm//';
5912             my $here_quote = $1;
5913             my $delimiter = $2;
5914 0 0       0  
5915 0         0 # get here document
5916 0         0 if ($here_script eq '') {
5917             $here_script = CORE::substr $_, pos $_;
5918 0 0       0 $here_script =~ s/.*?\n//oxm;
5919 0         0 }
5920 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5921             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5922             push @heredoc_delimiter, $delimiter;
5923 0         0 }
5924             else {
5925 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5926             }
5927             return $here_quote;
5928             }
5929              
5930 0         0 # <<= <=> <= < operator
5931             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
5932             return $1;
5933             }
5934              
5935 12         66 #
5936             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
5937             return $1;
5938             }
5939              
5940             # --- glob
5941              
5942             # avoid "Error: Runtime exception" of perl version 5.005_03
5943 0         0  
5944             elsif (/\G < ((?:[^\x80-\xFF>\0\a\e\f\n\r\t]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF])+?) > /oxgc) {
5945             return 'Eutf2::glob("' . $1 . '")';
5946             }
5947 0         0  
5948             # __DATA__
5949             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
5950 0         0  
5951             # __END__
5952             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
5953              
5954             # \cD Control-D
5955              
5956             # P.68 2.6.8. Other Literal Tokens
5957             # in Chapter 2: Bits and Pieces
5958             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5959              
5960             # P.76 Other Literal Tokens
5961             # in Chapter 2: Bits and Pieces
5962 306         2048 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5963              
5964             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
5965 0         0  
5966             # \cZ Control-Z
5967             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
5968              
5969             # any operator before div
5970             elsif (/\G (
5971             -- | \+\+ |
5972 0         0 [\)\}\]]
  8556         17132  
5973              
5974             ) /oxgc) { $slash = 'div'; return $1; }
5975              
5976             # yada-yada or triple-dot operator
5977             elsif (/\G (
5978 8556         37905 \.\.\.
  7         11  
5979              
5980             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
5981              
5982             # any operator before m//
5983              
5984             # //, //= (defined-or)
5985              
5986             # P.164 Logical Operators
5987             # in Chapter 10: More Control Structures
5988             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
5989              
5990             # P.119 C-Style Logical (Short-Circuit) Operators
5991             # in Chapter 3: Unary and Binary Operators
5992             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5993              
5994             # (and so on)
5995              
5996             # ~~
5997              
5998             # P.221 The Smart Match Operator
5999             # in Chapter 15: Smart Matching and given-when
6000             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6001              
6002             # P.112 Smartmatch Operator
6003             # in Chapter 3: Unary and Binary Operators
6004             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6005              
6006             # (and so on)
6007              
6008             elsif (/\G ((?>
6009              
6010             !~~ | !~ | != | ! |
6011             %= | % |
6012             &&= | && | &= | &\.= | &\. | & |
6013             -= | -> | - |
6014             :(?>\s*)= |
6015             : |
6016             <<>> |
6017             <<= | <=> | <= | < |
6018             == | => | =~ | = |
6019             >>= | >> | >= | > |
6020             \*\*= | \*\* | \*= | \* |
6021             \+= | \+ |
6022             \.\. | \.= | \. |
6023             \/\/= | \/\/ |
6024             \/= | \/ |
6025             \? |
6026             \\ |
6027             \^= | \^\.= | \^\. | \^ |
6028             \b x= |
6029             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
6030             ~~ | ~\. | ~ |
6031             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
6032             \b(?: print )\b |
6033              
6034 7         23 [,;\(\{\[]
  16324         30225  
6035              
6036             )) /oxgc) { $slash = 'm//'; return $1; }
6037 16324         69504  
  23499         42625  
6038             # other any character
6039             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
6040              
6041 23499         118717 # system error
6042             else {
6043             die __FILE__, ": Oops, this shouldn't happen!\n";
6044             }
6045             }
6046              
6047 0     2512 0 0 # escape UTF-8 string
6048 2512         5543 sub e_string {
6049             my($string) = @_;
6050 2512         3696 my $e_string = '';
6051              
6052             local $slash = 'm//';
6053              
6054             # P.1024 Appendix W.10 Multibyte Processing
6055             # of ISBN 1-56592-224-7 CJKV Information Processing
6056 2512         3513 # (and so on)
6057              
6058             my @char = $string =~ / \G (?>[^\x80-\xFF\\]|\\$q_char|$q_char) /oxmsg;
6059 2512 100 66     35769  
6060 2512 50       11242 # without { ... }
6061 2473         5046 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
6062             if ($string !~ /<
6063             return $string;
6064             }
6065             }
6066 2473         5960  
6067 39 50       126 E_STRING_LOOP:
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
6068             while ($string !~ /\G \z/oxgc) {
6069             if (0) {
6070             }
6071 293         27418  
6072 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Eutf2::PREMATCH()]}
6073 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
6074             $e_string .= q{Eutf2::PREMATCH()};
6075             $slash = 'div';
6076             }
6077              
6078 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Eutf2::MATCH()]}
6079 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
6080             $e_string .= q{Eutf2::MATCH()};
6081             $slash = 'div';
6082             }
6083              
6084 0         0 # $', ${'} --> $', ${'}
6085 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
6086             $e_string .= $1;
6087             $slash = 'div';
6088             }
6089              
6090 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Eutf2::POSTMATCH()]}
6091 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
6092             $e_string .= q{Eutf2::POSTMATCH()};
6093             $slash = 'div';
6094             }
6095              
6096 0         0 # bareword
6097 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
6098             $e_string .= $1;
6099             $slash = 'div';
6100             }
6101              
6102 0         0 # $0 --> $0
6103 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
6104             $e_string .= $1;
6105             $slash = 'div';
6106 0         0 }
6107 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
6108             $e_string .= $1;
6109             $slash = 'div';
6110             }
6111              
6112 0         0 # $$ --> $$
6113 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
6114             $e_string .= $1;
6115             $slash = 'div';
6116             }
6117              
6118             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6119 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6120 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
6121             $e_string .= e_capture($1);
6122             $slash = 'div';
6123 0         0 }
6124 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
6125             $e_string .= e_capture($1);
6126             $slash = 'div';
6127             }
6128              
6129 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6130 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
6131             $e_string .= e_capture($1.'->'.$2);
6132             $slash = 'div';
6133             }
6134              
6135 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6136 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
6137             $e_string .= e_capture($1.'->'.$2);
6138             $slash = 'div';
6139             }
6140              
6141 0         0 # $$foo
6142 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
6143             $e_string .= e_capture($1);
6144             $slash = 'div';
6145             }
6146              
6147 0         0 # ${ foo }
6148 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
6149             $e_string .= '${' . $1 . '}';
6150             $slash = 'div';
6151             }
6152              
6153 0         0 # ${ ... }
6154 3         21 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
6155             $e_string .= e_capture($1);
6156             $slash = 'div';
6157             }
6158              
6159             # variable or function
6160 3         24 # $ @ % & * $ #
6161 1         4 elsif ($string =~ /\G ( (?: [\$\@\%\&\*] | \$\# | -> | \b sub \b) (?>\s*) (?: split | chop | index | rindex | lc | uc | fc | chr | ord | reverse | getc | tr | y | q | qq | qx | qw | m | s | qr | glob | lstat | opendir | stat | unlink | chdir ) ) \b /oxmsgc) {
6162             $e_string .= $1;
6163             $slash = 'div';
6164             }
6165             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
6166 1         7 # $ @ # \ ' " / ? ( ) [ ] < >
6167 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
6168             $e_string .= $1;
6169             $slash = 'div';
6170             }
6171 0         0  
  0         0  
6172 0         0 # subroutines of package Eutf2
  0         0  
6173 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
6174 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
6175 0         0 elsif ($string =~ /\G \b UTF2::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
6176 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
6177 0         0 elsif ($string =~ /\G \b UTF2::eval \b /oxgc) { $e_string .= 'eval UTF2::escape'; $slash = 'm//'; }
  0         0  
6178 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
6179 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Eutf2::chop'; $slash = 'm//'; }
  0         0  
6180 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
6181 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
6182 0         0 elsif ($string =~ /\G \b UTF2::index \b /oxgc) { $e_string .= 'UTF2::index'; $slash = 'm//'; }
  0         0  
6183 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Eutf2::index'; $slash = 'm//'; }
  0         0  
6184 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
6185 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
6186 0         0 elsif ($string =~ /\G \b UTF2::rindex \b /oxgc) { $e_string .= 'UTF2::rindex'; $slash = 'm//'; }
  0         0  
6187 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Eutf2::rindex'; $slash = 'm//'; }
  0         0  
6188 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eutf2::lc'; $slash = 'm//'; }
  0         0  
6189 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eutf2::lcfirst'; $slash = 'm//'; }
  0         0  
6190 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eutf2::uc'; $slash = 'm//'; }
  0         0  
6191             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eutf2::ucfirst'; $slash = 'm//'; }
6192             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eutf2::fc'; $slash = 'm//'; }
6193 0         0  
  0         0  
6194 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
6195 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
6196 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
6197 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
6198 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
6199 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
6200             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
6201 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
6202 0         0  
  0         0  
6203 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
6204 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
6205 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
6206 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
6207 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
6208             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
6209             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
6210 0         0  
  0         0  
6211 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
6212 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
6213 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
6214             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
6215 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
6216 0         0  
  0         0  
6217 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
6218 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
6219 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eutf2::chr'; $slash = 'm//'; }
  0         0  
6220 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
6221 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
6222 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eutf2::glob'; $slash = 'm//'; }
  0         0  
6223 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Eutf2::lc_'; $slash = 'm//'; }
  0         0  
6224 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Eutf2::lcfirst_'; $slash = 'm//'; }
  0         0  
6225 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Eutf2::uc_'; $slash = 'm//'; }
  0         0  
6226 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Eutf2::ucfirst_'; $slash = 'm//'; }
  0         0  
6227             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Eutf2::fc_'; $slash = 'm//'; }
6228 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
6229 0         0  
  0         0  
6230 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
6231 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
6232 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Eutf2::chr_'; $slash = 'm//'; }
  0         0  
6233 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
6234 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
6235 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Eutf2::glob_'; $slash = 'm//'; }
  0         0  
6236             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
6237             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
6238 0         0 # split
6239             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
6240 0         0 $slash = 'm//';
6241 0         0  
6242 0         0 my $e = '';
6243             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
6244             $e .= $1;
6245             }
6246 0 0       0  
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
6247             # end of split
6248             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Eutf2::split' . $e; }
6249 0         0  
  0         0  
6250             # split scalar value
6251             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Eutf2::split' . $e . e_string($1); next E_STRING_LOOP; }
6252 0         0  
  0         0  
6253 0         0 # split literal space
  0         0  
6254 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
6255 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6256 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6257 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6258 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6259 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6260 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
6261 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6262 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6263 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6264 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6265 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Eutf2::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6266             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Eutf2::split' . $e . qq {' '}; next E_STRING_LOOP; }
6267             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Eutf2::split' . $e . qq {" "}; next E_STRING_LOOP; }
6268              
6269 0 0       0 # split qq//
  0         0  
  0         0  
6270             elsif ($string =~ /\G \b (qq) \b /oxgc) {
6271 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
6272 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6273 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6274 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
6275 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq ( ) --> qr ( )
  0         0  
6276 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq { } --> qr { }
  0         0  
6277 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq [ ] --> qr [ ]
  0         0  
6278 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq < > --> qr < >
  0         0  
6279             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
6280 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq * * --> qr * *
6281             }
6282             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6283             }
6284             }
6285              
6286 0 0       0 # split qr//
  0         0  
  0         0  
6287             elsif ($string =~ /\G \b (qr) \b /oxgc) {
6288 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
6289 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
6290 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6291 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
6292 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ( )
  0         0  
6293 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr { }
  0         0  
6294 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr [ ]
  0         0  
6295 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr < >
  0         0  
6296 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ' '
  0         0  
6297             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
6298 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr * *
6299             }
6300             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6301             }
6302             }
6303              
6304 0 0       0 # split q//
  0         0  
  0         0  
6305             elsif ($string =~ /\G \b (q) \b /oxgc) {
6306 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
6307 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6308 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6309 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
6310 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q ( ) --> qr ( )
  0         0  
6311 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q { } --> qr { }
  0         0  
6312 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q [ ] --> qr [ ]
  0         0  
6313 0         0 elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q < > --> qr < >
  0         0  
6314             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
6315 0         0 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q * * --> qr * *
6316             }
6317             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6318             }
6319             }
6320              
6321 0 0       0 # split m//
  0         0  
  0         0  
6322             elsif ($string =~ /\G \b (m) \b /oxgc) {
6323 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # m# # --> qr # #
6324 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
6325 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6326 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
6327 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ( ) --> qr ( )
  0         0  
6328 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m { } --> qr { }
  0         0  
6329 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m [ ] --> qr [ ]
  0         0  
6330 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m < > --> qr < >
  0         0  
6331 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ' ' --> qr ' '
  0         0  
6332             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
6333 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m * * --> qr * *
6334             }
6335             die __FILE__, ": Search pattern not terminated\n";
6336             }
6337             }
6338              
6339 0         0 # split ''
6340 0         0 elsif ($string =~ /\G (\') /oxgc) {
6341 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
6342 0         0 while ($string !~ /\G \z/oxgc) {
6343 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
6344 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
6345             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
6346 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
6347             }
6348             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6349             }
6350              
6351 0         0 # split ""
6352 0         0 elsif ($string =~ /\G (\") /oxgc) {
6353 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
6354 0         0 while ($string !~ /\G \z/oxgc) {
6355 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
6356 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
6357             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
6358 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
6359             }
6360             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6361             }
6362              
6363 0         0 # split //
6364 0         0 elsif ($string =~ /\G (\/) /oxgc) {
6365 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
6366 0         0 while ($string !~ /\G \z/oxgc) {
6367 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
6368 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
6369             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
6370 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
6371             }
6372             die __FILE__, ": Search pattern not terminated\n";
6373             }
6374             }
6375              
6376 0         0 # qq//
6377 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
6378 0         0 my $ope = $1;
6379             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
6380             $e_string .= e_qq($ope,$1,$3,$2);
6381 0         0 }
6382 0         0 else {
6383 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
6384 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6385 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
6386 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
6387 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
6388 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
6389             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
6390 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
6391             }
6392             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6393             }
6394             }
6395              
6396 0         0 # qx//
6397 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
6398 0         0 my $ope = $1;
6399             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
6400             $e_string .= e_qq($ope,$1,$3,$2);
6401 0         0 }
6402 0         0 else {
6403 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6404 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6405 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
6406 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
6407 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
6408 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
6409 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
6410             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
6411 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
6412             }
6413             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6414             }
6415             }
6416              
6417 0         0 # q//
6418 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
6419 0         0 my $ope = $1;
6420             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
6421             $e_string .= e_q($ope,$1,$3,$2);
6422 0         0 }
6423 0         0 else {
6424 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
6425 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6426 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
6427 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
6428 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
6429 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
6430             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
6431 0         0 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q * *
6432             }
6433             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6434             }
6435             }
6436 0         0  
6437             # ''
6438             elsif ($string =~ /\G (?
6439 12         43  
6440             # ""
6441             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
6442 6         23  
6443             # ``
6444             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
6445 0         0  
6446             # <<>> (a safer ARGV)
6447             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
6448 0         0  
6449             # <<= <=> <= < operator
6450             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
6451 0         0  
6452             #
6453             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
6454              
6455 0         0 # --- glob
6456             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
6457             $e_string .= 'Eutf2::glob("' . $1 . '")';
6458             }
6459              
6460 0         0 # << (bit shift) --- not here document
6461 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
6462             $slash = 'm//';
6463             $e_string .= $1;
6464             }
6465              
6466 0         0 # <<~'HEREDOC'
6467 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
6468 0         0 $slash = 'm//';
6469             my $here_quote = $1;
6470             my $delimiter = $2;
6471 0 0       0  
6472 0         0 # get here document
6473 0         0 if ($here_script eq '') {
6474             $here_script = CORE::substr $_, pos $_;
6475 0 0       0 $here_script =~ s/.*?\n//oxm;
6476 0         0 }
6477 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6478 0         0 my $heredoc = $1;
6479 0         0 my $indent = $2;
6480 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6481             push @heredoc, $heredoc . qq{\n$delimiter\n};
6482             push @heredoc_delimiter, qq{\\s*$delimiter};
6483 0         0 }
6484             else {
6485 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6486             }
6487             $e_string .= qq{<<'$delimiter'};
6488             }
6489              
6490 0         0 # <<~\HEREDOC
6491 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
6492 0         0 $slash = 'm//';
6493             my $here_quote = $1;
6494             my $delimiter = $2;
6495 0 0       0  
6496 0         0 # get here document
6497 0         0 if ($here_script eq '') {
6498             $here_script = CORE::substr $_, pos $_;
6499 0 0       0 $here_script =~ s/.*?\n//oxm;
6500 0         0 }
6501 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6502 0         0 my $heredoc = $1;
6503 0         0 my $indent = $2;
6504 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6505             push @heredoc, $heredoc . qq{\n$delimiter\n};
6506             push @heredoc_delimiter, qq{\\s*$delimiter};
6507 0         0 }
6508             else {
6509 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6510             }
6511             $e_string .= qq{<<\\$delimiter};
6512             }
6513              
6514 0         0 # <<~"HEREDOC"
6515 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
6516 0         0 $slash = 'm//';
6517             my $here_quote = $1;
6518             my $delimiter = $2;
6519 0 0       0  
6520 0         0 # get here document
6521 0         0 if ($here_script eq '') {
6522             $here_script = CORE::substr $_, pos $_;
6523 0 0       0 $here_script =~ s/.*?\n//oxm;
6524 0         0 }
6525 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6526 0         0 my $heredoc = $1;
6527 0         0 my $indent = $2;
6528 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6529             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
6530             push @heredoc_delimiter, qq{\\s*$delimiter};
6531 0         0 }
6532             else {
6533 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6534             }
6535             $e_string .= qq{<<"$delimiter"};
6536             }
6537              
6538 0         0 # <<~HEREDOC
6539 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
6540 0         0 $slash = 'm//';
6541             my $here_quote = $1;
6542             my $delimiter = $2;
6543 0 0       0  
6544 0         0 # get here document
6545 0         0 if ($here_script eq '') {
6546             $here_script = CORE::substr $_, pos $_;
6547 0 0       0 $here_script =~ s/.*?\n//oxm;
6548 0         0 }
6549 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6550 0         0 my $heredoc = $1;
6551 0         0 my $indent = $2;
6552 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6553             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
6554             push @heredoc_delimiter, qq{\\s*$delimiter};
6555 0         0 }
6556             else {
6557 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6558             }
6559             $e_string .= qq{<<$delimiter};
6560             }
6561              
6562 0         0 # <<~`HEREDOC`
6563 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
6564 0         0 $slash = 'm//';
6565             my $here_quote = $1;
6566             my $delimiter = $2;
6567 0 0       0  
6568 0         0 # get here document
6569 0         0 if ($here_script eq '') {
6570             $here_script = CORE::substr $_, pos $_;
6571 0 0       0 $here_script =~ s/.*?\n//oxm;
6572 0         0 }
6573 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6574 0         0 my $heredoc = $1;
6575 0         0 my $indent = $2;
6576 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6577             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
6578             push @heredoc_delimiter, qq{\\s*$delimiter};
6579 0         0 }
6580             else {
6581 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6582             }
6583             $e_string .= qq{<<`$delimiter`};
6584             }
6585              
6586 0         0 # <<'HEREDOC'
6587 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
6588 0         0 $slash = 'm//';
6589             my $here_quote = $1;
6590             my $delimiter = $2;
6591 0 0       0  
6592 0         0 # get here document
6593 0         0 if ($here_script eq '') {
6594             $here_script = CORE::substr $_, pos $_;
6595 0 0       0 $here_script =~ s/.*?\n//oxm;
6596 0         0 }
6597 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6598             push @heredoc, $1 . qq{\n$delimiter\n};
6599             push @heredoc_delimiter, $delimiter;
6600 0         0 }
6601             else {
6602 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6603             }
6604             $e_string .= $here_quote;
6605             }
6606              
6607 0         0 # <<\HEREDOC
6608 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
6609 0         0 $slash = 'm//';
6610             my $here_quote = $1;
6611             my $delimiter = $2;
6612 0 0       0  
6613 0         0 # get here document
6614 0         0 if ($here_script eq '') {
6615             $here_script = CORE::substr $_, pos $_;
6616 0 0       0 $here_script =~ s/.*?\n//oxm;
6617 0         0 }
6618 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6619             push @heredoc, $1 . qq{\n$delimiter\n};
6620             push @heredoc_delimiter, $delimiter;
6621 0         0 }
6622             else {
6623 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6624             }
6625             $e_string .= $here_quote;
6626             }
6627              
6628 0         0 # <<"HEREDOC"
6629 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
6630 0         0 $slash = 'm//';
6631             my $here_quote = $1;
6632             my $delimiter = $2;
6633 0 0       0  
6634 0         0 # get here document
6635 0         0 if ($here_script eq '') {
6636             $here_script = CORE::substr $_, pos $_;
6637 0 0       0 $here_script =~ s/.*?\n//oxm;
6638 0         0 }
6639 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6640             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
6641             push @heredoc_delimiter, $delimiter;
6642 0         0 }
6643             else {
6644 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6645             }
6646             $e_string .= $here_quote;
6647             }
6648              
6649 0         0 # <
6650 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
6651 0         0 $slash = 'm//';
6652             my $here_quote = $1;
6653             my $delimiter = $2;
6654 0 0       0  
6655 0         0 # get here document
6656 0         0 if ($here_script eq '') {
6657             $here_script = CORE::substr $_, pos $_;
6658 0 0       0 $here_script =~ s/.*?\n//oxm;
6659 0         0 }
6660 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6661             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
6662             push @heredoc_delimiter, $delimiter;
6663 0         0 }
6664             else {
6665 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6666             }
6667             $e_string .= $here_quote;
6668             }
6669              
6670 0         0 # <<`HEREDOC`
6671 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
6672 0         0 $slash = 'm//';
6673             my $here_quote = $1;
6674             my $delimiter = $2;
6675 0 0       0  
6676 0         0 # get here document
6677 0         0 if ($here_script eq '') {
6678             $here_script = CORE::substr $_, pos $_;
6679 0 0       0 $here_script =~ s/.*?\n//oxm;
6680 0         0 }
6681 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6682             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
6683             push @heredoc_delimiter, $delimiter;
6684 0         0 }
6685             else {
6686 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6687             }
6688             $e_string .= $here_quote;
6689             }
6690              
6691             # any operator before div
6692             elsif ($string =~ /\G (
6693             -- | \+\+ |
6694 0         0 [\)\}\]]
  40         61  
6695              
6696             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
6697              
6698             # yada-yada or triple-dot operator
6699             elsif ($string =~ /\G (
6700 40         125 \.\.\.
  0         0  
6701              
6702             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
6703              
6704             # any operator before m//
6705             elsif ($string =~ /\G ((?>
6706              
6707             !~~ | !~ | != | ! |
6708             %= | % |
6709             &&= | && | &= | &\.= | &\. | & |
6710             -= | -> | - |
6711             :(?>\s*)= |
6712             : |
6713             <<>> |
6714             <<= | <=> | <= | < |
6715             == | => | =~ | = |
6716             >>= | >> | >= | > |
6717             \*\*= | \*\* | \*= | \* |
6718             \+= | \+ |
6719             \.\. | \.= | \. |
6720             \/\/= | \/\/ |
6721             \/= | \/ |
6722             \? |
6723             \\ |
6724             \^= | \^\.= | \^\. | \^ |
6725             \b x= |
6726             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
6727             ~~ | ~\. | ~ |
6728             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
6729             \b(?: print )\b |
6730              
6731 0         0 [,;\(\{\[]
  50         109  
6732              
6733             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
6734 50         205  
6735             # other any character
6736             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
6737              
6738 181         965 # system error
6739             else {
6740             die __FILE__, ": Oops, this shouldn't happen!\n";
6741             }
6742 0         0 }
6743              
6744             return $e_string;
6745             }
6746              
6747             #
6748             # character class
6749 39     2935 0 183 #
6750             sub character_class {
6751 2935 100       5654 my($char,$modifier) = @_;
6752 2935 100       4650  
6753 115         236 if ($char eq '.') {
6754             if ($modifier =~ /s/) {
6755             return '${Eutf2::dot_s}';
6756 23         58 }
6757             else {
6758             return '${Eutf2::dot}';
6759             }
6760 92         190 }
6761             else {
6762             return Eutf2::classic_character_class($char);
6763             }
6764             }
6765              
6766             #
6767             # escape capture ($1, $2, $3, ...)
6768             #
6769 2820     469 0 5495 sub e_capture {
6770              
6771             return join '', '${', $_[0], '}';
6772             }
6773              
6774             #
6775             # escape transliteration (tr/// or y///)
6776 469     11 0 2215 #
6777 11         65 sub e_tr {
6778 11   100     26 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
6779             my $e_tr = '';
6780 11         33 $modifier ||= '';
6781              
6782             $slash = 'div';
6783 11         16  
6784             # quote character class 1
6785             $charclass = q_tr($charclass);
6786 11         20  
6787             # quote character class 2
6788             $charclass2 = q_tr($charclass2);
6789 11 50       22  
6790 11 0       32 # /b /B modifier
6791 0         0 if ($modifier =~ tr/bB//d) {
6792             if ($variable eq '') {
6793             $e_tr = qq{tr$charclass$e$charclass2$modifier};
6794 0         0 }
6795             else {
6796             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
6797             }
6798 0 100       0 }
6799 11         31 else {
6800             if ($variable eq '') {
6801             $e_tr = qq{Eutf2::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
6802 2         7 }
6803             else {
6804             $e_tr = qq{Eutf2::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
6805             }
6806             }
6807 9         30  
6808 11         14 # clear tr/// variable
6809             $tr_variable = '';
6810 11         16 $bind_operator = '';
6811              
6812             return $e_tr;
6813             }
6814              
6815             #
6816             # quote for escape transliteration (tr/// or y///)
6817 11     22 0 101 #
6818             sub q_tr {
6819             my($charclass) = @_;
6820 22 50       36  
    0          
    0          
    0          
    0          
    0          
6821 22         41 # quote character class
6822             if ($charclass !~ /'/oxms) {
6823             return e_q('', "'", "'", $charclass); # --> q' '
6824 22         37 }
6825             elsif ($charclass !~ /\//oxms) {
6826             return e_q('q', '/', '/', $charclass); # --> q/ /
6827 0         0 }
6828             elsif ($charclass !~ /\#/oxms) {
6829             return e_q('q', '#', '#', $charclass); # --> q# #
6830 0         0 }
6831             elsif ($charclass !~ /[\<\>]/oxms) {
6832             return e_q('q', '<', '>', $charclass); # --> q< >
6833 0         0 }
6834             elsif ($charclass !~ /[\(\)]/oxms) {
6835             return e_q('q', '(', ')', $charclass); # --> q( )
6836 0         0 }
6837             elsif ($charclass !~ /[\{\}]/oxms) {
6838             return e_q('q', '{', '}', $charclass); # --> q{ }
6839 0         0 }
6840 0 0       0 else {
6841 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6842             if ($charclass !~ /\Q$char\E/xms) {
6843             return e_q('q', $char, $char, $charclass);
6844             }
6845             }
6846 0         0 }
6847              
6848             return e_q('q', '{', '}', $charclass);
6849             }
6850              
6851             #
6852             # escape q string (q//, '')
6853 0     2150 0 0 #
6854             sub e_q {
6855 2150         4908 my($ope,$delimiter,$end_delimiter,$string) = @_;
6856              
6857 2150         2838 $slash = 'div';
6858              
6859             return join '', $ope, $delimiter, $string, $end_delimiter;
6860             }
6861              
6862             #
6863             # escape qq string (qq//, "", qx//, ``)
6864 2150     9533 0 10022 #
6865             sub e_qq {
6866 9533         19950 my($ope,$delimiter,$end_delimiter,$string) = @_;
6867              
6868 9533         11402 $slash = 'div';
6869 9533         10441  
6870             my $left_e = 0;
6871             my $right_e = 0;
6872 9533         9962  
6873             # split regexp
6874             my @char = $string =~ /\G((?>
6875             [^\x80-\xFF\\\$]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
6876             \\x\{ (?>[0-9A-Fa-f]+) \} |
6877             \\o\{ (?>[0-7]+) \} |
6878             \\N\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
6879             \\ $q_char |
6880             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6881             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6882             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6883             \$ (?>\s* [0-9]+) |
6884             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6885             \$ \$ (?![\w\{]) |
6886             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6887             $q_char
6888 9533         353569 ))/oxmsg;
6889              
6890             for (my $i=0; $i <= $#char; $i++) {
6891 9533 50 66     27721  
    50 33        
    100          
    100          
    50          
6892 225573         678771 # "\L\u" --> "\u\L"
6893             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6894             @char[$i,$i+1] = @char[$i+1,$i];
6895             }
6896              
6897 0         0 # "\U\l" --> "\l\U"
6898             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6899             @char[$i,$i+1] = @char[$i+1,$i];
6900             }
6901              
6902 0         0 # octal escape sequence
6903             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6904             $char[$i] = Eutf2::octchr($1);
6905             }
6906              
6907 1         4 # hexadecimal escape sequence
6908             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6909             $char[$i] = Eutf2::hexchr($1);
6910             }
6911              
6912 1         4 # \N{CHARNAME} --> N{CHARNAME}
6913             elsif ($char[$i] =~ /\A \\ ( N\{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
6914             $char[$i] = $1;
6915 0 100       0 }
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
6916              
6917             if (0) {
6918             }
6919              
6920             # \F
6921             #
6922             # P.69 Table 2-6. Translation escapes
6923             # in Chapter 2: Bits and Pieces
6924             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6925             # (and so on)
6926 225573         1789487  
6927 0 50       0 # \u \l \U \L \F \Q \E
6928 602         1283 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
6929             if ($right_e < $left_e) {
6930             $char[$i] = '\\' . $char[$i];
6931             }
6932             }
6933             elsif ($char[$i] eq '\u') {
6934              
6935             # "STRING @{[ LIST EXPR ]} MORE STRING"
6936              
6937             # P.257 Other Tricks You Can Do with Hard References
6938             # in Chapter 8: References
6939             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6940              
6941             # P.353 Other Tricks You Can Do with Hard References
6942             # in Chapter 8: References
6943             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6944              
6945 0         0 # (and so on)
6946 0         0  
6947             $char[$i] = '@{[Eutf2::ucfirst qq<';
6948             $left_e++;
6949 0         0 }
6950 0         0 elsif ($char[$i] eq '\l') {
6951             $char[$i] = '@{[Eutf2::lcfirst qq<';
6952             $left_e++;
6953 0         0 }
6954 0         0 elsif ($char[$i] eq '\U') {
6955             $char[$i] = '@{[Eutf2::uc qq<';
6956             $left_e++;
6957 0         0 }
6958 6         14 elsif ($char[$i] eq '\L') {
6959             $char[$i] = '@{[Eutf2::lc qq<';
6960             $left_e++;
6961 6         11 }
6962 23         29 elsif ($char[$i] eq '\F') {
6963             $char[$i] = '@{[Eutf2::fc qq<';
6964             $left_e++;
6965 23         36 }
6966 0         0 elsif ($char[$i] eq '\Q') {
6967             $char[$i] = '@{[CORE::quotemeta qq<';
6968             $left_e++;
6969 0 50       0 }
6970 26         41 elsif ($char[$i] eq '\E') {
6971 26         46 if ($right_e < $left_e) {
6972             $char[$i] = '>]}';
6973             $right_e++;
6974 26         42 }
6975             else {
6976             $char[$i] = '';
6977             }
6978 0         0 }
6979 0 0       0 elsif ($char[$i] eq '\Q') {
6980 0         0 while (1) {
6981             if (++$i > $#char) {
6982 0 0       0 last;
6983 0         0 }
6984             if ($char[$i] eq '\E') {
6985             last;
6986             }
6987             }
6988             }
6989             elsif ($char[$i] eq '\E') {
6990             }
6991              
6992             # $0 --> $0
6993             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6994             }
6995             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6996             }
6997              
6998             # $$ --> $$
6999             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7000             }
7001              
7002             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7003 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7004             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7005             $char[$i] = e_capture($1);
7006 409         840 }
7007             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7008             $char[$i] = e_capture($1);
7009             }
7010              
7011 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7012             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7013             $char[$i] = e_capture($1.'->'.$2);
7014             }
7015              
7016 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7017             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
7018             $char[$i] = e_capture($1.'->'.$2);
7019             }
7020              
7021 0         0 # $$foo
7022             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7023             $char[$i] = e_capture($1);
7024             }
7025              
7026 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eutf2::PREMATCH()
7027             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7028             $char[$i] = '@{[Eutf2::PREMATCH()]}';
7029             }
7030              
7031 44         116 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eutf2::MATCH()
7032             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7033             $char[$i] = '@{[Eutf2::MATCH()]}';
7034             }
7035              
7036 45         121 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eutf2::POSTMATCH()
7037             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7038             $char[$i] = '@{[Eutf2::POSTMATCH()]}';
7039             }
7040              
7041             # ${ foo } --> ${ foo }
7042             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
7043             }
7044              
7045 33         82 # ${ ... }
7046             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7047             $char[$i] = e_capture($1);
7048             }
7049             }
7050 0 100       0  
7051 9533         15985 # return string
7052             if ($left_e > $right_e) {
7053 3         18 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
7054             }
7055             return join '', $ope, $delimiter, @char, $end_delimiter;
7056             }
7057              
7058             #
7059             # escape qw string (qw//)
7060 9530     34 0 66212 #
7061             sub e_qw {
7062 34         163 my($ope,$delimiter,$end_delimiter,$string) = @_;
7063              
7064             $slash = 'div';
7065 34         67  
  34         377  
7066 856 50       1323 # choice again delimiter
    0          
    0          
    0          
    0          
7067 34         184 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
7068             if (not $octet{$end_delimiter}) {
7069             return join '', $ope, $delimiter, $string, $end_delimiter;
7070 34         242 }
7071             elsif (not $octet{')'}) {
7072             return join '', $ope, '(', $string, ')';
7073 0         0 }
7074             elsif (not $octet{'}'}) {
7075             return join '', $ope, '{', $string, '}';
7076 0         0 }
7077             elsif (not $octet{']'}) {
7078             return join '', $ope, '[', $string, ']';
7079 0         0 }
7080             elsif (not $octet{'>'}) {
7081             return join '', $ope, '<', $string, '>';
7082 0         0 }
7083 0 0       0 else {
7084 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7085             if (not $octet{$char}) {
7086             return join '', $ope, $char, $string, $char;
7087             }
7088             }
7089             }
7090 0         0  
7091 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
7092 0         0 my @string = CORE::split(/\s+/, $string);
7093 0         0 for my $string (@string) {
7094 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
7095 0         0 for my $octet (@octet) {
7096             if ($octet =~ /\A (['\\]) \z/oxms) {
7097             $octet = '\\' . $1;
7098 0         0 }
7099             }
7100 0         0 $string = join '', @octet;
  0         0  
7101             }
7102             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
7103             }
7104              
7105             #
7106             # escape here document (<<"HEREDOC", <
7107 0     108 0 0 #
7108             sub e_heredoc {
7109 108         288 my($string) = @_;
7110              
7111 108         167 $slash = 'm//';
7112              
7113 108         366 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
7114 108         201  
7115             my $left_e = 0;
7116             my $right_e = 0;
7117 108         136  
7118             # split regexp
7119             my @char = $string =~ /\G((?>
7120             [^\x80-\xFF\\\$]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
7121             \\x\{ (?>[0-9A-Fa-f]+) \} |
7122             \\o\{ (?>[0-7]+) \} |
7123             \\N\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
7124             \\ $q_char |
7125             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7126             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7127             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7128             \$ (?>\s* [0-9]+) |
7129             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7130             \$ \$ (?![\w\{]) |
7131             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7132             $q_char
7133 108         16332 ))/oxmsg;
7134              
7135             for (my $i=0; $i <= $#char; $i++) {
7136 108 50 66     722  
    50 33        
    100          
    100          
    50          
7137 3305         10760 # "\L\u" --> "\u\L"
7138             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7139             @char[$i,$i+1] = @char[$i+1,$i];
7140             }
7141              
7142 0         0 # "\U\l" --> "\l\U"
7143             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7144             @char[$i,$i+1] = @char[$i+1,$i];
7145             }
7146              
7147 0         0 # octal escape sequence
7148             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7149             $char[$i] = Eutf2::octchr($1);
7150             }
7151              
7152 1         3 # hexadecimal escape sequence
7153             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7154             $char[$i] = Eutf2::hexchr($1);
7155             }
7156              
7157 1         4 # \N{CHARNAME} --> N{CHARNAME}
7158             elsif ($char[$i] =~ /\A \\ ( N\{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
7159             $char[$i] = $1;
7160 0 100       0 }
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
7161              
7162             if (0) {
7163             }
7164 3305         30492  
7165 0 50       0 # \u \l \U \L \F \Q \E
7166 72         129 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7167             if ($right_e < $left_e) {
7168             $char[$i] = '\\' . $char[$i];
7169             }
7170 0         0 }
7171 0         0 elsif ($char[$i] eq '\u') {
7172             $char[$i] = '@{[Eutf2::ucfirst qq<';
7173             $left_e++;
7174 0         0 }
7175 0         0 elsif ($char[$i] eq '\l') {
7176             $char[$i] = '@{[Eutf2::lcfirst qq<';
7177             $left_e++;
7178 0         0 }
7179 0         0 elsif ($char[$i] eq '\U') {
7180             $char[$i] = '@{[Eutf2::uc qq<';
7181             $left_e++;
7182 0         0 }
7183 6         9 elsif ($char[$i] eq '\L') {
7184             $char[$i] = '@{[Eutf2::lc qq<';
7185             $left_e++;
7186 6         11 }
7187 0         0 elsif ($char[$i] eq '\F') {
7188             $char[$i] = '@{[Eutf2::fc qq<';
7189             $left_e++;
7190 0         0 }
7191 0         0 elsif ($char[$i] eq '\Q') {
7192             $char[$i] = '@{[CORE::quotemeta qq<';
7193             $left_e++;
7194 0 50       0 }
7195 3         5 elsif ($char[$i] eq '\E') {
7196 3         4 if ($right_e < $left_e) {
7197             $char[$i] = '>]}';
7198             $right_e++;
7199 3         7 }
7200             else {
7201             $char[$i] = '';
7202             }
7203 0         0 }
7204 0 0       0 elsif ($char[$i] eq '\Q') {
7205 0         0 while (1) {
7206             if (++$i > $#char) {
7207 0 0       0 last;
7208 0         0 }
7209             if ($char[$i] eq '\E') {
7210             last;
7211             }
7212             }
7213             }
7214             elsif ($char[$i] eq '\E') {
7215             }
7216              
7217             # $0 --> $0
7218             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7219             }
7220             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7221             }
7222              
7223             # $$ --> $$
7224             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7225             }
7226              
7227             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7228 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7229             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7230             $char[$i] = e_capture($1);
7231 0         0 }
7232             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7233             $char[$i] = e_capture($1);
7234             }
7235              
7236 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7237             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7238             $char[$i] = e_capture($1.'->'.$2);
7239             }
7240              
7241 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7242             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
7243             $char[$i] = e_capture($1.'->'.$2);
7244             }
7245              
7246 0         0 # $$foo
7247             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7248             $char[$i] = e_capture($1);
7249             }
7250              
7251 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eutf2::PREMATCH()
7252             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7253             $char[$i] = '@{[Eutf2::PREMATCH()]}';
7254             }
7255              
7256 8         56 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eutf2::MATCH()
7257             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7258             $char[$i] = '@{[Eutf2::MATCH()]}';
7259             }
7260              
7261 8         53 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eutf2::POSTMATCH()
7262             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7263             $char[$i] = '@{[Eutf2::POSTMATCH()]}';
7264             }
7265              
7266             # ${ foo } --> ${ foo }
7267             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
7268             }
7269              
7270 6         43 # ${ ... }
7271             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7272             $char[$i] = e_capture($1);
7273             }
7274             }
7275 0 100       0  
7276 108         239 # return string
7277             if ($left_e > $right_e) {
7278 3         24 return join '', @char, '>]}' x ($left_e - $right_e);
7279             }
7280             return join '', @char;
7281             }
7282              
7283             #
7284             # escape regexp (m//, qr//)
7285 105     1377 0 795 #
7286 1377   100     5500 sub e_qr {
7287             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7288 1377         4491 $modifier ||= '';
7289 1377 50       2351  
7290 1377         2957 $modifier =~ tr/p//d;
7291 0         0 if ($modifier =~ /([adlu])/oxms) {
7292 0 0       0 my $line = 0;
7293 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7294 0         0 if ($filename ne __FILE__) {
7295             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7296             last;
7297 0         0 }
7298             }
7299             die qq{Unsupported modifier "$1" used at line $line.\n};
7300 0         0 }
7301              
7302             $slash = 'div';
7303 1377 100       1901  
    100          
7304 1377         3399 # literal null string pattern
7305 8         11 if ($string eq '') {
7306 8         11 $modifier =~ tr/bB//d;
7307             $modifier =~ tr/i//d;
7308             return join '', $ope, $delimiter, $end_delimiter, $modifier;
7309             }
7310              
7311             # /b /B modifier
7312             elsif ($modifier =~ tr/bB//d) {
7313 8 50       38  
7314 25         76 # choice again delimiter
7315 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
7316 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
7317 0         0 my %octet = map {$_ => 1} @char;
7318 0         0 if (not $octet{')'}) {
7319             $delimiter = '(';
7320             $end_delimiter = ')';
7321 0         0 }
7322 0         0 elsif (not $octet{'}'}) {
7323             $delimiter = '{';
7324             $end_delimiter = '}';
7325 0         0 }
7326 0         0 elsif (not $octet{']'}) {
7327             $delimiter = '[';
7328             $end_delimiter = ']';
7329 0         0 }
7330 0         0 elsif (not $octet{'>'}) {
7331             $delimiter = '<';
7332             $end_delimiter = '>';
7333 0         0 }
7334 0 0       0 else {
7335 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7336 0         0 if (not $octet{$char}) {
7337 0         0 $delimiter = $char;
7338             $end_delimiter = $char;
7339             last;
7340             }
7341             }
7342             }
7343 0 100 100     0 }
7344 25         131  
7345             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
7346             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
7347 4         36 }
7348             else {
7349             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
7350             }
7351 21 100       160 }
7352 1344         2634  
7353             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7354             my $metachar = qr/[\@\\|[\]{^]/oxms;
7355 1344         4330  
7356             # split regexp
7357             my @char = $string =~ /\G((?>
7358             [^\x80-\xFF\\\$\@\[\(]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
7359             \\x (?>[0-9A-Fa-f]{1,2}) |
7360             \\ (?>[0-7]{2,3}) |
7361             \\c [\x40-\x5F] |
7362             \\x\{ (?>[0-9A-Fa-f]+) \} |
7363             \\o\{ (?>[0-7]+) \} |
7364             \\[bBNpP]\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
7365             \\ $q_char |
7366             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7367             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7368             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7369             [\$\@] $qq_variable |
7370             \$ (?>\s* [0-9]+) |
7371             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7372             \$ \$ (?![\w\{]) |
7373             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7374             \[\^ |
7375             \[\: (?>[a-z]+) :\] |
7376             \[\:\^ (?>[a-z]+) :\] |
7377             \(\? |
7378             $q_char
7379             ))/oxmsg;
7380 1344 50       225476  
7381 1344         8626 # choice again delimiter
  0         0  
7382 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
7383 0         0 my %octet = map {$_ => 1} @char;
7384 0         0 if (not $octet{')'}) {
7385             $delimiter = '(';
7386             $end_delimiter = ')';
7387 0         0 }
7388 0         0 elsif (not $octet{'}'}) {
7389             $delimiter = '{';
7390             $end_delimiter = '}';
7391 0         0 }
7392 0         0 elsif (not $octet{']'}) {
7393             $delimiter = '[';
7394             $end_delimiter = ']';
7395 0         0 }
7396 0         0 elsif (not $octet{'>'}) {
7397             $delimiter = '<';
7398             $end_delimiter = '>';
7399 0         0 }
7400 0 0       0 else {
7401 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7402 0         0 if (not $octet{$char}) {
7403 0         0 $delimiter = $char;
7404             $end_delimiter = $char;
7405             last;
7406             }
7407             }
7408             }
7409 0         0 }
7410 1344         1971  
7411 1344         1580 my $left_e = 0;
7412             my $right_e = 0;
7413             for (my $i=0; $i <= $#char; $i++) {
7414 1344 50 66     2991  
    50 66        
    100          
    100          
    100          
    100          
7415 3231         15864 # "\L\u" --> "\u\L"
7416             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7417             @char[$i,$i+1] = @char[$i+1,$i];
7418             }
7419              
7420 0         0 # "\U\l" --> "\l\U"
7421             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7422             @char[$i,$i+1] = @char[$i+1,$i];
7423             }
7424              
7425 0         0 # octal escape sequence
7426             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7427             $char[$i] = Eutf2::octchr($1);
7428             }
7429              
7430 1         5 # hexadecimal escape sequence
7431             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7432             $char[$i] = Eutf2::hexchr($1);
7433             }
7434              
7435             # \b{...} --> b\{...}
7436             # \B{...} --> B\{...}
7437             # \N{CHARNAME} --> N\{CHARNAME}
7438             # \p{PROPERTY} --> p\{PROPERTY}
7439 1         5 # \P{PROPERTY} --> P\{PROPERTY}
7440             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
7441             $char[$i] = $1 . '\\' . $2;
7442             }
7443              
7444 6         19 # \p, \P, \X --> p, P, X
7445             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7446             $char[$i] = $1;
7447 4 100 100     10 }
    100 100        
    100 100        
    100          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
7448              
7449             if (0) {
7450             }
7451 3231         9356  
7452 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
7453 6         88 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7454             if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
7455             $char[$i] .= join '', splice @char, $i+1, 3;
7456 0         0 }
7457             elsif (($i+2 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+2]) == 2) and (CORE::eval(sprintf '"%s%s%s"', @char[$i..$i+2]) =~ /\A $q_char \z/oxms)) {
7458             $char[$i] .= join '', splice @char, $i+1, 2;
7459 0         0 }
7460             elsif (($i+1 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, $char[$i+1 ]) == 1) and (CORE::eval(sprintf '"%s%s"', @char[$i..$i+1]) =~ /\A $q_char \z/oxms)) {
7461             $char[$i] .= join '', splice @char, $i+1, 1;
7462             }
7463             }
7464              
7465 0         0 # open character class [...]
7466             elsif ($char[$i] eq '[') {
7467             my $left = $i;
7468              
7469             # [] make die "Unmatched [] in regexp ...\n"
7470 598 100       720 # (and so on)
7471 598         1225  
7472             if ($char[$i+1] eq ']') {
7473             $i++;
7474 3         7 }
7475 598 50       682  
7476 2607         3550 while (1) {
7477             if (++$i > $#char) {
7478 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7479 2607         3739 }
7480             if ($char[$i] eq ']') {
7481             my $right = $i;
7482 598 100       658  
7483 598         2646 # [...]
  90         185  
7484             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7485             splice @char, $left, $right-$left+1, sprintf(q{@{[Eutf2::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7486 270         413 }
7487             else {
7488             splice @char, $left, $right-$left+1, Eutf2::charlist_qr(@char[$left+1..$right-1], $modifier);
7489 508         1556 }
7490 598         1000  
7491             $i = $left;
7492             last;
7493             }
7494             }
7495             }
7496              
7497 598         1486 # open character class [^...]
7498             elsif ($char[$i] eq '[^') {
7499             my $left = $i;
7500              
7501             # [^] make die "Unmatched [] in regexp ...\n"
7502 328 100       407 # (and so on)
7503 328         620  
7504             if ($char[$i+1] eq ']') {
7505             $i++;
7506 5         8 }
7507 328 50       346  
7508 1447         1899 while (1) {
7509             if (++$i > $#char) {
7510 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7511 1447         2005 }
7512             if ($char[$i] eq ']') {
7513             my $right = $i;
7514 328 100       352  
7515 328         1391 # [^...]
  90         198  
7516             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7517             splice @char, $left, $right-$left+1, sprintf(q{@{[Eutf2::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7518 270         489 }
7519             else {
7520             splice @char, $left, $right-$left+1, Eutf2::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7521 238         718 }
7522 328         578  
7523             $i = $left;
7524             last;
7525             }
7526             }
7527             }
7528              
7529 328         780 # rewrite character class or escape character
7530             elsif (my $char = character_class($char[$i],$modifier)) {
7531             $char[$i] = $char;
7532             }
7533              
7534 215 50       514 # /i modifier
7535 44         78 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eutf2::uc($char[$i]) ne Eutf2::fc($char[$i]))) {
7536             if (CORE::length(Eutf2::fc($char[$i])) == 1) {
7537             $char[$i] = '[' . Eutf2::uc($char[$i]) . Eutf2::fc($char[$i]) . ']';
7538 44         96 }
7539             else {
7540             $char[$i] = '(?:' . Eutf2::uc($char[$i]) . '|' . Eutf2::fc($char[$i]) . ')';
7541             }
7542             }
7543              
7544 0 50       0 # \u \l \U \L \F \Q \E
7545 1         5 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
7546             if ($right_e < $left_e) {
7547             $char[$i] = '\\' . $char[$i];
7548             }
7549 0         0 }
7550 0         0 elsif ($char[$i] eq '\u') {
7551             $char[$i] = '@{[Eutf2::ucfirst qq<';
7552             $left_e++;
7553 0         0 }
7554 0         0 elsif ($char[$i] eq '\l') {
7555             $char[$i] = '@{[Eutf2::lcfirst qq<';
7556             $left_e++;
7557 0         0 }
7558 1         2 elsif ($char[$i] eq '\U') {
7559             $char[$i] = '@{[Eutf2::uc qq<';
7560             $left_e++;
7561 1         3 }
7562 1         2 elsif ($char[$i] eq '\L') {
7563             $char[$i] = '@{[Eutf2::lc qq<';
7564             $left_e++;
7565 1         2 }
7566 16         29 elsif ($char[$i] eq '\F') {
7567             $char[$i] = '@{[Eutf2::fc qq<';
7568             $left_e++;
7569 16         33 }
7570 20         35 elsif ($char[$i] eq '\Q') {
7571             $char[$i] = '@{[CORE::quotemeta qq<';
7572             $left_e++;
7573 20 50       40 }
7574 38         79 elsif ($char[$i] eq '\E') {
7575 38         51 if ($right_e < $left_e) {
7576             $char[$i] = '>]}';
7577             $right_e++;
7578 38         80 }
7579             else {
7580             $char[$i] = '';
7581             }
7582 0         0 }
7583 0 0       0 elsif ($char[$i] eq '\Q') {
7584 0         0 while (1) {
7585             if (++$i > $#char) {
7586 0 0       0 last;
7587 0         0 }
7588             if ($char[$i] eq '\E') {
7589             last;
7590             }
7591             }
7592             }
7593             elsif ($char[$i] eq '\E') {
7594             }
7595              
7596 0 0       0 # $0 --> $0
7597 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7598             if ($ignorecase) {
7599             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7600             }
7601 0 0       0 }
7602 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7603             if ($ignorecase) {
7604             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7605             }
7606             }
7607              
7608             # $$ --> $$
7609             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7610             }
7611              
7612             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7613 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7614 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7615 0         0 $char[$i] = e_capture($1);
7616             if ($ignorecase) {
7617             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7618             }
7619 0         0 }
7620 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7621 0         0 $char[$i] = e_capture($1);
7622             if ($ignorecase) {
7623             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7624             }
7625             }
7626              
7627 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7628 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7629 0         0 $char[$i] = e_capture($1.'->'.$2);
7630             if ($ignorecase) {
7631             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7632             }
7633             }
7634              
7635 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7636 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
7637 0         0 $char[$i] = e_capture($1.'->'.$2);
7638             if ($ignorecase) {
7639             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7640             }
7641             }
7642              
7643 0         0 # $$foo
7644 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7645 0         0 $char[$i] = e_capture($1);
7646             if ($ignorecase) {
7647             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7648             }
7649             }
7650              
7651 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eutf2::PREMATCH()
7652 8         151 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7653             if ($ignorecase) {
7654             $char[$i] = '@{[Eutf2::ignorecase(Eutf2::PREMATCH())]}';
7655 0         0 }
7656             else {
7657             $char[$i] = '@{[Eutf2::PREMATCH()]}';
7658             }
7659             }
7660              
7661 8 50       31 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eutf2::MATCH()
7662 8         164 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7663             if ($ignorecase) {
7664             $char[$i] = '@{[Eutf2::ignorecase(Eutf2::MATCH())]}';
7665 0         0 }
7666             else {
7667             $char[$i] = '@{[Eutf2::MATCH()]}';
7668             }
7669             }
7670              
7671 8 50       30 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eutf2::POSTMATCH()
7672 6         86 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7673             if ($ignorecase) {
7674             $char[$i] = '@{[Eutf2::ignorecase(Eutf2::POSTMATCH())]}';
7675 0         0 }
7676             else {
7677             $char[$i] = '@{[Eutf2::POSTMATCH()]}';
7678             }
7679             }
7680              
7681 6 0       20 # ${ foo }
7682 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
7683             if ($ignorecase) {
7684             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7685             }
7686             }
7687              
7688 0         0 # ${ ... }
7689 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7690 0         0 $char[$i] = e_capture($1);
7691             if ($ignorecase) {
7692             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7693             }
7694             }
7695              
7696 0         0 # $scalar or @array
7697 42 100       101 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7698 42         120 $char[$i] = e_string($char[$i]);
7699             if ($ignorecase) {
7700             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
7701             }
7702             }
7703              
7704 9 100 66     32 # quote character before ? + * {
    50          
7705             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7706             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7707 188         1339 }
7708 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
7709 0         0 my $char = $char[$i-1];
7710             if ($char[$i] eq '{') {
7711             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
7712 0         0 }
7713             else {
7714             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
7715             }
7716 0         0 }
7717             else {
7718             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7719             }
7720             }
7721             }
7722 187         724  
7723 1344 50       2251 # make regexp string
7724 1344 0 0     2802 $modifier =~ tr/i//d;
7725 0         0 if ($left_e > $right_e) {
7726             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
7727             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
7728 0         0 }
7729             else {
7730             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
7731 0 100 100     0 }
7732 1344         6527 }
7733             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
7734             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
7735 32         275 }
7736             else {
7737             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
7738             }
7739             }
7740              
7741             #
7742             # double quote stuff
7743 1312     540 0 11008 #
7744             sub qq_stuff {
7745             my($delimiter,$end_delimiter,$stuff) = @_;
7746 540 100       782  
7747 540         1007 # scalar variable or array variable
7748             if ($stuff =~ /\A [\$\@] /oxms) {
7749             return $stuff;
7750             }
7751 300         935  
  240         567  
7752 320         757 # quote by delimiter
7753 240 50       564 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
7754 240 50       390 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7755 240 50       324 next if $char eq $delimiter;
7756 240         404 next if $char eq $end_delimiter;
7757             if (not $octet{$char}) {
7758             return join '', 'qq', $char, $stuff, $char;
7759 240         861 }
7760             }
7761             return join '', 'qq', '<', $stuff, '>';
7762             }
7763              
7764             #
7765             # escape regexp (m'', qr'', and m''b, qr''b)
7766 0     15 0 0 #
7767 15   100     79 sub e_qr_q {
7768             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7769 15         66 $modifier ||= '';
7770 15 50       29  
7771 15         37 $modifier =~ tr/p//d;
7772 0         0 if ($modifier =~ /([adlu])/oxms) {
7773 0 0       0 my $line = 0;
7774 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7775 0         0 if ($filename ne __FILE__) {
7776             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7777             last;
7778 0         0 }
7779             }
7780             die qq{Unsupported modifier "$1" used at line $line.\n};
7781 0         0 }
7782              
7783             $slash = 'div';
7784 15 100       24  
    100          
7785 15         47 # literal null string pattern
7786 8         11 if ($string eq '') {
7787 8         10 $modifier =~ tr/bB//d;
7788             $modifier =~ tr/i//d;
7789             return join '', $ope, $delimiter, $end_delimiter, $modifier;
7790             }
7791              
7792 8         37 # with /b /B modifier
7793             elsif ($modifier =~ tr/bB//d) {
7794             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
7795             }
7796              
7797 3         10 # without /b /B modifier
7798             else {
7799             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
7800             }
7801             }
7802              
7803             #
7804             # escape regexp (m'', qr'')
7805 4     4 0 15 #
7806             sub e_qr_qt {
7807 4 50       20 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7808              
7809             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7810 4         12  
7811             # split regexp
7812             my @char = $string =~ /\G((?>
7813             [^\x80-\xFF\\\[\$\@\/] |
7814             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
7815             \[\^ |
7816             \[\: (?>[a-z]+) \:\] |
7817             \[\:\^ (?>[a-z]+) \:\] |
7818             [\$\@\/] |
7819             \\ (?:$q_char) |
7820             (?:$q_char)
7821             ))/oxmsg;
7822 4         465  
7823 4 50 33     36 # unescape character
    50 33        
    50 66        
    50          
    50          
    50          
7824             for (my $i=0; $i <= $#char; $i++) {
7825             if (0) {
7826             }
7827 5         44  
7828 0         0 # open character class [...]
7829 0 0       0 elsif ($char[$i] eq '[') {
7830 0         0 my $left = $i;
7831             if ($char[$i+1] eq ']') {
7832 0         0 $i++;
7833 0 0       0 }
7834 0         0 while (1) {
7835             if (++$i > $#char) {
7836 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7837 0         0 }
7838             if ($char[$i] eq ']') {
7839             my $right = $i;
7840 0         0  
7841             # [...]
7842 0         0 splice @char, $left, $right-$left+1, Eutf2::charlist_qr(@char[$left+1..$right-1], $modifier);
7843 0         0  
7844             $i = $left;
7845             last;
7846             }
7847             }
7848             }
7849              
7850 0         0 # open character class [^...]
7851 0 0       0 elsif ($char[$i] eq '[^') {
7852 0         0 my $left = $i;
7853             if ($char[$i+1] eq ']') {
7854 0         0 $i++;
7855 0 0       0 }
7856 0         0 while (1) {
7857             if (++$i > $#char) {
7858 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7859 0         0 }
7860             if ($char[$i] eq ']') {
7861             my $right = $i;
7862 0         0  
7863             # [^...]
7864 0         0 splice @char, $left, $right-$left+1, Eutf2::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7865 0         0  
7866             $i = $left;
7867             last;
7868             }
7869             }
7870             }
7871              
7872 0         0 # escape $ @ / and \
7873             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7874             $char[$i] = '\\' . $char[$i];
7875             }
7876              
7877 0         0 # rewrite character class or escape character
7878             elsif (my $char = character_class($char[$i],$modifier)) {
7879             $char[$i] = $char;
7880             }
7881              
7882 0 0       0 # /i modifier
7883 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eutf2::uc($char[$i]) ne Eutf2::fc($char[$i]))) {
7884             if (CORE::length(Eutf2::fc($char[$i])) == 1) {
7885             $char[$i] = '[' . Eutf2::uc($char[$i]) . Eutf2::fc($char[$i]) . ']';
7886 0         0 }
7887             else {
7888             $char[$i] = '(?:' . Eutf2::uc($char[$i]) . '|' . Eutf2::fc($char[$i]) . ')';
7889             }
7890             }
7891              
7892 0 0       0 # quote character before ? + * {
7893             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7894             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7895 0         0 }
7896             else {
7897             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7898             }
7899             }
7900 0         0 }
7901 4         12  
7902             $delimiter = '/';
7903 4         6 $end_delimiter = '/';
7904 4         13  
7905             $modifier =~ tr/i//d;
7906             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
7907             }
7908              
7909             #
7910             # escape regexp (m''b, qr''b)
7911 4     3 0 57 #
7912             sub e_qr_qb {
7913             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7914 3         9  
7915             # split regexp
7916             my @char = $string =~ /\G ((?>[^\\]|\\\\|[\x00-\xFF])) /oxmsg;
7917 3         13  
7918 3 50       12 # unescape character
    50          
7919             for (my $i=0; $i <= $#char; $i++) {
7920             if (0) {
7921             }
7922 9         33  
7923             # remain \\
7924             elsif ($char[$i] eq '\\\\') {
7925             }
7926              
7927 0         0 # escape $ @ / and \
7928             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7929             $char[$i] = '\\' . $char[$i];
7930             }
7931 0         0 }
7932 3         7  
7933 3         3 $delimiter = '/';
7934             $end_delimiter = '/';
7935             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
7936             }
7937              
7938             #
7939             # escape regexp (s/here//)
7940 3     110 0 19 #
7941 110   100     346 sub e_s1 {
7942             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7943 110         498 $modifier ||= '';
7944 110 50       201  
7945 110         341 $modifier =~ tr/p//d;
7946 0         0 if ($modifier =~ /([adlu])/oxms) {
7947 0 0       0 my $line = 0;
7948 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7949 0         0 if ($filename ne __FILE__) {
7950             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7951             last;
7952 0         0 }
7953             }
7954             die qq{Unsupported modifier "$1" used at line $line.\n};
7955 0         0 }
7956              
7957             $slash = 'div';
7958 110 100       212  
    100          
7959 110         417 # literal null string pattern
7960 8         9 if ($string eq '') {
7961 8         11 $modifier =~ tr/bB//d;
7962             $modifier =~ tr/i//d;
7963             return join '', $ope, $delimiter, $end_delimiter, $modifier;
7964             }
7965              
7966             # /b /B modifier
7967             elsif ($modifier =~ tr/bB//d) {
7968 8 50       55  
7969 1         4 # choice again delimiter
7970 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
7971 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
7972 0         0 my %octet = map {$_ => 1} @char;
7973 0         0 if (not $octet{')'}) {
7974             $delimiter = '(';
7975             $end_delimiter = ')';
7976 0         0 }
7977 0         0 elsif (not $octet{'}'}) {
7978             $delimiter = '{';
7979             $end_delimiter = '}';
7980 0         0 }
7981 0         0 elsif (not $octet{']'}) {
7982             $delimiter = '[';
7983             $end_delimiter = ']';
7984 0         0 }
7985 0         0 elsif (not $octet{'>'}) {
7986             $delimiter = '<';
7987             $end_delimiter = '>';
7988 0         0 }
7989 0 0       0 else {
7990 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7991 0         0 if (not $octet{$char}) {
7992 0         0 $delimiter = $char;
7993             $end_delimiter = $char;
7994             last;
7995             }
7996             }
7997             }
7998 0         0 }
7999 1         2  
8000             my $prematch = '';
8001             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
8002 1 100       12 }
8003 101         339  
8004             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
8005             my $metachar = qr/[\@\\|[\]{^]/oxms;
8006 101         438  
8007             # split regexp
8008             my @char = $string =~ /\G((?>
8009             [^\x80-\xFF\\\$\@\[\(]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
8010             \\ (?>[1-9][0-9]*) |
8011             \\g (?>\s*) (?>[1-9][0-9]*) |
8012             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
8013             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
8014             \\x (?>[0-9A-Fa-f]{1,2}) |
8015             \\ (?>[0-7]{2,3}) |
8016             \\c [\x40-\x5F] |
8017             \\x\{ (?>[0-9A-Fa-f]+) \} |
8018             \\o\{ (?>[0-7]+) \} |
8019             \\[bBNpP]\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
8020             \\ $q_char |
8021             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
8022             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
8023             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
8024             [\$\@] $qq_variable |
8025             \$ (?>\s* [0-9]+) |
8026             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
8027             \$ \$ (?![\w\{]) |
8028             \$ (?>\s*) \$ (?>\s*) $qq_variable |
8029             \[\^ |
8030             \[\: (?>[a-z]+) :\] |
8031             \[\:\^ (?>[a-z]+) :\] |
8032             \(\? |
8033             $q_char
8034             ))/oxmsg;
8035 101 50       63066  
8036 101         2053 # choice again delimiter
  0         0  
8037 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
8038 0         0 my %octet = map {$_ => 1} @char;
8039 0         0 if (not $octet{')'}) {
8040             $delimiter = '(';
8041             $end_delimiter = ')';
8042 0         0 }
8043 0         0 elsif (not $octet{'}'}) {
8044             $delimiter = '{';
8045             $end_delimiter = '}';
8046 0         0 }
8047 0         0 elsif (not $octet{']'}) {
8048             $delimiter = '[';
8049             $end_delimiter = ']';
8050 0         0 }
8051 0         0 elsif (not $octet{'>'}) {
8052             $delimiter = '<';
8053             $end_delimiter = '>';
8054 0         0 }
8055 0 0       0 else {
8056 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
8057 0         0 if (not $octet{$char}) {
8058 0         0 $delimiter = $char;
8059             $end_delimiter = $char;
8060             last;
8061             }
8062             }
8063             }
8064             }
8065 0         0  
  101         230  
8066             # count '('
8067 425         767 my $parens = grep { $_ eq '(' } @char;
8068 101         157  
8069 101         227 my $left_e = 0;
8070             my $right_e = 0;
8071             for (my $i=0; $i <= $#char; $i++) {
8072 101 50 33     304  
    50 33        
    100          
    100          
    50          
    50          
8073 346         2549 # "\L\u" --> "\u\L"
8074             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
8075             @char[$i,$i+1] = @char[$i+1,$i];
8076             }
8077              
8078 0         0 # "\U\l" --> "\l\U"
8079             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
8080             @char[$i,$i+1] = @char[$i+1,$i];
8081             }
8082              
8083 0         0 # octal escape sequence
8084             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
8085             $char[$i] = Eutf2::octchr($1);
8086             }
8087              
8088 1         3 # hexadecimal escape sequence
8089             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
8090             $char[$i] = Eutf2::hexchr($1);
8091             }
8092              
8093             # \b{...} --> b\{...}
8094             # \B{...} --> B\{...}
8095             # \N{CHARNAME} --> N\{CHARNAME}
8096             # \p{PROPERTY} --> p\{PROPERTY}
8097 1         3 # \P{PROPERTY} --> P\{PROPERTY}
8098             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
8099             $char[$i] = $1 . '\\' . $2;
8100             }
8101              
8102 0         0 # \p, \P, \X --> p, P, X
8103             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
8104             $char[$i] = $1;
8105 0 50 66     0 }
    100 66        
    50 100        
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
8106              
8107             if (0) {
8108             }
8109 346         1258  
8110 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
8111 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
8112             if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
8113             $char[$i] .= join '', splice @char, $i+1, 3;
8114 0         0 }
8115             elsif (($i+2 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+2]) == 2) and (CORE::eval(sprintf '"%s%s%s"', @char[$i..$i+2]) =~ /\A $q_char \z/oxms)) {
8116             $char[$i] .= join '', splice @char, $i+1, 2;
8117 0         0 }
8118             elsif (($i+1 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, $char[$i+1 ]) == 1) and (CORE::eval(sprintf '"%s%s"', @char[$i..$i+1]) =~ /\A $q_char \z/oxms)) {
8119             $char[$i] .= join '', splice @char, $i+1, 1;
8120             }
8121             }
8122              
8123 0         0 # open character class [...]
8124 20 50       31 elsif ($char[$i] eq '[') {
8125 20         77 my $left = $i;
8126             if ($char[$i+1] eq ']') {
8127 0         0 $i++;
8128 20 50       29 }
8129 79         130 while (1) {
8130             if (++$i > $#char) {
8131 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
8132 79         319 }
8133             if ($char[$i] eq ']') {
8134             my $right = $i;
8135 20 50       40  
8136 20         138 # [...]
  0         0  
8137             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8138             splice @char, $left, $right-$left+1, sprintf(q{@{[Eutf2::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8139 0         0 }
8140             else {
8141             splice @char, $left, $right-$left+1, Eutf2::charlist_qr(@char[$left+1..$right-1], $modifier);
8142 20         98 }
8143 20         57  
8144             $i = $left;
8145             last;
8146             }
8147             }
8148             }
8149              
8150 20         64 # open character class [^...]
8151 0 0       0 elsif ($char[$i] eq '[^') {
8152 0         0 my $left = $i;
8153             if ($char[$i+1] eq ']') {
8154 0         0 $i++;
8155 0 0       0 }
8156 0         0 while (1) {
8157             if (++$i > $#char) {
8158 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
8159 0         0 }
8160             if ($char[$i] eq ']') {
8161             my $right = $i;
8162 0 0       0  
8163 0         0 # [^...]
  0         0  
8164             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8165             splice @char, $left, $right-$left+1, sprintf(q{@{[Eutf2::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8166 0         0 }
8167             else {
8168             splice @char, $left, $right-$left+1, Eutf2::charlist_not_qr(@char[$left+1..$right-1], $modifier);
8169 0         0 }
8170 0         0  
8171             $i = $left;
8172             last;
8173             }
8174             }
8175             }
8176              
8177 0         0 # rewrite character class or escape character
8178             elsif (my $char = character_class($char[$i],$modifier)) {
8179             $char[$i] = $char;
8180             }
8181              
8182 11 50       24 # /i modifier
8183 3         5 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eutf2::uc($char[$i]) ne Eutf2::fc($char[$i]))) {
8184             if (CORE::length(Eutf2::fc($char[$i])) == 1) {
8185             $char[$i] = '[' . Eutf2::uc($char[$i]) . Eutf2::fc($char[$i]) . ']';
8186 3         4 }
8187             else {
8188             $char[$i] = '(?:' . Eutf2::uc($char[$i]) . '|' . Eutf2::fc($char[$i]) . ')';
8189             }
8190             }
8191              
8192 0 50       0 # \u \l \U \L \F \Q \E
8193 8         24 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
8194             if ($right_e < $left_e) {
8195             $char[$i] = '\\' . $char[$i];
8196             }
8197 0         0 }
8198 0         0 elsif ($char[$i] eq '\u') {
8199             $char[$i] = '@{[Eutf2::ucfirst qq<';
8200             $left_e++;
8201 0         0 }
8202 0         0 elsif ($char[$i] eq '\l') {
8203             $char[$i] = '@{[Eutf2::lcfirst qq<';
8204             $left_e++;
8205 0         0 }
8206 0         0 elsif ($char[$i] eq '\U') {
8207             $char[$i] = '@{[Eutf2::uc qq<';
8208             $left_e++;
8209 0         0 }
8210 0         0 elsif ($char[$i] eq '\L') {
8211             $char[$i] = '@{[Eutf2::lc qq<';
8212             $left_e++;
8213 0         0 }
8214 0         0 elsif ($char[$i] eq '\F') {
8215             $char[$i] = '@{[Eutf2::fc qq<';
8216             $left_e++;
8217 0         0 }
8218 5         12 elsif ($char[$i] eq '\Q') {
8219             $char[$i] = '@{[CORE::quotemeta qq<';
8220             $left_e++;
8221 5 50       157 }
8222 5         13 elsif ($char[$i] eq '\E') {
8223 5         7 if ($right_e < $left_e) {
8224             $char[$i] = '>]}';
8225             $right_e++;
8226 5         10 }
8227             else {
8228             $char[$i] = '';
8229             }
8230 0         0 }
8231 0 0       0 elsif ($char[$i] eq '\Q') {
8232 0         0 while (1) {
8233             if (++$i > $#char) {
8234 0 0       0 last;
8235 0         0 }
8236             if ($char[$i] eq '\E') {
8237             last;
8238             }
8239             }
8240             }
8241             elsif ($char[$i] eq '\E') {
8242             }
8243              
8244             # \0 --> \0
8245             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
8246             }
8247              
8248             # \g{N}, \g{-N}
8249              
8250             # P.108 Using Simple Patterns
8251             # in Chapter 7: In the World of Regular Expressions
8252             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
8253              
8254             # P.221 Capturing
8255             # in Chapter 5: Pattern Matching
8256             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
8257              
8258             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
8259             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
8260             }
8261              
8262             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
8263             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
8264             }
8265              
8266             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
8267             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
8268             }
8269              
8270             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
8271             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
8272             }
8273              
8274 0 0       0 # $0 --> $0
8275 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
8276             if ($ignorecase) {
8277             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8278             }
8279 0 0       0 }
8280 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
8281             if ($ignorecase) {
8282             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8283             }
8284             }
8285              
8286             # $$ --> $$
8287             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
8288             }
8289              
8290             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
8291 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
8292 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
8293 0         0 $char[$i] = e_capture($1);
8294             if ($ignorecase) {
8295             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8296             }
8297 0         0 }
8298 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
8299 0         0 $char[$i] = e_capture($1);
8300             if ($ignorecase) {
8301             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8302             }
8303             }
8304              
8305 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
8306 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
8307 0         0 $char[$i] = e_capture($1.'->'.$2);
8308             if ($ignorecase) {
8309             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8310             }
8311             }
8312              
8313 0         0 # $$foo{ ... } --> $ $foo->{ ... }
8314 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
8315 0         0 $char[$i] = e_capture($1.'->'.$2);
8316             if ($ignorecase) {
8317             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8318             }
8319             }
8320              
8321 0         0 # $$foo
8322 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
8323 0         0 $char[$i] = e_capture($1);
8324             if ($ignorecase) {
8325             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8326             }
8327             }
8328              
8329 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eutf2::PREMATCH()
8330 4         14 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
8331             if ($ignorecase) {
8332             $char[$i] = '@{[Eutf2::ignorecase(Eutf2::PREMATCH())]}';
8333 0         0 }
8334             else {
8335             $char[$i] = '@{[Eutf2::PREMATCH()]}';
8336             }
8337             }
8338              
8339 4 50       14 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eutf2::MATCH()
8340 4         16 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
8341             if ($ignorecase) {
8342             $char[$i] = '@{[Eutf2::ignorecase(Eutf2::MATCH())]}';
8343 0         0 }
8344             else {
8345             $char[$i] = '@{[Eutf2::MATCH()]}';
8346             }
8347             }
8348              
8349 4 50       15 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eutf2::POSTMATCH()
8350 3         10 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
8351             if ($ignorecase) {
8352             $char[$i] = '@{[Eutf2::ignorecase(Eutf2::POSTMATCH())]}';
8353 0         0 }
8354             else {
8355             $char[$i] = '@{[Eutf2::POSTMATCH()]}';
8356             }
8357             }
8358              
8359 3 0       12 # ${ foo }
8360 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
8361             if ($ignorecase) {
8362             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8363             }
8364             }
8365              
8366 0         0 # ${ ... }
8367 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
8368 0         0 $char[$i] = e_capture($1);
8369             if ($ignorecase) {
8370             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8371             }
8372             }
8373              
8374 0         0 # $scalar or @array
8375 9 50       33 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
8376 9         176 $char[$i] = e_string($char[$i]);
8377             if ($ignorecase) {
8378             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
8379             }
8380             }
8381              
8382 0 50       0 # quote character before ? + * {
8383             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
8384             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
8385 23         128 }
8386             else {
8387             $char[$i-1] = '(?:' . $char[$i-1] . ')';
8388             }
8389             }
8390             }
8391 23         133  
8392 101         249 # make regexp string
8393 101 50       318 my $prematch = '';
8394 101         288 $modifier =~ tr/i//d;
8395             if ($left_e > $right_e) {
8396 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
8397             }
8398             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
8399             }
8400              
8401             #
8402             # escape regexp (s'here'' or s'here''b)
8403 101     22 0 1191 #
8404 22   100     53 sub e_s1_q {
8405             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8406 22         83 $modifier ||= '';
8407 22 50       29  
8408 22         47 $modifier =~ tr/p//d;
8409 0         0 if ($modifier =~ /([adlu])/oxms) {
8410 0 0       0 my $line = 0;
8411 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
8412 0         0 if ($filename ne __FILE__) {
8413             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
8414             last;
8415 0         0 }
8416             }
8417             die qq{Unsupported modifier "$1" used at line $line.\n};
8418 0         0 }
8419              
8420             $slash = 'div';
8421 22 100       30  
    100          
8422 22         59 # literal null string pattern
8423 8         10 if ($string eq '') {
8424 8         9 $modifier =~ tr/bB//d;
8425             $modifier =~ tr/i//d;
8426             return join '', $ope, $delimiter, $end_delimiter, $modifier;
8427             }
8428              
8429 8         70 # with /b /B modifier
8430             elsif ($modifier =~ tr/bB//d) {
8431             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
8432             }
8433              
8434 1         3 # without /b /B modifier
8435             else {
8436             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
8437             }
8438             }
8439              
8440             #
8441             # escape regexp (s'here'')
8442 13     13 0 29 #
8443             sub e_s1_qt {
8444 13 50       31 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8445              
8446             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
8447 13         39  
8448             # split regexp
8449             my @char = $string =~ /\G((?>
8450             [^\x80-\xFF\\\[\$\@\/] |
8451             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
8452             \[\^ |
8453             \[\: (?>[a-z]+) \:\] |
8454             \[\:\^ (?>[a-z]+) \:\] |
8455             [\$\@\/] |
8456             \\ (?:$q_char) |
8457             (?:$q_char)
8458             ))/oxmsg;
8459 13         453  
8460 13 50 33     50 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
8461             for (my $i=0; $i <= $#char; $i++) {
8462             if (0) {
8463             }
8464 25         96  
8465 0         0 # open character class [...]
8466 0 0       0 elsif ($char[$i] eq '[') {
8467 0         0 my $left = $i;
8468             if ($char[$i+1] eq ']') {
8469 0         0 $i++;
8470 0 0       0 }
8471 0         0 while (1) {
8472             if (++$i > $#char) {
8473 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
8474 0         0 }
8475             if ($char[$i] eq ']') {
8476             my $right = $i;
8477 0         0  
8478             # [...]
8479 0         0 splice @char, $left, $right-$left+1, Eutf2::charlist_qr(@char[$left+1..$right-1], $modifier);
8480 0         0  
8481             $i = $left;
8482             last;
8483             }
8484             }
8485             }
8486              
8487 0         0 # open character class [^...]
8488 0 0       0 elsif ($char[$i] eq '[^') {
8489 0         0 my $left = $i;
8490             if ($char[$i+1] eq ']') {
8491 0         0 $i++;
8492 0 0       0 }
8493 0         0 while (1) {
8494             if (++$i > $#char) {
8495 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
8496 0         0 }
8497             if ($char[$i] eq ']') {
8498             my $right = $i;
8499 0         0  
8500             # [^...]
8501 0         0 splice @char, $left, $right-$left+1, Eutf2::charlist_not_qr(@char[$left+1..$right-1], $modifier);
8502 0         0  
8503             $i = $left;
8504             last;
8505             }
8506             }
8507             }
8508              
8509 0         0 # escape $ @ / and \
8510             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
8511             $char[$i] = '\\' . $char[$i];
8512             }
8513              
8514 0         0 # rewrite character class or escape character
8515             elsif (my $char = character_class($char[$i],$modifier)) {
8516             $char[$i] = $char;
8517             }
8518              
8519 6 0       12 # /i modifier
8520 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eutf2::uc($char[$i]) ne Eutf2::fc($char[$i]))) {
8521             if (CORE::length(Eutf2::fc($char[$i])) == 1) {
8522             $char[$i] = '[' . Eutf2::uc($char[$i]) . Eutf2::fc($char[$i]) . ']';
8523 0         0 }
8524             else {
8525             $char[$i] = '(?:' . Eutf2::uc($char[$i]) . '|' . Eutf2::fc($char[$i]) . ')';
8526             }
8527             }
8528              
8529 0 0       0 # quote character before ? + * {
8530             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
8531             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
8532 0         0 }
8533             else {
8534             $char[$i-1] = '(?:' . $char[$i-1] . ')';
8535             }
8536             }
8537 0         0 }
8538 13         23  
8539 13         17 $modifier =~ tr/i//d;
8540 13         26 $delimiter = '/';
8541 13         17 $end_delimiter = '/';
8542             my $prematch = '';
8543             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
8544             }
8545              
8546             #
8547             # escape regexp (s'here''b)
8548 13     1 0 106 #
8549             sub e_s1_qb {
8550             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8551 1         14  
8552             # split regexp
8553             my @char = $string =~ /\G (?>[^\\]|\\\\|[\x00-\xFF]) /oxmsg;
8554 1         6  
8555 1 50       6 # unescape character
    50          
8556             for (my $i=0; $i <= $#char; $i++) {
8557             if (0) {
8558             }
8559 3         11  
8560             # remain \\
8561             elsif ($char[$i] eq '\\\\') {
8562             }
8563              
8564 0         0 # escape $ @ / and \
8565             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
8566             $char[$i] = '\\' . $char[$i];
8567             }
8568 0         0 }
8569 1         2  
8570 1         2 $delimiter = '/';
8571 1         2 $end_delimiter = '/';
8572             my $prematch = '';
8573             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
8574             }
8575              
8576             #
8577             # escape regexp (s''here')
8578 1     17 0 7 #
8579             sub e_s2_q {
8580 17         38 my($ope,$delimiter,$end_delimiter,$string) = @_;
8581              
8582 17         22 $slash = 'div';
8583 17         221  
8584 17 100       57 my @char = $string =~ / \G (?>[^\x80-\xFF\\]|\\\\|$q_char) /oxmsg;
    100          
8585             for (my $i=0; $i <= $#char; $i++) {
8586             if (0) {
8587             }
8588 9         32  
8589             # not escape \\
8590             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
8591             }
8592              
8593 0         0 # escape $ @ / and \
8594             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
8595             $char[$i] = '\\' . $char[$i];
8596             }
8597 5         12 }
8598              
8599             return join '', $ope, $delimiter, @char, $end_delimiter;
8600             }
8601              
8602             #
8603             # escape regexp (s/here/and here/modifier)
8604 17     132 0 64 #
8605 132   100     1111 sub e_sub {
8606             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
8607 132         573 $modifier ||= '';
8608 132 50       251  
8609 132         390 $modifier =~ tr/p//d;
8610 0         0 if ($modifier =~ /([adlu])/oxms) {
8611 0 0       0 my $line = 0;
8612 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
8613 0         0 if ($filename ne __FILE__) {
8614             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
8615             last;
8616 0         0 }
8617             }
8618             die qq{Unsupported modifier "$1" used at line $line.\n};
8619 0 100       0 }
8620 132         355  
8621 37         46 if ($variable eq '') {
8622             $variable = '$_';
8623             $bind_operator = ' =~ ';
8624 37         47 }
8625              
8626             $slash = 'div';
8627              
8628             # P.128 Start of match (or end of previous match): \G
8629             # P.130 Advanced Use of \G with Perl
8630             # in Chapter 3: Overview of Regular Expression Features and Flavors
8631             # P.312 Iterative Matching: Scalar Context, with /g
8632             # in Chapter 7: Perl
8633             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
8634              
8635             # P.181 Where You Left Off: The \G Assertion
8636             # in Chapter 5: Pattern Matching
8637             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
8638              
8639             # P.220 Where You Left Off: The \G Assertion
8640             # in Chapter 5: Pattern Matching
8641 132         233 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
8642 132         250  
8643             my $e_modifier = $modifier =~ tr/e//d;
8644 132         238 my $r_modifier = $modifier =~ tr/r//d;
8645 132 50       1060  
8646 132         366 my $my = '';
8647 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
8648 0         0 $my = $variable;
8649             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
8650             $variable =~ s/ = .+ \z//oxms;
8651 0         0 }
8652 132         378  
8653             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
8654             $variable_basename =~ s/ \s+ \z//oxms;
8655 132         259  
8656 132 100       212 # quote replacement string
8657 132         314 my $e_replacement = '';
8658 17         34 if ($e_modifier >= 1) {
8659             $e_replacement = e_qq('', '', '', $replacement);
8660             $e_modifier--;
8661 17 100       26 }
8662 115         308 else {
8663             if ($delimiter2 eq "'") {
8664             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
8665 17         37 }
8666             else {
8667             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
8668             }
8669 98         272 }
8670              
8671             my $sub = '';
8672 132 100       254  
8673 132 100       324 # with /r
8674             if ($r_modifier) {
8675             if (0) {
8676             }
8677 8         17  
8678 0 50       0 # s///gr without multibyte anchoring
8679             elsif ($modifier =~ /g/oxms) {
8680             $sub = sprintf(
8681             # 1 2 3 4 5
8682             q,
8683              
8684             $variable, # 1
8685             ($delimiter1 eq "'") ? # 2
8686             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
8687             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
8688             $s_matched, # 3
8689             $e_replacement, # 4
8690             '$Eutf2::re_r=CORE::eval $Eutf2::re_r; ' x $e_modifier, # 5
8691             );
8692             }
8693              
8694             # s///r
8695 4         13 else {
8696              
8697 4 50       5 my $prematch = q{$`};
8698              
8699             $sub = sprintf(
8700             # 1 2 3 4 5 6 7
8701             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Eutf2::re_r=%s; %s"%s$Eutf2::re_r$'" } : %s>,
8702              
8703             $variable, # 1
8704             ($delimiter1 eq "'") ? # 2
8705             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
8706             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
8707             $s_matched, # 3
8708             $e_replacement, # 4
8709             '$Eutf2::re_r=CORE::eval $Eutf2::re_r; ' x $e_modifier, # 5
8710             $prematch, # 6
8711             $variable, # 7
8712             );
8713             }
8714 4 50       12  
8715 8         23 # $var !~ s///r doesn't make sense
8716             if ($bind_operator =~ / !~ /oxms) {
8717             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
8718             }
8719             }
8720              
8721 0 100       0 # without /r
8722             else {
8723             if (0) {
8724             }
8725 124         331  
8726 0 100       0 # s///g without multibyte anchoring
    100          
8727             elsif ($modifier =~ /g/oxms) {
8728             $sub = sprintf(
8729             # 1 2 3 4 5 6 7 8
8730             q,
8731              
8732             $variable, # 1
8733             ($delimiter1 eq "'") ? # 2
8734             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
8735             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
8736             $s_matched, # 3
8737             $e_replacement, # 4
8738             '$Eutf2::re_r=CORE::eval $Eutf2::re_r; ' x $e_modifier, # 5
8739             $variable, # 6
8740             $variable, # 7
8741             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
8742             );
8743             }
8744              
8745             # s///
8746 29         126 else {
8747              
8748 95 100       166 my $prematch = q{$`};
    100          
8749              
8750             $sub = sprintf(
8751              
8752             ($bind_operator =~ / =~ /oxms) ?
8753              
8754             # 1 2 3 4 5 6 7 8
8755             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Eutf2::re_r=%s; %s%s="%s$Eutf2::re_r$'"; 1 } : undef> :
8756              
8757             # 1 2 3 4 5 6 7 8
8758             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Eutf2::re_r=%s; %s%s="%s$Eutf2::re_r$'"; undef }>,
8759              
8760             $variable, # 1
8761             $bind_operator, # 2
8762             ($delimiter1 eq "'") ? # 3
8763             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
8764             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
8765             $s_matched, # 4
8766             $e_replacement, # 5
8767             '$Eutf2::re_r=CORE::eval $Eutf2::re_r; ' x $e_modifier, # 6
8768             $variable, # 7
8769             $prematch, # 8
8770             );
8771             }
8772             }
8773 95 50       581  
8774 132         423 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
8775             if ($my ne '') {
8776             $sub = "($my, $sub)[1]";
8777             }
8778 0         0  
8779 132         215 # clear s/// variable
8780             $sub_variable = '';
8781 132         275 $bind_operator = '';
8782              
8783             return $sub;
8784             }
8785              
8786             #
8787             # escape regexp of split qr//
8788 132     101 0 2264 #
8789 101   100     621 sub e_split {
8790             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8791 101         435 $modifier ||= '';
8792 101 50       163  
8793 101         354 $modifier =~ tr/p//d;
8794 0         0 if ($modifier =~ /([adlu])/oxms) {
8795 0 0       0 my $line = 0;
8796 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
8797 0         0 if ($filename ne __FILE__) {
8798             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
8799             last;
8800 0         0 }
8801             }
8802             die qq{Unsupported modifier "$1" used at line $line.\n};
8803 0         0 }
8804              
8805             $slash = 'div';
8806 101 50       185  
8807 101         212 # /b /B modifier
8808             if ($modifier =~ tr/bB//d) {
8809             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
8810 0 50       0 }
8811 101         236  
8812             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
8813             my $metachar = qr/[\@\\|[\]{^]/oxms;
8814 101         369  
8815             # split regexp
8816             my @char = $string =~ /\G((?>
8817             [^\x80-\xFF\\\$\@\[\(]|(?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
8818             \\x (?>[0-9A-Fa-f]{1,2}) |
8819             \\ (?>[0-7]{2,3}) |
8820             \\c [\x40-\x5F] |
8821             \\x\{ (?>[0-9A-Fa-f]+) \} |
8822             \\o\{ (?>[0-7]+) \} |
8823             \\[bBNpP]\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
8824             \\ $q_char |
8825             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
8826             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
8827             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
8828             [\$\@] $qq_variable |
8829             \$ (?>\s* [0-9]+) |
8830             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
8831             \$ \$ (?![\w\{]) |
8832             \$ (?>\s*) \$ (?>\s*) $qq_variable |
8833             \[\^ |
8834             \[\: (?>[a-z]+) :\] |
8835             \[\:\^ (?>[a-z]+) :\] |
8836             \(\? |
8837             $q_char
8838 101         25709 ))/oxmsg;
8839 101         811  
8840 101         141 my $left_e = 0;
8841             my $right_e = 0;
8842             for (my $i=0; $i <= $#char; $i++) {
8843 101 50 33     281  
    50 33        
    100          
    100          
    50          
    50          
8844 284         1510 # "\L\u" --> "\u\L"
8845             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
8846             @char[$i,$i+1] = @char[$i+1,$i];
8847             }
8848              
8849 0         0 # "\U\l" --> "\l\U"
8850             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
8851             @char[$i,$i+1] = @char[$i+1,$i];
8852             }
8853              
8854 0         0 # octal escape sequence
8855             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
8856             $char[$i] = Eutf2::octchr($1);
8857             }
8858              
8859 1         4 # hexadecimal escape sequence
8860             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
8861             $char[$i] = Eutf2::hexchr($1);
8862             }
8863              
8864             # \b{...} --> b\{...}
8865             # \B{...} --> B\{...}
8866             # \N{CHARNAME} --> N\{CHARNAME}
8867             # \p{PROPERTY} --> p\{PROPERTY}
8868 1         3 # \P{PROPERTY} --> P\{PROPERTY}
8869             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
8870             $char[$i] = $1 . '\\' . $2;
8871             }
8872              
8873 0         0 # \p, \P, \X --> p, P, X
8874             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
8875             $char[$i] = $1;
8876 0 50 100     0 }
    100 33        
    100 33        
    100 100        
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
8877              
8878             if (0) {
8879             }
8880 284         1173  
8881 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
8882 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
8883             if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
8884             $char[$i] .= join '', splice @char, $i+1, 3;
8885 0         0 }
8886             elsif (($i+2 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+2]) == 2) and (CORE::eval(sprintf '"%s%s%s"', @char[$i..$i+2]) =~ /\A $q_char \z/oxms)) {
8887             $char[$i] .= join '', splice @char, $i+1, 2;
8888 0         0 }
8889             elsif (($i+1 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, $char[$i+1 ]) == 1) and (CORE::eval(sprintf '"%s%s"', @char[$i..$i+1]) =~ /\A $q_char \z/oxms)) {
8890             $char[$i] .= join '', splice @char, $i+1, 1;
8891             }
8892             }
8893              
8894 0         0 # open character class [...]
8895 3 50       6 elsif ($char[$i] eq '[') {
8896 3         6 my $left = $i;
8897             if ($char[$i+1] eq ']') {
8898 0         0 $i++;
8899 3 50       4 }
8900 7         12 while (1) {
8901             if (++$i > $#char) {
8902 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
8903 7         10 }
8904             if ($char[$i] eq ']') {
8905             my $right = $i;
8906 3 50       5  
8907 3         13 # [...]
  0         0  
8908             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8909             splice @char, $left, $right-$left+1, sprintf(q{@{[Eutf2::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8910 0         0 }
8911             else {
8912             splice @char, $left, $right-$left+1, Eutf2::charlist_qr(@char[$left+1..$right-1], $modifier);
8913 3         11 }
8914 3         5  
8915             $i = $left;
8916             last;
8917             }
8918             }
8919             }
8920              
8921 3         8 # open character class [^...]
8922 1 50       2 elsif ($char[$i] eq '[^') {
8923 1         4 my $left = $i;
8924             if ($char[$i+1] eq ']') {
8925 0         0 $i++;
8926 1 50       2 }
8927 2         4 while (1) {
8928             if (++$i > $#char) {
8929 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
8930 2         6 }
8931             if ($char[$i] eq ']') {
8932             my $right = $i;
8933 1 50       2  
8934 1         6 # [^...]
  0         0  
8935             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8936             splice @char, $left, $right-$left+1, sprintf(q{@{[Eutf2::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8937 0         0 }
8938             else {
8939             splice @char, $left, $right-$left+1, Eutf2::charlist_not_qr(@char[$left+1..$right-1], $modifier);
8940 1         5 }
8941 1         2  
8942             $i = $left;
8943             last;
8944             }
8945             }
8946             }
8947              
8948 1         3 # rewrite character class or escape character
8949             elsif (my $char = character_class($char[$i],$modifier)) {
8950             $char[$i] = $char;
8951             }
8952              
8953             # P.794 29.2.161. split
8954             # in Chapter 29: Functions
8955             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
8956              
8957             # P.951 split
8958             # in Chapter 27: Functions
8959             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
8960              
8961             # said "The //m modifier is assumed when you split on the pattern /^/",
8962             # but perl5.008 is not so. Therefore, this software adds //m.
8963             # (and so on)
8964              
8965 5         17 # split(m/^/) --> split(m/^/m)
8966             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
8967             $modifier .= 'm';
8968             }
8969              
8970 11 0       37 # /i modifier
8971 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eutf2::uc($char[$i]) ne Eutf2::fc($char[$i]))) {
8972             if (CORE::length(Eutf2::fc($char[$i])) == 1) {
8973             $char[$i] = '[' . Eutf2::uc($char[$i]) . Eutf2::fc($char[$i]) . ']';
8974 0         0 }
8975             else {
8976             $char[$i] = '(?:' . Eutf2::uc($char[$i]) . '|' . Eutf2::fc($char[$i]) . ')';
8977             }
8978             }
8979              
8980 0 50       0 # \u \l \U \L \F \Q \E
8981 2         9 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
8982             if ($right_e < $left_e) {
8983             $char[$i] = '\\' . $char[$i];
8984             }
8985 0         0 }
8986 0         0 elsif ($char[$i] eq '\u') {
8987             $char[$i] = '@{[Eutf2::ucfirst qq<';
8988             $left_e++;
8989 0         0 }
8990 0         0 elsif ($char[$i] eq '\l') {
8991             $char[$i] = '@{[Eutf2::lcfirst qq<';
8992             $left_e++;
8993 0         0 }
8994 0         0 elsif ($char[$i] eq '\U') {
8995             $char[$i] = '@{[Eutf2::uc qq<';
8996             $left_e++;
8997 0         0 }
8998 0         0 elsif ($char[$i] eq '\L') {
8999             $char[$i] = '@{[Eutf2::lc qq<';
9000             $left_e++;
9001 0         0 }
9002 0         0 elsif ($char[$i] eq '\F') {
9003             $char[$i] = '@{[Eutf2::fc qq<';
9004             $left_e++;
9005 0         0 }
9006 0         0 elsif ($char[$i] eq '\Q') {
9007             $char[$i] = '@{[CORE::quotemeta qq<';
9008             $left_e++;
9009 0 0       0 }
9010 0         0 elsif ($char[$i] eq '\E') {
9011 0         0 if ($right_e < $left_e) {
9012             $char[$i] = '>]}';
9013             $right_e++;
9014 0         0 }
9015             else {
9016             $char[$i] = '';
9017             }
9018 0         0 }
9019 0 0       0 elsif ($char[$i] eq '\Q') {
9020 0         0 while (1) {
9021             if (++$i > $#char) {
9022 0 0       0 last;
9023 0         0 }
9024             if ($char[$i] eq '\E') {
9025             last;
9026             }
9027             }
9028             }
9029             elsif ($char[$i] eq '\E') {
9030             }
9031              
9032 0 0       0 # $0 --> $0
9033 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
9034             if ($ignorecase) {
9035             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
9036             }
9037 0 0       0 }
9038 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
9039             if ($ignorecase) {
9040             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
9041             }
9042             }
9043              
9044             # $$ --> $$
9045             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
9046             }
9047              
9048             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
9049 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
9050 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
9051 0         0 $char[$i] = e_capture($1);
9052             if ($ignorecase) {
9053             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
9054             }
9055 0         0 }
9056 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
9057 0         0 $char[$i] = e_capture($1);
9058             if ($ignorecase) {
9059             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
9060             }
9061             }
9062              
9063 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
9064 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
9065 0         0 $char[$i] = e_capture($1.'->'.$2);
9066             if ($ignorecase) {
9067             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
9068             }
9069             }
9070              
9071 0         0 # $$foo{ ... } --> $ $foo->{ ... }
9072 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
9073 0         0 $char[$i] = e_capture($1.'->'.$2);
9074             if ($ignorecase) {
9075             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
9076             }
9077             }
9078              
9079 0         0 # $$foo
9080 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
9081 0         0 $char[$i] = e_capture($1);
9082             if ($ignorecase) {
9083             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
9084             }
9085             }
9086              
9087 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eutf2::PREMATCH()
9088 12         30 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
9089             if ($ignorecase) {
9090             $char[$i] = '@{[Eutf2::ignorecase(Eutf2::PREMATCH())]}';
9091 0         0 }
9092             else {
9093             $char[$i] = '@{[Eutf2::PREMATCH()]}';
9094             }
9095             }
9096              
9097 12 50       65 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eutf2::MATCH()
9098 12         32 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
9099             if ($ignorecase) {
9100             $char[$i] = '@{[Eutf2::ignorecase(Eutf2::MATCH())]}';
9101 0         0 }
9102             else {
9103             $char[$i] = '@{[Eutf2::MATCH()]}';
9104             }
9105             }
9106              
9107 12 50       65 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eutf2::POSTMATCH()
9108 9         23 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
9109             if ($ignorecase) {
9110             $char[$i] = '@{[Eutf2::ignorecase(Eutf2::POSTMATCH())]}';
9111 0         0 }
9112             else {
9113             $char[$i] = '@{[Eutf2::POSTMATCH()]}';
9114             }
9115             }
9116              
9117 9 0       47 # ${ foo }
9118 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
9119             if ($ignorecase) {
9120             $char[$i] = '@{[Eutf2::ignorecase(' . $1 . ')]}';
9121             }
9122             }
9123              
9124 0         0 # ${ ... }
9125 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
9126 0         0 $char[$i] = e_capture($1);
9127             if ($ignorecase) {
9128             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
9129             }
9130             }
9131              
9132 0         0 # $scalar or @array
9133 3 50       14 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
9134 3         30 $char[$i] = e_string($char[$i]);
9135             if ($ignorecase) {
9136             $char[$i] = '@{[Eutf2::ignorecase(' . $char[$i] . ')]}';
9137             }
9138             }
9139              
9140 0 100       0 # quote character before ? + * {
9141             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
9142             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
9143 7         42 }
9144             else {
9145             $char[$i-1] = '(?:' . $char[$i-1] . ')';
9146             }
9147             }
9148             }
9149 4         29  
9150 101 50       198 # make regexp string
9151 101         219 $modifier =~ tr/i//d;
9152             if ($left_e > $right_e) {
9153 0         0 return join '', 'Eutf2::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
9154             }
9155             return join '', 'Eutf2::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
9156             }
9157              
9158             #
9159             # escape regexp of split qr''
9160 101     0 0 1565 #
9161 0   0       sub e_split_q {
9162             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
9163 0           $modifier ||= '';
9164 0 0          
9165 0           $modifier =~ tr/p//d;
9166 0           if ($modifier =~ /([adlu])/oxms) {
9167 0 0         my $line = 0;
9168 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
9169 0           if ($filename ne __FILE__) {
9170             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
9171             last;
9172 0           }
9173             }
9174             die qq{Unsupported modifier "$1" used at line $line.\n};
9175 0           }
9176              
9177             $slash = 'div';
9178 0 0          
9179 0           # /b /B modifier
9180             if ($modifier =~ tr/bB//d) {
9181             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
9182 0 0         }
9183              
9184             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
9185 0            
9186             # split regexp
9187             my @char = $string =~ /\G((?>
9188             [^\x80-\xFF\\\[] |
9189             (?:[\xC2-\xDF]|[\xE0-\xE0][\xA0-\xBF]|[\xE1-\xEC][\x80-\xBF]|[\xED-\xED][\x80-\x9F]|[\xEE-\xEF][\x80-\xBF]|[\xF0-\xF0][\x90-\xBF][\x80-\xBF]|[\xF1-\xF3][\x80-\xBF][\x80-\xBF]|[\xF4-\xF4][\x80-\x8F][\x80-\xBF])[\x80-\xBF] |
9190             \[\^ |
9191             \[\: (?>[a-z]+) \:\] |
9192             \[\:\^ (?>[a-z]+) \:\] |
9193             \\ (?:$q_char) |
9194             (?:$q_char)
9195             ))/oxmsg;
9196 0            
9197 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
9198             for (my $i=0; $i <= $#char; $i++) {
9199             if (0) {
9200             }
9201 0            
9202 0           # open character class [...]
9203 0 0         elsif ($char[$i] eq '[') {
9204 0           my $left = $i;
9205             if ($char[$i+1] eq ']') {
9206 0           $i++;
9207 0 0         }
9208 0           while (1) {
9209             if (++$i > $#char) {
9210 0 0         die __FILE__, ": Unmatched [] in regexp\n";
9211 0           }
9212             if ($char[$i] eq ']') {
9213             my $right = $i;
9214 0            
9215             # [...]
9216 0           splice @char, $left, $right-$left+1, Eutf2::charlist_qr(@char[$left+1..$right-1], $modifier);
9217 0            
9218             $i = $left;
9219             last;
9220             }
9221             }
9222             }
9223              
9224 0           # open character class [^...]
9225 0 0         elsif ($char[$i] eq '[^') {
9226 0           my $left = $i;
9227             if ($char[$i+1] eq ']') {
9228 0           $i++;
9229 0 0         }
9230 0           while (1) {
9231             if (++$i > $#char) {
9232 0 0         die __FILE__, ": Unmatched [] in regexp\n";
9233 0           }
9234             if ($char[$i] eq ']') {
9235             my $right = $i;
9236 0            
9237             # [^...]
9238 0           splice @char, $left, $right-$left+1, Eutf2::charlist_not_qr(@char[$left+1..$right-1], $modifier);
9239 0            
9240             $i = $left;
9241             last;
9242             }
9243             }
9244             }
9245              
9246 0           # rewrite character class or escape character
9247             elsif (my $char = character_class($char[$i],$modifier)) {
9248             $char[$i] = $char;
9249             }
9250              
9251 0           # split(m/^/) --> split(m/^/m)
9252             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
9253             $modifier .= 'm';
9254             }
9255              
9256 0 0         # /i modifier
9257 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eutf2::uc($char[$i]) ne Eutf2::fc($char[$i]))) {
9258             if (CORE::length(Eutf2::fc($char[$i])) == 1) {
9259             $char[$i] = '[' . Eutf2::uc($char[$i]) . Eutf2::fc($char[$i]) . ']';
9260 0           }
9261             else {
9262             $char[$i] = '(?:' . Eutf2::uc($char[$i]) . '|' . Eutf2::fc($char[$i]) . ')';
9263             }
9264             }
9265              
9266 0 0         # quote character before ? + * {
9267             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
9268             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
9269 0           }
9270             else {
9271             $char[$i-1] = '(?:' . $char[$i-1] . ')';
9272             }
9273             }
9274 0           }
9275 0            
9276             $modifier =~ tr/i//d;
9277             return join '', 'Eutf2::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
9278             }
9279              
9280             #
9281             # instead of Carp::carp
9282 0     0 0   #
9283 0           sub carp {
9284             my($package,$filename,$line) = caller(1);
9285             print STDERR "@_ at $filename line $line.\n";
9286             }
9287              
9288             #
9289             # instead of Carp::croak
9290 0     0 0   #
9291 0           sub croak {
9292 0           my($package,$filename,$line) = caller(1);
9293             print STDERR "@_ at $filename line $line.\n";
9294             die "\n";
9295             }
9296              
9297             #
9298             # instead of Carp::cluck
9299 0     0 0   #
9300 0           sub cluck {
9301 0           my $i = 0;
9302 0           my @cluck = ();
9303 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
9304             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
9305 0           $i++;
9306 0           }
9307 0           print STDERR CORE::reverse @cluck;
9308             print STDERR "\n";
9309             print STDERR @_;
9310             }
9311              
9312             #
9313             # instead of Carp::confess
9314 0     0 0   #
9315 0           sub confess {
9316 0           my $i = 0;
9317 0           my @confess = ();
9318 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
9319             push @confess, "[$i] $filename($line) $package::$subroutine\n";
9320 0           $i++;
9321 0           }
9322 0           print STDERR CORE::reverse @confess;
9323 0           print STDERR "\n";
9324             print STDERR @_;
9325             die "\n";
9326             }
9327              
9328             1;
9329              
9330             __END__