File Coverage

blib/lib/Eoldutf8.pm
Criterion Covered Total %
statement 1045 3230 32.3
branch 1093 2772 39.4
condition 122 355 34.3
subroutine 55 110 50.0
pod 7 74 9.4
total 2322 6541 35.5


line stmt bran cond sub pod time code
1             package Eoldutf8;
2 306     306   2001 use strict;
  306         616  
  306         11377  
3             ######################################################################
4             #
5             # Eoldutf8 - Run-time routines for OldUTF8.pm
6             #
7             # http://search.cpan.org/dist/Char-OldUTF8/
8             #
9             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
10             ######################################################################
11              
12 306     306   5191 use 5.00503; # Galapagos Consensus 1998 for primetools
  306         1106  
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   1397 use vars qw($VERSION);
  306         530  
  306         52206  
28             $VERSION = '1.13';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 306 50   306   2906 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 306         652 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 306         49159 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   25590 CORE::eval q{
  306     306   2055  
  306     88   23216  
  306         42913  
  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       132928 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 (Eoldutf8::index($name,'::') >= 0) {
83 0         0 return $name;
84             }
85             elsif (Eoldutf8::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   2182 no strict qw(refs);
  306         564  
  306         26187  
118 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
119             }
120             else {
121 306     306   3158 no strict qw(refs);
  306     0   588  
  306         63043  
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{(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF]|[\x00-\x7F\xF5-\xFF]};
153 306     306   2091 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  306         558  
  306         19235  
154 306     306   2060 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  306         689  
  306         4458397  
155              
156             #
157             # old UTF-8 character range per length
158             #
159             my %range_tr = ();
160              
161             #
162             # old 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 Eoldutf8 \z/oxms) {
178             %range_tr = (
179             1 => [ [0x00..0x7F],
180             [0xF5..0xFF], # malformed octet
181             ],
182             2 => [ [0xC0..0xDF],[0x80..0xBF],
183             ],
184             3 => [ [0xE0..0xEF],[0x80..0xBF],[0x80..0xBF],
185             ],
186             4 => [ [0xF0..0xF4],[0x80..0xBF],[0x80..0xBF],[0x80..0xBF],
187             ],
188             );
189              
190             # CaseFolding-12.0.0.txt
191             # Date: 2019-01-22, 08:18:22 GMT
192             # c 2019 UnicodeR, Inc.
193             # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
194             # For terms of use, see http://www.unicode.org/terms_of_use.html
195             #
196             # Unicode Character Database
197             # For documentation, see http://www.unicode.org/reports/tr44/
198              
199             # you can use "make_CaseFolding.pl" to update this hash
200              
201             %fc = (
202             "\x41" => "\x61", # LATIN CAPITAL LETTER A
203             "\x42" => "\x62", # LATIN CAPITAL LETTER B
204             "\x43" => "\x63", # LATIN CAPITAL LETTER C
205             "\x44" => "\x64", # LATIN CAPITAL LETTER D
206             "\x45" => "\x65", # LATIN CAPITAL LETTER E
207             "\x46" => "\x66", # LATIN CAPITAL LETTER F
208             "\x47" => "\x67", # LATIN CAPITAL LETTER G
209             "\x48" => "\x68", # LATIN CAPITAL LETTER H
210             "\x49" => "\x69", # LATIN CAPITAL LETTER I
211             "\x4A" => "\x6A", # LATIN CAPITAL LETTER J
212             "\x4B" => "\x6B", # LATIN CAPITAL LETTER K
213             "\x4C" => "\x6C", # LATIN CAPITAL LETTER L
214             "\x4D" => "\x6D", # LATIN CAPITAL LETTER M
215             "\x4E" => "\x6E", # LATIN CAPITAL LETTER N
216             "\x4F" => "\x6F", # LATIN CAPITAL LETTER O
217             "\x50" => "\x70", # LATIN CAPITAL LETTER P
218             "\x51" => "\x71", # LATIN CAPITAL LETTER Q
219             "\x52" => "\x72", # LATIN CAPITAL LETTER R
220             "\x53" => "\x73", # LATIN CAPITAL LETTER S
221             "\x54" => "\x74", # LATIN CAPITAL LETTER T
222             "\x55" => "\x75", # LATIN CAPITAL LETTER U
223             "\x56" => "\x76", # LATIN CAPITAL LETTER V
224             "\x57" => "\x77", # LATIN CAPITAL LETTER W
225             "\x58" => "\x78", # LATIN CAPITAL LETTER X
226             "\x59" => "\x79", # LATIN CAPITAL LETTER Y
227             "\x5A" => "\x7A", # LATIN CAPITAL LETTER Z
228             "\xC2\xB5" => "\xCE\xBC", # MICRO SIGN
229             "\xC3\x80" => "\xC3\xA0", # LATIN CAPITAL LETTER A WITH GRAVE
230             "\xC3\x81" => "\xC3\xA1", # LATIN CAPITAL LETTER A WITH ACUTE
231             "\xC3\x82" => "\xC3\xA2", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
232             "\xC3\x83" => "\xC3\xA3", # LATIN CAPITAL LETTER A WITH TILDE
233             "\xC3\x84" => "\xC3\xA4", # LATIN CAPITAL LETTER A WITH DIAERESIS
234             "\xC3\x85" => "\xC3\xA5", # LATIN CAPITAL LETTER A WITH RING ABOVE
235             "\xC3\x86" => "\xC3\xA6", # LATIN CAPITAL LETTER AE
236             "\xC3\x87" => "\xC3\xA7", # LATIN CAPITAL LETTER C WITH CEDILLA
237             "\xC3\x88" => "\xC3\xA8", # LATIN CAPITAL LETTER E WITH GRAVE
238             "\xC3\x89" => "\xC3\xA9", # LATIN CAPITAL LETTER E WITH ACUTE
239             "\xC3\x8A" => "\xC3\xAA", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
240             "\xC3\x8B" => "\xC3\xAB", # LATIN CAPITAL LETTER E WITH DIAERESIS
241             "\xC3\x8C" => "\xC3\xAC", # LATIN CAPITAL LETTER I WITH GRAVE
242             "\xC3\x8D" => "\xC3\xAD", # LATIN CAPITAL LETTER I WITH ACUTE
243             "\xC3\x8E" => "\xC3\xAE", # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
244             "\xC3\x8F" => "\xC3\xAF", # LATIN CAPITAL LETTER I WITH DIAERESIS
245             "\xC3\x90" => "\xC3\xB0", # LATIN CAPITAL LETTER ETH
246             "\xC3\x91" => "\xC3\xB1", # LATIN CAPITAL LETTER N WITH TILDE
247             "\xC3\x92" => "\xC3\xB2", # LATIN CAPITAL LETTER O WITH GRAVE
248             "\xC3\x93" => "\xC3\xB3", # LATIN CAPITAL LETTER O WITH ACUTE
249             "\xC3\x94" => "\xC3\xB4", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
250             "\xC3\x95" => "\xC3\xB5", # LATIN CAPITAL LETTER O WITH TILDE
251             "\xC3\x96" => "\xC3\xB6", # LATIN CAPITAL LETTER O WITH DIAERESIS
252             "\xC3\x98" => "\xC3\xB8", # LATIN CAPITAL LETTER O WITH STROKE
253             "\xC3\x99" => "\xC3\xB9", # LATIN CAPITAL LETTER U WITH GRAVE
254             "\xC3\x9A" => "\xC3\xBA", # LATIN CAPITAL LETTER U WITH ACUTE
255             "\xC3\x9B" => "\xC3\xBB", # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
256             "\xC3\x9C" => "\xC3\xBC", # LATIN CAPITAL LETTER U WITH DIAERESIS
257             "\xC3\x9D" => "\xC3\xBD", # LATIN CAPITAL LETTER Y WITH ACUTE
258             "\xC3\x9E" => "\xC3\xBE", # LATIN CAPITAL LETTER THORN
259             "\xC3\x9F" => "\x73\x73", # LATIN SMALL LETTER SHARP S
260             "\xC4\x80" => "\xC4\x81", # LATIN CAPITAL LETTER A WITH MACRON
261             "\xC4\x82" => "\xC4\x83", # LATIN CAPITAL LETTER A WITH BREVE
262             "\xC4\x84" => "\xC4\x85", # LATIN CAPITAL LETTER A WITH OGONEK
263             "\xC4\x86" => "\xC4\x87", # LATIN CAPITAL LETTER C WITH ACUTE
264             "\xC4\x88" => "\xC4\x89", # LATIN CAPITAL LETTER C WITH CIRCUMFLEX
265             "\xC4\x8A" => "\xC4\x8B", # LATIN CAPITAL LETTER C WITH DOT ABOVE
266             "\xC4\x8C" => "\xC4\x8D", # LATIN CAPITAL LETTER C WITH CARON
267             "\xC4\x8E" => "\xC4\x8F", # LATIN CAPITAL LETTER D WITH CARON
268             "\xC4\x90" => "\xC4\x91", # LATIN CAPITAL LETTER D WITH STROKE
269             "\xC4\x92" => "\xC4\x93", # LATIN CAPITAL LETTER E WITH MACRON
270             "\xC4\x94" => "\xC4\x95", # LATIN CAPITAL LETTER E WITH BREVE
271             "\xC4\x96" => "\xC4\x97", # LATIN CAPITAL LETTER E WITH DOT ABOVE
272             "\xC4\x98" => "\xC4\x99", # LATIN CAPITAL LETTER E WITH OGONEK
273             "\xC4\x9A" => "\xC4\x9B", # LATIN CAPITAL LETTER E WITH CARON
274             "\xC4\x9C" => "\xC4\x9D", # LATIN CAPITAL LETTER G WITH CIRCUMFLEX
275             "\xC4\x9E" => "\xC4\x9F", # LATIN CAPITAL LETTER G WITH BREVE
276             "\xC4\xA0" => "\xC4\xA1", # LATIN CAPITAL LETTER G WITH DOT ABOVE
277             "\xC4\xA2" => "\xC4\xA3", # LATIN CAPITAL LETTER G WITH CEDILLA
278             "\xC4\xA4" => "\xC4\xA5", # LATIN CAPITAL LETTER H WITH CIRCUMFLEX
279             "\xC4\xA6" => "\xC4\xA7", # LATIN CAPITAL LETTER H WITH STROKE
280             "\xC4\xA8" => "\xC4\xA9", # LATIN CAPITAL LETTER I WITH TILDE
281             "\xC4\xAA" => "\xC4\xAB", # LATIN CAPITAL LETTER I WITH MACRON
282             "\xC4\xAC" => "\xC4\xAD", # LATIN CAPITAL LETTER I WITH BREVE
283             "\xC4\xAE" => "\xC4\xAF", # LATIN CAPITAL LETTER I WITH OGONEK
284             "\xC4\xB0" => "\x69\xCC\x87", # LATIN CAPITAL LETTER I WITH DOT ABOVE
285             "\xC4\xB2" => "\xC4\xB3", # LATIN CAPITAL LIGATURE IJ
286             "\xC4\xB4" => "\xC4\xB5", # LATIN CAPITAL LETTER J WITH CIRCUMFLEX
287             "\xC4\xB6" => "\xC4\xB7", # LATIN CAPITAL LETTER K WITH CEDILLA
288             "\xC4\xB9" => "\xC4\xBA", # LATIN CAPITAL LETTER L WITH ACUTE
289             "\xC4\xBB" => "\xC4\xBC", # LATIN CAPITAL LETTER L WITH CEDILLA
290             "\xC4\xBD" => "\xC4\xBE", # LATIN CAPITAL LETTER L WITH CARON
291             "\xC4\xBF" => "\xC5\x80", # LATIN CAPITAL LETTER L WITH MIDDLE DOT
292             "\xC5\x81" => "\xC5\x82", # LATIN CAPITAL LETTER L WITH STROKE
293             "\xC5\x83" => "\xC5\x84", # LATIN CAPITAL LETTER N WITH ACUTE
294             "\xC5\x85" => "\xC5\x86", # LATIN CAPITAL LETTER N WITH CEDILLA
295             "\xC5\x87" => "\xC5\x88", # LATIN CAPITAL LETTER N WITH CARON
296             "\xC5\x89" => "\xCA\xBC\x6E", # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
297             "\xC5\x8A" => "\xC5\x8B", # LATIN CAPITAL LETTER ENG
298             "\xC5\x8C" => "\xC5\x8D", # LATIN CAPITAL LETTER O WITH MACRON
299             "\xC5\x8E" => "\xC5\x8F", # LATIN CAPITAL LETTER O WITH BREVE
300             "\xC5\x90" => "\xC5\x91", # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
301             "\xC5\x92" => "\xC5\x93", # LATIN CAPITAL LIGATURE OE
302             "\xC5\x94" => "\xC5\x95", # LATIN CAPITAL LETTER R WITH ACUTE
303             "\xC5\x96" => "\xC5\x97", # LATIN CAPITAL LETTER R WITH CEDILLA
304             "\xC5\x98" => "\xC5\x99", # LATIN CAPITAL LETTER R WITH CARON
305             "\xC5\x9A" => "\xC5\x9B", # LATIN CAPITAL LETTER S WITH ACUTE
306             "\xC5\x9C" => "\xC5\x9D", # LATIN CAPITAL LETTER S WITH CIRCUMFLEX
307             "\xC5\x9E" => "\xC5\x9F", # LATIN CAPITAL LETTER S WITH CEDILLA
308             "\xC5\xA0" => "\xC5\xA1", # LATIN CAPITAL LETTER S WITH CARON
309             "\xC5\xA2" => "\xC5\xA3", # LATIN CAPITAL LETTER T WITH CEDILLA
310             "\xC5\xA4" => "\xC5\xA5", # LATIN CAPITAL LETTER T WITH CARON
311             "\xC5\xA6" => "\xC5\xA7", # LATIN CAPITAL LETTER T WITH STROKE
312             "\xC5\xA8" => "\xC5\xA9", # LATIN CAPITAL LETTER U WITH TILDE
313             "\xC5\xAA" => "\xC5\xAB", # LATIN CAPITAL LETTER U WITH MACRON
314             "\xC5\xAC" => "\xC5\xAD", # LATIN CAPITAL LETTER U WITH BREVE
315             "\xC5\xAE" => "\xC5\xAF", # LATIN CAPITAL LETTER U WITH RING ABOVE
316             "\xC5\xB0" => "\xC5\xB1", # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
317             "\xC5\xB2" => "\xC5\xB3", # LATIN CAPITAL LETTER U WITH OGONEK
318             "\xC5\xB4" => "\xC5\xB5", # LATIN CAPITAL LETTER W WITH CIRCUMFLEX
319             "\xC5\xB6" => "\xC5\xB7", # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
320             "\xC5\xB8" => "\xC3\xBF", # LATIN CAPITAL LETTER Y WITH DIAERESIS
321             "\xC5\xB9" => "\xC5\xBA", # LATIN CAPITAL LETTER Z WITH ACUTE
322             "\xC5\xBB" => "\xC5\xBC", # LATIN CAPITAL LETTER Z WITH DOT ABOVE
323             "\xC5\xBD" => "\xC5\xBE", # LATIN CAPITAL LETTER Z WITH CARON
324             "\xC5\xBF" => "\x73", # LATIN SMALL LETTER LONG S
325             "\xC6\x81" => "\xC9\x93", # LATIN CAPITAL LETTER B WITH HOOK
326             "\xC6\x82" => "\xC6\x83", # LATIN CAPITAL LETTER B WITH TOPBAR
327             "\xC6\x84" => "\xC6\x85", # LATIN CAPITAL LETTER TONE SIX
328             "\xC6\x86" => "\xC9\x94", # LATIN CAPITAL LETTER OPEN O
329             "\xC6\x87" => "\xC6\x88", # LATIN CAPITAL LETTER C WITH HOOK
330             "\xC6\x89" => "\xC9\x96", # LATIN CAPITAL LETTER AFRICAN D
331             "\xC6\x8A" => "\xC9\x97", # LATIN CAPITAL LETTER D WITH HOOK
332             "\xC6\x8B" => "\xC6\x8C", # LATIN CAPITAL LETTER D WITH TOPBAR
333             "\xC6\x8E" => "\xC7\x9D", # LATIN CAPITAL LETTER REVERSED E
334             "\xC6\x8F" => "\xC9\x99", # LATIN CAPITAL LETTER SCHWA
335             "\xC6\x90" => "\xC9\x9B", # LATIN CAPITAL LETTER OPEN E
336             "\xC6\x91" => "\xC6\x92", # LATIN CAPITAL LETTER F WITH HOOK
337             "\xC6\x93" => "\xC9\xA0", # LATIN CAPITAL LETTER G WITH HOOK
338             "\xC6\x94" => "\xC9\xA3", # LATIN CAPITAL LETTER GAMMA
339             "\xC6\x96" => "\xC9\xA9", # LATIN CAPITAL LETTER IOTA
340             "\xC6\x97" => "\xC9\xA8", # LATIN CAPITAL LETTER I WITH STROKE
341             "\xC6\x98" => "\xC6\x99", # LATIN CAPITAL LETTER K WITH HOOK
342             "\xC6\x9C" => "\xC9\xAF", # LATIN CAPITAL LETTER TURNED M
343             "\xC6\x9D" => "\xC9\xB2", # LATIN CAPITAL LETTER N WITH LEFT HOOK
344             "\xC6\x9F" => "\xC9\xB5", # LATIN CAPITAL LETTER O WITH MIDDLE TILDE
345             "\xC6\xA0" => "\xC6\xA1", # LATIN CAPITAL LETTER O WITH HORN
346             "\xC6\xA2" => "\xC6\xA3", # LATIN CAPITAL LETTER OI
347             "\xC6\xA4" => "\xC6\xA5", # LATIN CAPITAL LETTER P WITH HOOK
348             "\xC6\xA6" => "\xCA\x80", # LATIN LETTER YR
349             "\xC6\xA7" => "\xC6\xA8", # LATIN CAPITAL LETTER TONE TWO
350             "\xC6\xA9" => "\xCA\x83", # LATIN CAPITAL LETTER ESH
351             "\xC6\xAC" => "\xC6\xAD", # LATIN CAPITAL LETTER T WITH HOOK
352             "\xC6\xAE" => "\xCA\x88", # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
353             "\xC6\xAF" => "\xC6\xB0", # LATIN CAPITAL LETTER U WITH HORN
354             "\xC6\xB1" => "\xCA\x8A", # LATIN CAPITAL LETTER UPSILON
355             "\xC6\xB2" => "\xCA\x8B", # LATIN CAPITAL LETTER V WITH HOOK
356             "\xC6\xB3" => "\xC6\xB4", # LATIN CAPITAL LETTER Y WITH HOOK
357             "\xC6\xB5" => "\xC6\xB6", # LATIN CAPITAL LETTER Z WITH STROKE
358             "\xC6\xB7" => "\xCA\x92", # LATIN CAPITAL LETTER EZH
359             "\xC6\xB8" => "\xC6\xB9", # LATIN CAPITAL LETTER EZH REVERSED
360             "\xC6\xBC" => "\xC6\xBD", # LATIN CAPITAL LETTER TONE FIVE
361             "\xC7\x84" => "\xC7\x86", # LATIN CAPITAL LETTER DZ WITH CARON
362             "\xC7\x85" => "\xC7\x86", # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
363             "\xC7\x87" => "\xC7\x89", # LATIN CAPITAL LETTER LJ
364             "\xC7\x88" => "\xC7\x89", # LATIN CAPITAL LETTER L WITH SMALL LETTER J
365             "\xC7\x8A" => "\xC7\x8C", # LATIN CAPITAL LETTER NJ
366             "\xC7\x8B" => "\xC7\x8C", # LATIN CAPITAL LETTER N WITH SMALL LETTER J
367             "\xC7\x8D" => "\xC7\x8E", # LATIN CAPITAL LETTER A WITH CARON
368             "\xC7\x8F" => "\xC7\x90", # LATIN CAPITAL LETTER I WITH CARON
369             "\xC7\x91" => "\xC7\x92", # LATIN CAPITAL LETTER O WITH CARON
370             "\xC7\x93" => "\xC7\x94", # LATIN CAPITAL LETTER U WITH CARON
371             "\xC7\x95" => "\xC7\x96", # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
372             "\xC7\x97" => "\xC7\x98", # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
373             "\xC7\x99" => "\xC7\x9A", # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
374             "\xC7\x9B" => "\xC7\x9C", # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
375             "\xC7\x9E" => "\xC7\x9F", # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
376             "\xC7\xA0" => "\xC7\xA1", # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
377             "\xC7\xA2" => "\xC7\xA3", # LATIN CAPITAL LETTER AE WITH MACRON
378             "\xC7\xA4" => "\xC7\xA5", # LATIN CAPITAL LETTER G WITH STROKE
379             "\xC7\xA6" => "\xC7\xA7", # LATIN CAPITAL LETTER G WITH CARON
380             "\xC7\xA8" => "\xC7\xA9", # LATIN CAPITAL LETTER K WITH CARON
381             "\xC7\xAA" => "\xC7\xAB", # LATIN CAPITAL LETTER O WITH OGONEK
382             "\xC7\xAC" => "\xC7\xAD", # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
383             "\xC7\xAE" => "\xC7\xAF", # LATIN CAPITAL LETTER EZH WITH CARON
384             "\xC7\xB0" => "\x6A\xCC\x8C", # LATIN SMALL LETTER J WITH CARON
385             "\xC7\xB1" => "\xC7\xB3", # LATIN CAPITAL LETTER DZ
386             "\xC7\xB2" => "\xC7\xB3", # LATIN CAPITAL LETTER D WITH SMALL LETTER Z
387             "\xC7\xB4" => "\xC7\xB5", # LATIN CAPITAL LETTER G WITH ACUTE
388             "\xC7\xB6" => "\xC6\x95", # LATIN CAPITAL LETTER HWAIR
389             "\xC7\xB7" => "\xC6\xBF", # LATIN CAPITAL LETTER WYNN
390             "\xC7\xB8" => "\xC7\xB9", # LATIN CAPITAL LETTER N WITH GRAVE
391             "\xC7\xBA" => "\xC7\xBB", # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
392             "\xC7\xBC" => "\xC7\xBD", # LATIN CAPITAL LETTER AE WITH ACUTE
393             "\xC7\xBE" => "\xC7\xBF", # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
394             "\xC8\x80" => "\xC8\x81", # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
395             "\xC8\x82" => "\xC8\x83", # LATIN CAPITAL LETTER A WITH INVERTED BREVE
396             "\xC8\x84" => "\xC8\x85", # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
397             "\xC8\x86" => "\xC8\x87", # LATIN CAPITAL LETTER E WITH INVERTED BREVE
398             "\xC8\x88" => "\xC8\x89", # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
399             "\xC8\x8A" => "\xC8\x8B", # LATIN CAPITAL LETTER I WITH INVERTED BREVE
400             "\xC8\x8C" => "\xC8\x8D", # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
401             "\xC8\x8E" => "\xC8\x8F", # LATIN CAPITAL LETTER O WITH INVERTED BREVE
402             "\xC8\x90" => "\xC8\x91", # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
403             "\xC8\x92" => "\xC8\x93", # LATIN CAPITAL LETTER R WITH INVERTED BREVE
404             "\xC8\x94" => "\xC8\x95", # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
405             "\xC8\x96" => "\xC8\x97", # LATIN CAPITAL LETTER U WITH INVERTED BREVE
406             "\xC8\x98" => "\xC8\x99", # LATIN CAPITAL LETTER S WITH COMMA BELOW
407             "\xC8\x9A" => "\xC8\x9B", # LATIN CAPITAL LETTER T WITH COMMA BELOW
408             "\xC8\x9C" => "\xC8\x9D", # LATIN CAPITAL LETTER YOGH
409             "\xC8\x9E" => "\xC8\x9F", # LATIN CAPITAL LETTER H WITH CARON
410             "\xC8\xA0" => "\xC6\x9E", # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
411             "\xC8\xA2" => "\xC8\xA3", # LATIN CAPITAL LETTER OU
412             "\xC8\xA4" => "\xC8\xA5", # LATIN CAPITAL LETTER Z WITH HOOK
413             "\xC8\xA6" => "\xC8\xA7", # LATIN CAPITAL LETTER A WITH DOT ABOVE
414             "\xC8\xA8" => "\xC8\xA9", # LATIN CAPITAL LETTER E WITH CEDILLA
415             "\xC8\xAA" => "\xC8\xAB", # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
416             "\xC8\xAC" => "\xC8\xAD", # LATIN CAPITAL LETTER O WITH TILDE AND MACRON
417             "\xC8\xAE" => "\xC8\xAF", # LATIN CAPITAL LETTER O WITH DOT ABOVE
418             "\xC8\xB0" => "\xC8\xB1", # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
419             "\xC8\xB2" => "\xC8\xB3", # LATIN CAPITAL LETTER Y WITH MACRON
420             "\xC8\xBA" => "\xE2\xB1\xA5", # LATIN CAPITAL LETTER A WITH STROKE
421             "\xC8\xBB" => "\xC8\xBC", # LATIN CAPITAL LETTER C WITH STROKE
422             "\xC8\xBD" => "\xC6\x9A", # LATIN CAPITAL LETTER L WITH BAR
423             "\xC8\xBE" => "\xE2\xB1\xA6", # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
424             "\xC9\x81" => "\xC9\x82", # LATIN CAPITAL LETTER GLOTTAL STOP
425             "\xC9\x83" => "\xC6\x80", # LATIN CAPITAL LETTER B WITH STROKE
426             "\xC9\x84" => "\xCA\x89", # LATIN CAPITAL LETTER U BAR
427             "\xC9\x85" => "\xCA\x8C", # LATIN CAPITAL LETTER TURNED V
428             "\xC9\x86" => "\xC9\x87", # LATIN CAPITAL LETTER E WITH STROKE
429             "\xC9\x88" => "\xC9\x89", # LATIN CAPITAL LETTER J WITH STROKE
430             "\xC9\x8A" => "\xC9\x8B", # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
431             "\xC9\x8C" => "\xC9\x8D", # LATIN CAPITAL LETTER R WITH STROKE
432             "\xC9\x8E" => "\xC9\x8F", # LATIN CAPITAL LETTER Y WITH STROKE
433             "\xCD\x85" => "\xCE\xB9", # COMBINING GREEK YPOGEGRAMMENI
434             "\xCD\xB0" => "\xCD\xB1", # GREEK CAPITAL LETTER HETA
435             "\xCD\xB2" => "\xCD\xB3", # GREEK CAPITAL LETTER ARCHAIC SAMPI
436             "\xCD\xB6" => "\xCD\xB7", # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA
437             "\xCD\xBF" => "\xCF\xB3", # GREEK CAPITAL LETTER YOT
438             "\xCE\x86" => "\xCE\xAC", # GREEK CAPITAL LETTER ALPHA WITH TONOS
439             "\xCE\x88" => "\xCE\xAD", # GREEK CAPITAL LETTER EPSILON WITH TONOS
440             "\xCE\x89" => "\xCE\xAE", # GREEK CAPITAL LETTER ETA WITH TONOS
441             "\xCE\x8A" => "\xCE\xAF", # GREEK CAPITAL LETTER IOTA WITH TONOS
442             "\xCE\x8C" => "\xCF\x8C", # GREEK CAPITAL LETTER OMICRON WITH TONOS
443             "\xCE\x8E" => "\xCF\x8D", # GREEK CAPITAL LETTER UPSILON WITH TONOS
444             "\xCE\x8F" => "\xCF\x8E", # GREEK CAPITAL LETTER OMEGA WITH TONOS
445             "\xCE\x90" => "\xCE\xB9\xCC\x88\xCC\x81", # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
446             "\xCE\x91" => "\xCE\xB1", # GREEK CAPITAL LETTER ALPHA
447             "\xCE\x92" => "\xCE\xB2", # GREEK CAPITAL LETTER BETA
448             "\xCE\x93" => "\xCE\xB3", # GREEK CAPITAL LETTER GAMMA
449             "\xCE\x94" => "\xCE\xB4", # GREEK CAPITAL LETTER DELTA
450             "\xCE\x95" => "\xCE\xB5", # GREEK CAPITAL LETTER EPSILON
451             "\xCE\x96" => "\xCE\xB6", # GREEK CAPITAL LETTER ZETA
452             "\xCE\x97" => "\xCE\xB7", # GREEK CAPITAL LETTER ETA
453             "\xCE\x98" => "\xCE\xB8", # GREEK CAPITAL LETTER THETA
454             "\xCE\x99" => "\xCE\xB9", # GREEK CAPITAL LETTER IOTA
455             "\xCE\x9A" => "\xCE\xBA", # GREEK CAPITAL LETTER KAPPA
456             "\xCE\x9B" => "\xCE\xBB", # GREEK CAPITAL LETTER LAMDA
457             "\xCE\x9C" => "\xCE\xBC", # GREEK CAPITAL LETTER MU
458             "\xCE\x9D" => "\xCE\xBD", # GREEK CAPITAL LETTER NU
459             "\xCE\x9E" => "\xCE\xBE", # GREEK CAPITAL LETTER XI
460             "\xCE\x9F" => "\xCE\xBF", # GREEK CAPITAL LETTER OMICRON
461             "\xCE\xA0" => "\xCF\x80", # GREEK CAPITAL LETTER PI
462             "\xCE\xA1" => "\xCF\x81", # GREEK CAPITAL LETTER RHO
463             "\xCE\xA3" => "\xCF\x83", # GREEK CAPITAL LETTER SIGMA
464             "\xCE\xA4" => "\xCF\x84", # GREEK CAPITAL LETTER TAU
465             "\xCE\xA5" => "\xCF\x85", # GREEK CAPITAL LETTER UPSILON
466             "\xCE\xA6" => "\xCF\x86", # GREEK CAPITAL LETTER PHI
467             "\xCE\xA7" => "\xCF\x87", # GREEK CAPITAL LETTER CHI
468             "\xCE\xA8" => "\xCF\x88", # GREEK CAPITAL LETTER PSI
469             "\xCE\xA9" => "\xCF\x89", # GREEK CAPITAL LETTER OMEGA
470             "\xCE\xAA" => "\xCF\x8A", # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
471             "\xCE\xAB" => "\xCF\x8B", # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
472             "\xCE\xB0" => "\xCF\x85\xCC\x88\xCC\x81", # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
473             "\xCF\x82" => "\xCF\x83", # GREEK SMALL LETTER FINAL SIGMA
474             "\xCF\x8F" => "\xCF\x97", # GREEK CAPITAL KAI SYMBOL
475             "\xCF\x90" => "\xCE\xB2", # GREEK BETA SYMBOL
476             "\xCF\x91" => "\xCE\xB8", # GREEK THETA SYMBOL
477             "\xCF\x95" => "\xCF\x86", # GREEK PHI SYMBOL
478             "\xCF\x96" => "\xCF\x80", # GREEK PI SYMBOL
479             "\xCF\x98" => "\xCF\x99", # GREEK LETTER ARCHAIC KOPPA
480             "\xCF\x9A" => "\xCF\x9B", # GREEK LETTER STIGMA
481             "\xCF\x9C" => "\xCF\x9D", # GREEK LETTER DIGAMMA
482             "\xCF\x9E" => "\xCF\x9F", # GREEK LETTER KOPPA
483             "\xCF\xA0" => "\xCF\xA1", # GREEK LETTER SAMPI
484             "\xCF\xA2" => "\xCF\xA3", # COPTIC CAPITAL LETTER SHEI
485             "\xCF\xA4" => "\xCF\xA5", # COPTIC CAPITAL LETTER FEI
486             "\xCF\xA6" => "\xCF\xA7", # COPTIC CAPITAL LETTER KHEI
487             "\xCF\xA8" => "\xCF\xA9", # COPTIC CAPITAL LETTER HORI
488             "\xCF\xAA" => "\xCF\xAB", # COPTIC CAPITAL LETTER GANGIA
489             "\xCF\xAC" => "\xCF\xAD", # COPTIC CAPITAL LETTER SHIMA
490             "\xCF\xAE" => "\xCF\xAF", # COPTIC CAPITAL LETTER DEI
491             "\xCF\xB0" => "\xCE\xBA", # GREEK KAPPA SYMBOL
492             "\xCF\xB1" => "\xCF\x81", # GREEK RHO SYMBOL
493             "\xCF\xB4" => "\xCE\xB8", # GREEK CAPITAL THETA SYMBOL
494             "\xCF\xB5" => "\xCE\xB5", # GREEK LUNATE EPSILON SYMBOL
495             "\xCF\xB7" => "\xCF\xB8", # GREEK CAPITAL LETTER SHO
496             "\xCF\xB9" => "\xCF\xB2", # GREEK CAPITAL LUNATE SIGMA SYMBOL
497             "\xCF\xBA" => "\xCF\xBB", # GREEK CAPITAL LETTER SAN
498             "\xCF\xBD" => "\xCD\xBB", # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL
499             "\xCF\xBE" => "\xCD\xBC", # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL
500             "\xCF\xBF" => "\xCD\xBD", # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
501             "\xD0\x80" => "\xD1\x90", # CYRILLIC CAPITAL LETTER IE WITH GRAVE
502             "\xD0\x81" => "\xD1\x91", # CYRILLIC CAPITAL LETTER IO
503             "\xD0\x82" => "\xD1\x92", # CYRILLIC CAPITAL LETTER DJE
504             "\xD0\x83" => "\xD1\x93", # CYRILLIC CAPITAL LETTER GJE
505             "\xD0\x84" => "\xD1\x94", # CYRILLIC CAPITAL LETTER UKRAINIAN IE
506             "\xD0\x85" => "\xD1\x95", # CYRILLIC CAPITAL LETTER DZE
507             "\xD0\x86" => "\xD1\x96", # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
508             "\xD0\x87" => "\xD1\x97", # CYRILLIC CAPITAL LETTER YI
509             "\xD0\x88" => "\xD1\x98", # CYRILLIC CAPITAL LETTER JE
510             "\xD0\x89" => "\xD1\x99", # CYRILLIC CAPITAL LETTER LJE
511             "\xD0\x8A" => "\xD1\x9A", # CYRILLIC CAPITAL LETTER NJE
512             "\xD0\x8B" => "\xD1\x9B", # CYRILLIC CAPITAL LETTER TSHE
513             "\xD0\x8C" => "\xD1\x9C", # CYRILLIC CAPITAL LETTER KJE
514             "\xD0\x8D" => "\xD1\x9D", # CYRILLIC CAPITAL LETTER I WITH GRAVE
515             "\xD0\x8E" => "\xD1\x9E", # CYRILLIC CAPITAL LETTER SHORT U
516             "\xD0\x8F" => "\xD1\x9F", # CYRILLIC CAPITAL LETTER DZHE
517             "\xD0\x90" => "\xD0\xB0", # CYRILLIC CAPITAL LETTER A
518             "\xD0\x91" => "\xD0\xB1", # CYRILLIC CAPITAL LETTER BE
519             "\xD0\x92" => "\xD0\xB2", # CYRILLIC CAPITAL LETTER VE
520             "\xD0\x93" => "\xD0\xB3", # CYRILLIC CAPITAL LETTER GHE
521             "\xD0\x94" => "\xD0\xB4", # CYRILLIC CAPITAL LETTER DE
522             "\xD0\x95" => "\xD0\xB5", # CYRILLIC CAPITAL LETTER IE
523             "\xD0\x96" => "\xD0\xB6", # CYRILLIC CAPITAL LETTER ZHE
524             "\xD0\x97" => "\xD0\xB7", # CYRILLIC CAPITAL LETTER ZE
525             "\xD0\x98" => "\xD0\xB8", # CYRILLIC CAPITAL LETTER I
526             "\xD0\x99" => "\xD0\xB9", # CYRILLIC CAPITAL LETTER SHORT I
527             "\xD0\x9A" => "\xD0\xBA", # CYRILLIC CAPITAL LETTER KA
528             "\xD0\x9B" => "\xD0\xBB", # CYRILLIC CAPITAL LETTER EL
529             "\xD0\x9C" => "\xD0\xBC", # CYRILLIC CAPITAL LETTER EM
530             "\xD0\x9D" => "\xD0\xBD", # CYRILLIC CAPITAL LETTER EN
531             "\xD0\x9E" => "\xD0\xBE", # CYRILLIC CAPITAL LETTER O
532             "\xD0\x9F" => "\xD0\xBF", # CYRILLIC CAPITAL LETTER PE
533             "\xD0\xA0" => "\xD1\x80", # CYRILLIC CAPITAL LETTER ER
534             "\xD0\xA1" => "\xD1\x81", # CYRILLIC CAPITAL LETTER ES
535             "\xD0\xA2" => "\xD1\x82", # CYRILLIC CAPITAL LETTER TE
536             "\xD0\xA3" => "\xD1\x83", # CYRILLIC CAPITAL LETTER U
537             "\xD0\xA4" => "\xD1\x84", # CYRILLIC CAPITAL LETTER EF
538             "\xD0\xA5" => "\xD1\x85", # CYRILLIC CAPITAL LETTER HA
539             "\xD0\xA6" => "\xD1\x86", # CYRILLIC CAPITAL LETTER TSE
540             "\xD0\xA7" => "\xD1\x87", # CYRILLIC CAPITAL LETTER CHE
541             "\xD0\xA8" => "\xD1\x88", # CYRILLIC CAPITAL LETTER SHA
542             "\xD0\xA9" => "\xD1\x89", # CYRILLIC CAPITAL LETTER SHCHA
543             "\xD0\xAA" => "\xD1\x8A", # CYRILLIC CAPITAL LETTER HARD SIGN
544             "\xD0\xAB" => "\xD1\x8B", # CYRILLIC CAPITAL LETTER YERU
545             "\xD0\xAC" => "\xD1\x8C", # CYRILLIC CAPITAL LETTER SOFT SIGN
546             "\xD0\xAD" => "\xD1\x8D", # CYRILLIC CAPITAL LETTER E
547             "\xD0\xAE" => "\xD1\x8E", # CYRILLIC CAPITAL LETTER YU
548             "\xD0\xAF" => "\xD1\x8F", # CYRILLIC CAPITAL LETTER YA
549             "\xD1\xA0" => "\xD1\xA1", # CYRILLIC CAPITAL LETTER OMEGA
550             "\xD1\xA2" => "\xD1\xA3", # CYRILLIC CAPITAL LETTER YAT
551             "\xD1\xA4" => "\xD1\xA5", # CYRILLIC CAPITAL LETTER IOTIFIED E
552             "\xD1\xA6" => "\xD1\xA7", # CYRILLIC CAPITAL LETTER LITTLE YUS
553             "\xD1\xA8" => "\xD1\xA9", # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
554             "\xD1\xAA" => "\xD1\xAB", # CYRILLIC CAPITAL LETTER BIG YUS
555             "\xD1\xAC" => "\xD1\xAD", # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
556             "\xD1\xAE" => "\xD1\xAF", # CYRILLIC CAPITAL LETTER KSI
557             "\xD1\xB0" => "\xD1\xB1", # CYRILLIC CAPITAL LETTER PSI
558             "\xD1\xB2" => "\xD1\xB3", # CYRILLIC CAPITAL LETTER FITA
559             "\xD1\xB4" => "\xD1\xB5", # CYRILLIC CAPITAL LETTER IZHITSA
560             "\xD1\xB6" => "\xD1\xB7", # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
561             "\xD1\xB8" => "\xD1\xB9", # CYRILLIC CAPITAL LETTER UK
562             "\xD1\xBA" => "\xD1\xBB", # CYRILLIC CAPITAL LETTER ROUND OMEGA
563             "\xD1\xBC" => "\xD1\xBD", # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
564             "\xD1\xBE" => "\xD1\xBF", # CYRILLIC CAPITAL LETTER OT
565             "\xD2\x80" => "\xD2\x81", # CYRILLIC CAPITAL LETTER KOPPA
566             "\xD2\x8A" => "\xD2\x8B", # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
567             "\xD2\x8C" => "\xD2\x8D", # CYRILLIC CAPITAL LETTER SEMISOFT SIGN
568             "\xD2\x8E" => "\xD2\x8F", # CYRILLIC CAPITAL LETTER ER WITH TICK
569             "\xD2\x90" => "\xD2\x91", # CYRILLIC CAPITAL LETTER GHE WITH UPTURN
570             "\xD2\x92" => "\xD2\x93", # CYRILLIC CAPITAL LETTER GHE WITH STROKE
571             "\xD2\x94" => "\xD2\x95", # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
572             "\xD2\x96" => "\xD2\x97", # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
573             "\xD2\x98" => "\xD2\x99", # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
574             "\xD2\x9A" => "\xD2\x9B", # CYRILLIC CAPITAL LETTER KA WITH DESCENDER
575             "\xD2\x9C" => "\xD2\x9D", # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
576             "\xD2\x9E" => "\xD2\x9F", # CYRILLIC CAPITAL LETTER KA WITH STROKE
577             "\xD2\xA0" => "\xD2\xA1", # CYRILLIC CAPITAL LETTER BASHKIR KA
578             "\xD2\xA2" => "\xD2\xA3", # CYRILLIC CAPITAL LETTER EN WITH DESCENDER
579             "\xD2\xA4" => "\xD2\xA5", # CYRILLIC CAPITAL LIGATURE EN GHE
580             "\xD2\xA6" => "\xD2\xA7", # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
581             "\xD2\xA8" => "\xD2\xA9", # CYRILLIC CAPITAL LETTER ABKHASIAN HA
582             "\xD2\xAA" => "\xD2\xAB", # CYRILLIC CAPITAL LETTER ES WITH DESCENDER
583             "\xD2\xAC" => "\xD2\xAD", # CYRILLIC CAPITAL LETTER TE WITH DESCENDER
584             "\xD2\xAE" => "\xD2\xAF", # CYRILLIC CAPITAL LETTER STRAIGHT U
585             "\xD2\xB0" => "\xD2\xB1", # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
586             "\xD2\xB2" => "\xD2\xB3", # CYRILLIC CAPITAL LETTER HA WITH DESCENDER
587             "\xD2\xB4" => "\xD2\xB5", # CYRILLIC CAPITAL LIGATURE TE TSE
588             "\xD2\xB6" => "\xD2\xB7", # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
589             "\xD2\xB8" => "\xD2\xB9", # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
590             "\xD2\xBA" => "\xD2\xBB", # CYRILLIC CAPITAL LETTER SHHA
591             "\xD2\xBC" => "\xD2\xBD", # CYRILLIC CAPITAL LETTER ABKHASIAN CHE
592             "\xD2\xBE" => "\xD2\xBF", # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
593             "\xD3\x80" => "\xD3\x8F", # CYRILLIC LETTER PALOCHKA
594             "\xD3\x81" => "\xD3\x82", # CYRILLIC CAPITAL LETTER ZHE WITH BREVE
595             "\xD3\x83" => "\xD3\x84", # CYRILLIC CAPITAL LETTER KA WITH HOOK
596             "\xD3\x85" => "\xD3\x86", # CYRILLIC CAPITAL LETTER EL WITH TAIL
597             "\xD3\x87" => "\xD3\x88", # CYRILLIC CAPITAL LETTER EN WITH HOOK
598             "\xD3\x89" => "\xD3\x8A", # CYRILLIC CAPITAL LETTER EN WITH TAIL
599             "\xD3\x8B" => "\xD3\x8C", # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
600             "\xD3\x8D" => "\xD3\x8E", # CYRILLIC CAPITAL LETTER EM WITH TAIL
601             "\xD3\x90" => "\xD3\x91", # CYRILLIC CAPITAL LETTER A WITH BREVE
602             "\xD3\x92" => "\xD3\x93", # CYRILLIC CAPITAL LETTER A WITH DIAERESIS
603             "\xD3\x94" => "\xD3\x95", # CYRILLIC CAPITAL LIGATURE A IE
604             "\xD3\x96" => "\xD3\x97", # CYRILLIC CAPITAL LETTER IE WITH BREVE
605             "\xD3\x98" => "\xD3\x99", # CYRILLIC CAPITAL LETTER SCHWA
606             "\xD3\x9A" => "\xD3\x9B", # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
607             "\xD3\x9C" => "\xD3\x9D", # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
608             "\xD3\x9E" => "\xD3\x9F", # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
609             "\xD3\xA0" => "\xD3\xA1", # CYRILLIC CAPITAL LETTER ABKHASIAN DZE
610             "\xD3\xA2" => "\xD3\xA3", # CYRILLIC CAPITAL LETTER I WITH MACRON
611             "\xD3\xA4" => "\xD3\xA5", # CYRILLIC CAPITAL LETTER I WITH DIAERESIS
612             "\xD3\xA6" => "\xD3\xA7", # CYRILLIC CAPITAL LETTER O WITH DIAERESIS
613             "\xD3\xA8" => "\xD3\xA9", # CYRILLIC CAPITAL LETTER BARRED O
614             "\xD3\xAA" => "\xD3\xAB", # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
615             "\xD3\xAC" => "\xD3\xAD", # CYRILLIC CAPITAL LETTER E WITH DIAERESIS
616             "\xD3\xAE" => "\xD3\xAF", # CYRILLIC CAPITAL LETTER U WITH MACRON
617             "\xD3\xB0" => "\xD3\xB1", # CYRILLIC CAPITAL LETTER U WITH DIAERESIS
618             "\xD3\xB2" => "\xD3\xB3", # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
619             "\xD3\xB4" => "\xD3\xB5", # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
620             "\xD3\xB6" => "\xD3\xB7", # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
621             "\xD3\xB8" => "\xD3\xB9", # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
622             "\xD3\xBA" => "\xD3\xBB", # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
623             "\xD3\xBC" => "\xD3\xBD", # CYRILLIC CAPITAL LETTER HA WITH HOOK
624             "\xD3\xBE" => "\xD3\xBF", # CYRILLIC CAPITAL LETTER HA WITH STROKE
625             "\xD4\x80" => "\xD4\x81", # CYRILLIC CAPITAL LETTER KOMI DE
626             "\xD4\x82" => "\xD4\x83", # CYRILLIC CAPITAL LETTER KOMI DJE
627             "\xD4\x84" => "\xD4\x85", # CYRILLIC CAPITAL LETTER KOMI ZJE
628             "\xD4\x86" => "\xD4\x87", # CYRILLIC CAPITAL LETTER KOMI DZJE
629             "\xD4\x88" => "\xD4\x89", # CYRILLIC CAPITAL LETTER KOMI LJE
630             "\xD4\x8A" => "\xD4\x8B", # CYRILLIC CAPITAL LETTER KOMI NJE
631             "\xD4\x8C" => "\xD4\x8D", # CYRILLIC CAPITAL LETTER KOMI SJE
632             "\xD4\x8E" => "\xD4\x8F", # CYRILLIC CAPITAL LETTER KOMI TJE
633             "\xD4\x90" => "\xD4\x91", # CYRILLIC CAPITAL LETTER REVERSED ZE
634             "\xD4\x92" => "\xD4\x93", # CYRILLIC CAPITAL LETTER EL WITH HOOK
635             "\xD4\x94" => "\xD4\x95", # CYRILLIC CAPITAL LETTER LHA
636             "\xD4\x96" => "\xD4\x97", # CYRILLIC CAPITAL LETTER RHA
637             "\xD4\x98" => "\xD4\x99", # CYRILLIC CAPITAL LETTER YAE
638             "\xD4\x9A" => "\xD4\x9B", # CYRILLIC CAPITAL LETTER QA
639             "\xD4\x9C" => "\xD4\x9D", # CYRILLIC CAPITAL LETTER WE
640             "\xD4\x9E" => "\xD4\x9F", # CYRILLIC CAPITAL LETTER ALEUT KA
641             "\xD4\xA0" => "\xD4\xA1", # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK
642             "\xD4\xA2" => "\xD4\xA3", # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK
643             "\xD4\xA4" => "\xD4\xA5", # CYRILLIC CAPITAL LETTER PE WITH DESCENDER
644             "\xD4\xA6" => "\xD4\xA7", # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER
645             "\xD4\xA8" => "\xD4\xA9", # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK
646             "\xD4\xAA" => "\xD4\xAB", # CYRILLIC CAPITAL LETTER DZZHE
647             "\xD4\xAC" => "\xD4\xAD", # CYRILLIC CAPITAL LETTER DCHE
648             "\xD4\xAE" => "\xD4\xAF", # CYRILLIC CAPITAL LETTER EL WITH DESCENDER
649             "\xD4\xB1" => "\xD5\xA1", # ARMENIAN CAPITAL LETTER AYB
650             "\xD4\xB2" => "\xD5\xA2", # ARMENIAN CAPITAL LETTER BEN
651             "\xD4\xB3" => "\xD5\xA3", # ARMENIAN CAPITAL LETTER GIM
652             "\xD4\xB4" => "\xD5\xA4", # ARMENIAN CAPITAL LETTER DA
653             "\xD4\xB5" => "\xD5\xA5", # ARMENIAN CAPITAL LETTER ECH
654             "\xD4\xB6" => "\xD5\xA6", # ARMENIAN CAPITAL LETTER ZA
655             "\xD4\xB7" => "\xD5\xA7", # ARMENIAN CAPITAL LETTER EH
656             "\xD4\xB8" => "\xD5\xA8", # ARMENIAN CAPITAL LETTER ET
657             "\xD4\xB9" => "\xD5\xA9", # ARMENIAN CAPITAL LETTER TO
658             "\xD4\xBA" => "\xD5\xAA", # ARMENIAN CAPITAL LETTER ZHE
659             "\xD4\xBB" => "\xD5\xAB", # ARMENIAN CAPITAL LETTER INI
660             "\xD4\xBC" => "\xD5\xAC", # ARMENIAN CAPITAL LETTER LIWN
661             "\xD4\xBD" => "\xD5\xAD", # ARMENIAN CAPITAL LETTER XEH
662             "\xD4\xBE" => "\xD5\xAE", # ARMENIAN CAPITAL LETTER CA
663             "\xD4\xBF" => "\xD5\xAF", # ARMENIAN CAPITAL LETTER KEN
664             "\xD5\x80" => "\xD5\xB0", # ARMENIAN CAPITAL LETTER HO
665             "\xD5\x81" => "\xD5\xB1", # ARMENIAN CAPITAL LETTER JA
666             "\xD5\x82" => "\xD5\xB2", # ARMENIAN CAPITAL LETTER GHAD
667             "\xD5\x83" => "\xD5\xB3", # ARMENIAN CAPITAL LETTER CHEH
668             "\xD5\x84" => "\xD5\xB4", # ARMENIAN CAPITAL LETTER MEN
669             "\xD5\x85" => "\xD5\xB5", # ARMENIAN CAPITAL LETTER YI
670             "\xD5\x86" => "\xD5\xB6", # ARMENIAN CAPITAL LETTER NOW
671             "\xD5\x87" => "\xD5\xB7", # ARMENIAN CAPITAL LETTER SHA
672             "\xD5\x88" => "\xD5\xB8", # ARMENIAN CAPITAL LETTER VO
673             "\xD5\x89" => "\xD5\xB9", # ARMENIAN CAPITAL LETTER CHA
674             "\xD5\x8A" => "\xD5\xBA", # ARMENIAN CAPITAL LETTER PEH
675             "\xD5\x8B" => "\xD5\xBB", # ARMENIAN CAPITAL LETTER JHEH
676             "\xD5\x8C" => "\xD5\xBC", # ARMENIAN CAPITAL LETTER RA
677             "\xD5\x8D" => "\xD5\xBD", # ARMENIAN CAPITAL LETTER SEH
678             "\xD5\x8E" => "\xD5\xBE", # ARMENIAN CAPITAL LETTER VEW
679             "\xD5\x8F" => "\xD5\xBF", # ARMENIAN CAPITAL LETTER TIWN
680             "\xD5\x90" => "\xD6\x80", # ARMENIAN CAPITAL LETTER REH
681             "\xD5\x91" => "\xD6\x81", # ARMENIAN CAPITAL LETTER CO
682             "\xD5\x92" => "\xD6\x82", # ARMENIAN CAPITAL LETTER YIWN
683             "\xD5\x93" => "\xD6\x83", # ARMENIAN CAPITAL LETTER PIWR
684             "\xD5\x94" => "\xD6\x84", # ARMENIAN CAPITAL LETTER KEH
685             "\xD5\x95" => "\xD6\x85", # ARMENIAN CAPITAL LETTER OH
686             "\xD5\x96" => "\xD6\x86", # ARMENIAN CAPITAL LETTER FEH
687             "\xD6\x87" => "\xD5\xA5\xD6\x82", # ARMENIAN SMALL LIGATURE ECH YIWN
688             "\xE1\x82\xA0" => "\xE2\xB4\x80", # GEORGIAN CAPITAL LETTER AN
689             "\xE1\x82\xA1" => "\xE2\xB4\x81", # GEORGIAN CAPITAL LETTER BAN
690             "\xE1\x82\xA2" => "\xE2\xB4\x82", # GEORGIAN CAPITAL LETTER GAN
691             "\xE1\x82\xA3" => "\xE2\xB4\x83", # GEORGIAN CAPITAL LETTER DON
692             "\xE1\x82\xA4" => "\xE2\xB4\x84", # GEORGIAN CAPITAL LETTER EN
693             "\xE1\x82\xA5" => "\xE2\xB4\x85", # GEORGIAN CAPITAL LETTER VIN
694             "\xE1\x82\xA6" => "\xE2\xB4\x86", # GEORGIAN CAPITAL LETTER ZEN
695             "\xE1\x82\xA7" => "\xE2\xB4\x87", # GEORGIAN CAPITAL LETTER TAN
696             "\xE1\x82\xA8" => "\xE2\xB4\x88", # GEORGIAN CAPITAL LETTER IN
697             "\xE1\x82\xA9" => "\xE2\xB4\x89", # GEORGIAN CAPITAL LETTER KAN
698             "\xE1\x82\xAA" => "\xE2\xB4\x8A", # GEORGIAN CAPITAL LETTER LAS
699             "\xE1\x82\xAB" => "\xE2\xB4\x8B", # GEORGIAN CAPITAL LETTER MAN
700             "\xE1\x82\xAC" => "\xE2\xB4\x8C", # GEORGIAN CAPITAL LETTER NAR
701             "\xE1\x82\xAD" => "\xE2\xB4\x8D", # GEORGIAN CAPITAL LETTER ON
702             "\xE1\x82\xAE" => "\xE2\xB4\x8E", # GEORGIAN CAPITAL LETTER PAR
703             "\xE1\x82\xAF" => "\xE2\xB4\x8F", # GEORGIAN CAPITAL LETTER ZHAR
704             "\xE1\x82\xB0" => "\xE2\xB4\x90", # GEORGIAN CAPITAL LETTER RAE
705             "\xE1\x82\xB1" => "\xE2\xB4\x91", # GEORGIAN CAPITAL LETTER SAN
706             "\xE1\x82\xB2" => "\xE2\xB4\x92", # GEORGIAN CAPITAL LETTER TAR
707             "\xE1\x82\xB3" => "\xE2\xB4\x93", # GEORGIAN CAPITAL LETTER UN
708             "\xE1\x82\xB4" => "\xE2\xB4\x94", # GEORGIAN CAPITAL LETTER PHAR
709             "\xE1\x82\xB5" => "\xE2\xB4\x95", # GEORGIAN CAPITAL LETTER KHAR
710             "\xE1\x82\xB6" => "\xE2\xB4\x96", # GEORGIAN CAPITAL LETTER GHAN
711             "\xE1\x82\xB7" => "\xE2\xB4\x97", # GEORGIAN CAPITAL LETTER QAR
712             "\xE1\x82\xB8" => "\xE2\xB4\x98", # GEORGIAN CAPITAL LETTER SHIN
713             "\xE1\x82\xB9" => "\xE2\xB4\x99", # GEORGIAN CAPITAL LETTER CHIN
714             "\xE1\x82\xBA" => "\xE2\xB4\x9A", # GEORGIAN CAPITAL LETTER CAN
715             "\xE1\x82\xBB" => "\xE2\xB4\x9B", # GEORGIAN CAPITAL LETTER JIL
716             "\xE1\x82\xBC" => "\xE2\xB4\x9C", # GEORGIAN CAPITAL LETTER CIL
717             "\xE1\x82\xBD" => "\xE2\xB4\x9D", # GEORGIAN CAPITAL LETTER CHAR
718             "\xE1\x82\xBE" => "\xE2\xB4\x9E", # GEORGIAN CAPITAL LETTER XAN
719             "\xE1\x82\xBF" => "\xE2\xB4\x9F", # GEORGIAN CAPITAL LETTER JHAN
720             "\xE1\x83\x80" => "\xE2\xB4\xA0", # GEORGIAN CAPITAL LETTER HAE
721             "\xE1\x83\x81" => "\xE2\xB4\xA1", # GEORGIAN CAPITAL LETTER HE
722             "\xE1\x83\x82" => "\xE2\xB4\xA2", # GEORGIAN CAPITAL LETTER HIE
723             "\xE1\x83\x83" => "\xE2\xB4\xA3", # GEORGIAN CAPITAL LETTER WE
724             "\xE1\x83\x84" => "\xE2\xB4\xA4", # GEORGIAN CAPITAL LETTER HAR
725             "\xE1\x83\x85" => "\xE2\xB4\xA5", # GEORGIAN CAPITAL LETTER HOE
726             "\xE1\x83\x87" => "\xE2\xB4\xA7", # GEORGIAN CAPITAL LETTER YN
727             "\xE1\x83\x8D" => "\xE2\xB4\xAD", # GEORGIAN CAPITAL LETTER AEN
728             "\xE1\x8F\xB8" => "\xE1\x8F\xB0", # CHEROKEE SMALL LETTER YE
729             "\xE1\x8F\xB9" => "\xE1\x8F\xB1", # CHEROKEE SMALL LETTER YI
730             "\xE1\x8F\xBA" => "\xE1\x8F\xB2", # CHEROKEE SMALL LETTER YO
731             "\xE1\x8F\xBB" => "\xE1\x8F\xB3", # CHEROKEE SMALL LETTER YU
732             "\xE1\x8F\xBC" => "\xE1\x8F\xB4", # CHEROKEE SMALL LETTER YV
733             "\xE1\x8F\xBD" => "\xE1\x8F\xB5", # CHEROKEE SMALL LETTER MV
734             "\xE1\xB2\x80" => "\xD0\xB2", # CYRILLIC SMALL LETTER ROUNDED VE
735             "\xE1\xB2\x81" => "\xD0\xB4", # CYRILLIC SMALL LETTER LONG-LEGGED DE
736             "\xE1\xB2\x82" => "\xD0\xBE", # CYRILLIC SMALL LETTER NARROW O
737             "\xE1\xB2\x83" => "\xD1\x81", # CYRILLIC SMALL LETTER WIDE ES
738             "\xE1\xB2\x84" => "\xD1\x82", # CYRILLIC SMALL LETTER TALL TE
739             "\xE1\xB2\x85" => "\xD1\x82", # CYRILLIC SMALL LETTER THREE-LEGGED TE
740             "\xE1\xB2\x86" => "\xD1\x8A", # CYRILLIC SMALL LETTER TALL HARD SIGN
741             "\xE1\xB2\x87" => "\xD1\xA3", # CYRILLIC SMALL LETTER TALL YAT
742             "\xE1\xB2\x88" => "\xEA\x99\x8B", # CYRILLIC SMALL LETTER UNBLENDED UK
743             "\xE1\xB2\x90" => "\xE1\x83\x90", # GEORGIAN MTAVRULI CAPITAL LETTER AN
744             "\xE1\xB2\x91" => "\xE1\x83\x91", # GEORGIAN MTAVRULI CAPITAL LETTER BAN
745             "\xE1\xB2\x92" => "\xE1\x83\x92", # GEORGIAN MTAVRULI CAPITAL LETTER GAN
746             "\xE1\xB2\x93" => "\xE1\x83\x93", # GEORGIAN MTAVRULI CAPITAL LETTER DON
747             "\xE1\xB2\x94" => "\xE1\x83\x94", # GEORGIAN MTAVRULI CAPITAL LETTER EN
748             "\xE1\xB2\x95" => "\xE1\x83\x95", # GEORGIAN MTAVRULI CAPITAL LETTER VIN
749             "\xE1\xB2\x96" => "\xE1\x83\x96", # GEORGIAN MTAVRULI CAPITAL LETTER ZEN
750             "\xE1\xB2\x97" => "\xE1\x83\x97", # GEORGIAN MTAVRULI CAPITAL LETTER TAN
751             "\xE1\xB2\x98" => "\xE1\x83\x98", # GEORGIAN MTAVRULI CAPITAL LETTER IN
752             "\xE1\xB2\x99" => "\xE1\x83\x99", # GEORGIAN MTAVRULI CAPITAL LETTER KAN
753             "\xE1\xB2\x9A" => "\xE1\x83\x9A", # GEORGIAN MTAVRULI CAPITAL LETTER LAS
754             "\xE1\xB2\x9B" => "\xE1\x83\x9B", # GEORGIAN MTAVRULI CAPITAL LETTER MAN
755             "\xE1\xB2\x9C" => "\xE1\x83\x9C", # GEORGIAN MTAVRULI CAPITAL LETTER NAR
756             "\xE1\xB2\x9D" => "\xE1\x83\x9D", # GEORGIAN MTAVRULI CAPITAL LETTER ON
757             "\xE1\xB2\x9E" => "\xE1\x83\x9E", # GEORGIAN MTAVRULI CAPITAL LETTER PAR
758             "\xE1\xB2\x9F" => "\xE1\x83\x9F", # GEORGIAN MTAVRULI CAPITAL LETTER ZHAR
759             "\xE1\xB2\xA0" => "\xE1\x83\xA0", # GEORGIAN MTAVRULI CAPITAL LETTER RAE
760             "\xE1\xB2\xA1" => "\xE1\x83\xA1", # GEORGIAN MTAVRULI CAPITAL LETTER SAN
761             "\xE1\xB2\xA2" => "\xE1\x83\xA2", # GEORGIAN MTAVRULI CAPITAL LETTER TAR
762             "\xE1\xB2\xA3" => "\xE1\x83\xA3", # GEORGIAN MTAVRULI CAPITAL LETTER UN
763             "\xE1\xB2\xA4" => "\xE1\x83\xA4", # GEORGIAN MTAVRULI CAPITAL LETTER PHAR
764             "\xE1\xB2\xA5" => "\xE1\x83\xA5", # GEORGIAN MTAVRULI CAPITAL LETTER KHAR
765             "\xE1\xB2\xA6" => "\xE1\x83\xA6", # GEORGIAN MTAVRULI CAPITAL LETTER GHAN
766             "\xE1\xB2\xA7" => "\xE1\x83\xA7", # GEORGIAN MTAVRULI CAPITAL LETTER QAR
767             "\xE1\xB2\xA8" => "\xE1\x83\xA8", # GEORGIAN MTAVRULI CAPITAL LETTER SHIN
768             "\xE1\xB2\xA9" => "\xE1\x83\xA9", # GEORGIAN MTAVRULI CAPITAL LETTER CHIN
769             "\xE1\xB2\xAA" => "\xE1\x83\xAA", # GEORGIAN MTAVRULI CAPITAL LETTER CAN
770             "\xE1\xB2\xAB" => "\xE1\x83\xAB", # GEORGIAN MTAVRULI CAPITAL LETTER JIL
771             "\xE1\xB2\xAC" => "\xE1\x83\xAC", # GEORGIAN MTAVRULI CAPITAL LETTER CIL
772             "\xE1\xB2\xAD" => "\xE1\x83\xAD", # GEORGIAN MTAVRULI CAPITAL LETTER CHAR
773             "\xE1\xB2\xAE" => "\xE1\x83\xAE", # GEORGIAN MTAVRULI CAPITAL LETTER XAN
774             "\xE1\xB2\xAF" => "\xE1\x83\xAF", # GEORGIAN MTAVRULI CAPITAL LETTER JHAN
775             "\xE1\xB2\xB0" => "\xE1\x83\xB0", # GEORGIAN MTAVRULI CAPITAL LETTER HAE
776             "\xE1\xB2\xB1" => "\xE1\x83\xB1", # GEORGIAN MTAVRULI CAPITAL LETTER HE
777             "\xE1\xB2\xB2" => "\xE1\x83\xB2", # GEORGIAN MTAVRULI CAPITAL LETTER HIE
778             "\xE1\xB2\xB3" => "\xE1\x83\xB3", # GEORGIAN MTAVRULI CAPITAL LETTER WE
779             "\xE1\xB2\xB4" => "\xE1\x83\xB4", # GEORGIAN MTAVRULI CAPITAL LETTER HAR
780             "\xE1\xB2\xB5" => "\xE1\x83\xB5", # GEORGIAN MTAVRULI CAPITAL LETTER HOE
781             "\xE1\xB2\xB6" => "\xE1\x83\xB6", # GEORGIAN MTAVRULI CAPITAL LETTER FI
782             "\xE1\xB2\xB7" => "\xE1\x83\xB7", # GEORGIAN MTAVRULI CAPITAL LETTER YN
783             "\xE1\xB2\xB8" => "\xE1\x83\xB8", # GEORGIAN MTAVRULI CAPITAL LETTER ELIFI
784             "\xE1\xB2\xB9" => "\xE1\x83\xB9", # GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN
785             "\xE1\xB2\xBA" => "\xE1\x83\xBA", # GEORGIAN MTAVRULI CAPITAL LETTER AIN
786             "\xE1\xB2\xBD" => "\xE1\x83\xBD", # GEORGIAN MTAVRULI CAPITAL LETTER AEN
787             "\xE1\xB2\xBE" => "\xE1\x83\xBE", # GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN
788             "\xE1\xB2\xBF" => "\xE1\x83\xBF", # GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN
789             "\xE1\xB8\x80" => "\xE1\xB8\x81", # LATIN CAPITAL LETTER A WITH RING BELOW
790             "\xE1\xB8\x82" => "\xE1\xB8\x83", # LATIN CAPITAL LETTER B WITH DOT ABOVE
791             "\xE1\xB8\x84" => "\xE1\xB8\x85", # LATIN CAPITAL LETTER B WITH DOT BELOW
792             "\xE1\xB8\x86" => "\xE1\xB8\x87", # LATIN CAPITAL LETTER B WITH LINE BELOW
793             "\xE1\xB8\x88" => "\xE1\xB8\x89", # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
794             "\xE1\xB8\x8A" => "\xE1\xB8\x8B", # LATIN CAPITAL LETTER D WITH DOT ABOVE
795             "\xE1\xB8\x8C" => "\xE1\xB8\x8D", # LATIN CAPITAL LETTER D WITH DOT BELOW
796             "\xE1\xB8\x8E" => "\xE1\xB8\x8F", # LATIN CAPITAL LETTER D WITH LINE BELOW
797             "\xE1\xB8\x90" => "\xE1\xB8\x91", # LATIN CAPITAL LETTER D WITH CEDILLA
798             "\xE1\xB8\x92" => "\xE1\xB8\x93", # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
799             "\xE1\xB8\x94" => "\xE1\xB8\x95", # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
800             "\xE1\xB8\x96" => "\xE1\xB8\x97", # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
801             "\xE1\xB8\x98" => "\xE1\xB8\x99", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
802             "\xE1\xB8\x9A" => "\xE1\xB8\x9B", # LATIN CAPITAL LETTER E WITH TILDE BELOW
803             "\xE1\xB8\x9C" => "\xE1\xB8\x9D", # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
804             "\xE1\xB8\x9E" => "\xE1\xB8\x9F", # LATIN CAPITAL LETTER F WITH DOT ABOVE
805             "\xE1\xB8\xA0" => "\xE1\xB8\xA1", # LATIN CAPITAL LETTER G WITH MACRON
806             "\xE1\xB8\xA2" => "\xE1\xB8\xA3", # LATIN CAPITAL LETTER H WITH DOT ABOVE
807             "\xE1\xB8\xA4" => "\xE1\xB8\xA5", # LATIN CAPITAL LETTER H WITH DOT BELOW
808             "\xE1\xB8\xA6" => "\xE1\xB8\xA7", # LATIN CAPITAL LETTER H WITH DIAERESIS
809             "\xE1\xB8\xA8" => "\xE1\xB8\xA9", # LATIN CAPITAL LETTER H WITH CEDILLA
810             "\xE1\xB8\xAA" => "\xE1\xB8\xAB", # LATIN CAPITAL LETTER H WITH BREVE BELOW
811             "\xE1\xB8\xAC" => "\xE1\xB8\xAD", # LATIN CAPITAL LETTER I WITH TILDE BELOW
812             "\xE1\xB8\xAE" => "\xE1\xB8\xAF", # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
813             "\xE1\xB8\xB0" => "\xE1\xB8\xB1", # LATIN CAPITAL LETTER K WITH ACUTE
814             "\xE1\xB8\xB2" => "\xE1\xB8\xB3", # LATIN CAPITAL LETTER K WITH DOT BELOW
815             "\xE1\xB8\xB4" => "\xE1\xB8\xB5", # LATIN CAPITAL LETTER K WITH LINE BELOW
816             "\xE1\xB8\xB6" => "\xE1\xB8\xB7", # LATIN CAPITAL LETTER L WITH DOT BELOW
817             "\xE1\xB8\xB8" => "\xE1\xB8\xB9", # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
818             "\xE1\xB8\xBA" => "\xE1\xB8\xBB", # LATIN CAPITAL LETTER L WITH LINE BELOW
819             "\xE1\xB8\xBC" => "\xE1\xB8\xBD", # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
820             "\xE1\xB8\xBE" => "\xE1\xB8\xBF", # LATIN CAPITAL LETTER M WITH ACUTE
821             "\xE1\xB9\x80" => "\xE1\xB9\x81", # LATIN CAPITAL LETTER M WITH DOT ABOVE
822             "\xE1\xB9\x82" => "\xE1\xB9\x83", # LATIN CAPITAL LETTER M WITH DOT BELOW
823             "\xE1\xB9\x84" => "\xE1\xB9\x85", # LATIN CAPITAL LETTER N WITH DOT ABOVE
824             "\xE1\xB9\x86" => "\xE1\xB9\x87", # LATIN CAPITAL LETTER N WITH DOT BELOW
825             "\xE1\xB9\x88" => "\xE1\xB9\x89", # LATIN CAPITAL LETTER N WITH LINE BELOW
826             "\xE1\xB9\x8A" => "\xE1\xB9\x8B", # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
827             "\xE1\xB9\x8C" => "\xE1\xB9\x8D", # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
828             "\xE1\xB9\x8E" => "\xE1\xB9\x8F", # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
829             "\xE1\xB9\x90" => "\xE1\xB9\x91", # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
830             "\xE1\xB9\x92" => "\xE1\xB9\x93", # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
831             "\xE1\xB9\x94" => "\xE1\xB9\x95", # LATIN CAPITAL LETTER P WITH ACUTE
832             "\xE1\xB9\x96" => "\xE1\xB9\x97", # LATIN CAPITAL LETTER P WITH DOT ABOVE
833             "\xE1\xB9\x98" => "\xE1\xB9\x99", # LATIN CAPITAL LETTER R WITH DOT ABOVE
834             "\xE1\xB9\x9A" => "\xE1\xB9\x9B", # LATIN CAPITAL LETTER R WITH DOT BELOW
835             "\xE1\xB9\x9C" => "\xE1\xB9\x9D", # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
836             "\xE1\xB9\x9E" => "\xE1\xB9\x9F", # LATIN CAPITAL LETTER R WITH LINE BELOW
837             "\xE1\xB9\xA0" => "\xE1\xB9\xA1", # LATIN CAPITAL LETTER S WITH DOT ABOVE
838             "\xE1\xB9\xA2" => "\xE1\xB9\xA3", # LATIN CAPITAL LETTER S WITH DOT BELOW
839             "\xE1\xB9\xA4" => "\xE1\xB9\xA5", # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
840             "\xE1\xB9\xA6" => "\xE1\xB9\xA7", # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
841             "\xE1\xB9\xA8" => "\xE1\xB9\xA9", # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
842             "\xE1\xB9\xAA" => "\xE1\xB9\xAB", # LATIN CAPITAL LETTER T WITH DOT ABOVE
843             "\xE1\xB9\xAC" => "\xE1\xB9\xAD", # LATIN CAPITAL LETTER T WITH DOT BELOW
844             "\xE1\xB9\xAE" => "\xE1\xB9\xAF", # LATIN CAPITAL LETTER T WITH LINE BELOW
845             "\xE1\xB9\xB0" => "\xE1\xB9\xB1", # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
846             "\xE1\xB9\xB2" => "\xE1\xB9\xB3", # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
847             "\xE1\xB9\xB4" => "\xE1\xB9\xB5", # LATIN CAPITAL LETTER U WITH TILDE BELOW
848             "\xE1\xB9\xB6" => "\xE1\xB9\xB7", # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
849             "\xE1\xB9\xB8" => "\xE1\xB9\xB9", # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
850             "\xE1\xB9\xBA" => "\xE1\xB9\xBB", # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
851             "\xE1\xB9\xBC" => "\xE1\xB9\xBD", # LATIN CAPITAL LETTER V WITH TILDE
852             "\xE1\xB9\xBE" => "\xE1\xB9\xBF", # LATIN CAPITAL LETTER V WITH DOT BELOW
853             "\xE1\xBA\x80" => "\xE1\xBA\x81", # LATIN CAPITAL LETTER W WITH GRAVE
854             "\xE1\xBA\x82" => "\xE1\xBA\x83", # LATIN CAPITAL LETTER W WITH ACUTE
855             "\xE1\xBA\x84" => "\xE1\xBA\x85", # LATIN CAPITAL LETTER W WITH DIAERESIS
856             "\xE1\xBA\x86" => "\xE1\xBA\x87", # LATIN CAPITAL LETTER W WITH DOT ABOVE
857             "\xE1\xBA\x88" => "\xE1\xBA\x89", # LATIN CAPITAL LETTER W WITH DOT BELOW
858             "\xE1\xBA\x8A" => "\xE1\xBA\x8B", # LATIN CAPITAL LETTER X WITH DOT ABOVE
859             "\xE1\xBA\x8C" => "\xE1\xBA\x8D", # LATIN CAPITAL LETTER X WITH DIAERESIS
860             "\xE1\xBA\x8E" => "\xE1\xBA\x8F", # LATIN CAPITAL LETTER Y WITH DOT ABOVE
861             "\xE1\xBA\x90" => "\xE1\xBA\x91", # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
862             "\xE1\xBA\x92" => "\xE1\xBA\x93", # LATIN CAPITAL LETTER Z WITH DOT BELOW
863             "\xE1\xBA\x94" => "\xE1\xBA\x95", # LATIN CAPITAL LETTER Z WITH LINE BELOW
864             "\xE1\xBA\x96" => "\x68\xCC\xB1", # LATIN SMALL LETTER H WITH LINE BELOW
865             "\xE1\xBA\x97" => "\x74\xCC\x88", # LATIN SMALL LETTER T WITH DIAERESIS
866             "\xE1\xBA\x98" => "\x77\xCC\x8A", # LATIN SMALL LETTER W WITH RING ABOVE
867             "\xE1\xBA\x99" => "\x79\xCC\x8A", # LATIN SMALL LETTER Y WITH RING ABOVE
868             "\xE1\xBA\x9A" => "\x61\xCA\xBE", # LATIN SMALL LETTER A WITH RIGHT HALF RING
869             "\xE1\xBA\x9B" => "\xE1\xB9\xA1", # LATIN SMALL LETTER LONG S WITH DOT ABOVE
870             "\xE1\xBA\x9E" => "\x73\x73", # LATIN CAPITAL LETTER SHARP S
871             "\xE1\xBA\xA0" => "\xE1\xBA\xA1", # LATIN CAPITAL LETTER A WITH DOT BELOW
872             "\xE1\xBA\xA2" => "\xE1\xBA\xA3", # LATIN CAPITAL LETTER A WITH HOOK ABOVE
873             "\xE1\xBA\xA4" => "\xE1\xBA\xA5", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
874             "\xE1\xBA\xA6" => "\xE1\xBA\xA7", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
875             "\xE1\xBA\xA8" => "\xE1\xBA\xA9", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
876             "\xE1\xBA\xAA" => "\xE1\xBA\xAB", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
877             "\xE1\xBA\xAC" => "\xE1\xBA\xAD", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
878             "\xE1\xBA\xAE" => "\xE1\xBA\xAF", # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
879             "\xE1\xBA\xB0" => "\xE1\xBA\xB1", # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
880             "\xE1\xBA\xB2" => "\xE1\xBA\xB3", # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
881             "\xE1\xBA\xB4" => "\xE1\xBA\xB5", # LATIN CAPITAL LETTER A WITH BREVE AND TILDE
882             "\xE1\xBA\xB6" => "\xE1\xBA\xB7", # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
883             "\xE1\xBA\xB8" => "\xE1\xBA\xB9", # LATIN CAPITAL LETTER E WITH DOT BELOW
884             "\xE1\xBA\xBA" => "\xE1\xBA\xBB", # LATIN CAPITAL LETTER E WITH HOOK ABOVE
885             "\xE1\xBA\xBC" => "\xE1\xBA\xBD", # LATIN CAPITAL LETTER E WITH TILDE
886             "\xE1\xBA\xBE" => "\xE1\xBA\xBF", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
887             "\xE1\xBB\x80" => "\xE1\xBB\x81", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
888             "\xE1\xBB\x82" => "\xE1\xBB\x83", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
889             "\xE1\xBB\x84" => "\xE1\xBB\x85", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
890             "\xE1\xBB\x86" => "\xE1\xBB\x87", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
891             "\xE1\xBB\x88" => "\xE1\xBB\x89", # LATIN CAPITAL LETTER I WITH HOOK ABOVE
892             "\xE1\xBB\x8A" => "\xE1\xBB\x8B", # LATIN CAPITAL LETTER I WITH DOT BELOW
893             "\xE1\xBB\x8C" => "\xE1\xBB\x8D", # LATIN CAPITAL LETTER O WITH DOT BELOW
894             "\xE1\xBB\x8E" => "\xE1\xBB\x8F", # LATIN CAPITAL LETTER O WITH HOOK ABOVE
895             "\xE1\xBB\x90" => "\xE1\xBB\x91", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
896             "\xE1\xBB\x92" => "\xE1\xBB\x93", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
897             "\xE1\xBB\x94" => "\xE1\xBB\x95", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
898             "\xE1\xBB\x96" => "\xE1\xBB\x97", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
899             "\xE1\xBB\x98" => "\xE1\xBB\x99", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
900             "\xE1\xBB\x9A" => "\xE1\xBB\x9B", # LATIN CAPITAL LETTER O WITH HORN AND ACUTE
901             "\xE1\xBB\x9C" => "\xE1\xBB\x9D", # LATIN CAPITAL LETTER O WITH HORN AND GRAVE
902             "\xE1\xBB\x9E" => "\xE1\xBB\x9F", # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
903             "\xE1\xBB\xA0" => "\xE1\xBB\xA1", # LATIN CAPITAL LETTER O WITH HORN AND TILDE
904             "\xE1\xBB\xA2" => "\xE1\xBB\xA3", # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
905             "\xE1\xBB\xA4" => "\xE1\xBB\xA5", # LATIN CAPITAL LETTER U WITH DOT BELOW
906             "\xE1\xBB\xA6" => "\xE1\xBB\xA7", # LATIN CAPITAL LETTER U WITH HOOK ABOVE
907             "\xE1\xBB\xA8" => "\xE1\xBB\xA9", # LATIN CAPITAL LETTER U WITH HORN AND ACUTE
908             "\xE1\xBB\xAA" => "\xE1\xBB\xAB", # LATIN CAPITAL LETTER U WITH HORN AND GRAVE
909             "\xE1\xBB\xAC" => "\xE1\xBB\xAD", # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
910             "\xE1\xBB\xAE" => "\xE1\xBB\xAF", # LATIN CAPITAL LETTER U WITH HORN AND TILDE
911             "\xE1\xBB\xB0" => "\xE1\xBB\xB1", # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
912             "\xE1\xBB\xB2" => "\xE1\xBB\xB3", # LATIN CAPITAL LETTER Y WITH GRAVE
913             "\xE1\xBB\xB4" => "\xE1\xBB\xB5", # LATIN CAPITAL LETTER Y WITH DOT BELOW
914             "\xE1\xBB\xB6" => "\xE1\xBB\xB7", # LATIN CAPITAL LETTER Y WITH HOOK ABOVE
915             "\xE1\xBB\xB8" => "\xE1\xBB\xB9", # LATIN CAPITAL LETTER Y WITH TILDE
916             "\xE1\xBB\xBA" => "\xE1\xBB\xBB", # LATIN CAPITAL LETTER MIDDLE-WELSH LL
917             "\xE1\xBB\xBC" => "\xE1\xBB\xBD", # LATIN CAPITAL LETTER MIDDLE-WELSH V
918             "\xE1\xBB\xBE" => "\xE1\xBB\xBF", # LATIN CAPITAL LETTER Y WITH LOOP
919             "\xE1\xBC\x88" => "\xE1\xBC\x80", # GREEK CAPITAL LETTER ALPHA WITH PSILI
920             "\xE1\xBC\x89" => "\xE1\xBC\x81", # GREEK CAPITAL LETTER ALPHA WITH DASIA
921             "\xE1\xBC\x8A" => "\xE1\xBC\x82", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
922             "\xE1\xBC\x8B" => "\xE1\xBC\x83", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
923             "\xE1\xBC\x8C" => "\xE1\xBC\x84", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
924             "\xE1\xBC\x8D" => "\xE1\xBC\x85", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
925             "\xE1\xBC\x8E" => "\xE1\xBC\x86", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
926             "\xE1\xBC\x8F" => "\xE1\xBC\x87", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
927             "\xE1\xBC\x98" => "\xE1\xBC\x90", # GREEK CAPITAL LETTER EPSILON WITH PSILI
928             "\xE1\xBC\x99" => "\xE1\xBC\x91", # GREEK CAPITAL LETTER EPSILON WITH DASIA
929             "\xE1\xBC\x9A" => "\xE1\xBC\x92", # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
930             "\xE1\xBC\x9B" => "\xE1\xBC\x93", # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
931             "\xE1\xBC\x9C" => "\xE1\xBC\x94", # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
932             "\xE1\xBC\x9D" => "\xE1\xBC\x95", # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
933             "\xE1\xBC\xA8" => "\xE1\xBC\xA0", # GREEK CAPITAL LETTER ETA WITH PSILI
934             "\xE1\xBC\xA9" => "\xE1\xBC\xA1", # GREEK CAPITAL LETTER ETA WITH DASIA
935             "\xE1\xBC\xAA" => "\xE1\xBC\xA2", # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
936             "\xE1\xBC\xAB" => "\xE1\xBC\xA3", # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
937             "\xE1\xBC\xAC" => "\xE1\xBC\xA4", # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
938             "\xE1\xBC\xAD" => "\xE1\xBC\xA5", # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
939             "\xE1\xBC\xAE" => "\xE1\xBC\xA6", # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
940             "\xE1\xBC\xAF" => "\xE1\xBC\xA7", # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
941             "\xE1\xBC\xB8" => "\xE1\xBC\xB0", # GREEK CAPITAL LETTER IOTA WITH PSILI
942             "\xE1\xBC\xB9" => "\xE1\xBC\xB1", # GREEK CAPITAL LETTER IOTA WITH DASIA
943             "\xE1\xBC\xBA" => "\xE1\xBC\xB2", # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
944             "\xE1\xBC\xBB" => "\xE1\xBC\xB3", # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
945             "\xE1\xBC\xBC" => "\xE1\xBC\xB4", # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
946             "\xE1\xBC\xBD" => "\xE1\xBC\xB5", # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
947             "\xE1\xBC\xBE" => "\xE1\xBC\xB6", # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
948             "\xE1\xBC\xBF" => "\xE1\xBC\xB7", # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
949             "\xE1\xBD\x88" => "\xE1\xBD\x80", # GREEK CAPITAL LETTER OMICRON WITH PSILI
950             "\xE1\xBD\x89" => "\xE1\xBD\x81", # GREEK CAPITAL LETTER OMICRON WITH DASIA
951             "\xE1\xBD\x8A" => "\xE1\xBD\x82", # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
952             "\xE1\xBD\x8B" => "\xE1\xBD\x83", # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
953             "\xE1\xBD\x8C" => "\xE1\xBD\x84", # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
954             "\xE1\xBD\x8D" => "\xE1\xBD\x85", # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
955             "\xE1\xBD\x90" => "\xCF\x85\xCC\x93", # GREEK SMALL LETTER UPSILON WITH PSILI
956             "\xE1\xBD\x92" => "\xCF\x85\xCC\x93\xCC\x80", # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
957             "\xE1\xBD\x94" => "\xCF\x85\xCC\x93\xCC\x81", # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
958             "\xE1\xBD\x96" => "\xCF\x85\xCC\x93\xCD\x82", # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
959             "\xE1\xBD\x99" => "\xE1\xBD\x91", # GREEK CAPITAL LETTER UPSILON WITH DASIA
960             "\xE1\xBD\x9B" => "\xE1\xBD\x93", # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
961             "\xE1\xBD\x9D" => "\xE1\xBD\x95", # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
962             "\xE1\xBD\x9F" => "\xE1\xBD\x97", # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
963             "\xE1\xBD\xA8" => "\xE1\xBD\xA0", # GREEK CAPITAL LETTER OMEGA WITH PSILI
964             "\xE1\xBD\xA9" => "\xE1\xBD\xA1", # GREEK CAPITAL LETTER OMEGA WITH DASIA
965             "\xE1\xBD\xAA" => "\xE1\xBD\xA2", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
966             "\xE1\xBD\xAB" => "\xE1\xBD\xA3", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
967             "\xE1\xBD\xAC" => "\xE1\xBD\xA4", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
968             "\xE1\xBD\xAD" => "\xE1\xBD\xA5", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
969             "\xE1\xBD\xAE" => "\xE1\xBD\xA6", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
970             "\xE1\xBD\xAF" => "\xE1\xBD\xA7", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
971             "\xE1\xBE\x80" => "\xE1\xBC\x80\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
972             "\xE1\xBE\x81" => "\xE1\xBC\x81\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
973             "\xE1\xBE\x82" => "\xE1\xBC\x82\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
974             "\xE1\xBE\x83" => "\xE1\xBC\x83\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
975             "\xE1\xBE\x84" => "\xE1\xBC\x84\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
976             "\xE1\xBE\x85" => "\xE1\xBC\x85\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
977             "\xE1\xBE\x86" => "\xE1\xBC\x86\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
978             "\xE1\xBE\x87" => "\xE1\xBC\x87\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
979             "\xE1\xBE\x88" => "\xE1\xBC\x80\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
980             "\xE1\xBE\x89" => "\xE1\xBC\x81\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
981             "\xE1\xBE\x8A" => "\xE1\xBC\x82\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
982             "\xE1\xBE\x8B" => "\xE1\xBC\x83\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
983             "\xE1\xBE\x8C" => "\xE1\xBC\x84\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
984             "\xE1\xBE\x8D" => "\xE1\xBC\x85\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
985             "\xE1\xBE\x8E" => "\xE1\xBC\x86\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
986             "\xE1\xBE\x8F" => "\xE1\xBC\x87\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
987             "\xE1\xBE\x90" => "\xE1\xBC\xA0\xCE\xB9", # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
988             "\xE1\xBE\x91" => "\xE1\xBC\xA1\xCE\xB9", # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
989             "\xE1\xBE\x92" => "\xE1\xBC\xA2\xCE\xB9", # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
990             "\xE1\xBE\x93" => "\xE1\xBC\xA3\xCE\xB9", # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
991             "\xE1\xBE\x94" => "\xE1\xBC\xA4\xCE\xB9", # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
992             "\xE1\xBE\x95" => "\xE1\xBC\xA5\xCE\xB9", # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
993             "\xE1\xBE\x96" => "\xE1\xBC\xA6\xCE\xB9", # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
994             "\xE1\xBE\x97" => "\xE1\xBC\xA7\xCE\xB9", # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
995             "\xE1\xBE\x98" => "\xE1\xBC\xA0\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
996             "\xE1\xBE\x99" => "\xE1\xBC\xA1\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
997             "\xE1\xBE\x9A" => "\xE1\xBC\xA2\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
998             "\xE1\xBE\x9B" => "\xE1\xBC\xA3\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
999             "\xE1\xBE\x9C" => "\xE1\xBC\xA4\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1000             "\xE1\xBE\x9D" => "\xE1\xBC\xA5\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1001             "\xE1\xBE\x9E" => "\xE1\xBC\xA6\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1002             "\xE1\xBE\x9F" => "\xE1\xBC\xA7\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1003             "\xE1\xBE\xA0" => "\xE1\xBD\xA0\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
1004             "\xE1\xBE\xA1" => "\xE1\xBD\xA1\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
1005             "\xE1\xBE\xA2" => "\xE1\xBD\xA2\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1006             "\xE1\xBE\xA3" => "\xE1\xBD\xA3\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1007             "\xE1\xBE\xA4" => "\xE1\xBD\xA4\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1008             "\xE1\xBE\xA5" => "\xE1\xBD\xA5\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1009             "\xE1\xBE\xA6" => "\xE1\xBD\xA6\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1010             "\xE1\xBE\xA7" => "\xE1\xBD\xA7\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1011             "\xE1\xBE\xA8" => "\xE1\xBD\xA0\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
1012             "\xE1\xBE\xA9" => "\xE1\xBD\xA1\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
1013             "\xE1\xBE\xAA" => "\xE1\xBD\xA2\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1014             "\xE1\xBE\xAB" => "\xE1\xBD\xA3\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1015             "\xE1\xBE\xAC" => "\xE1\xBD\xA4\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1016             "\xE1\xBE\xAD" => "\xE1\xBD\xA5\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1017             "\xE1\xBE\xAE" => "\xE1\xBD\xA6\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1018             "\xE1\xBE\xAF" => "\xE1\xBD\xA7\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1019             "\xE1\xBE\xB2" => "\xE1\xBD\xB0\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
1020             "\xE1\xBE\xB3" => "\xCE\xB1\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
1021             "\xE1\xBE\xB4" => "\xCE\xAC\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
1022             "\xE1\xBE\xB6" => "\xCE\xB1\xCD\x82", # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
1023             "\xE1\xBE\xB7" => "\xCE\xB1\xCD\x82\xCE\xB9", # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
1024             "\xE1\xBE\xB8" => "\xE1\xBE\xB0", # GREEK CAPITAL LETTER ALPHA WITH VRACHY
1025             "\xE1\xBE\xB9" => "\xE1\xBE\xB1", # GREEK CAPITAL LETTER ALPHA WITH MACRON
1026             "\xE1\xBE\xBA" => "\xE1\xBD\xB0", # GREEK CAPITAL LETTER ALPHA WITH VARIA
1027             "\xE1\xBE\xBB" => "\xE1\xBD\xB1", # GREEK CAPITAL LETTER ALPHA WITH OXIA
1028             "\xE1\xBE\xBC" => "\xCE\xB1\xCE\xB9", # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
1029             "\xE1\xBE\xBE" => "\xCE\xB9", # GREEK PROSGEGRAMMENI
1030             "\xE1\xBF\x82" => "\xE1\xBD\xB4\xCE\xB9", # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
1031             "\xE1\xBF\x83" => "\xCE\xB7\xCE\xB9", # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
1032             "\xE1\xBF\x84" => "\xCE\xAE\xCE\xB9", # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
1033             "\xE1\xBF\x86" => "\xCE\xB7\xCD\x82", # GREEK SMALL LETTER ETA WITH PERISPOMENI
1034             "\xE1\xBF\x87" => "\xCE\xB7\xCD\x82\xCE\xB9", # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
1035             "\xE1\xBF\x88" => "\xE1\xBD\xB2", # GREEK CAPITAL LETTER EPSILON WITH VARIA
1036             "\xE1\xBF\x89" => "\xE1\xBD\xB3", # GREEK CAPITAL LETTER EPSILON WITH OXIA
1037             "\xE1\xBF\x8A" => "\xE1\xBD\xB4", # GREEK CAPITAL LETTER ETA WITH VARIA
1038             "\xE1\xBF\x8B" => "\xE1\xBD\xB5", # GREEK CAPITAL LETTER ETA WITH OXIA
1039             "\xE1\xBF\x8C" => "\xCE\xB7\xCE\xB9", # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
1040             "\xE1\xBF\x92" => "\xCE\xB9\xCC\x88\xCC\x80", # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
1041             "\xE1\xBF\x93" => "\xCE\xB9\xCC\x88\xCC\x81", # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
1042             "\xE1\xBF\x96" => "\xCE\xB9\xCD\x82", # GREEK SMALL LETTER IOTA WITH PERISPOMENI
1043             "\xE1\xBF\x97" => "\xCE\xB9\xCC\x88\xCD\x82", # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
1044             "\xE1\xBF\x98" => "\xE1\xBF\x90", # GREEK CAPITAL LETTER IOTA WITH VRACHY
1045             "\xE1\xBF\x99" => "\xE1\xBF\x91", # GREEK CAPITAL LETTER IOTA WITH MACRON
1046             "\xE1\xBF\x9A" => "\xE1\xBD\xB6", # GREEK CAPITAL LETTER IOTA WITH VARIA
1047             "\xE1\xBF\x9B" => "\xE1\xBD\xB7", # GREEK CAPITAL LETTER IOTA WITH OXIA
1048             "\xE1\xBF\xA2" => "\xCF\x85\xCC\x88\xCC\x80", # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
1049             "\xE1\xBF\xA3" => "\xCF\x85\xCC\x88\xCC\x81", # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
1050             "\xE1\xBF\xA4" => "\xCF\x81\xCC\x93", # GREEK SMALL LETTER RHO WITH PSILI
1051             "\xE1\xBF\xA6" => "\xCF\x85\xCD\x82", # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
1052             "\xE1\xBF\xA7" => "\xCF\x85\xCC\x88\xCD\x82", # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
1053             "\xE1\xBF\xA8" => "\xE1\xBF\xA0", # GREEK CAPITAL LETTER UPSILON WITH VRACHY
1054             "\xE1\xBF\xA9" => "\xE1\xBF\xA1", # GREEK CAPITAL LETTER UPSILON WITH MACRON
1055             "\xE1\xBF\xAA" => "\xE1\xBD\xBA", # GREEK CAPITAL LETTER UPSILON WITH VARIA
1056             "\xE1\xBF\xAB" => "\xE1\xBD\xBB", # GREEK CAPITAL LETTER UPSILON WITH OXIA
1057             "\xE1\xBF\xAC" => "\xE1\xBF\xA5", # GREEK CAPITAL LETTER RHO WITH DASIA
1058             "\xE1\xBF\xB2" => "\xE1\xBD\xBC\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
1059             "\xE1\xBF\xB3" => "\xCF\x89\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
1060             "\xE1\xBF\xB4" => "\xCF\x8E\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
1061             "\xE1\xBF\xB6" => "\xCF\x89\xCD\x82", # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
1062             "\xE1\xBF\xB7" => "\xCF\x89\xCD\x82\xCE\xB9", # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
1063             "\xE1\xBF\xB8" => "\xE1\xBD\xB8", # GREEK CAPITAL LETTER OMICRON WITH VARIA
1064             "\xE1\xBF\xB9" => "\xE1\xBD\xB9", # GREEK CAPITAL LETTER OMICRON WITH OXIA
1065             "\xE1\xBF\xBA" => "\xE1\xBD\xBC", # GREEK CAPITAL LETTER OMEGA WITH VARIA
1066             "\xE1\xBF\xBB" => "\xE1\xBD\xBD", # GREEK CAPITAL LETTER OMEGA WITH OXIA
1067             "\xE1\xBF\xBC" => "\xCF\x89\xCE\xB9", # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
1068             "\xE2\x84\xA6" => "\xCF\x89", # OHM SIGN
1069             "\xE2\x84\xAA" => "\x6B", # KELVIN SIGN
1070             "\xE2\x84\xAB" => "\xC3\xA5", # ANGSTROM SIGN
1071             "\xE2\x84\xB2" => "\xE2\x85\x8E", # TURNED CAPITAL F
1072             "\xE2\x85\xA0" => "\xE2\x85\xB0", # ROMAN NUMERAL ONE
1073             "\xE2\x85\xA1" => "\xE2\x85\xB1", # ROMAN NUMERAL TWO
1074             "\xE2\x85\xA2" => "\xE2\x85\xB2", # ROMAN NUMERAL THREE
1075             "\xE2\x85\xA3" => "\xE2\x85\xB3", # ROMAN NUMERAL FOUR
1076             "\xE2\x85\xA4" => "\xE2\x85\xB4", # ROMAN NUMERAL FIVE
1077             "\xE2\x85\xA5" => "\xE2\x85\xB5", # ROMAN NUMERAL SIX
1078             "\xE2\x85\xA6" => "\xE2\x85\xB6", # ROMAN NUMERAL SEVEN
1079             "\xE2\x85\xA7" => "\xE2\x85\xB7", # ROMAN NUMERAL EIGHT
1080             "\xE2\x85\xA8" => "\xE2\x85\xB8", # ROMAN NUMERAL NINE
1081             "\xE2\x85\xA9" => "\xE2\x85\xB9", # ROMAN NUMERAL TEN
1082             "\xE2\x85\xAA" => "\xE2\x85\xBA", # ROMAN NUMERAL ELEVEN
1083             "\xE2\x85\xAB" => "\xE2\x85\xBB", # ROMAN NUMERAL TWELVE
1084             "\xE2\x85\xAC" => "\xE2\x85\xBC", # ROMAN NUMERAL FIFTY
1085             "\xE2\x85\xAD" => "\xE2\x85\xBD", # ROMAN NUMERAL ONE HUNDRED
1086             "\xE2\x85\xAE" => "\xE2\x85\xBE", # ROMAN NUMERAL FIVE HUNDRED
1087             "\xE2\x85\xAF" => "\xE2\x85\xBF", # ROMAN NUMERAL ONE THOUSAND
1088             "\xE2\x86\x83" => "\xE2\x86\x84", # ROMAN NUMERAL REVERSED ONE HUNDRED
1089             "\xE2\x92\xB6" => "\xE2\x93\x90", # CIRCLED LATIN CAPITAL LETTER A
1090             "\xE2\x92\xB7" => "\xE2\x93\x91", # CIRCLED LATIN CAPITAL LETTER B
1091             "\xE2\x92\xB8" => "\xE2\x93\x92", # CIRCLED LATIN CAPITAL LETTER C
1092             "\xE2\x92\xB9" => "\xE2\x93\x93", # CIRCLED LATIN CAPITAL LETTER D
1093             "\xE2\x92\xBA" => "\xE2\x93\x94", # CIRCLED LATIN CAPITAL LETTER E
1094             "\xE2\x92\xBB" => "\xE2\x93\x95", # CIRCLED LATIN CAPITAL LETTER F
1095             "\xE2\x92\xBC" => "\xE2\x93\x96", # CIRCLED LATIN CAPITAL LETTER G
1096             "\xE2\x92\xBD" => "\xE2\x93\x97", # CIRCLED LATIN CAPITAL LETTER H
1097             "\xE2\x92\xBE" => "\xE2\x93\x98", # CIRCLED LATIN CAPITAL LETTER I
1098             "\xE2\x92\xBF" => "\xE2\x93\x99", # CIRCLED LATIN CAPITAL LETTER J
1099             "\xE2\x93\x80" => "\xE2\x93\x9A", # CIRCLED LATIN CAPITAL LETTER K
1100             "\xE2\x93\x81" => "\xE2\x93\x9B", # CIRCLED LATIN CAPITAL LETTER L
1101             "\xE2\x93\x82" => "\xE2\x93\x9C", # CIRCLED LATIN CAPITAL LETTER M
1102             "\xE2\x93\x83" => "\xE2\x93\x9D", # CIRCLED LATIN CAPITAL LETTER N
1103             "\xE2\x93\x84" => "\xE2\x93\x9E", # CIRCLED LATIN CAPITAL LETTER O
1104             "\xE2\x93\x85" => "\xE2\x93\x9F", # CIRCLED LATIN CAPITAL LETTER P
1105             "\xE2\x93\x86" => "\xE2\x93\xA0", # CIRCLED LATIN CAPITAL LETTER Q
1106             "\xE2\x93\x87" => "\xE2\x93\xA1", # CIRCLED LATIN CAPITAL LETTER R
1107             "\xE2\x93\x88" => "\xE2\x93\xA2", # CIRCLED LATIN CAPITAL LETTER S
1108             "\xE2\x93\x89" => "\xE2\x93\xA3", # CIRCLED LATIN CAPITAL LETTER T
1109             "\xE2\x93\x8A" => "\xE2\x93\xA4", # CIRCLED LATIN CAPITAL LETTER U
1110             "\xE2\x93\x8B" => "\xE2\x93\xA5", # CIRCLED LATIN CAPITAL LETTER V
1111             "\xE2\x93\x8C" => "\xE2\x93\xA6", # CIRCLED LATIN CAPITAL LETTER W
1112             "\xE2\x93\x8D" => "\xE2\x93\xA7", # CIRCLED LATIN CAPITAL LETTER X
1113             "\xE2\x93\x8E" => "\xE2\x93\xA8", # CIRCLED LATIN CAPITAL LETTER Y
1114             "\xE2\x93\x8F" => "\xE2\x93\xA9", # CIRCLED LATIN CAPITAL LETTER Z
1115             "\xE2\xB0\x80" => "\xE2\xB0\xB0", # GLAGOLITIC CAPITAL LETTER AZU
1116             "\xE2\xB0\x81" => "\xE2\xB0\xB1", # GLAGOLITIC CAPITAL LETTER BUKY
1117             "\xE2\xB0\x82" => "\xE2\xB0\xB2", # GLAGOLITIC CAPITAL LETTER VEDE
1118             "\xE2\xB0\x83" => "\xE2\xB0\xB3", # GLAGOLITIC CAPITAL LETTER GLAGOLI
1119             "\xE2\xB0\x84" => "\xE2\xB0\xB4", # GLAGOLITIC CAPITAL LETTER DOBRO
1120             "\xE2\xB0\x85" => "\xE2\xB0\xB5", # GLAGOLITIC CAPITAL LETTER YESTU
1121             "\xE2\xB0\x86" => "\xE2\xB0\xB6", # GLAGOLITIC CAPITAL LETTER ZHIVETE
1122             "\xE2\xB0\x87" => "\xE2\xB0\xB7", # GLAGOLITIC CAPITAL LETTER DZELO
1123             "\xE2\xB0\x88" => "\xE2\xB0\xB8", # GLAGOLITIC CAPITAL LETTER ZEMLJA
1124             "\xE2\xB0\x89" => "\xE2\xB0\xB9", # GLAGOLITIC CAPITAL LETTER IZHE
1125             "\xE2\xB0\x8A" => "\xE2\xB0\xBA", # GLAGOLITIC CAPITAL LETTER INITIAL IZHE
1126             "\xE2\xB0\x8B" => "\xE2\xB0\xBB", # GLAGOLITIC CAPITAL LETTER I
1127             "\xE2\xB0\x8C" => "\xE2\xB0\xBC", # GLAGOLITIC CAPITAL LETTER DJERVI
1128             "\xE2\xB0\x8D" => "\xE2\xB0\xBD", # GLAGOLITIC CAPITAL LETTER KAKO
1129             "\xE2\xB0\x8E" => "\xE2\xB0\xBE", # GLAGOLITIC CAPITAL LETTER LJUDIJE
1130             "\xE2\xB0\x8F" => "\xE2\xB0\xBF", # GLAGOLITIC CAPITAL LETTER MYSLITE
1131             "\xE2\xB0\x90" => "\xE2\xB1\x80", # GLAGOLITIC CAPITAL LETTER NASHI
1132             "\xE2\xB0\x91" => "\xE2\xB1\x81", # GLAGOLITIC CAPITAL LETTER ONU
1133             "\xE2\xB0\x92" => "\xE2\xB1\x82", # GLAGOLITIC CAPITAL LETTER POKOJI
1134             "\xE2\xB0\x93" => "\xE2\xB1\x83", # GLAGOLITIC CAPITAL LETTER RITSI
1135             "\xE2\xB0\x94" => "\xE2\xB1\x84", # GLAGOLITIC CAPITAL LETTER SLOVO
1136             "\xE2\xB0\x95" => "\xE2\xB1\x85", # GLAGOLITIC CAPITAL LETTER TVRIDO
1137             "\xE2\xB0\x96" => "\xE2\xB1\x86", # GLAGOLITIC CAPITAL LETTER UKU
1138             "\xE2\xB0\x97" => "\xE2\xB1\x87", # GLAGOLITIC CAPITAL LETTER FRITU
1139             "\xE2\xB0\x98" => "\xE2\xB1\x88", # GLAGOLITIC CAPITAL LETTER HERU
1140             "\xE2\xB0\x99" => "\xE2\xB1\x89", # GLAGOLITIC CAPITAL LETTER OTU
1141             "\xE2\xB0\x9A" => "\xE2\xB1\x8A", # GLAGOLITIC CAPITAL LETTER PE
1142             "\xE2\xB0\x9B" => "\xE2\xB1\x8B", # GLAGOLITIC CAPITAL LETTER SHTA
1143             "\xE2\xB0\x9C" => "\xE2\xB1\x8C", # GLAGOLITIC CAPITAL LETTER TSI
1144             "\xE2\xB0\x9D" => "\xE2\xB1\x8D", # GLAGOLITIC CAPITAL LETTER CHRIVI
1145             "\xE2\xB0\x9E" => "\xE2\xB1\x8E", # GLAGOLITIC CAPITAL LETTER SHA
1146             "\xE2\xB0\x9F" => "\xE2\xB1\x8F", # GLAGOLITIC CAPITAL LETTER YERU
1147             "\xE2\xB0\xA0" => "\xE2\xB1\x90", # GLAGOLITIC CAPITAL LETTER YERI
1148             "\xE2\xB0\xA1" => "\xE2\xB1\x91", # GLAGOLITIC CAPITAL LETTER YATI
1149             "\xE2\xB0\xA2" => "\xE2\xB1\x92", # GLAGOLITIC CAPITAL LETTER SPIDERY HA
1150             "\xE2\xB0\xA3" => "\xE2\xB1\x93", # GLAGOLITIC CAPITAL LETTER YU
1151             "\xE2\xB0\xA4" => "\xE2\xB1\x94", # GLAGOLITIC CAPITAL LETTER SMALL YUS
1152             "\xE2\xB0\xA5" => "\xE2\xB1\x95", # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
1153             "\xE2\xB0\xA6" => "\xE2\xB1\x96", # GLAGOLITIC CAPITAL LETTER YO
1154             "\xE2\xB0\xA7" => "\xE2\xB1\x97", # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
1155             "\xE2\xB0\xA8" => "\xE2\xB1\x98", # GLAGOLITIC CAPITAL LETTER BIG YUS
1156             "\xE2\xB0\xA9" => "\xE2\xB1\x99", # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
1157             "\xE2\xB0\xAA" => "\xE2\xB1\x9A", # GLAGOLITIC CAPITAL LETTER FITA
1158             "\xE2\xB0\xAB" => "\xE2\xB1\x9B", # GLAGOLITIC CAPITAL LETTER IZHITSA
1159             "\xE2\xB0\xAC" => "\xE2\xB1\x9C", # GLAGOLITIC CAPITAL LETTER SHTAPIC
1160             "\xE2\xB0\xAD" => "\xE2\xB1\x9D", # GLAGOLITIC CAPITAL LETTER TROKUTASTI A
1161             "\xE2\xB0\xAE" => "\xE2\xB1\x9E", # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
1162             "\xE2\xB1\xA0" => "\xE2\xB1\xA1", # LATIN CAPITAL LETTER L WITH DOUBLE BAR
1163             "\xE2\xB1\xA2" => "\xC9\xAB", # LATIN CAPITAL LETTER L WITH MIDDLE TILDE
1164             "\xE2\xB1\xA3" => "\xE1\xB5\xBD", # LATIN CAPITAL LETTER P WITH STROKE
1165             "\xE2\xB1\xA4" => "\xC9\xBD", # LATIN CAPITAL LETTER R WITH TAIL
1166             "\xE2\xB1\xA7" => "\xE2\xB1\xA8", # LATIN CAPITAL LETTER H WITH DESCENDER
1167             "\xE2\xB1\xA9" => "\xE2\xB1\xAA", # LATIN CAPITAL LETTER K WITH DESCENDER
1168             "\xE2\xB1\xAB" => "\xE2\xB1\xAC", # LATIN CAPITAL LETTER Z WITH DESCENDER
1169             "\xE2\xB1\xAD" => "\xC9\x91", # LATIN CAPITAL LETTER ALPHA
1170             "\xE2\xB1\xAE" => "\xC9\xB1", # LATIN CAPITAL LETTER M WITH HOOK
1171             "\xE2\xB1\xAF" => "\xC9\x90", # LATIN CAPITAL LETTER TURNED A
1172             "\xE2\xB1\xB0" => "\xC9\x92", # LATIN CAPITAL LETTER TURNED ALPHA
1173             "\xE2\xB1\xB2" => "\xE2\xB1\xB3", # LATIN CAPITAL LETTER W WITH HOOK
1174             "\xE2\xB1\xB5" => "\xE2\xB1\xB6", # LATIN CAPITAL LETTER HALF H
1175             "\xE2\xB1\xBE" => "\xC8\xBF", # LATIN CAPITAL LETTER S WITH SWASH TAIL
1176             "\xE2\xB1\xBF" => "\xC9\x80", # LATIN CAPITAL LETTER Z WITH SWASH TAIL
1177             "\xE2\xB2\x80" => "\xE2\xB2\x81", # COPTIC CAPITAL LETTER ALFA
1178             "\xE2\xB2\x82" => "\xE2\xB2\x83", # COPTIC CAPITAL LETTER VIDA
1179             "\xE2\xB2\x84" => "\xE2\xB2\x85", # COPTIC CAPITAL LETTER GAMMA
1180             "\xE2\xB2\x86" => "\xE2\xB2\x87", # COPTIC CAPITAL LETTER DALDA
1181             "\xE2\xB2\x88" => "\xE2\xB2\x89", # COPTIC CAPITAL LETTER EIE
1182             "\xE2\xB2\x8A" => "\xE2\xB2\x8B", # COPTIC CAPITAL LETTER SOU
1183             "\xE2\xB2\x8C" => "\xE2\xB2\x8D", # COPTIC CAPITAL LETTER ZATA
1184             "\xE2\xB2\x8E" => "\xE2\xB2\x8F", # COPTIC CAPITAL LETTER HATE
1185             "\xE2\xB2\x90" => "\xE2\xB2\x91", # COPTIC CAPITAL LETTER THETHE
1186             "\xE2\xB2\x92" => "\xE2\xB2\x93", # COPTIC CAPITAL LETTER IAUDA
1187             "\xE2\xB2\x94" => "\xE2\xB2\x95", # COPTIC CAPITAL LETTER KAPA
1188             "\xE2\xB2\x96" => "\xE2\xB2\x97", # COPTIC CAPITAL LETTER LAULA
1189             "\xE2\xB2\x98" => "\xE2\xB2\x99", # COPTIC CAPITAL LETTER MI
1190             "\xE2\xB2\x9A" => "\xE2\xB2\x9B", # COPTIC CAPITAL LETTER NI
1191             "\xE2\xB2\x9C" => "\xE2\xB2\x9D", # COPTIC CAPITAL LETTER KSI
1192             "\xE2\xB2\x9E" => "\xE2\xB2\x9F", # COPTIC CAPITAL LETTER O
1193             "\xE2\xB2\xA0" => "\xE2\xB2\xA1", # COPTIC CAPITAL LETTER PI
1194             "\xE2\xB2\xA2" => "\xE2\xB2\xA3", # COPTIC CAPITAL LETTER RO
1195             "\xE2\xB2\xA4" => "\xE2\xB2\xA5", # COPTIC CAPITAL LETTER SIMA
1196             "\xE2\xB2\xA6" => "\xE2\xB2\xA7", # COPTIC CAPITAL LETTER TAU
1197             "\xE2\xB2\xA8" => "\xE2\xB2\xA9", # COPTIC CAPITAL LETTER UA
1198             "\xE2\xB2\xAA" => "\xE2\xB2\xAB", # COPTIC CAPITAL LETTER FI
1199             "\xE2\xB2\xAC" => "\xE2\xB2\xAD", # COPTIC CAPITAL LETTER KHI
1200             "\xE2\xB2\xAE" => "\xE2\xB2\xAF", # COPTIC CAPITAL LETTER PSI
1201             "\xE2\xB2\xB0" => "\xE2\xB2\xB1", # COPTIC CAPITAL LETTER OOU
1202             "\xE2\xB2\xB2" => "\xE2\xB2\xB3", # COPTIC CAPITAL LETTER DIALECT-P ALEF
1203             "\xE2\xB2\xB4" => "\xE2\xB2\xB5", # COPTIC CAPITAL LETTER OLD COPTIC AIN
1204             "\xE2\xB2\xB6" => "\xE2\xB2\xB7", # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
1205             "\xE2\xB2\xB8" => "\xE2\xB2\xB9", # COPTIC CAPITAL LETTER DIALECT-P KAPA
1206             "\xE2\xB2\xBA" => "\xE2\xB2\xBB", # COPTIC CAPITAL LETTER DIALECT-P NI
1207             "\xE2\xB2\xBC" => "\xE2\xB2\xBD", # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
1208             "\xE2\xB2\xBE" => "\xE2\xB2\xBF", # COPTIC CAPITAL LETTER OLD COPTIC OOU
1209             "\xE2\xB3\x80" => "\xE2\xB3\x81", # COPTIC CAPITAL LETTER SAMPI
1210             "\xE2\xB3\x82" => "\xE2\xB3\x83", # COPTIC CAPITAL LETTER CROSSED SHEI
1211             "\xE2\xB3\x84" => "\xE2\xB3\x85", # COPTIC CAPITAL LETTER OLD COPTIC SHEI
1212             "\xE2\xB3\x86" => "\xE2\xB3\x87", # COPTIC CAPITAL LETTER OLD COPTIC ESH
1213             "\xE2\xB3\x88" => "\xE2\xB3\x89", # COPTIC CAPITAL LETTER AKHMIMIC KHEI
1214             "\xE2\xB3\x8A" => "\xE2\xB3\x8B", # COPTIC CAPITAL LETTER DIALECT-P HORI
1215             "\xE2\xB3\x8C" => "\xE2\xB3\x8D", # COPTIC CAPITAL LETTER OLD COPTIC HORI
1216             "\xE2\xB3\x8E" => "\xE2\xB3\x8F", # COPTIC CAPITAL LETTER OLD COPTIC HA
1217             "\xE2\xB3\x90" => "\xE2\xB3\x91", # COPTIC CAPITAL LETTER L-SHAPED HA
1218             "\xE2\xB3\x92" => "\xE2\xB3\x93", # COPTIC CAPITAL LETTER OLD COPTIC HEI
1219             "\xE2\xB3\x94" => "\xE2\xB3\x95", # COPTIC CAPITAL LETTER OLD COPTIC HAT
1220             "\xE2\xB3\x96" => "\xE2\xB3\x97", # COPTIC CAPITAL LETTER OLD COPTIC GANGIA
1221             "\xE2\xB3\x98" => "\xE2\xB3\x99", # COPTIC CAPITAL LETTER OLD COPTIC DJA
1222             "\xE2\xB3\x9A" => "\xE2\xB3\x9B", # COPTIC CAPITAL LETTER OLD COPTIC SHIMA
1223             "\xE2\xB3\x9C" => "\xE2\xB3\x9D", # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
1224             "\xE2\xB3\x9E" => "\xE2\xB3\x9F", # COPTIC CAPITAL LETTER OLD NUBIAN NGI
1225             "\xE2\xB3\xA0" => "\xE2\xB3\xA1", # COPTIC CAPITAL LETTER OLD NUBIAN NYI
1226             "\xE2\xB3\xA2" => "\xE2\xB3\xA3", # COPTIC CAPITAL LETTER OLD NUBIAN WAU
1227             "\xE2\xB3\xAB" => "\xE2\xB3\xAC", # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI
1228             "\xE2\xB3\xAD" => "\xE2\xB3\xAE", # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA
1229             "\xE2\xB3\xB2" => "\xE2\xB3\xB3", # COPTIC CAPITAL LETTER BOHAIRIC KHEI
1230             "\xEA\x99\x80" => "\xEA\x99\x81", # CYRILLIC CAPITAL LETTER ZEMLYA
1231             "\xEA\x99\x82" => "\xEA\x99\x83", # CYRILLIC CAPITAL LETTER DZELO
1232             "\xEA\x99\x84" => "\xEA\x99\x85", # CYRILLIC CAPITAL LETTER REVERSED DZE
1233             "\xEA\x99\x86" => "\xEA\x99\x87", # CYRILLIC CAPITAL LETTER IOTA
1234             "\xEA\x99\x88" => "\xEA\x99\x89", # CYRILLIC CAPITAL LETTER DJERV
1235             "\xEA\x99\x8A" => "\xEA\x99\x8B", # CYRILLIC CAPITAL LETTER MONOGRAPH UK
1236             "\xEA\x99\x8C" => "\xEA\x99\x8D", # CYRILLIC CAPITAL LETTER BROAD OMEGA
1237             "\xEA\x99\x8E" => "\xEA\x99\x8F", # CYRILLIC CAPITAL LETTER NEUTRAL YER
1238             "\xEA\x99\x90" => "\xEA\x99\x91", # CYRILLIC CAPITAL LETTER YERU WITH BACK YER
1239             "\xEA\x99\x92" => "\xEA\x99\x93", # CYRILLIC CAPITAL LETTER IOTIFIED YAT
1240             "\xEA\x99\x94" => "\xEA\x99\x95", # CYRILLIC CAPITAL LETTER REVERSED YU
1241             "\xEA\x99\x96" => "\xEA\x99\x97", # CYRILLIC CAPITAL LETTER IOTIFIED A
1242             "\xEA\x99\x98" => "\xEA\x99\x99", # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS
1243             "\xEA\x99\x9A" => "\xEA\x99\x9B", # CYRILLIC CAPITAL LETTER BLENDED YUS
1244             "\xEA\x99\x9C" => "\xEA\x99\x9D", # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS
1245             "\xEA\x99\x9E" => "\xEA\x99\x9F", # CYRILLIC CAPITAL LETTER YN
1246             "\xEA\x99\xA0" => "\xEA\x99\xA1", # CYRILLIC CAPITAL LETTER REVERSED TSE
1247             "\xEA\x99\xA2" => "\xEA\x99\xA3", # CYRILLIC CAPITAL LETTER SOFT DE
1248             "\xEA\x99\xA4" => "\xEA\x99\xA5", # CYRILLIC CAPITAL LETTER SOFT EL
1249             "\xEA\x99\xA6" => "\xEA\x99\xA7", # CYRILLIC CAPITAL LETTER SOFT EM
1250             "\xEA\x99\xA8" => "\xEA\x99\xA9", # CYRILLIC CAPITAL LETTER MONOCULAR O
1251             "\xEA\x99\xAA" => "\xEA\x99\xAB", # CYRILLIC CAPITAL LETTER BINOCULAR O
1252             "\xEA\x99\xAC" => "\xEA\x99\xAD", # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O
1253             "\xEA\x9A\x80" => "\xEA\x9A\x81", # CYRILLIC CAPITAL LETTER DWE
1254             "\xEA\x9A\x82" => "\xEA\x9A\x83", # CYRILLIC CAPITAL LETTER DZWE
1255             "\xEA\x9A\x84" => "\xEA\x9A\x85", # CYRILLIC CAPITAL LETTER ZHWE
1256             "\xEA\x9A\x86" => "\xEA\x9A\x87", # CYRILLIC CAPITAL LETTER CCHE
1257             "\xEA\x9A\x88" => "\xEA\x9A\x89", # CYRILLIC CAPITAL LETTER DZZE
1258             "\xEA\x9A\x8A" => "\xEA\x9A\x8B", # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK
1259             "\xEA\x9A\x8C" => "\xEA\x9A\x8D", # CYRILLIC CAPITAL LETTER TWE
1260             "\xEA\x9A\x8E" => "\xEA\x9A\x8F", # CYRILLIC CAPITAL LETTER TSWE
1261             "\xEA\x9A\x90" => "\xEA\x9A\x91", # CYRILLIC CAPITAL LETTER TSSE
1262             "\xEA\x9A\x92" => "\xEA\x9A\x93", # CYRILLIC CAPITAL LETTER TCHE
1263             "\xEA\x9A\x94" => "\xEA\x9A\x95", # CYRILLIC CAPITAL LETTER HWE
1264             "\xEA\x9A\x96" => "\xEA\x9A\x97", # CYRILLIC CAPITAL LETTER SHWE
1265             "\xEA\x9A\x98" => "\xEA\x9A\x99", # CYRILLIC CAPITAL LETTER DOUBLE O
1266             "\xEA\x9A\x9A" => "\xEA\x9A\x9B", # CYRILLIC CAPITAL LETTER CROSSED O
1267             "\xEA\x9C\xA2" => "\xEA\x9C\xA3", # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF
1268             "\xEA\x9C\xA4" => "\xEA\x9C\xA5", # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN
1269             "\xEA\x9C\xA6" => "\xEA\x9C\xA7", # LATIN CAPITAL LETTER HENG
1270             "\xEA\x9C\xA8" => "\xEA\x9C\xA9", # LATIN CAPITAL LETTER TZ
1271             "\xEA\x9C\xAA" => "\xEA\x9C\xAB", # LATIN CAPITAL LETTER TRESILLO
1272             "\xEA\x9C\xAC" => "\xEA\x9C\xAD", # LATIN CAPITAL LETTER CUATRILLO
1273             "\xEA\x9C\xAE" => "\xEA\x9C\xAF", # LATIN CAPITAL LETTER CUATRILLO WITH COMMA
1274             "\xEA\x9C\xB2" => "\xEA\x9C\xB3", # LATIN CAPITAL LETTER AA
1275             "\xEA\x9C\xB4" => "\xEA\x9C\xB5", # LATIN CAPITAL LETTER AO
1276             "\xEA\x9C\xB6" => "\xEA\x9C\xB7", # LATIN CAPITAL LETTER AU
1277             "\xEA\x9C\xB8" => "\xEA\x9C\xB9", # LATIN CAPITAL LETTER AV
1278             "\xEA\x9C\xBA" => "\xEA\x9C\xBB", # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR
1279             "\xEA\x9C\xBC" => "\xEA\x9C\xBD", # LATIN CAPITAL LETTER AY
1280             "\xEA\x9C\xBE" => "\xEA\x9C\xBF", # LATIN CAPITAL LETTER REVERSED C WITH DOT
1281             "\xEA\x9D\x80" => "\xEA\x9D\x81", # LATIN CAPITAL LETTER K WITH STROKE
1282             "\xEA\x9D\x82" => "\xEA\x9D\x83", # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE
1283             "\xEA\x9D\x84" => "\xEA\x9D\x85", # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE
1284             "\xEA\x9D\x86" => "\xEA\x9D\x87", # LATIN CAPITAL LETTER BROKEN L
1285             "\xEA\x9D\x88" => "\xEA\x9D\x89", # LATIN CAPITAL LETTER L WITH HIGH STROKE
1286             "\xEA\x9D\x8A" => "\xEA\x9D\x8B", # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY
1287             "\xEA\x9D\x8C" => "\xEA\x9D\x8D", # LATIN CAPITAL LETTER O WITH LOOP
1288             "\xEA\x9D\x8E" => "\xEA\x9D\x8F", # LATIN CAPITAL LETTER OO
1289             "\xEA\x9D\x90" => "\xEA\x9D\x91", # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER
1290             "\xEA\x9D\x92" => "\xEA\x9D\x93", # LATIN CAPITAL LETTER P WITH FLOURISH
1291             "\xEA\x9D\x94" => "\xEA\x9D\x95", # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL
1292             "\xEA\x9D\x96" => "\xEA\x9D\x97", # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER
1293             "\xEA\x9D\x98" => "\xEA\x9D\x99", # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE
1294             "\xEA\x9D\x9A" => "\xEA\x9D\x9B", # LATIN CAPITAL LETTER R ROTUNDA
1295             "\xEA\x9D\x9C" => "\xEA\x9D\x9D", # LATIN CAPITAL LETTER RUM ROTUNDA
1296             "\xEA\x9D\x9E" => "\xEA\x9D\x9F", # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE
1297             "\xEA\x9D\xA0" => "\xEA\x9D\xA1", # LATIN CAPITAL LETTER VY
1298             "\xEA\x9D\xA2" => "\xEA\x9D\xA3", # LATIN CAPITAL LETTER VISIGOTHIC Z
1299             "\xEA\x9D\xA4" => "\xEA\x9D\xA5", # LATIN CAPITAL LETTER THORN WITH STROKE
1300             "\xEA\x9D\xA6" => "\xEA\x9D\xA7", # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER
1301             "\xEA\x9D\xA8" => "\xEA\x9D\xA9", # LATIN CAPITAL LETTER VEND
1302             "\xEA\x9D\xAA" => "\xEA\x9D\xAB", # LATIN CAPITAL LETTER ET
1303             "\xEA\x9D\xAC" => "\xEA\x9D\xAD", # LATIN CAPITAL LETTER IS
1304             "\xEA\x9D\xAE" => "\xEA\x9D\xAF", # LATIN CAPITAL LETTER CON
1305             "\xEA\x9D\xB9" => "\xEA\x9D\xBA", # LATIN CAPITAL LETTER INSULAR D
1306             "\xEA\x9D\xBB" => "\xEA\x9D\xBC", # LATIN CAPITAL LETTER INSULAR F
1307             "\xEA\x9D\xBD" => "\xE1\xB5\xB9", # LATIN CAPITAL LETTER INSULAR G
1308             "\xEA\x9D\xBE" => "\xEA\x9D\xBF", # LATIN CAPITAL LETTER TURNED INSULAR G
1309             "\xEA\x9E\x80" => "\xEA\x9E\x81", # LATIN CAPITAL LETTER TURNED L
1310             "\xEA\x9E\x82" => "\xEA\x9E\x83", # LATIN CAPITAL LETTER INSULAR R
1311             "\xEA\x9E\x84" => "\xEA\x9E\x85", # LATIN CAPITAL LETTER INSULAR S
1312             "\xEA\x9E\x86" => "\xEA\x9E\x87", # LATIN CAPITAL LETTER INSULAR T
1313             "\xEA\x9E\x8B" => "\xEA\x9E\x8C", # LATIN CAPITAL LETTER SALTILLO
1314             "\xEA\x9E\x8D" => "\xC9\xA5", # LATIN CAPITAL LETTER TURNED H
1315             "\xEA\x9E\x90" => "\xEA\x9E\x91", # LATIN CAPITAL LETTER N WITH DESCENDER
1316             "\xEA\x9E\x92" => "\xEA\x9E\x93", # LATIN CAPITAL LETTER C WITH BAR
1317             "\xEA\x9E\x96" => "\xEA\x9E\x97", # LATIN CAPITAL LETTER B WITH FLOURISH
1318             "\xEA\x9E\x98" => "\xEA\x9E\x99", # LATIN CAPITAL LETTER F WITH STROKE
1319             "\xEA\x9E\x9A" => "\xEA\x9E\x9B", # LATIN CAPITAL LETTER VOLAPUK AE
1320             "\xEA\x9E\x9C" => "\xEA\x9E\x9D", # LATIN CAPITAL LETTER VOLAPUK OE
1321             "\xEA\x9E\x9E" => "\xEA\x9E\x9F", # LATIN CAPITAL LETTER VOLAPUK UE
1322             "\xEA\x9E\xA0" => "\xEA\x9E\xA1", # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE
1323             "\xEA\x9E\xA2" => "\xEA\x9E\xA3", # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE
1324             "\xEA\x9E\xA4" => "\xEA\x9E\xA5", # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE
1325             "\xEA\x9E\xA6" => "\xEA\x9E\xA7", # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE
1326             "\xEA\x9E\xA8" => "\xEA\x9E\xA9", # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE
1327             "\xEA\x9E\xAA" => "\xC9\xA6", # LATIN CAPITAL LETTER H WITH HOOK
1328             "\xEA\x9E\xAB" => "\xC9\x9C", # LATIN CAPITAL LETTER REVERSED OPEN E
1329             "\xEA\x9E\xAC" => "\xC9\xA1", # LATIN CAPITAL LETTER SCRIPT G
1330             "\xEA\x9E\xAD" => "\xC9\xAC", # LATIN CAPITAL LETTER L WITH BELT
1331             "\xEA\x9E\xAE" => "\xC9\xAA", # LATIN CAPITAL LETTER SMALL CAPITAL I
1332             "\xEA\x9E\xB0" => "\xCA\x9E", # LATIN CAPITAL LETTER TURNED K
1333             "\xEA\x9E\xB1" => "\xCA\x87", # LATIN CAPITAL LETTER TURNED T
1334             "\xEA\x9E\xB2" => "\xCA\x9D", # LATIN CAPITAL LETTER J WITH CROSSED-TAIL
1335             "\xEA\x9E\xB3" => "\xEA\xAD\x93", # LATIN CAPITAL LETTER CHI
1336             "\xEA\x9E\xB4" => "\xEA\x9E\xB5", # LATIN CAPITAL LETTER BETA
1337             "\xEA\x9E\xB6" => "\xEA\x9E\xB7", # LATIN CAPITAL LETTER OMEGA
1338             "\xEA\x9E\xB8" => "\xEA\x9E\xB9", # LATIN CAPITAL LETTER U WITH STROKE
1339             "\xEA\x9E\xBA" => "\xEA\x9E\xBB", # LATIN CAPITAL LETTER GLOTTAL A
1340             "\xEA\x9E\xBC" => "\xEA\x9E\xBD", # LATIN CAPITAL LETTER GLOTTAL I
1341             "\xEA\x9E\xBE" => "\xEA\x9E\xBF", # LATIN CAPITAL LETTER GLOTTAL U
1342             "\xEA\x9F\x82" => "\xEA\x9F\x83", # LATIN CAPITAL LETTER ANGLICANA W
1343             "\xEA\x9F\x84" => "\xEA\x9E\x94", # LATIN CAPITAL LETTER C WITH PALATAL HOOK
1344             "\xEA\x9F\x85" => "\xCA\x82", # LATIN CAPITAL LETTER S WITH HOOK
1345             "\xEA\x9F\x86" => "\xE1\xB6\x8E", # LATIN CAPITAL LETTER Z WITH PALATAL HOOK
1346             "\xEA\xAD\xB0" => "\xE1\x8E\xA0", # CHEROKEE SMALL LETTER A
1347             "\xEA\xAD\xB1" => "\xE1\x8E\xA1", # CHEROKEE SMALL LETTER E
1348             "\xEA\xAD\xB2" => "\xE1\x8E\xA2", # CHEROKEE SMALL LETTER I
1349             "\xEA\xAD\xB3" => "\xE1\x8E\xA3", # CHEROKEE SMALL LETTER O
1350             "\xEA\xAD\xB4" => "\xE1\x8E\xA4", # CHEROKEE SMALL LETTER U
1351             "\xEA\xAD\xB5" => "\xE1\x8E\xA5", # CHEROKEE SMALL LETTER V
1352             "\xEA\xAD\xB6" => "\xE1\x8E\xA6", # CHEROKEE SMALL LETTER GA
1353             "\xEA\xAD\xB7" => "\xE1\x8E\xA7", # CHEROKEE SMALL LETTER KA
1354             "\xEA\xAD\xB8" => "\xE1\x8E\xA8", # CHEROKEE SMALL LETTER GE
1355             "\xEA\xAD\xB9" => "\xE1\x8E\xA9", # CHEROKEE SMALL LETTER GI
1356             "\xEA\xAD\xBA" => "\xE1\x8E\xAA", # CHEROKEE SMALL LETTER GO
1357             "\xEA\xAD\xBB" => "\xE1\x8E\xAB", # CHEROKEE SMALL LETTER GU
1358             "\xEA\xAD\xBC" => "\xE1\x8E\xAC", # CHEROKEE SMALL LETTER GV
1359             "\xEA\xAD\xBD" => "\xE1\x8E\xAD", # CHEROKEE SMALL LETTER HA
1360             "\xEA\xAD\xBE" => "\xE1\x8E\xAE", # CHEROKEE SMALL LETTER HE
1361             "\xEA\xAD\xBF" => "\xE1\x8E\xAF", # CHEROKEE SMALL LETTER HI
1362             "\xEA\xAE\x80" => "\xE1\x8E\xB0", # CHEROKEE SMALL LETTER HO
1363             "\xEA\xAE\x81" => "\xE1\x8E\xB1", # CHEROKEE SMALL LETTER HU
1364             "\xEA\xAE\x82" => "\xE1\x8E\xB2", # CHEROKEE SMALL LETTER HV
1365             "\xEA\xAE\x83" => "\xE1\x8E\xB3", # CHEROKEE SMALL LETTER LA
1366             "\xEA\xAE\x84" => "\xE1\x8E\xB4", # CHEROKEE SMALL LETTER LE
1367             "\xEA\xAE\x85" => "\xE1\x8E\xB5", # CHEROKEE SMALL LETTER LI
1368             "\xEA\xAE\x86" => "\xE1\x8E\xB6", # CHEROKEE SMALL LETTER LO
1369             "\xEA\xAE\x87" => "\xE1\x8E\xB7", # CHEROKEE SMALL LETTER LU
1370             "\xEA\xAE\x88" => "\xE1\x8E\xB8", # CHEROKEE SMALL LETTER LV
1371             "\xEA\xAE\x89" => "\xE1\x8E\xB9", # CHEROKEE SMALL LETTER MA
1372             "\xEA\xAE\x8A" => "\xE1\x8E\xBA", # CHEROKEE SMALL LETTER ME
1373             "\xEA\xAE\x8B" => "\xE1\x8E\xBB", # CHEROKEE SMALL LETTER MI
1374             "\xEA\xAE\x8C" => "\xE1\x8E\xBC", # CHEROKEE SMALL LETTER MO
1375             "\xEA\xAE\x8D" => "\xE1\x8E\xBD", # CHEROKEE SMALL LETTER MU
1376             "\xEA\xAE\x8E" => "\xE1\x8E\xBE", # CHEROKEE SMALL LETTER NA
1377             "\xEA\xAE\x8F" => "\xE1\x8E\xBF", # CHEROKEE SMALL LETTER HNA
1378             "\xEA\xAE\x90" => "\xE1\x8F\x80", # CHEROKEE SMALL LETTER NAH
1379             "\xEA\xAE\x91" => "\xE1\x8F\x81", # CHEROKEE SMALL LETTER NE
1380             "\xEA\xAE\x92" => "\xE1\x8F\x82", # CHEROKEE SMALL LETTER NI
1381             "\xEA\xAE\x93" => "\xE1\x8F\x83", # CHEROKEE SMALL LETTER NO
1382             "\xEA\xAE\x94" => "\xE1\x8F\x84", # CHEROKEE SMALL LETTER NU
1383             "\xEA\xAE\x95" => "\xE1\x8F\x85", # CHEROKEE SMALL LETTER NV
1384             "\xEA\xAE\x96" => "\xE1\x8F\x86", # CHEROKEE SMALL LETTER QUA
1385             "\xEA\xAE\x97" => "\xE1\x8F\x87", # CHEROKEE SMALL LETTER QUE
1386             "\xEA\xAE\x98" => "\xE1\x8F\x88", # CHEROKEE SMALL LETTER QUI
1387             "\xEA\xAE\x99" => "\xE1\x8F\x89", # CHEROKEE SMALL LETTER QUO
1388             "\xEA\xAE\x9A" => "\xE1\x8F\x8A", # CHEROKEE SMALL LETTER QUU
1389             "\xEA\xAE\x9B" => "\xE1\x8F\x8B", # CHEROKEE SMALL LETTER QUV
1390             "\xEA\xAE\x9C" => "\xE1\x8F\x8C", # CHEROKEE SMALL LETTER SA
1391             "\xEA\xAE\x9D" => "\xE1\x8F\x8D", # CHEROKEE SMALL LETTER S
1392             "\xEA\xAE\x9E" => "\xE1\x8F\x8E", # CHEROKEE SMALL LETTER SE
1393             "\xEA\xAE\x9F" => "\xE1\x8F\x8F", # CHEROKEE SMALL LETTER SI
1394             "\xEA\xAE\xA0" => "\xE1\x8F\x90", # CHEROKEE SMALL LETTER SO
1395             "\xEA\xAE\xA1" => "\xE1\x8F\x91", # CHEROKEE SMALL LETTER SU
1396             "\xEA\xAE\xA2" => "\xE1\x8F\x92", # CHEROKEE SMALL LETTER SV
1397             "\xEA\xAE\xA3" => "\xE1\x8F\x93", # CHEROKEE SMALL LETTER DA
1398             "\xEA\xAE\xA4" => "\xE1\x8F\x94", # CHEROKEE SMALL LETTER TA
1399             "\xEA\xAE\xA5" => "\xE1\x8F\x95", # CHEROKEE SMALL LETTER DE
1400             "\xEA\xAE\xA6" => "\xE1\x8F\x96", # CHEROKEE SMALL LETTER TE
1401             "\xEA\xAE\xA7" => "\xE1\x8F\x97", # CHEROKEE SMALL LETTER DI
1402             "\xEA\xAE\xA8" => "\xE1\x8F\x98", # CHEROKEE SMALL LETTER TI
1403             "\xEA\xAE\xA9" => "\xE1\x8F\x99", # CHEROKEE SMALL LETTER DO
1404             "\xEA\xAE\xAA" => "\xE1\x8F\x9A", # CHEROKEE SMALL LETTER DU
1405             "\xEA\xAE\xAB" => "\xE1\x8F\x9B", # CHEROKEE SMALL LETTER DV
1406             "\xEA\xAE\xAC" => "\xE1\x8F\x9C", # CHEROKEE SMALL LETTER DLA
1407             "\xEA\xAE\xAD" => "\xE1\x8F\x9D", # CHEROKEE SMALL LETTER TLA
1408             "\xEA\xAE\xAE" => "\xE1\x8F\x9E", # CHEROKEE SMALL LETTER TLE
1409             "\xEA\xAE\xAF" => "\xE1\x8F\x9F", # CHEROKEE SMALL LETTER TLI
1410             "\xEA\xAE\xB0" => "\xE1\x8F\xA0", # CHEROKEE SMALL LETTER TLO
1411             "\xEA\xAE\xB1" => "\xE1\x8F\xA1", # CHEROKEE SMALL LETTER TLU
1412             "\xEA\xAE\xB2" => "\xE1\x8F\xA2", # CHEROKEE SMALL LETTER TLV
1413             "\xEA\xAE\xB3" => "\xE1\x8F\xA3", # CHEROKEE SMALL LETTER TSA
1414             "\xEA\xAE\xB4" => "\xE1\x8F\xA4", # CHEROKEE SMALL LETTER TSE
1415             "\xEA\xAE\xB5" => "\xE1\x8F\xA5", # CHEROKEE SMALL LETTER TSI
1416             "\xEA\xAE\xB6" => "\xE1\x8F\xA6", # CHEROKEE SMALL LETTER TSO
1417             "\xEA\xAE\xB7" => "\xE1\x8F\xA7", # CHEROKEE SMALL LETTER TSU
1418             "\xEA\xAE\xB8" => "\xE1\x8F\xA8", # CHEROKEE SMALL LETTER TSV
1419             "\xEA\xAE\xB9" => "\xE1\x8F\xA9", # CHEROKEE SMALL LETTER WA
1420             "\xEA\xAE\xBA" => "\xE1\x8F\xAA", # CHEROKEE SMALL LETTER WE
1421             "\xEA\xAE\xBB" => "\xE1\x8F\xAB", # CHEROKEE SMALL LETTER WI
1422             "\xEA\xAE\xBC" => "\xE1\x8F\xAC", # CHEROKEE SMALL LETTER WO
1423             "\xEA\xAE\xBD" => "\xE1\x8F\xAD", # CHEROKEE SMALL LETTER WU
1424             "\xEA\xAE\xBE" => "\xE1\x8F\xAE", # CHEROKEE SMALL LETTER WV
1425             "\xEA\xAE\xBF" => "\xE1\x8F\xAF", # CHEROKEE SMALL LETTER YA
1426             "\xEF\xAC\x80" => "\x66\x66", # LATIN SMALL LIGATURE FF
1427             "\xEF\xAC\x81" => "\x66\x69", # LATIN SMALL LIGATURE FI
1428             "\xEF\xAC\x82" => "\x66\x6C", # LATIN SMALL LIGATURE FL
1429             "\xEF\xAC\x83" => "\x66\x66\x69", # LATIN SMALL LIGATURE FFI
1430             "\xEF\xAC\x84" => "\x66\x66\x6C", # LATIN SMALL LIGATURE FFL
1431             "\xEF\xAC\x85" => "\x73\x74", # LATIN SMALL LIGATURE LONG S T
1432             "\xEF\xAC\x86" => "\x73\x74", # LATIN SMALL LIGATURE ST
1433             "\xEF\xAC\x93" => "\xD5\xB4\xD5\xB6", # ARMENIAN SMALL LIGATURE MEN NOW
1434             "\xEF\xAC\x94" => "\xD5\xB4\xD5\xA5", # ARMENIAN SMALL LIGATURE MEN ECH
1435             "\xEF\xAC\x95" => "\xD5\xB4\xD5\xAB", # ARMENIAN SMALL LIGATURE MEN INI
1436             "\xEF\xAC\x96" => "\xD5\xBE\xD5\xB6", # ARMENIAN SMALL LIGATURE VEW NOW
1437             "\xEF\xAC\x97" => "\xD5\xB4\xD5\xAD", # ARMENIAN SMALL LIGATURE MEN XEH
1438             "\xEF\xBC\xA1" => "\xEF\xBD\x81", # FULLWIDTH LATIN CAPITAL LETTER A
1439             "\xEF\xBC\xA2" => "\xEF\xBD\x82", # FULLWIDTH LATIN CAPITAL LETTER B
1440             "\xEF\xBC\xA3" => "\xEF\xBD\x83", # FULLWIDTH LATIN CAPITAL LETTER C
1441             "\xEF\xBC\xA4" => "\xEF\xBD\x84", # FULLWIDTH LATIN CAPITAL LETTER D
1442             "\xEF\xBC\xA5" => "\xEF\xBD\x85", # FULLWIDTH LATIN CAPITAL LETTER E
1443             "\xEF\xBC\xA6" => "\xEF\xBD\x86", # FULLWIDTH LATIN CAPITAL LETTER F
1444             "\xEF\xBC\xA7" => "\xEF\xBD\x87", # FULLWIDTH LATIN CAPITAL LETTER G
1445             "\xEF\xBC\xA8" => "\xEF\xBD\x88", # FULLWIDTH LATIN CAPITAL LETTER H
1446             "\xEF\xBC\xA9" => "\xEF\xBD\x89", # FULLWIDTH LATIN CAPITAL LETTER I
1447             "\xEF\xBC\xAA" => "\xEF\xBD\x8A", # FULLWIDTH LATIN CAPITAL LETTER J
1448             "\xEF\xBC\xAB" => "\xEF\xBD\x8B", # FULLWIDTH LATIN CAPITAL LETTER K
1449             "\xEF\xBC\xAC" => "\xEF\xBD\x8C", # FULLWIDTH LATIN CAPITAL LETTER L
1450             "\xEF\xBC\xAD" => "\xEF\xBD\x8D", # FULLWIDTH LATIN CAPITAL LETTER M
1451             "\xEF\xBC\xAE" => "\xEF\xBD\x8E", # FULLWIDTH LATIN CAPITAL LETTER N
1452             "\xEF\xBC\xAF" => "\xEF\xBD\x8F", # FULLWIDTH LATIN CAPITAL LETTER O
1453             "\xEF\xBC\xB0" => "\xEF\xBD\x90", # FULLWIDTH LATIN CAPITAL LETTER P
1454             "\xEF\xBC\xB1" => "\xEF\xBD\x91", # FULLWIDTH LATIN CAPITAL LETTER Q
1455             "\xEF\xBC\xB2" => "\xEF\xBD\x92", # FULLWIDTH LATIN CAPITAL LETTER R
1456             "\xEF\xBC\xB3" => "\xEF\xBD\x93", # FULLWIDTH LATIN CAPITAL LETTER S
1457             "\xEF\xBC\xB4" => "\xEF\xBD\x94", # FULLWIDTH LATIN CAPITAL LETTER T
1458             "\xEF\xBC\xB5" => "\xEF\xBD\x95", # FULLWIDTH LATIN CAPITAL LETTER U
1459             "\xEF\xBC\xB6" => "\xEF\xBD\x96", # FULLWIDTH LATIN CAPITAL LETTER V
1460             "\xEF\xBC\xB7" => "\xEF\xBD\x97", # FULLWIDTH LATIN CAPITAL LETTER W
1461             "\xEF\xBC\xB8" => "\xEF\xBD\x98", # FULLWIDTH LATIN CAPITAL LETTER X
1462             "\xEF\xBC\xB9" => "\xEF\xBD\x99", # FULLWIDTH LATIN CAPITAL LETTER Y
1463             "\xEF\xBC\xBA" => "\xEF\xBD\x9A", # FULLWIDTH LATIN CAPITAL LETTER Z
1464             "\xF0\x90\x90\x80" => "\xF0\x90\x90\xA8", # DESERET CAPITAL LETTER LONG I
1465             "\xF0\x90\x90\x81" => "\xF0\x90\x90\xA9", # DESERET CAPITAL LETTER LONG E
1466             "\xF0\x90\x90\x82" => "\xF0\x90\x90\xAA", # DESERET CAPITAL LETTER LONG A
1467             "\xF0\x90\x90\x83" => "\xF0\x90\x90\xAB", # DESERET CAPITAL LETTER LONG AH
1468             "\xF0\x90\x90\x84" => "\xF0\x90\x90\xAC", # DESERET CAPITAL LETTER LONG O
1469             "\xF0\x90\x90\x85" => "\xF0\x90\x90\xAD", # DESERET CAPITAL LETTER LONG OO
1470             "\xF0\x90\x90\x86" => "\xF0\x90\x90\xAE", # DESERET CAPITAL LETTER SHORT I
1471             "\xF0\x90\x90\x87" => "\xF0\x90\x90\xAF", # DESERET CAPITAL LETTER SHORT E
1472             "\xF0\x90\x90\x88" => "\xF0\x90\x90\xB0", # DESERET CAPITAL LETTER SHORT A
1473             "\xF0\x90\x90\x89" => "\xF0\x90\x90\xB1", # DESERET CAPITAL LETTER SHORT AH
1474             "\xF0\x90\x90\x8A" => "\xF0\x90\x90\xB2", # DESERET CAPITAL LETTER SHORT O
1475             "\xF0\x90\x90\x8B" => "\xF0\x90\x90\xB3", # DESERET CAPITAL LETTER SHORT OO
1476             "\xF0\x90\x90\x8C" => "\xF0\x90\x90\xB4", # DESERET CAPITAL LETTER AY
1477             "\xF0\x90\x90\x8D" => "\xF0\x90\x90\xB5", # DESERET CAPITAL LETTER OW
1478             "\xF0\x90\x90\x8E" => "\xF0\x90\x90\xB6", # DESERET CAPITAL LETTER WU
1479             "\xF0\x90\x90\x8F" => "\xF0\x90\x90\xB7", # DESERET CAPITAL LETTER YEE
1480             "\xF0\x90\x90\x90" => "\xF0\x90\x90\xB8", # DESERET CAPITAL LETTER H
1481             "\xF0\x90\x90\x91" => "\xF0\x90\x90\xB9", # DESERET CAPITAL LETTER PEE
1482             "\xF0\x90\x90\x92" => "\xF0\x90\x90\xBA", # DESERET CAPITAL LETTER BEE
1483             "\xF0\x90\x90\x93" => "\xF0\x90\x90\xBB", # DESERET CAPITAL LETTER TEE
1484             "\xF0\x90\x90\x94" => "\xF0\x90\x90\xBC", # DESERET CAPITAL LETTER DEE
1485             "\xF0\x90\x90\x95" => "\xF0\x90\x90\xBD", # DESERET CAPITAL LETTER CHEE
1486             "\xF0\x90\x90\x96" => "\xF0\x90\x90\xBE", # DESERET CAPITAL LETTER JEE
1487             "\xF0\x90\x90\x97" => "\xF0\x90\x90\xBF", # DESERET CAPITAL LETTER KAY
1488             "\xF0\x90\x90\x98" => "\xF0\x90\x91\x80", # DESERET CAPITAL LETTER GAY
1489             "\xF0\x90\x90\x99" => "\xF0\x90\x91\x81", # DESERET CAPITAL LETTER EF
1490             "\xF0\x90\x90\x9A" => "\xF0\x90\x91\x82", # DESERET CAPITAL LETTER VEE
1491             "\xF0\x90\x90\x9B" => "\xF0\x90\x91\x83", # DESERET CAPITAL LETTER ETH
1492             "\xF0\x90\x90\x9C" => "\xF0\x90\x91\x84", # DESERET CAPITAL LETTER THEE
1493             "\xF0\x90\x90\x9D" => "\xF0\x90\x91\x85", # DESERET CAPITAL LETTER ES
1494             "\xF0\x90\x90\x9E" => "\xF0\x90\x91\x86", # DESERET CAPITAL LETTER ZEE
1495             "\xF0\x90\x90\x9F" => "\xF0\x90\x91\x87", # DESERET CAPITAL LETTER ESH
1496             "\xF0\x90\x90\xA0" => "\xF0\x90\x91\x88", # DESERET CAPITAL LETTER ZHEE
1497             "\xF0\x90\x90\xA1" => "\xF0\x90\x91\x89", # DESERET CAPITAL LETTER ER
1498             "\xF0\x90\x90\xA2" => "\xF0\x90\x91\x8A", # DESERET CAPITAL LETTER EL
1499             "\xF0\x90\x90\xA3" => "\xF0\x90\x91\x8B", # DESERET CAPITAL LETTER EM
1500             "\xF0\x90\x90\xA4" => "\xF0\x90\x91\x8C", # DESERET CAPITAL LETTER EN
1501             "\xF0\x90\x90\xA5" => "\xF0\x90\x91\x8D", # DESERET CAPITAL LETTER ENG
1502             "\xF0\x90\x90\xA6" => "\xF0\x90\x91\x8E", # DESERET CAPITAL LETTER OI
1503             "\xF0\x90\x90\xA7" => "\xF0\x90\x91\x8F", # DESERET CAPITAL LETTER EW
1504             "\xF0\x90\x92\xB0" => "\xF0\x90\x93\x98", # OSAGE CAPITAL LETTER A
1505             "\xF0\x90\x92\xB1" => "\xF0\x90\x93\x99", # OSAGE CAPITAL LETTER AI
1506             "\xF0\x90\x92\xB2" => "\xF0\x90\x93\x9A", # OSAGE CAPITAL LETTER AIN
1507             "\xF0\x90\x92\xB3" => "\xF0\x90\x93\x9B", # OSAGE CAPITAL LETTER AH
1508             "\xF0\x90\x92\xB4" => "\xF0\x90\x93\x9C", # OSAGE CAPITAL LETTER BRA
1509             "\xF0\x90\x92\xB5" => "\xF0\x90\x93\x9D", # OSAGE CAPITAL LETTER CHA
1510             "\xF0\x90\x92\xB6" => "\xF0\x90\x93\x9E", # OSAGE CAPITAL LETTER EHCHA
1511             "\xF0\x90\x92\xB7" => "\xF0\x90\x93\x9F", # OSAGE CAPITAL LETTER E
1512             "\xF0\x90\x92\xB8" => "\xF0\x90\x93\xA0", # OSAGE CAPITAL LETTER EIN
1513             "\xF0\x90\x92\xB9" => "\xF0\x90\x93\xA1", # OSAGE CAPITAL LETTER HA
1514             "\xF0\x90\x92\xBA" => "\xF0\x90\x93\xA2", # OSAGE CAPITAL LETTER HYA
1515             "\xF0\x90\x92\xBB" => "\xF0\x90\x93\xA3", # OSAGE CAPITAL LETTER I
1516             "\xF0\x90\x92\xBC" => "\xF0\x90\x93\xA4", # OSAGE CAPITAL LETTER KA
1517             "\xF0\x90\x92\xBD" => "\xF0\x90\x93\xA5", # OSAGE CAPITAL LETTER EHKA
1518             "\xF0\x90\x92\xBE" => "\xF0\x90\x93\xA6", # OSAGE CAPITAL LETTER KYA
1519             "\xF0\x90\x92\xBF" => "\xF0\x90\x93\xA7", # OSAGE CAPITAL LETTER LA
1520             "\xF0\x90\x93\x80" => "\xF0\x90\x93\xA8", # OSAGE CAPITAL LETTER MA
1521             "\xF0\x90\x93\x81" => "\xF0\x90\x93\xA9", # OSAGE CAPITAL LETTER NA
1522             "\xF0\x90\x93\x82" => "\xF0\x90\x93\xAA", # OSAGE CAPITAL LETTER O
1523             "\xF0\x90\x93\x83" => "\xF0\x90\x93\xAB", # OSAGE CAPITAL LETTER OIN
1524             "\xF0\x90\x93\x84" => "\xF0\x90\x93\xAC", # OSAGE CAPITAL LETTER PA
1525             "\xF0\x90\x93\x85" => "\xF0\x90\x93\xAD", # OSAGE CAPITAL LETTER EHPA
1526             "\xF0\x90\x93\x86" => "\xF0\x90\x93\xAE", # OSAGE CAPITAL LETTER SA
1527             "\xF0\x90\x93\x87" => "\xF0\x90\x93\xAF", # OSAGE CAPITAL LETTER SHA
1528             "\xF0\x90\x93\x88" => "\xF0\x90\x93\xB0", # OSAGE CAPITAL LETTER TA
1529             "\xF0\x90\x93\x89" => "\xF0\x90\x93\xB1", # OSAGE CAPITAL LETTER EHTA
1530             "\xF0\x90\x93\x8A" => "\xF0\x90\x93\xB2", # OSAGE CAPITAL LETTER TSA
1531             "\xF0\x90\x93\x8B" => "\xF0\x90\x93\xB3", # OSAGE CAPITAL LETTER EHTSA
1532             "\xF0\x90\x93\x8C" => "\xF0\x90\x93\xB4", # OSAGE CAPITAL LETTER TSHA
1533             "\xF0\x90\x93\x8D" => "\xF0\x90\x93\xB5", # OSAGE CAPITAL LETTER DHA
1534             "\xF0\x90\x93\x8E" => "\xF0\x90\x93\xB6", # OSAGE CAPITAL LETTER U
1535             "\xF0\x90\x93\x8F" => "\xF0\x90\x93\xB7", # OSAGE CAPITAL LETTER WA
1536             "\xF0\x90\x93\x90" => "\xF0\x90\x93\xB8", # OSAGE CAPITAL LETTER KHA
1537             "\xF0\x90\x93\x91" => "\xF0\x90\x93\xB9", # OSAGE CAPITAL LETTER GHA
1538             "\xF0\x90\x93\x92" => "\xF0\x90\x93\xBA", # OSAGE CAPITAL LETTER ZA
1539             "\xF0\x90\x93\x93" => "\xF0\x90\x93\xBB", # OSAGE CAPITAL LETTER ZHA
1540             "\xF0\x90\xB2\x80" => "\xF0\x90\xB3\x80", # OLD HUNGARIAN CAPITAL LETTER A
1541             "\xF0\x90\xB2\x81" => "\xF0\x90\xB3\x81", # OLD HUNGARIAN CAPITAL LETTER AA
1542             "\xF0\x90\xB2\x82" => "\xF0\x90\xB3\x82", # OLD HUNGARIAN CAPITAL LETTER EB
1543             "\xF0\x90\xB2\x83" => "\xF0\x90\xB3\x83", # OLD HUNGARIAN CAPITAL LETTER AMB
1544             "\xF0\x90\xB2\x84" => "\xF0\x90\xB3\x84", # OLD HUNGARIAN CAPITAL LETTER EC
1545             "\xF0\x90\xB2\x85" => "\xF0\x90\xB3\x85", # OLD HUNGARIAN CAPITAL LETTER ENC
1546             "\xF0\x90\xB2\x86" => "\xF0\x90\xB3\x86", # OLD HUNGARIAN CAPITAL LETTER ECS
1547             "\xF0\x90\xB2\x87" => "\xF0\x90\xB3\x87", # OLD HUNGARIAN CAPITAL LETTER ED
1548             "\xF0\x90\xB2\x88" => "\xF0\x90\xB3\x88", # OLD HUNGARIAN CAPITAL LETTER AND
1549             "\xF0\x90\xB2\x89" => "\xF0\x90\xB3\x89", # OLD HUNGARIAN CAPITAL LETTER E
1550             "\xF0\x90\xB2\x8A" => "\xF0\x90\xB3\x8A", # OLD HUNGARIAN CAPITAL LETTER CLOSE E
1551             "\xF0\x90\xB2\x8B" => "\xF0\x90\xB3\x8B", # OLD HUNGARIAN CAPITAL LETTER EE
1552             "\xF0\x90\xB2\x8C" => "\xF0\x90\xB3\x8C", # OLD HUNGARIAN CAPITAL LETTER EF
1553             "\xF0\x90\xB2\x8D" => "\xF0\x90\xB3\x8D", # OLD HUNGARIAN CAPITAL LETTER EG
1554             "\xF0\x90\xB2\x8E" => "\xF0\x90\xB3\x8E", # OLD HUNGARIAN CAPITAL LETTER EGY
1555             "\xF0\x90\xB2\x8F" => "\xF0\x90\xB3\x8F", # OLD HUNGARIAN CAPITAL LETTER EH
1556             "\xF0\x90\xB2\x90" => "\xF0\x90\xB3\x90", # OLD HUNGARIAN CAPITAL LETTER I
1557             "\xF0\x90\xB2\x91" => "\xF0\x90\xB3\x91", # OLD HUNGARIAN CAPITAL LETTER II
1558             "\xF0\x90\xB2\x92" => "\xF0\x90\xB3\x92", # OLD HUNGARIAN CAPITAL LETTER EJ
1559             "\xF0\x90\xB2\x93" => "\xF0\x90\xB3\x93", # OLD HUNGARIAN CAPITAL LETTER EK
1560             "\xF0\x90\xB2\x94" => "\xF0\x90\xB3\x94", # OLD HUNGARIAN CAPITAL LETTER AK
1561             "\xF0\x90\xB2\x95" => "\xF0\x90\xB3\x95", # OLD HUNGARIAN CAPITAL LETTER UNK
1562             "\xF0\x90\xB2\x96" => "\xF0\x90\xB3\x96", # OLD HUNGARIAN CAPITAL LETTER EL
1563             "\xF0\x90\xB2\x97" => "\xF0\x90\xB3\x97", # OLD HUNGARIAN CAPITAL LETTER ELY
1564             "\xF0\x90\xB2\x98" => "\xF0\x90\xB3\x98", # OLD HUNGARIAN CAPITAL LETTER EM
1565             "\xF0\x90\xB2\x99" => "\xF0\x90\xB3\x99", # OLD HUNGARIAN CAPITAL LETTER EN
1566             "\xF0\x90\xB2\x9A" => "\xF0\x90\xB3\x9A", # OLD HUNGARIAN CAPITAL LETTER ENY
1567             "\xF0\x90\xB2\x9B" => "\xF0\x90\xB3\x9B", # OLD HUNGARIAN CAPITAL LETTER O
1568             "\xF0\x90\xB2\x9C" => "\xF0\x90\xB3\x9C", # OLD HUNGARIAN CAPITAL LETTER OO
1569             "\xF0\x90\xB2\x9D" => "\xF0\x90\xB3\x9D", # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE
1570             "\xF0\x90\xB2\x9E" => "\xF0\x90\xB3\x9E", # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE
1571             "\xF0\x90\xB2\x9F" => "\xF0\x90\xB3\x9F", # OLD HUNGARIAN CAPITAL LETTER OEE
1572             "\xF0\x90\xB2\xA0" => "\xF0\x90\xB3\xA0", # OLD HUNGARIAN CAPITAL LETTER EP
1573             "\xF0\x90\xB2\xA1" => "\xF0\x90\xB3\xA1", # OLD HUNGARIAN CAPITAL LETTER EMP
1574             "\xF0\x90\xB2\xA2" => "\xF0\x90\xB3\xA2", # OLD HUNGARIAN CAPITAL LETTER ER
1575             "\xF0\x90\xB2\xA3" => "\xF0\x90\xB3\xA3", # OLD HUNGARIAN CAPITAL LETTER SHORT ER
1576             "\xF0\x90\xB2\xA4" => "\xF0\x90\xB3\xA4", # OLD HUNGARIAN CAPITAL LETTER ES
1577             "\xF0\x90\xB2\xA5" => "\xF0\x90\xB3\xA5", # OLD HUNGARIAN CAPITAL LETTER ESZ
1578             "\xF0\x90\xB2\xA6" => "\xF0\x90\xB3\xA6", # OLD HUNGARIAN CAPITAL LETTER ET
1579             "\xF0\x90\xB2\xA7" => "\xF0\x90\xB3\xA7", # OLD HUNGARIAN CAPITAL LETTER ENT
1580             "\xF0\x90\xB2\xA8" => "\xF0\x90\xB3\xA8", # OLD HUNGARIAN CAPITAL LETTER ETY
1581             "\xF0\x90\xB2\xA9" => "\xF0\x90\xB3\xA9", # OLD HUNGARIAN CAPITAL LETTER ECH
1582             "\xF0\x90\xB2\xAA" => "\xF0\x90\xB3\xAA", # OLD HUNGARIAN CAPITAL LETTER U
1583             "\xF0\x90\xB2\xAB" => "\xF0\x90\xB3\xAB", # OLD HUNGARIAN CAPITAL LETTER UU
1584             "\xF0\x90\xB2\xAC" => "\xF0\x90\xB3\xAC", # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE
1585             "\xF0\x90\xB2\xAD" => "\xF0\x90\xB3\xAD", # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE
1586             "\xF0\x90\xB2\xAE" => "\xF0\x90\xB3\xAE", # OLD HUNGARIAN CAPITAL LETTER EV
1587             "\xF0\x90\xB2\xAF" => "\xF0\x90\xB3\xAF", # OLD HUNGARIAN CAPITAL LETTER EZ
1588             "\xF0\x90\xB2\xB0" => "\xF0\x90\xB3\xB0", # OLD HUNGARIAN CAPITAL LETTER EZS
1589             "\xF0\x90\xB2\xB1" => "\xF0\x90\xB3\xB1", # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN
1590             "\xF0\x90\xB2\xB2" => "\xF0\x90\xB3\xB2", # OLD HUNGARIAN CAPITAL LETTER US
1591             "\xF0\x91\xA2\xA0" => "\xF0\x91\xA3\x80", # WARANG CITI CAPITAL LETTER NGAA
1592             "\xF0\x91\xA2\xA1" => "\xF0\x91\xA3\x81", # WARANG CITI CAPITAL LETTER A
1593             "\xF0\x91\xA2\xA2" => "\xF0\x91\xA3\x82", # WARANG CITI CAPITAL LETTER WI
1594             "\xF0\x91\xA2\xA3" => "\xF0\x91\xA3\x83", # WARANG CITI CAPITAL LETTER YU
1595             "\xF0\x91\xA2\xA4" => "\xF0\x91\xA3\x84", # WARANG CITI CAPITAL LETTER YA
1596             "\xF0\x91\xA2\xA5" => "\xF0\x91\xA3\x85", # WARANG CITI CAPITAL LETTER YO
1597             "\xF0\x91\xA2\xA6" => "\xF0\x91\xA3\x86", # WARANG CITI CAPITAL LETTER II
1598             "\xF0\x91\xA2\xA7" => "\xF0\x91\xA3\x87", # WARANG CITI CAPITAL LETTER UU
1599             "\xF0\x91\xA2\xA8" => "\xF0\x91\xA3\x88", # WARANG CITI CAPITAL LETTER E
1600             "\xF0\x91\xA2\xA9" => "\xF0\x91\xA3\x89", # WARANG CITI CAPITAL LETTER O
1601             "\xF0\x91\xA2\xAA" => "\xF0\x91\xA3\x8A", # WARANG CITI CAPITAL LETTER ANG
1602             "\xF0\x91\xA2\xAB" => "\xF0\x91\xA3\x8B", # WARANG CITI CAPITAL LETTER GA
1603             "\xF0\x91\xA2\xAC" => "\xF0\x91\xA3\x8C", # WARANG CITI CAPITAL LETTER KO
1604             "\xF0\x91\xA2\xAD" => "\xF0\x91\xA3\x8D", # WARANG CITI CAPITAL LETTER ENY
1605             "\xF0\x91\xA2\xAE" => "\xF0\x91\xA3\x8E", # WARANG CITI CAPITAL LETTER YUJ
1606             "\xF0\x91\xA2\xAF" => "\xF0\x91\xA3\x8F", # WARANG CITI CAPITAL LETTER UC
1607             "\xF0\x91\xA2\xB0" => "\xF0\x91\xA3\x90", # WARANG CITI CAPITAL LETTER ENN
1608             "\xF0\x91\xA2\xB1" => "\xF0\x91\xA3\x91", # WARANG CITI CAPITAL LETTER ODD
1609             "\xF0\x91\xA2\xB2" => "\xF0\x91\xA3\x92", # WARANG CITI CAPITAL LETTER TTE
1610             "\xF0\x91\xA2\xB3" => "\xF0\x91\xA3\x93", # WARANG CITI CAPITAL LETTER NUNG
1611             "\xF0\x91\xA2\xB4" => "\xF0\x91\xA3\x94", # WARANG CITI CAPITAL LETTER DA
1612             "\xF0\x91\xA2\xB5" => "\xF0\x91\xA3\x95", # WARANG CITI CAPITAL LETTER AT
1613             "\xF0\x91\xA2\xB6" => "\xF0\x91\xA3\x96", # WARANG CITI CAPITAL LETTER AM
1614             "\xF0\x91\xA2\xB7" => "\xF0\x91\xA3\x97", # WARANG CITI CAPITAL LETTER BU
1615             "\xF0\x91\xA2\xB8" => "\xF0\x91\xA3\x98", # WARANG CITI CAPITAL LETTER PU
1616             "\xF0\x91\xA2\xB9" => "\xF0\x91\xA3\x99", # WARANG CITI CAPITAL LETTER HIYO
1617             "\xF0\x91\xA2\xBA" => "\xF0\x91\xA3\x9A", # WARANG CITI CAPITAL LETTER HOLO
1618             "\xF0\x91\xA2\xBB" => "\xF0\x91\xA3\x9B", # WARANG CITI CAPITAL LETTER HORR
1619             "\xF0\x91\xA2\xBC" => "\xF0\x91\xA3\x9C", # WARANG CITI CAPITAL LETTER HAR
1620             "\xF0\x91\xA2\xBD" => "\xF0\x91\xA3\x9D", # WARANG CITI CAPITAL LETTER SSUU
1621             "\xF0\x91\xA2\xBE" => "\xF0\x91\xA3\x9E", # WARANG CITI CAPITAL LETTER SII
1622             "\xF0\x91\xA2\xBF" => "\xF0\x91\xA3\x9F", # WARANG CITI CAPITAL LETTER VIYO
1623             "\xF0\x96\xB9\x80" => "\xF0\x96\xB9\xA0", # MEDEFAIDRIN CAPITAL LETTER M
1624             "\xF0\x96\xB9\x81" => "\xF0\x96\xB9\xA1", # MEDEFAIDRIN CAPITAL LETTER S
1625             "\xF0\x96\xB9\x82" => "\xF0\x96\xB9\xA2", # MEDEFAIDRIN CAPITAL LETTER V
1626             "\xF0\x96\xB9\x83" => "\xF0\x96\xB9\xA3", # MEDEFAIDRIN CAPITAL LETTER W
1627             "\xF0\x96\xB9\x84" => "\xF0\x96\xB9\xA4", # MEDEFAIDRIN CAPITAL LETTER ATIU
1628             "\xF0\x96\xB9\x85" => "\xF0\x96\xB9\xA5", # MEDEFAIDRIN CAPITAL LETTER Z
1629             "\xF0\x96\xB9\x86" => "\xF0\x96\xB9\xA6", # MEDEFAIDRIN CAPITAL LETTER KP
1630             "\xF0\x96\xB9\x87" => "\xF0\x96\xB9\xA7", # MEDEFAIDRIN CAPITAL LETTER P
1631             "\xF0\x96\xB9\x88" => "\xF0\x96\xB9\xA8", # MEDEFAIDRIN CAPITAL LETTER T
1632             "\xF0\x96\xB9\x89" => "\xF0\x96\xB9\xA9", # MEDEFAIDRIN CAPITAL LETTER G
1633             "\xF0\x96\xB9\x8A" => "\xF0\x96\xB9\xAA", # MEDEFAIDRIN CAPITAL LETTER F
1634             "\xF0\x96\xB9\x8B" => "\xF0\x96\xB9\xAB", # MEDEFAIDRIN CAPITAL LETTER I
1635             "\xF0\x96\xB9\x8C" => "\xF0\x96\xB9\xAC", # MEDEFAIDRIN CAPITAL LETTER K
1636             "\xF0\x96\xB9\x8D" => "\xF0\x96\xB9\xAD", # MEDEFAIDRIN CAPITAL LETTER A
1637             "\xF0\x96\xB9\x8E" => "\xF0\x96\xB9\xAE", # MEDEFAIDRIN CAPITAL LETTER J
1638             "\xF0\x96\xB9\x8F" => "\xF0\x96\xB9\xAF", # MEDEFAIDRIN CAPITAL LETTER E
1639             "\xF0\x96\xB9\x90" => "\xF0\x96\xB9\xB0", # MEDEFAIDRIN CAPITAL LETTER B
1640             "\xF0\x96\xB9\x91" => "\xF0\x96\xB9\xB1", # MEDEFAIDRIN CAPITAL LETTER C
1641             "\xF0\x96\xB9\x92" => "\xF0\x96\xB9\xB2", # MEDEFAIDRIN CAPITAL LETTER U
1642             "\xF0\x96\xB9\x93" => "\xF0\x96\xB9\xB3", # MEDEFAIDRIN CAPITAL LETTER YU
1643             "\xF0\x96\xB9\x94" => "\xF0\x96\xB9\xB4", # MEDEFAIDRIN CAPITAL LETTER L
1644             "\xF0\x96\xB9\x95" => "\xF0\x96\xB9\xB5", # MEDEFAIDRIN CAPITAL LETTER Q
1645             "\xF0\x96\xB9\x96" => "\xF0\x96\xB9\xB6", # MEDEFAIDRIN CAPITAL LETTER HP
1646             "\xF0\x96\xB9\x97" => "\xF0\x96\xB9\xB7", # MEDEFAIDRIN CAPITAL LETTER NY
1647             "\xF0\x96\xB9\x98" => "\xF0\x96\xB9\xB8", # MEDEFAIDRIN CAPITAL LETTER X
1648             "\xF0\x96\xB9\x99" => "\xF0\x96\xB9\xB9", # MEDEFAIDRIN CAPITAL LETTER D
1649             "\xF0\x96\xB9\x9A" => "\xF0\x96\xB9\xBA", # MEDEFAIDRIN CAPITAL LETTER OE
1650             "\xF0\x96\xB9\x9B" => "\xF0\x96\xB9\xBB", # MEDEFAIDRIN CAPITAL LETTER N
1651             "\xF0\x96\xB9\x9C" => "\xF0\x96\xB9\xBC", # MEDEFAIDRIN CAPITAL LETTER R
1652             "\xF0\x96\xB9\x9D" => "\xF0\x96\xB9\xBD", # MEDEFAIDRIN CAPITAL LETTER O
1653             "\xF0\x96\xB9\x9E" => "\xF0\x96\xB9\xBE", # MEDEFAIDRIN CAPITAL LETTER AI
1654             "\xF0\x96\xB9\x9F" => "\xF0\x96\xB9\xBF", # MEDEFAIDRIN CAPITAL LETTER Y
1655             "\xF0\x9E\xA4\x80" => "\xF0\x9E\xA4\xA2", # ADLAM CAPITAL LETTER ALIF
1656             "\xF0\x9E\xA4\x81" => "\xF0\x9E\xA4\xA3", # ADLAM CAPITAL LETTER DAALI
1657             "\xF0\x9E\xA4\x82" => "\xF0\x9E\xA4\xA4", # ADLAM CAPITAL LETTER LAAM
1658             "\xF0\x9E\xA4\x83" => "\xF0\x9E\xA4\xA5", # ADLAM CAPITAL LETTER MIIM
1659             "\xF0\x9E\xA4\x84" => "\xF0\x9E\xA4\xA6", # ADLAM CAPITAL LETTER BA
1660             "\xF0\x9E\xA4\x85" => "\xF0\x9E\xA4\xA7", # ADLAM CAPITAL LETTER SINNYIIYHE
1661             "\xF0\x9E\xA4\x86" => "\xF0\x9E\xA4\xA8", # ADLAM CAPITAL LETTER PE
1662             "\xF0\x9E\xA4\x87" => "\xF0\x9E\xA4\xA9", # ADLAM CAPITAL LETTER BHE
1663             "\xF0\x9E\xA4\x88" => "\xF0\x9E\xA4\xAA", # ADLAM CAPITAL LETTER RA
1664             "\xF0\x9E\xA4\x89" => "\xF0\x9E\xA4\xAB", # ADLAM CAPITAL LETTER E
1665             "\xF0\x9E\xA4\x8A" => "\xF0\x9E\xA4\xAC", # ADLAM CAPITAL LETTER FA
1666             "\xF0\x9E\xA4\x8B" => "\xF0\x9E\xA4\xAD", # ADLAM CAPITAL LETTER I
1667             "\xF0\x9E\xA4\x8C" => "\xF0\x9E\xA4\xAE", # ADLAM CAPITAL LETTER O
1668             "\xF0\x9E\xA4\x8D" => "\xF0\x9E\xA4\xAF", # ADLAM CAPITAL LETTER DHA
1669             "\xF0\x9E\xA4\x8E" => "\xF0\x9E\xA4\xB0", # ADLAM CAPITAL LETTER YHE
1670             "\xF0\x9E\xA4\x8F" => "\xF0\x9E\xA4\xB1", # ADLAM CAPITAL LETTER WAW
1671             "\xF0\x9E\xA4\x90" => "\xF0\x9E\xA4\xB2", # ADLAM CAPITAL LETTER NUN
1672             "\xF0\x9E\xA4\x91" => "\xF0\x9E\xA4\xB3", # ADLAM CAPITAL LETTER KAF
1673             "\xF0\x9E\xA4\x92" => "\xF0\x9E\xA4\xB4", # ADLAM CAPITAL LETTER YA
1674             "\xF0\x9E\xA4\x93" => "\xF0\x9E\xA4\xB5", # ADLAM CAPITAL LETTER U
1675             "\xF0\x9E\xA4\x94" => "\xF0\x9E\xA4\xB6", # ADLAM CAPITAL LETTER JIIM
1676             "\xF0\x9E\xA4\x95" => "\xF0\x9E\xA4\xB7", # ADLAM CAPITAL LETTER CHI
1677             "\xF0\x9E\xA4\x96" => "\xF0\x9E\xA4\xB8", # ADLAM CAPITAL LETTER HA
1678             "\xF0\x9E\xA4\x97" => "\xF0\x9E\xA4\xB9", # ADLAM CAPITAL LETTER QAAF
1679             "\xF0\x9E\xA4\x98" => "\xF0\x9E\xA4\xBA", # ADLAM CAPITAL LETTER GA
1680             "\xF0\x9E\xA4\x99" => "\xF0\x9E\xA4\xBB", # ADLAM CAPITAL LETTER NYA
1681             "\xF0\x9E\xA4\x9A" => "\xF0\x9E\xA4\xBC", # ADLAM CAPITAL LETTER TU
1682             "\xF0\x9E\xA4\x9B" => "\xF0\x9E\xA4\xBD", # ADLAM CAPITAL LETTER NHA
1683             "\xF0\x9E\xA4\x9C" => "\xF0\x9E\xA4\xBE", # ADLAM CAPITAL LETTER VA
1684             "\xF0\x9E\xA4\x9D" => "\xF0\x9E\xA4\xBF", # ADLAM CAPITAL LETTER KHA
1685             "\xF0\x9E\xA4\x9E" => "\xF0\x9E\xA5\x80", # ADLAM CAPITAL LETTER GBE
1686             "\xF0\x9E\xA4\x9F" => "\xF0\x9E\xA5\x81", # ADLAM CAPITAL LETTER ZAL
1687             "\xF0\x9E\xA4\xA0" => "\xF0\x9E\xA5\x82", # ADLAM CAPITAL LETTER KPO
1688             "\xF0\x9E\xA4\xA1" => "\xF0\x9E\xA5\x83", # ADLAM CAPITAL LETTER SHA
1689             );
1690             }
1691              
1692             else {
1693             croak "Don't know my package name '@{[__PACKAGE__]}'";
1694             }
1695              
1696             #
1697             # @ARGV wildcard globbing
1698             #
1699             sub import {
1700              
1701 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
1702 0         0 my @argv = ();
1703 0         0 for (@ARGV) {
1704              
1705             # has space
1706 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
1707 0 0       0 if (my @glob = Eoldutf8::glob(qq{"$_"})) {
1708 0         0 push @argv, @glob;
1709             }
1710             else {
1711 0         0 push @argv, $_;
1712             }
1713             }
1714              
1715             # has wildcard metachar
1716             elsif (/\A (?:$q_char)*? [*?] /oxms) {
1717 0 0       0 if (my @glob = Eoldutf8::glob($_)) {
1718 0         0 push @argv, @glob;
1719             }
1720             else {
1721 0         0 push @argv, $_;
1722             }
1723             }
1724              
1725             # no wildcard globbing
1726             else {
1727 0         0 push @argv, $_;
1728             }
1729             }
1730 0         0 @ARGV = @argv;
1731             }
1732              
1733 0         0 *Char::ord = \&OldUTF8::ord;
1734 0         0 *Char::ord_ = \&OldUTF8::ord_;
1735 0         0 *Char::reverse = \&OldUTF8::reverse;
1736 0         0 *Char::getc = \&OldUTF8::getc;
1737 0         0 *Char::length = \&OldUTF8::length;
1738 0         0 *Char::substr = \&OldUTF8::substr;
1739 0         0 *Char::index = \&OldUTF8::index;
1740 0         0 *Char::rindex = \&OldUTF8::rindex;
1741 0         0 *Char::eval = \&OldUTF8::eval;
1742 0         0 *Char::escape = \&OldUTF8::escape;
1743 0         0 *Char::escape_token = \&OldUTF8::escape_token;
1744 0         0 *Char::escape_script = \&OldUTF8::escape_script;
1745             }
1746              
1747             # P.230 Care with Prototypes
1748             # in Chapter 6: Subroutines
1749             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1750             #
1751             # If you aren't careful, you can get yourself into trouble with prototypes.
1752             # But if you are careful, you can do a lot of neat things with them. This is
1753             # all very powerful, of course, and should only be used in moderation to make
1754             # the world a better place.
1755              
1756             # P.332 Care with Prototypes
1757             # in Chapter 7: Subroutines
1758             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1759             #
1760             # If you aren't careful, you can get yourself into trouble with prototypes.
1761             # But if you are careful, you can do a lot of neat things with them. This is
1762             # all very powerful, of course, and should only be used in moderation to make
1763             # the world a better place.
1764              
1765             #
1766             # Prototypes of subroutines
1767             #
1768       0     sub unimport {}
1769             sub Eoldutf8::split(;$$$);
1770             sub Eoldutf8::tr($$$$;$);
1771             sub Eoldutf8::chop(@);
1772             sub Eoldutf8::index($$;$);
1773             sub Eoldutf8::rindex($$;$);
1774             sub Eoldutf8::lcfirst(@);
1775             sub Eoldutf8::lcfirst_();
1776             sub Eoldutf8::lc(@);
1777             sub Eoldutf8::lc_();
1778             sub Eoldutf8::ucfirst(@);
1779             sub Eoldutf8::ucfirst_();
1780             sub Eoldutf8::uc(@);
1781             sub Eoldutf8::uc_();
1782             sub Eoldutf8::fc(@);
1783             sub Eoldutf8::fc_();
1784             sub Eoldutf8::ignorecase;
1785             sub Eoldutf8::classic_character_class;
1786             sub Eoldutf8::capture;
1787             sub Eoldutf8::chr(;$);
1788             sub Eoldutf8::chr_();
1789             sub Eoldutf8::glob($);
1790             sub Eoldutf8::glob_();
1791              
1792             sub OldUTF8::ord(;$);
1793             sub OldUTF8::ord_();
1794             sub OldUTF8::reverse(@);
1795             sub OldUTF8::getc(;*@);
1796             sub OldUTF8::length(;$);
1797             sub OldUTF8::substr($$;$$);
1798             sub OldUTF8::index($$;$);
1799             sub OldUTF8::rindex($$;$);
1800             sub OldUTF8::escape(;$);
1801              
1802             #
1803             # Regexp work
1804             #
1805 306         31453 use vars qw(
1806             $re_a
1807             $re_t
1808             $re_n
1809             $re_r
1810 306     306   4560 );
  306         737  
1811              
1812             #
1813             # Character class
1814             #
1815 306         5067463 use vars qw(
1816             $dot
1817             $dot_s
1818             $eD
1819             $eS
1820             $eW
1821             $eH
1822             $eV
1823             $eR
1824             $eN
1825             $not_alnum
1826             $not_alpha
1827             $not_ascii
1828             $not_blank
1829             $not_cntrl
1830             $not_digit
1831             $not_graph
1832             $not_lower
1833             $not_lower_i
1834             $not_print
1835             $not_punct
1836             $not_space
1837             $not_upper
1838             $not_upper_i
1839             $not_word
1840             $not_xdigit
1841             $eb
1842             $eB
1843 306     306   2221 );
  306         882  
1844              
1845             ${Eoldutf8::dot} = qr{(?>[^\x80-\xFF\x0A]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1846             ${Eoldutf8::dot_s} = qr{(?>[^\x80-\xFF]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1847             ${Eoldutf8::eD} = qr{(?>[^\x80-\xFF0-9]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1848              
1849             # Vertical tabs are now whitespace
1850             # \s in a regex now matches a vertical tab in all circumstances.
1851             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1852             # ${Eoldutf8::eS} = qr{(?>[^\x80-\xFF\x09\x0A \x0C\x0D\x20]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1853             # ${Eoldutf8::eS} = qr{(?>[^\x80-\xFF\x09\x0A\x0B\x0C\x0D\x20]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1854             ${Eoldutf8::eS} = qr{(?>[^\x80-\xFF\s]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1855              
1856             ${Eoldutf8::eW} = qr{(?>[^\x80-\xFF0-9A-Z_a-z]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1857             ${Eoldutf8::eH} = qr{(?>[^\x80-\xFF\x09\x20]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1858             ${Eoldutf8::eV} = qr{(?>[^\x80-\xFF\x0A\x0B\x0C\x0D]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1859             ${Eoldutf8::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
1860             ${Eoldutf8::eN} = qr{(?>[^\x80-\xFF\x0A]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1861             ${Eoldutf8::not_alnum} = qr{(?>[^\x80-\xFF\x30-\x39\x41-\x5A\x61-\x7A]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1862             ${Eoldutf8::not_alpha} = qr{(?>[^\x80-\xFF\x41-\x5A\x61-\x7A]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1863             ${Eoldutf8::not_ascii} = qr{(?>[^\x80-\xFF\x00-\x7F]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1864             ${Eoldutf8::not_blank} = qr{(?>[^\x80-\xFF\x09\x20]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1865             ${Eoldutf8::not_cntrl} = qr{(?>[^\x80-\xFF\x00-\x1F\x7F]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1866             ${Eoldutf8::not_digit} = qr{(?>[^\x80-\xFF\x30-\x39]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1867             ${Eoldutf8::not_graph} = qr{(?>[^\x80-\xFF\x21-\x7F]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1868             ${Eoldutf8::not_lower} = qr{(?>[^\x80-\xFF\x61-\x7A]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1869             ${Eoldutf8::not_lower_i} = qr{(?>[^\x80-\xFF\x41-\x5A\x61-\x7A]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])}; # Perl 5.16 compatible
1870             # ${Eoldutf8::not_lower_i} = qr{(?>[^\x80-\xFF]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])}; # older Perl compatible
1871             ${Eoldutf8::not_print} = qr{(?>[^\x80-\xFF\x20-\x7F]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1872             ${Eoldutf8::not_punct} = qr{(?>[^\x80-\xFF\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1873             ${Eoldutf8::not_space} = qr{(?>[^\x80-\xFF\s\x0B]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1874             ${Eoldutf8::not_upper} = qr{(?>[^\x80-\xFF\x41-\x5A]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1875             ${Eoldutf8::not_upper_i} = qr{(?>[^\x80-\xFF\x41-\x5A\x61-\x7A]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])}; # Perl 5.16 compatible
1876             # ${Eoldutf8::not_upper_i} = qr{(?>[^\x80-\xFF]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])}; # older Perl compatible
1877             ${Eoldutf8::not_word} = qr{(?>[^\x80-\xFF\x30-\x39\x41-\x5A\x5F\x61-\x7A]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1878             ${Eoldutf8::not_xdigit} = qr{(?>[^\x80-\xFF\x30-\x39\x41-\x46\x61-\x66]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])};
1879             ${Eoldutf8::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))};
1880             ${Eoldutf8::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]))};
1881              
1882             # avoid: Name "Eoldutf8::foo" used only once: possible typo at here.
1883             ${Eoldutf8::dot} = ${Eoldutf8::dot};
1884             ${Eoldutf8::dot_s} = ${Eoldutf8::dot_s};
1885             ${Eoldutf8::eD} = ${Eoldutf8::eD};
1886             ${Eoldutf8::eS} = ${Eoldutf8::eS};
1887             ${Eoldutf8::eW} = ${Eoldutf8::eW};
1888             ${Eoldutf8::eH} = ${Eoldutf8::eH};
1889             ${Eoldutf8::eV} = ${Eoldutf8::eV};
1890             ${Eoldutf8::eR} = ${Eoldutf8::eR};
1891             ${Eoldutf8::eN} = ${Eoldutf8::eN};
1892             ${Eoldutf8::not_alnum} = ${Eoldutf8::not_alnum};
1893             ${Eoldutf8::not_alpha} = ${Eoldutf8::not_alpha};
1894             ${Eoldutf8::not_ascii} = ${Eoldutf8::not_ascii};
1895             ${Eoldutf8::not_blank} = ${Eoldutf8::not_blank};
1896             ${Eoldutf8::not_cntrl} = ${Eoldutf8::not_cntrl};
1897             ${Eoldutf8::not_digit} = ${Eoldutf8::not_digit};
1898             ${Eoldutf8::not_graph} = ${Eoldutf8::not_graph};
1899             ${Eoldutf8::not_lower} = ${Eoldutf8::not_lower};
1900             ${Eoldutf8::not_lower_i} = ${Eoldutf8::not_lower_i};
1901             ${Eoldutf8::not_print} = ${Eoldutf8::not_print};
1902             ${Eoldutf8::not_punct} = ${Eoldutf8::not_punct};
1903             ${Eoldutf8::not_space} = ${Eoldutf8::not_space};
1904             ${Eoldutf8::not_upper} = ${Eoldutf8::not_upper};
1905             ${Eoldutf8::not_upper_i} = ${Eoldutf8::not_upper_i};
1906             ${Eoldutf8::not_word} = ${Eoldutf8::not_word};
1907             ${Eoldutf8::not_xdigit} = ${Eoldutf8::not_xdigit};
1908             ${Eoldutf8::eb} = ${Eoldutf8::eb};
1909             ${Eoldutf8::eB} = ${Eoldutf8::eB};
1910              
1911             #
1912             # old UTF-8 split
1913             #
1914             sub Eoldutf8::split(;$$$) {
1915              
1916             # P.794 29.2.161. split
1917             # in Chapter 29: Functions
1918             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1919              
1920             # P.951 split
1921             # in Chapter 27: Functions
1922             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1923              
1924 0     0 0 0 my $pattern = $_[0];
1925 0         0 my $string = $_[1];
1926 0         0 my $limit = $_[2];
1927              
1928             # if $pattern is also omitted or is the literal space, " "
1929 0 0       0 if (not defined $pattern) {
1930 0         0 $pattern = ' ';
1931             }
1932              
1933             # if $string is omitted, the function splits the $_ string
1934 0 0       0 if (not defined $string) {
1935 0 0       0 if (defined $_) {
1936 0         0 $string = $_;
1937             }
1938             else {
1939 0         0 $string = '';
1940             }
1941             }
1942              
1943 0         0 my @split = ();
1944              
1945             # when string is empty
1946 0 0       0 if ($string eq '') {
    0          
1947              
1948             # resulting list value in list context
1949 0 0       0 if (wantarray) {
1950 0         0 return @split;
1951             }
1952              
1953             # count of substrings in scalar context
1954             else {
1955 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
1956 0         0 @_ = @split;
1957 0         0 return scalar @_;
1958             }
1959             }
1960              
1961             # split's first argument is more consistently interpreted
1962             #
1963             # After some changes earlier in v5.17, split's behavior has been simplified:
1964             # if the PATTERN argument evaluates to a string containing one space, it is
1965             # treated the way that a literal string containing one space once was.
1966             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
1967              
1968             # if $pattern is also omitted or is the literal space, " ", the function splits
1969             # on whitespace, /\s+/, after skipping any leading whitespace
1970             # (and so on)
1971              
1972             elsif ($pattern eq ' ') {
1973 0 0       0 if (not defined $limit) {
1974 0         0 return CORE::split(' ', $string);
1975             }
1976             else {
1977 0         0 return CORE::split(' ', $string, $limit);
1978             }
1979             }
1980              
1981             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
1982 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
1983              
1984             # a pattern capable of matching either the null string or something longer than the
1985             # null string will split the value of $string into separate characters wherever it
1986             # matches the null string between characters
1987             # (and so on)
1988              
1989 0 0       0 if ('' =~ / \A $pattern \z /xms) {
1990 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
1991 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
1992              
1993             # P.1024 Appendix W.10 Multibyte Processing
1994             # of ISBN 1-56592-224-7 CJKV Information Processing
1995             # (and so on)
1996              
1997             # the //m modifier is assumed when you split on the pattern /^/
1998             # (and so on)
1999              
2000             # V
2001 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
2002              
2003             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
2004             # is included in the resulting list, interspersed with the fields that are ordinarily returned
2005             # (and so on)
2006              
2007 0         0 local $@;
2008 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
2009 0         0 push @split, CORE::eval('$' . $digit);
2010             }
2011             }
2012             }
2013              
2014             else {
2015 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
2016              
2017             # V
2018 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
2019 0         0 local $@;
2020 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
2021 0         0 push @split, CORE::eval('$' . $digit);
2022             }
2023             }
2024             }
2025             }
2026              
2027             elsif ($limit > 0) {
2028 0 0       0 if ('' =~ / \A $pattern \z /xms) {
2029 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
2030 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
2031              
2032             # V
2033 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
2034 0         0 local $@;
2035 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
2036 0         0 push @split, CORE::eval('$' . $digit);
2037             }
2038             }
2039             }
2040             }
2041             else {
2042 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
2043 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
2044              
2045             # V
2046 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
2047 0         0 local $@;
2048 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
2049 0         0 push @split, CORE::eval('$' . $digit);
2050             }
2051             }
2052             }
2053             }
2054             }
2055              
2056 0 0       0 if (CORE::length($string) > 0) {
2057 0         0 push @split, $string;
2058             }
2059              
2060             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
2061 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
2062 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
2063 0         0 pop @split;
2064             }
2065             }
2066              
2067             # resulting list value in list context
2068 0 0       0 if (wantarray) {
2069 0         0 return @split;
2070             }
2071              
2072             # count of substrings in scalar context
2073             else {
2074 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
2075 0         0 @_ = @split;
2076 0         0 return scalar @_;
2077             }
2078             }
2079              
2080             #
2081             # get last subexpression offsets
2082             #
2083             sub _last_subexpression_offsets {
2084 0     0   0 my $pattern = $_[0];
2085              
2086             # remove comment
2087 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
2088              
2089 0         0 my $modifier = '';
2090 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
2091 0         0 $modifier = $1;
2092 0         0 $modifier =~ s/-[A-Za-z]*//;
2093             }
2094              
2095             # with /x modifier
2096 0         0 my @char = ();
2097 0 0       0 if ($modifier =~ /x/oxms) {
2098 0         0 @char = $pattern =~ /\G((?>
2099             [^\x80-\xFF\\\#\[\(]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
2100             \\ $q_char |
2101             \# (?>[^\n]*) $ |
2102             \[ (?>(?:[^\x80-\xFF\\\]]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF]|\\\\|\\\]|$q_char)+) \] |
2103             \(\? |
2104             $q_char
2105             ))/oxmsg;
2106             }
2107              
2108             # without /x modifier
2109             else {
2110 0         0 @char = $pattern =~ /\G((?>
2111             [^\x80-\xFF\\\[\(]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
2112             \\ $q_char |
2113             \[ (?>(?:[^\x80-\xFF\\\]]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF]|\\\\|\\\]|$q_char)+) \] |
2114             \(\? |
2115             $q_char
2116             ))/oxmsg;
2117             }
2118              
2119 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
2120             }
2121              
2122             #
2123             # old UTF-8 transliteration (tr///)
2124             #
2125             sub Eoldutf8::tr($$$$;$) {
2126              
2127 0     0 0 0 my $bind_operator = $_[1];
2128 0         0 my $searchlist = $_[2];
2129 0         0 my $replacementlist = $_[3];
2130 0   0     0 my $modifier = $_[4] || '';
2131              
2132 0 0       0 if ($modifier =~ /r/oxms) {
2133 0 0       0 if ($bind_operator =~ / !~ /oxms) {
2134 0         0 croak "Using !~ with tr///r doesn't make sense";
2135             }
2136             }
2137              
2138 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2139 0         0 my @searchlist = _charlist_tr($searchlist);
2140 0         0 my @replacementlist = _charlist_tr($replacementlist);
2141              
2142 0         0 my %tr = ();
2143 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
2144 0 0       0 if (not exists $tr{$searchlist[$i]}) {
2145 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
2146 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
2147             }
2148             elsif ($modifier =~ /d/oxms) {
2149 0         0 $tr{$searchlist[$i]} = '';
2150             }
2151             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
2152 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
2153             }
2154             else {
2155 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
2156             }
2157             }
2158             }
2159              
2160 0         0 my $tr = 0;
2161 0         0 my $replaced = '';
2162 0 0       0 if ($modifier =~ /c/oxms) {
2163 0         0 while (defined(my $char = shift @char)) {
2164 0 0       0 if (not exists $tr{$char}) {
2165 0 0       0 if (defined $replacementlist[0]) {
2166 0         0 $replaced .= $replacementlist[0];
2167             }
2168 0         0 $tr++;
2169 0 0       0 if ($modifier =~ /s/oxms) {
2170 0   0     0 while (@char and (not exists $tr{$char[0]})) {
2171 0         0 shift @char;
2172 0         0 $tr++;
2173             }
2174             }
2175             }
2176             else {
2177 0         0 $replaced .= $char;
2178             }
2179             }
2180             }
2181             else {
2182 0         0 while (defined(my $char = shift @char)) {
2183 0 0       0 if (exists $tr{$char}) {
2184 0         0 $replaced .= $tr{$char};
2185 0         0 $tr++;
2186 0 0       0 if ($modifier =~ /s/oxms) {
2187 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
2188 0         0 shift @char;
2189 0         0 $tr++;
2190             }
2191             }
2192             }
2193             else {
2194 0         0 $replaced .= $char;
2195             }
2196             }
2197             }
2198              
2199 0 0       0 if ($modifier =~ /r/oxms) {
2200 0         0 return $replaced;
2201             }
2202             else {
2203 0         0 $_[0] = $replaced;
2204 0 0       0 if ($bind_operator =~ / !~ /oxms) {
2205 0         0 return not $tr;
2206             }
2207             else {
2208 0         0 return $tr;
2209             }
2210             }
2211             }
2212              
2213             #
2214             # old UTF-8 chop
2215             #
2216             sub Eoldutf8::chop(@) {
2217              
2218 0     0 0 0 my $chop;
2219 0 0       0 if (@_ == 0) {
2220 0         0 my @char = /\G (?>$q_char) /oxmsg;
2221 0         0 $chop = pop @char;
2222 0         0 $_ = join '', @char;
2223             }
2224             else {
2225 0         0 for (@_) {
2226 0         0 my @char = /\G (?>$q_char) /oxmsg;
2227 0         0 $chop = pop @char;
2228 0         0 $_ = join '', @char;
2229             }
2230             }
2231 0         0 return $chop;
2232             }
2233              
2234             #
2235             # old UTF-8 index by octet
2236             #
2237             sub Eoldutf8::index($$;$) {
2238              
2239 0     0 1 0 my($str,$substr,$position) = @_;
2240 0   0     0 $position ||= 0;
2241 0         0 my $pos = 0;
2242              
2243 0         0 while ($pos < CORE::length($str)) {
2244 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
2245 0 0       0 if ($pos >= $position) {
2246 0         0 return $pos;
2247             }
2248             }
2249 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
2250 0         0 $pos += CORE::length($1);
2251             }
2252             else {
2253 0         0 $pos += 1;
2254             }
2255             }
2256 0         0 return -1;
2257             }
2258              
2259             #
2260             # old UTF-8 reverse index
2261             #
2262             sub Eoldutf8::rindex($$;$) {
2263              
2264 0     0 0 0 my($str,$substr,$position) = @_;
2265 0   0     0 $position ||= CORE::length($str) - 1;
2266 0         0 my $pos = 0;
2267 0         0 my $rindex = -1;
2268              
2269 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
2270 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
2271 0         0 $rindex = $pos;
2272             }
2273 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
2274 0         0 $pos += CORE::length($1);
2275             }
2276             else {
2277 0         0 $pos += 1;
2278             }
2279             }
2280 0         0 return $rindex;
2281             }
2282              
2283             #
2284             # old UTF-8 lower case first with parameter
2285             #
2286             sub Eoldutf8::lcfirst(@) {
2287 0 0   0 0 0 if (@_) {
2288 0         0 my $s = shift @_;
2289 0 0 0     0 if (@_ and wantarray) {
2290 0         0 return Eoldutf8::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
2291             }
2292             else {
2293 0         0 return Eoldutf8::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
2294             }
2295             }
2296             else {
2297 0         0 return Eoldutf8::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
2298             }
2299             }
2300              
2301             #
2302             # old UTF-8 lower case first without parameter
2303             #
2304             sub Eoldutf8::lcfirst_() {
2305 0     0 0 0 return Eoldutf8::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
2306             }
2307              
2308             #
2309             # old UTF-8 lower case with parameter
2310             #
2311             sub Eoldutf8::lc(@) {
2312 0 0   0 0 0 if (@_) {
2313 0         0 my $s = shift @_;
2314 0 0 0     0 if (@_ and wantarray) {
2315 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
2316             }
2317             else {
2318 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
2319             }
2320             }
2321             else {
2322 0         0 return Eoldutf8::lc_();
2323             }
2324             }
2325              
2326             #
2327             # old UTF-8 lower case without parameter
2328             #
2329             sub Eoldutf8::lc_() {
2330 0     0 0 0 my $s = $_;
2331 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
2332             }
2333              
2334             #
2335             # old UTF-8 upper case first with parameter
2336             #
2337             sub Eoldutf8::ucfirst(@) {
2338 0 0   0 0 0 if (@_) {
2339 0         0 my $s = shift @_;
2340 0 0 0     0 if (@_ and wantarray) {
2341 0         0 return Eoldutf8::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
2342             }
2343             else {
2344 0         0 return Eoldutf8::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
2345             }
2346             }
2347             else {
2348 0         0 return Eoldutf8::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
2349             }
2350             }
2351              
2352             #
2353             # old UTF-8 upper case first without parameter
2354             #
2355             sub Eoldutf8::ucfirst_() {
2356 0     0 0 0 return Eoldutf8::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
2357             }
2358              
2359             #
2360             # old UTF-8 upper case with parameter
2361             #
2362             sub Eoldutf8::uc(@) {
2363 0 50   2478 0 0 if (@_) {
2364 2478         3783 my $s = shift @_;
2365 2478 50 33     3246 if (@_ and wantarray) {
2366 2478 0       4211 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
2367             }
2368             else {
2369 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  2478         6771  
2370             }
2371             }
2372             else {
2373 2478         18702 return Eoldutf8::uc_();
2374             }
2375             }
2376              
2377             #
2378             # old UTF-8 upper case without parameter
2379             #
2380             sub Eoldutf8::uc_() {
2381 0     0 0 0 my $s = $_;
2382 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
2383             }
2384              
2385             #
2386             # old UTF-8 fold case with parameter
2387             #
2388             sub Eoldutf8::fc(@) {
2389 0 50   2525 0 0 if (@_) {
2390 2525         4961 my $s = shift @_;
2391 2525 50 33     3115 if (@_ and wantarray) {
2392 2525 0       4443 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
2393             }
2394             else {
2395 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  2525         7614  
2396             }
2397             }
2398             else {
2399 2525         8226 return Eoldutf8::fc_();
2400             }
2401             }
2402              
2403             #
2404             # old UTF-8 fold case without parameter
2405             #
2406             sub Eoldutf8::fc_() {
2407 0     0 0 0 my $s = $_;
2408 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
2409             }
2410              
2411             #
2412             # old UTF-8 regexp capture
2413             #
2414             {
2415             sub Eoldutf8::capture {
2416 0     0 1 0 return $_[0];
2417             }
2418             }
2419              
2420             #
2421             # old UTF-8 regexp ignore case modifier
2422             #
2423             sub Eoldutf8::ignorecase {
2424              
2425 0     0 0 0 my @string = @_;
2426 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
2427              
2428             # ignore case of $scalar or @array
2429 0         0 for my $string (@string) {
2430              
2431             # split regexp
2432 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
2433              
2434             # unescape character
2435 0         0 for (my $i=0; $i <= $#char; $i++) {
2436 0 0       0 next if not defined $char[$i];
2437              
2438             # open character class [...]
2439 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
2440 0         0 my $left = $i;
2441              
2442             # [] make die "unmatched [] in regexp ...\n"
2443              
2444 0 0       0 if ($char[$i+1] eq ']') {
2445 0         0 $i++;
2446             }
2447              
2448 0         0 while (1) {
2449 0 0       0 if (++$i > $#char) {
2450 0         0 croak "Unmatched [] in regexp";
2451             }
2452 0 0       0 if ($char[$i] eq ']') {
2453 0         0 my $right = $i;
2454 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
2455              
2456             # escape character
2457 0         0 for my $char (@charlist) {
2458 0 0       0 if (0) {
2459             }
2460              
2461 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
2462 0         0 $char = '\\' . $char;
2463             }
2464             }
2465              
2466             # [...]
2467 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
2468              
2469 0         0 $i = $left;
2470 0         0 last;
2471             }
2472             }
2473             }
2474              
2475             # open character class [^...]
2476             elsif ($char[$i] eq '[^') {
2477 0         0 my $left = $i;
2478              
2479             # [^] make die "unmatched [] in regexp ...\n"
2480              
2481 0 0       0 if ($char[$i+1] eq ']') {
2482 0         0 $i++;
2483             }
2484              
2485 0         0 while (1) {
2486 0 0       0 if (++$i > $#char) {
2487 0         0 croak "Unmatched [] in regexp";
2488             }
2489 0 0       0 if ($char[$i] eq ']') {
2490 0         0 my $right = $i;
2491 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
2492              
2493             # escape character
2494 0         0 for my $char (@charlist) {
2495 0 0       0 if (0) {
2496             }
2497              
2498 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
2499 0         0 $char = '\\' . $char;
2500             }
2501             }
2502              
2503             # [^...]
2504 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
2505              
2506 0         0 $i = $left;
2507 0         0 last;
2508             }
2509             }
2510             }
2511              
2512             # rewrite classic character class or escape character
2513             elsif (my $char = classic_character_class($char[$i])) {
2514 0         0 $char[$i] = $char;
2515             }
2516              
2517             # with /i modifier
2518             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
2519 0         0 my $uc = Eoldutf8::uc($char[$i]);
2520 0         0 my $fc = Eoldutf8::fc($char[$i]);
2521 0 0       0 if ($uc ne $fc) {
2522 0 0       0 if (CORE::length($fc) == 1) {
2523 0         0 $char[$i] = '[' . $uc . $fc . ']';
2524             }
2525             else {
2526 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
2527             }
2528             }
2529             }
2530             }
2531              
2532             # characterize
2533 0         0 for (my $i=0; $i <= $#char; $i++) {
2534 0 0       0 next if not defined $char[$i];
2535              
2536 0 0       0 if (0) {
2537             }
2538              
2539             # quote character before ? + * {
2540 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
2541 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
2542 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
2543             }
2544             }
2545             }
2546              
2547 0         0 $string = join '', @char;
2548             }
2549              
2550             # make regexp string
2551 0         0 return @string;
2552             }
2553              
2554             #
2555             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
2556             #
2557             sub Eoldutf8::classic_character_class {
2558 0     2820 0 0 my($char) = @_;
2559              
2560             return {
2561             '\D' => '${Eoldutf8::eD}',
2562             '\S' => '${Eoldutf8::eS}',
2563             '\W' => '${Eoldutf8::eW}',
2564             '\d' => '[0-9]',
2565              
2566             # Before Perl 5.6, \s only matched the five whitespace characters
2567             # tab, newline, form-feed, carriage return, and the space character
2568             # itself, which, taken together, is the character class [\t\n\f\r ].
2569              
2570             # Vertical tabs are now whitespace
2571             # \s in a regex now matches a vertical tab in all circumstances.
2572             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
2573             # \t \n \v \f \r space
2574             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
2575             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
2576             '\s' => '\s',
2577              
2578             '\w' => '[0-9A-Z_a-z]',
2579             '\C' => '[\x00-\xFF]',
2580             '\X' => 'X',
2581              
2582             # \h \v \H \V
2583              
2584             # P.114 Character Class Shortcuts
2585             # in Chapter 7: In the World of Regular Expressions
2586             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
2587              
2588             # P.357 13.2.3 Whitespace
2589             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
2590             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
2591             #
2592             # 0x00009 CHARACTER TABULATION h s
2593             # 0x0000a LINE FEED (LF) vs
2594             # 0x0000b LINE TABULATION v
2595             # 0x0000c FORM FEED (FF) vs
2596             # 0x0000d CARRIAGE RETURN (CR) vs
2597             # 0x00020 SPACE h s
2598              
2599             # P.196 Table 5-9. Alphanumeric regex metasymbols
2600             # in Chapter 5. Pattern Matching
2601             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2602              
2603             # (and so on)
2604              
2605             '\H' => '${Eoldutf8::eH}',
2606             '\V' => '${Eoldutf8::eV}',
2607             '\h' => '[\x09\x20]',
2608             '\v' => '[\x0A\x0B\x0C\x0D]',
2609             '\R' => '${Eoldutf8::eR}',
2610              
2611             # \N
2612             #
2613             # http://perldoc.perl.org/perlre.html
2614             # Character Classes and other Special Escapes
2615             # Any character but \n (experimental). Not affected by /s modifier
2616              
2617             '\N' => '${Eoldutf8::eN}',
2618              
2619             # \b \B
2620              
2621             # P.180 Boundaries: The \b and \B Assertions
2622             # in Chapter 5: Pattern Matching
2623             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2624              
2625             # P.219 Boundaries: The \b and \B Assertions
2626             # in Chapter 5: Pattern Matching
2627             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2628              
2629             # \b really means (?:(?<=\w)(?!\w)|(?
2630             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
2631             '\b' => '${Eoldutf8::eb}',
2632              
2633             # \B really means (?:(?<=\w)(?=\w)|(?
2634             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
2635             '\B' => '${Eoldutf8::eB}',
2636              
2637 2820   100     4381 }->{$char} || '';
2638             }
2639              
2640             #
2641             # prepare old UTF-8 characters per length
2642             #
2643              
2644             # 1 octet characters
2645             my @chars1 = ();
2646             sub chars1 {
2647 2820 0   0 0 115322 if (@chars1) {
2648 0         0 return @chars1;
2649             }
2650 0 0       0 if (exists $range_tr{1}) {
2651 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
2652 0         0 while (my @range = splice(@ranges,0,1)) {
2653 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
2654 0         0 push @chars1, pack 'C', $oct0;
2655             }
2656             }
2657             }
2658 0         0 return @chars1;
2659             }
2660              
2661             # 2 octets characters
2662             my @chars2 = ();
2663             sub chars2 {
2664 0 0   0 0 0 if (@chars2) {
2665 0         0 return @chars2;
2666             }
2667 0 0       0 if (exists $range_tr{2}) {
2668 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
2669 0         0 while (my @range = splice(@ranges,0,2)) {
2670 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
2671 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
2672 0         0 push @chars2, pack 'CC', $oct0,$oct1;
2673             }
2674             }
2675             }
2676             }
2677 0         0 return @chars2;
2678             }
2679              
2680             # 3 octets characters
2681             my @chars3 = ();
2682             sub chars3 {
2683 0 0   0 0 0 if (@chars3) {
2684 0         0 return @chars3;
2685             }
2686 0 0       0 if (exists $range_tr{3}) {
2687 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
2688 0         0 while (my @range = splice(@ranges,0,3)) {
2689 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
2690 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
2691 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
2692 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
2693             }
2694             }
2695             }
2696             }
2697             }
2698 0         0 return @chars3;
2699             }
2700              
2701             # 4 octets characters
2702             my @chars4 = ();
2703             sub chars4 {
2704 0 0   0 0 0 if (@chars4) {
2705 0         0 return @chars4;
2706             }
2707 0 0       0 if (exists $range_tr{4}) {
2708 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
2709 0         0 while (my @range = splice(@ranges,0,4)) {
2710 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
2711 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
2712 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
2713 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
2714 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
2715             }
2716             }
2717             }
2718             }
2719             }
2720             }
2721 0         0 return @chars4;
2722             }
2723              
2724             #
2725             # old UTF-8 open character list for tr
2726             #
2727             sub _charlist_tr {
2728              
2729 0     0   0 local $_ = shift @_;
2730              
2731             # unescape character
2732 0         0 my @char = ();
2733 0         0 while (not /\G \z/oxmsgc) {
2734 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
2735 0         0 push @char, '\-';
2736             }
2737             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
2738 0         0 push @char, CORE::chr(oct $1);
2739             }
2740             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
2741 0         0 push @char, CORE::chr(hex $1);
2742             }
2743             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
2744 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
2745             }
2746             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
2747             push @char, {
2748             '\0' => "\0",
2749             '\n' => "\n",
2750             '\r' => "\r",
2751             '\t' => "\t",
2752             '\f' => "\f",
2753             '\b' => "\x08", # \b means backspace in character class
2754             '\a' => "\a",
2755             '\e' => "\e",
2756 0         0 }->{$1};
2757             }
2758             elsif (/\G \\ ($q_char) /oxmsgc) {
2759 0         0 push @char, $1;
2760             }
2761             elsif (/\G ($q_char) /oxmsgc) {
2762 0         0 push @char, $1;
2763             }
2764             }
2765              
2766             # join separated multiple-octet
2767 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
2768              
2769             # unescape '-'
2770 0         0 my @i = ();
2771 0         0 for my $i (0 .. $#char) {
2772 0 0       0 if ($char[$i] eq '\-') {
    0          
2773 0         0 $char[$i] = '-';
2774             }
2775             elsif ($char[$i] eq '-') {
2776 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
2777 0         0 push @i, $i;
2778             }
2779             }
2780             }
2781              
2782             # open character list (reverse for splice)
2783 0         0 for my $i (CORE::reverse @i) {
2784 0         0 my @range = ();
2785              
2786             # range error
2787 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
2788 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2789             }
2790              
2791             # range of multiple-octet code
2792 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
2793 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
2794 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
2795             }
2796             elsif (CORE::length($char[$i+1]) == 2) {
2797 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
2798 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
2799             }
2800             elsif (CORE::length($char[$i+1]) == 3) {
2801 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
2802 0         0 push @range, chars2();
2803 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
2804             }
2805             elsif (CORE::length($char[$i+1]) == 4) {
2806 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
2807 0         0 push @range, chars2();
2808 0         0 push @range, chars3();
2809 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
2810             }
2811             else {
2812 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2813             }
2814             }
2815             elsif (CORE::length($char[$i-1]) == 2) {
2816 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
2817 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
2818             }
2819             elsif (CORE::length($char[$i+1]) == 3) {
2820 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
2821 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
2822             }
2823             elsif (CORE::length($char[$i+1]) == 4) {
2824 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
2825 0         0 push @range, chars3();
2826 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
2827             }
2828             else {
2829 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2830             }
2831             }
2832             elsif (CORE::length($char[$i-1]) == 3) {
2833 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
2834 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
2835             }
2836             elsif (CORE::length($char[$i+1]) == 4) {
2837 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
2838 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
2839             }
2840             else {
2841 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2842             }
2843             }
2844             elsif (CORE::length($char[$i-1]) == 4) {
2845 0 0       0 if (CORE::length($char[$i+1]) == 4) {
2846 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
2847             }
2848             else {
2849 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2850             }
2851             }
2852             else {
2853 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
2854             }
2855              
2856 0         0 splice @char, $i-1, 3, @range;
2857             }
2858              
2859 0         0 return @char;
2860             }
2861              
2862             #
2863             # old UTF-8 open character class
2864             #
2865             sub _cc {
2866 0 50   753   0 if (scalar(@_) == 0) {
    100          
    50          
2867 753         2877 die __FILE__, ": subroutine cc got no parameter.\n";
2868             }
2869             elsif (scalar(@_) == 1) {
2870 0         0 return sprintf('\x%02X',$_[0]);
2871             }
2872             elsif (scalar(@_) == 2) {
2873 382 50       1272 if ($_[0] > $_[1]) {
    100          
    100          
2874 371         955 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
2875             }
2876             elsif ($_[0] == $_[1]) {
2877 0         0 return sprintf('\x%02X',$_[0]);
2878             }
2879             elsif (($_[0]+1) == $_[1]) {
2880 20         55 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
2881             }
2882             else {
2883 20         53 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
2884             }
2885             }
2886             else {
2887 331         1416 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
2888             }
2889             }
2890              
2891             #
2892             # old UTF-8 octet range
2893             #
2894             sub _octets {
2895 0     557   0 my $length = shift @_;
2896              
2897 557 100       1001 if ($length == 1) {
    100          
    50          
    0          
2898 557         1487 my($a1) = unpack 'C', $_[0];
2899 406         6094 my($z1) = unpack 'C', $_[1];
2900              
2901 406 50       734 if ($a1 > $z1) {
2902 406         862 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
2903             }
2904              
2905 0 50       0 if ($a1 == $z1) {
    50          
2906 406         1138 return sprintf('\x%02X',$a1);
2907             }
2908             elsif (($a1+1) == $z1) {
2909 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
2910             }
2911             else {
2912 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
2913             }
2914             }
2915             elsif ($length == 2) {
2916 406         2647 my($a1,$a2) = unpack 'CC', $_[0];
2917 20         49 my($z1,$z2) = unpack 'CC', $_[1];
2918 20         54 my($A1,$A2) = unpack 'CC', $_[2];
2919 20         37 my($Z1,$Z2) = unpack 'CC', $_[3];
2920              
2921 20 50       33 if ($a1 == $z1) {
    50          
2922             return (
2923             # 11111111 222222222222
2924             # A A Z
2925 20         55 _cc($a1) . _cc($a2,$z2), # a2-z2
2926             );
2927             }
2928             elsif (($a1+1) == $z1) {
2929             return (
2930             # 11111111111 222222222222
2931             # A Z A Z
2932 0         0 _cc($a1) . _cc($a2,$Z2), # a2-
2933             _cc( $z1) . _cc($A2,$z2), # -z2
2934             );
2935             }
2936             else {
2937             return (
2938             # 1111111111111111 222222222222
2939             # A Z A Z
2940 0         0 _cc($a1) . _cc($a2,$Z2), # a2-
2941             _cc($a1+1,$z1-1) . _cc($A2,$Z2), # -
2942             _cc( $z1) . _cc($A2,$z2), # -z2
2943             );
2944             }
2945             }
2946             elsif ($length == 3) {
2947 20         51 my($a1,$a2,$a3) = unpack 'CCC', $_[0];
2948 131         455 my($z1,$z2,$z3) = unpack 'CCC', $_[1];
2949 131         327 my($A1,$A2,$A3) = unpack 'CCC', $_[2];
2950 131         275 my($Z1,$Z2,$Z3) = unpack 'CCC', $_[3];
2951              
2952 131 100       579 if ($a1 == $z1) {
    50          
2953 131 50       278 if ($a2 == $z2) {
    0          
2954             return (
2955             # 11111111 22222222 333333333333
2956             # A A A Z
2957 111         249 _cc($a1) . _cc($a2) . _cc($a3,$z3), # a3-z3
2958             );
2959             }
2960             elsif (($a2+1) == $z2) {
2961             return (
2962             # 11111111 22222222222 333333333333
2963             # A A Z A Z
2964 111         288 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
2965             _cc($a1) . _cc( $z2) . _cc($A3,$z3), # -z3
2966             );
2967             }
2968             else {
2969             return (
2970             # 11111111 2222222222222222 333333333333
2971             # A A Z A Z
2972 0         0 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
2973             _cc($a1) . _cc($a2+1,$z2-1) . _cc($A3,$Z3), # -
2974             _cc($a1) . _cc( $z2) . _cc($A3,$z3), # -z3
2975             );
2976             }
2977             }
2978             elsif (($a1+1) == $z1) {
2979             return (
2980             # 11111111111 22222222222222 333333333333
2981             # A Z A Z A Z
2982 0         0 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
2983             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3), # -
2984             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3), # -
2985             _cc( $z1) . _cc( $z2) . _cc($A3,$z3), # -z3
2986             );
2987             }
2988             else {
2989             return (
2990             # 1111111111111111 22222222222222 333333333333
2991             # A Z A Z A Z
2992 0         0 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
2993             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3), # -
2994             _cc($a1+1,$z1-1) . _cc($A2,$Z2) . _cc($A3,$Z3), # -
2995             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3), # -
2996             _cc( $z1) . _cc( $z2) . _cc($A3,$z3), # -z3
2997             );
2998             }
2999             }
3000             elsif ($length == 4) {
3001 20         43 my($a1,$a2,$a3,$a4) = unpack 'CCCC', $_[0];
3002 0         0 my($z1,$z2,$z3,$z4) = unpack 'CCCC', $_[1];
3003 0         0 my($A1,$A2,$A3,$A4) = unpack 'CCCC', $_[0];
3004 0         0 my($Z1,$Z2,$Z3,$Z4) = unpack 'CCCC', $_[1];
3005              
3006 0 0       0 if ($a1 == $z1) {
    0          
3007 0 0       0 if ($a2 == $z2) {
    0          
3008 0 0       0 if ($a3 == $z3) {
    0          
3009             return (
3010             # 11111111 22222222 33333333 444444444444
3011             # A A A A Z
3012 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$z4), # a4-z4
3013             );
3014             }
3015             elsif (($a3+1) == $z3) {
3016             return (
3017             # 11111111 22222222 33333333333 444444444444
3018             # A A A Z A Z
3019 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3020             _cc($a1) . _cc($a2) . _cc( $z3) . _cc($A4,$z4), # -z4
3021             );
3022             }
3023             else {
3024             return (
3025             # 11111111 22222222 3333333333333333 444444444444
3026             # A A A Z A Z
3027 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3028             _cc($a1) . _cc($a2) . _cc($a3+1,$z3-1) . _cc($A4,$Z4), # -
3029             _cc($a1) . _cc($a2) . _cc( $z3) . _cc($A4,$z4), # -z4
3030             );
3031             }
3032             }
3033             elsif (($a2+1) == $z2) {
3034             return (
3035             # 11111111 22222222222 33333333333333 444444444444
3036             # A A Z A Z A Z
3037 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3038             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
3039             _cc($a1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
3040             _cc($a1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
3041             );
3042             }
3043             else {
3044             return (
3045             # 11111111 2222222222222222 33333333333333 444444444444
3046             # A A Z A Z A Z
3047 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3048             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
3049             _cc($a1) . _cc($a2+1,$z2-1) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3050             _cc($a1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
3051             _cc($a1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
3052             );
3053             }
3054             }
3055             elsif (($a1+1) == $z1) {
3056             return (
3057             # 11111111111 22222222222222 33333333333333 444444444444
3058             # A Z A Z A Z A Z
3059 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3060             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
3061             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3062             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3063             _cc( $z1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
3064             _cc( $z1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
3065             );
3066             }
3067             else {
3068             return (
3069             # 1111111111111111 22222222222222 33333333333333 444444444444
3070             # A Z A Z A Z A Z
3071 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
3072             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
3073             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3074             _cc($a1+1,$z1-1) . _cc($A2,$Z2) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3075             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
3076             _cc( $z1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
3077             _cc( $z1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
3078             );
3079             }
3080             }
3081             else {
3082 0         0 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
3083             }
3084             }
3085              
3086             #
3087             # old UTF-8 range regexp
3088             #
3089             sub _range_regexp {
3090 0     537   0 my($length,$first,$last) = @_;
3091              
3092 537         1203 my @range_regexp = ();
3093 537 50       1348 if (not exists $range_tr{$length}) {
3094 537         1384 return @range_regexp;
3095             }
3096              
3097 0         0 my @ranges = @{ $range_tr{$length} };
  537         718  
3098 537         1278 while (my @range = splice(@ranges,0,$length)) {
3099 537         2993 my $min = '';
3100 923         1509 my $max = '';
3101 923         2867 for (my $i=0; $i < $length; $i++) {
3102 923         3523 $min .= pack 'C', $range[$i][0];
3103 1205         3291 $max .= pack 'C', $range[$i][-1];
3104             }
3105              
3106             # min___max
3107             # FIRST_____________LAST
3108             # (nothing)
3109              
3110 1205 50 66     11220 if ($max lt $first) {
    100 100        
    50 33        
    100 100        
    100 66        
    100 66        
    50 66        
3111             }
3112              
3113             # **********
3114             # min_________max
3115             # FIRST_____________LAST
3116             # **********
3117              
3118             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
3119 923         10030 push @range_regexp, _octets($length,$first,$max,$min,$max);
3120             }
3121              
3122             # **********************
3123             # min________________max
3124             # FIRST_____________LAST
3125             # **********************
3126              
3127             elsif (($min eq $first) and ($max eq $last)) {
3128 28         72 push @range_regexp, _octets($length,$first,$last,$min,$max);
3129             }
3130              
3131             # *********
3132             # min___max
3133             # FIRST_____________LAST
3134             # *********
3135              
3136             elsif (($first le $min) and ($max le $last)) {
3137 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
3138             }
3139              
3140             # **********************
3141             # min__________________________max
3142             # FIRST_____________LAST
3143             # **********************
3144              
3145             elsif (($min le $first) and ($last le $max)) {
3146 40         72 push @range_regexp, _octets($length,$first,$last,$min,$max);
3147             }
3148              
3149             # *********
3150             # min________max
3151             # FIRST_____________LAST
3152             # *********
3153              
3154             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
3155 469         1279 push @range_regexp, _octets($length,$min,$last,$min,$max);
3156             }
3157              
3158             # min___max
3159             # FIRST_____________LAST
3160             # (nothing)
3161              
3162             elsif ($last lt $min) {
3163             }
3164              
3165             else {
3166 20         43 die __FILE__, ": subroutine _range_regexp panic.\n";
3167             }
3168             }
3169              
3170 0         0 return @range_regexp;
3171             }
3172              
3173             #
3174             # old UTF-8 open character list for qr and not qr
3175             #
3176             sub _charlist {
3177              
3178 537     770   1205 my $modifier = pop @_;
3179 770         1296 my @char = @_;
3180              
3181 770 100       1966 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
3182              
3183             # unescape character
3184 770         4584 for (my $i=0; $i <= $#char; $i++) {
3185              
3186             # escape - to ...
3187 770 100 100     2729 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
3188 2660 100 100     23564 if ((0 < $i) and ($i < $#char)) {
3189 522         2091 $char[$i] = '...';
3190             }
3191             }
3192              
3193             # octal escape sequence
3194             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
3195 497         1067 $char[$i] = octchr($1);
3196             }
3197              
3198             # hexadecimal escape sequence
3199             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
3200 0         0 $char[$i] = hexchr($1);
3201             }
3202              
3203             # \b{...} --> b\{...}
3204             # \B{...} --> B\{...}
3205             # \N{CHARNAME} --> N\{CHARNAME}
3206             # \p{PROPERTY} --> p\{PROPERTY}
3207             # \P{PROPERTY} --> P\{PROPERTY}
3208             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
3209 0         0 $char[$i] = $1 . '\\' . $2;
3210             }
3211              
3212             # \p, \P, \X --> p, P, X
3213             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
3214 0         0 $char[$i] = $1;
3215             }
3216              
3217             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
3218 0         0 $char[$i] = CORE::chr oct $1;
3219             }
3220             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
3221 0         0 $char[$i] = CORE::chr hex $1;
3222             }
3223             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
3224 206         990 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
3225             }
3226             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
3227             $char[$i] = {
3228             '\0' => "\0",
3229             '\n' => "\n",
3230             '\r' => "\r",
3231             '\t' => "\t",
3232             '\f' => "\f",
3233             '\b' => "\x08", # \b means backspace in character class
3234             '\a' => "\a",
3235             '\e' => "\e",
3236             '\d' => '[0-9]',
3237              
3238             # Vertical tabs are now whitespace
3239             # \s in a regex now matches a vertical tab in all circumstances.
3240             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
3241             # \t \n \v \f \r space
3242             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
3243             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
3244             '\s' => '\s',
3245              
3246             '\w' => '[0-9A-Z_a-z]',
3247             '\D' => '${Eoldutf8::eD}',
3248             '\S' => '${Eoldutf8::eS}',
3249             '\W' => '${Eoldutf8::eW}',
3250              
3251             '\H' => '${Eoldutf8::eH}',
3252             '\V' => '${Eoldutf8::eV}',
3253             '\h' => '[\x09\x20]',
3254             '\v' => '[\x0A\x0B\x0C\x0D]',
3255             '\R' => '${Eoldutf8::eR}',
3256              
3257 0         0 }->{$1};
3258             }
3259              
3260             # POSIX-style character classes
3261             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
3262             $char[$i] = {
3263              
3264             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
3265             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
3266             '[:^lower:]' => '${Eoldutf8::not_lower_i}',
3267             '[:^upper:]' => '${Eoldutf8::not_upper_i}',
3268              
3269 33         560 }->{$1};
3270             }
3271             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
3272             $char[$i] = {
3273              
3274             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
3275             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
3276             '[:ascii:]' => '[\x00-\x7F]',
3277             '[:blank:]' => '[\x09\x20]',
3278             '[:cntrl:]' => '[\x00-\x1F\x7F]',
3279             '[:digit:]' => '[\x30-\x39]',
3280             '[:graph:]' => '[\x21-\x7F]',
3281             '[:lower:]' => '[\x61-\x7A]',
3282             '[:print:]' => '[\x20-\x7F]',
3283             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
3284              
3285             # P.174 POSIX-Style Character Classes
3286             # in Chapter 5: Pattern Matching
3287             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
3288              
3289             # P.311 11.2.4 Character Classes and other Special Escapes
3290             # in Chapter 11: perlre: Perl regular expressions
3291             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
3292              
3293             # P.210 POSIX-Style Character Classes
3294             # in Chapter 5: Pattern Matching
3295             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3296              
3297             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
3298              
3299             '[:upper:]' => '[\x41-\x5A]',
3300             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
3301             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
3302             '[:^alnum:]' => '${Eoldutf8::not_alnum}',
3303             '[:^alpha:]' => '${Eoldutf8::not_alpha}',
3304             '[:^ascii:]' => '${Eoldutf8::not_ascii}',
3305             '[:^blank:]' => '${Eoldutf8::not_blank}',
3306             '[:^cntrl:]' => '${Eoldutf8::not_cntrl}',
3307             '[:^digit:]' => '${Eoldutf8::not_digit}',
3308             '[:^graph:]' => '${Eoldutf8::not_graph}',
3309             '[:^lower:]' => '${Eoldutf8::not_lower}',
3310             '[:^print:]' => '${Eoldutf8::not_print}',
3311             '[:^punct:]' => '${Eoldutf8::not_punct}',
3312             '[:^space:]' => '${Eoldutf8::not_space}',
3313             '[:^upper:]' => '${Eoldutf8::not_upper}',
3314             '[:^word:]' => '${Eoldutf8::not_word}',
3315             '[:^xdigit:]' => '${Eoldutf8::not_xdigit}',
3316              
3317 8         87 }->{$1};
3318             }
3319             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
3320 70         1512 $char[$i] = $1;
3321             }
3322             }
3323              
3324             # open character list
3325 7         31 my @singleoctet = ();
3326 770         1422 my @multipleoctet = ();
3327 770         1309 for (my $i=0; $i <= $#char; ) {
3328              
3329             # escaped -
3330 770 100 100     1940 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
3331 2163         9875 $i += 1;
3332 497         785 next;
3333             }
3334              
3335             # make range regexp
3336             elsif ($char[$i] eq '...') {
3337              
3338             # range error
3339 497 50       908 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    100          
3340 497         2117 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
3341             }
3342             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
3343 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
3344 477         2393 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
3345             }
3346             }
3347              
3348             # make range regexp per length
3349 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
3350 497         1543 my @regexp = ();
3351              
3352             # is first and last
3353 537 100 100     848 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    100 66        
    100          
    50          
3354 537         2099 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
3355             }
3356              
3357             # is first
3358             elsif ($length == CORE::length($char[$i-1])) {
3359 477         2585 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
3360             }
3361              
3362             # is inside in first and last
3363             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
3364 20         89 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
3365             }
3366              
3367             # is last
3368             elsif ($length == CORE::length($char[$i+1])) {
3369 20         63 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
3370             }
3371              
3372             else {
3373 20         57 die __FILE__, ": subroutine make_regexp panic.\n";
3374             }
3375              
3376 0 100       0 if ($length == 1) {
3377 537         1040 push @singleoctet, @regexp;
3378             }
3379             else {
3380 386         919 push @multipleoctet, @regexp;
3381             }
3382             }
3383              
3384 151         359 $i += 2;
3385             }
3386              
3387             # with /i modifier
3388             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
3389 497 100       1017 if ($modifier =~ /i/oxms) {
3390 764         1337 my $uc = Eoldutf8::uc($char[$i]);
3391 192         1451 my $fc = Eoldutf8::fc($char[$i]);
3392 192 50       355 if ($uc ne $fc) {
3393 192 50       529 if (CORE::length($fc) == 1) {
3394 192         372 push @singleoctet, $uc, $fc;
3395             }
3396             else {
3397 192         386 push @singleoctet, $uc;
3398 0         0 push @multipleoctet, $fc;
3399             }
3400             }
3401             else {
3402 0         0 push @singleoctet, $char[$i];
3403             }
3404             }
3405             else {
3406 0         0 push @singleoctet, $char[$i];
3407             }
3408 572         1015 $i += 1;
3409             }
3410              
3411             # single character of single octet code
3412             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
3413 764         1393 push @singleoctet, "\t", "\x20";
3414 0         0 $i += 1;
3415             }
3416             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
3417 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
3418 0         0 $i += 1;
3419             }
3420             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
3421 0         0 push @singleoctet, $char[$i];
3422 2         6 $i += 1;
3423             }
3424              
3425             # single character of multiple-octet code
3426             else {
3427 2         6 push @multipleoctet, $char[$i];
3428 403         844 $i += 1;
3429             }
3430             }
3431              
3432             # quote metachar
3433 403         696 for (@singleoctet) {
3434 770 50       1579 if ($_ eq '...') {
    100          
    100          
    100          
    100          
3435 1364         7827 $_ = '-';
3436             }
3437             elsif (/\A \n \z/oxms) {
3438 0         0 $_ = '\n';
3439             }
3440             elsif (/\A \r \z/oxms) {
3441 8         29 $_ = '\r';
3442             }
3443             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
3444 8         19 $_ = sprintf('\x%02X', CORE::ord $1);
3445             }
3446             elsif (/\A [\x00-\xFF] \z/oxms) {
3447 1         5 $_ = quotemeta $_;
3448             }
3449             }
3450              
3451             # return character list
3452 939         1605 return \@singleoctet, \@multipleoctet;
3453             }
3454              
3455             #
3456             # old UTF-8 octal escape sequence
3457             #
3458             sub octchr {
3459 770     5 0 3105 my($octdigit) = @_;
3460              
3461 5         14 my @binary = ();
3462 5         12 for my $octal (split(//,$octdigit)) {
3463             push @binary, {
3464             '0' => '000',
3465             '1' => '001',
3466             '2' => '010',
3467             '3' => '011',
3468             '4' => '100',
3469             '5' => '101',
3470             '6' => '110',
3471             '7' => '111',
3472 5         23 }->{$octal};
3473             }
3474 50         186 my $binary = join '', @binary;
3475              
3476             my $octchr = {
3477             # 1234567
3478             1 => pack('B*', "0000000$binary"),
3479             2 => pack('B*', "000000$binary"),
3480             3 => pack('B*', "00000$binary"),
3481             4 => pack('B*', "0000$binary"),
3482             5 => pack('B*', "000$binary"),
3483             6 => pack('B*', "00$binary"),
3484             7 => pack('B*', "0$binary"),
3485             0 => pack('B*', "$binary"),
3486              
3487 5         15 }->{CORE::length($binary) % 8};
3488              
3489 5         66 return $octchr;
3490             }
3491              
3492             #
3493             # old UTF-8 hexadecimal escape sequence
3494             #
3495             sub hexchr {
3496 5     5 0 20 my($hexdigit) = @_;
3497              
3498             my $hexchr = {
3499             1 => pack('H*', "0$hexdigit"),
3500             0 => pack('H*', "$hexdigit"),
3501              
3502 5         16 }->{CORE::length($_[0]) % 2};
3503              
3504 5         60 return $hexchr;
3505             }
3506              
3507             #
3508             # old UTF-8 open character list for qr
3509             #
3510             sub charlist_qr {
3511              
3512 5     531 0 18 my $modifier = pop @_;
3513 531         1167 my @char = @_;
3514              
3515 531         1487 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
3516 531         1760 my @singleoctet = @$singleoctet;
3517 531         1262 my @multipleoctet = @$multipleoctet;
3518              
3519             # return character list
3520 531 100       896 if (scalar(@singleoctet) >= 1) {
3521              
3522             # with /i modifier
3523 531 100       1290 if ($modifier =~ m/i/oxms) {
3524 384         957 my %singleoctet_ignorecase = ();
3525 107         178 for (@singleoctet) {
3526 107   66     200 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
3527 272         6080 for my $ord (hex($1) .. hex($2)) {
3528 80         330 my $char = CORE::chr($ord);
3529 1091         1480 my $uc = Eoldutf8::uc($char);
3530 1091         1761 my $fc = Eoldutf8::fc($char);
3531 1091 100       1597 if ($uc eq $fc) {
3532 1091         2254 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
3533             }
3534             else {
3535 502 50       1489 if (CORE::length($fc) == 1) {
3536 589         799 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
3537 589         1174 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
3538             }
3539             else {
3540 589         2808 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
3541 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
3542             }
3543             }
3544             }
3545             }
3546 0 100       0 if ($_ ne '') {
3547 272         563 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
3548             }
3549             }
3550 192         1961 my $i = 0;
3551 107         277 my @singleoctet_ignorecase = ();
3552 107         165 for my $ord (0 .. 255) {
3553 107 100       304 if (exists $singleoctet_ignorecase{$ord}) {
3554 27392         77114 push @{$singleoctet_ignorecase[$i]}, $ord;
  1622         1685  
3555             }
3556             else {
3557 1622         17198 $i++;
3558             }
3559             }
3560 25770         35599 @singleoctet = ();
3561 107         200 for my $range (@singleoctet_ignorecase) {
3562 107 100       4420 if (ref $range) {
3563 11367 50       23558 if (scalar(@{$range}) == 1) {
  214 50       226  
3564 214         357 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
3565             }
3566 0         0 elsif (scalar(@{$range}) == 2) {
3567 214         340 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
3568             }
3569             else {
3570 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  214         355  
  214         264  
3571             }
3572             }
3573             }
3574             }
3575              
3576 214         1075 my $not_anchor = '';
3577 384         700 $not_anchor = '(?!(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF]))';
3578              
3579 384         521 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
3580             }
3581 384 100       1057 if (scalar(@multipleoctet) >= 2) {
3582 531         1247 return '(?:' . join('|', @multipleoctet) . ')';
3583             }
3584             else {
3585 102         749 return $multipleoctet[0];
3586             }
3587             }
3588              
3589             #
3590             # old UTF-8 open character list for not qr
3591             #
3592             sub charlist_not_qr {
3593              
3594 429     239 0 1996 my $modifier = pop @_;
3595 239         732 my @char = @_;
3596              
3597 239         634 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
3598 239         590 my @singleoctet = @$singleoctet;
3599 239         717 my @multipleoctet = @$multipleoctet;
3600              
3601             # with /i modifier
3602 239 100       495 if ($modifier =~ m/i/oxms) {
3603 239         610 my %singleoctet_ignorecase = ();
3604 128         194 for (@singleoctet) {
3605 128   66     331 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
3606 272         1018 for my $ord (hex($1) .. hex($2)) {
3607 80         1438 my $char = CORE::chr($ord);
3608 1091         1692 my $uc = Eoldutf8::uc($char);
3609 1091         1822 my $fc = Eoldutf8::fc($char);
3610 1091 100       1587 if ($uc eq $fc) {
3611 1091         1714 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
3612             }
3613             else {
3614 502 50       1151 if (CORE::length($fc) == 1) {
3615 589         760 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
3616 589         1420 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
3617             }
3618             else {
3619 589         1425 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
3620 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
3621             }
3622             }
3623             }
3624             }
3625 0 100       0 if ($_ ne '') {
3626 272         459 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
3627             }
3628             }
3629 192         576 my $i = 0;
3630 128         205 my @singleoctet_ignorecase = ();
3631 128         204 for my $ord (0 .. 255) {
3632 128 100       213 if (exists $singleoctet_ignorecase{$ord}) {
3633 32768         53141 push @{$singleoctet_ignorecase[$i]}, $ord;
  1622         1650  
3634             }
3635             else {
3636 1622         2999 $i++;
3637             }
3638             }
3639 31146         57604 @singleoctet = ();
3640 128         218 for my $range (@singleoctet_ignorecase) {
3641 128 100       311 if (ref $range) {
3642 11367 50       22061 if (scalar(@{$range}) == 1) {
  214 50       217  
3643 214         375 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
3644             }
3645 0         0 elsif (scalar(@{$range}) == 2) {
3646 214         367 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
3647             }
3648             else {
3649 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  214         277  
  214         268  
3650             }
3651             }
3652             }
3653             }
3654              
3655             # return character list
3656 214 100       1081 if (scalar(@multipleoctet) >= 1) {
3657 239 100       677 if (scalar(@singleoctet) >= 1) {
3658              
3659             # any character other than multiple-octet and single octet character class
3660 114         229 return '(?!' . join('|', @multipleoctet) . ')(?:[^\x80-\xFF' . join('', @singleoctet) . ']|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])';
3661             }
3662             else {
3663              
3664             # any character other than multiple-octet character class
3665 70         596 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
3666             }
3667             }
3668             else {
3669 44 50       389 if (scalar(@singleoctet) >= 1) {
3670              
3671             # any character other than single octet character class
3672 125         251 return '(?:[^\x80-\xFF' . join('', @singleoctet) . ']|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])';
3673             }
3674             else {
3675              
3676             # any character
3677 125         816 return "(?:$your_char)";
3678             }
3679             }
3680             }
3681              
3682             #
3683             # open file in read mode
3684             #
3685             sub _open_r {
3686 0     612   0 my(undef,$file) = @_;
3687 306     306   8277 use Fcntl qw(O_RDONLY);
  306         3710  
  306         85692  
3688 612         1950 return CORE::sysopen($_[0], $file, &O_RDONLY);
3689             }
3690              
3691             #
3692             # open file in append mode
3693             #
3694             sub _open_a {
3695 612     306   30925 my(undef,$file) = @_;
3696 306     306   2422 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  306         893  
  306         1522319  
3697 306         1081 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
3698             }
3699              
3700             #
3701             # safe system
3702             #
3703             sub _systemx {
3704              
3705             # P.707 29.2.33. exec
3706             # in Chapter 29: Functions
3707             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
3708             #
3709             # Be aware that in older releases of Perl, exec (and system) did not flush
3710             # your output buffer, so you needed to enable command buffering by setting $|
3711             # on one or more filehandles to avoid lost output in the case of exec, or
3712             # misordererd output in the case of system. This situation was largely remedied
3713             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
3714              
3715             # P.855 exec
3716             # in Chapter 27: Functions
3717             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3718             #
3719             # In very old release of Perl (before v5.6), exec (and system) did not flush
3720             # your output buffer, so you needed to enable command buffering by setting $|
3721             # on one or more filehandles to avoid lost output with exec or misordered
3722             # output with system.
3723              
3724 306     306   84451 $| = 1;
3725              
3726             # P.565 23.1.2. Cleaning Up Your Environment
3727             # in Chapter 23: Security
3728             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
3729              
3730             # P.656 Cleaning Up Your Environment
3731             # in Chapter 20: Security
3732             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3733              
3734             # local $ENV{'PATH'} = '.';
3735 306         1186 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
3736              
3737             # P.707 29.2.33. exec
3738             # in Chapter 29: Functions
3739             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
3740             #
3741             # As we mentioned earlier, exec treats a discrete list of arguments as an
3742             # indication that it should bypass shell processing. However, there is one
3743             # place where you might still get tripped up. The exec call (and system, too)
3744             # will not distinguish between a single scalar argument and an array containing
3745             # only one element.
3746             #
3747             # @args = ("echo surprise"); # just one element in list
3748             # exec @args # still subject to shell escapes
3749             # or die "exec: $!"; # because @args == 1
3750             #
3751             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
3752             # first argument as the pathname, which forces the rest of the arguments to be
3753             # interpreted as a list, even if there is only one of them:
3754             #
3755             # exec { $args[0] } @args # safe even with one-argument list
3756             # or die "can't exec @args: $!";
3757              
3758             # P.855 exec
3759             # in Chapter 27: Functions
3760             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3761             #
3762             # As we mentioned earlier, exec treats a discrete list of arguments as a
3763             # directive to bypass shell processing. However, there is one place where
3764             # you might still get tripped up. The exec call (and system, too) cannot
3765             # distinguish between a single scalar argument and an array containing
3766             # only one element.
3767             #
3768             # @args = ("echo surprise"); # just one element in list
3769             # exec @args # still subject to shell escapes
3770             # || die "exec: $!"; # because @args == 1
3771             #
3772             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
3773             # argument as the pathname, which forces the rest of the arguments to be
3774             # interpreted as a list, even if there is only one of them:
3775             #
3776             # exec { $args[0] } @args # safe even with one-argument list
3777             # || die "can't exec @args: $!";
3778              
3779 306         2933 return CORE::system { $_[0] } @_; # safe even with one-argument list
  306         754  
3780             }
3781              
3782             #
3783             # old UTF-8 order to character (with parameter)
3784             #
3785             sub Eoldutf8::chr(;$) {
3786              
3787 306 0   0 0 45640977 my $c = @_ ? $_[0] : $_;
3788              
3789 0 0       0 if ($c == 0x00) {
3790 0         0 return "\x00";
3791             }
3792             else {
3793 0         0 my @chr = ();
3794 0         0 while ($c > 0) {
3795 0         0 unshift @chr, ($c % 0x100);
3796 0         0 $c = int($c / 0x100);
3797             }
3798 0         0 return pack 'C*', @chr;
3799             }
3800             }
3801              
3802             #
3803             # old UTF-8 order to character (without parameter)
3804             #
3805             sub Eoldutf8::chr_() {
3806              
3807 0     0 0 0 my $c = $_;
3808              
3809 0 0       0 if ($c == 0x00) {
3810 0         0 return "\x00";
3811             }
3812             else {
3813 0         0 my @chr = ();
3814 0         0 while ($c > 0) {
3815 0         0 unshift @chr, ($c % 0x100);
3816 0         0 $c = int($c / 0x100);
3817             }
3818 0         0 return pack 'C*', @chr;
3819             }
3820             }
3821              
3822             #
3823             # old UTF-8 path globbing (with parameter)
3824             #
3825             sub Eoldutf8::glob($) {
3826              
3827 0 0   0 0 0 if (wantarray) {
3828 0         0 my @glob = _DOS_like_glob(@_);
3829 0         0 for my $glob (@glob) {
3830 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
3831             }
3832 0         0 return @glob;
3833             }
3834             else {
3835 0         0 my $glob = _DOS_like_glob(@_);
3836 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
3837 0         0 return $glob;
3838             }
3839             }
3840              
3841             #
3842             # old UTF-8 path globbing (without parameter)
3843             #
3844             sub Eoldutf8::glob_() {
3845              
3846 0 0   0 0 0 if (wantarray) {
3847 0         0 my @glob = _DOS_like_glob();
3848 0         0 for my $glob (@glob) {
3849 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
3850             }
3851 0         0 return @glob;
3852             }
3853             else {
3854 0         0 my $glob = _DOS_like_glob();
3855 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
3856 0         0 return $glob;
3857             }
3858             }
3859              
3860             #
3861             # old UTF-8 path globbing via File::DosGlob 1.10
3862             #
3863             # Often I confuse "_dosglob" and "_doglob".
3864             # So, I renamed "_dosglob" to "_DOS_like_glob".
3865             #
3866             my %iter;
3867             my %entries;
3868             sub _DOS_like_glob {
3869              
3870             # context (keyed by second cxix argument provided by core)
3871 0     0   0 my($expr,$cxix) = @_;
3872              
3873             # glob without args defaults to $_
3874 0 0       0 $expr = $_ if not defined $expr;
3875              
3876             # represents the current user's home directory
3877             #
3878             # 7.3. Expanding Tildes in Filenames
3879             # in Chapter 7. File Access
3880             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3881             #
3882             # and File::HomeDir, File::HomeDir::Windows module
3883              
3884             # DOS-like system
3885 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
3886 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
3887             { my_home_MSWin32() }oxmse;
3888             }
3889              
3890             # UNIX-like system
3891 0 0 0     0 else {
  0         0  
3892             $expr =~ s{ \A ~ ( (?:[^\x80-\xFF/]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])* ) }
3893             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
3894             }
3895 0 0       0  
3896 0 0       0 # assume global context if not provided one
3897             $cxix = '_G_' if not defined $cxix;
3898             $iter{$cxix} = 0 if not exists $iter{$cxix};
3899 0 0       0  
3900 0         0 # if we're just beginning, do it all first
3901             if ($iter{$cxix} == 0) {
3902             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
3903             }
3904 0 0       0  
3905 0         0 # chuck it all out, quick or slow
3906 0         0 if (wantarray) {
  0         0  
3907             delete $iter{$cxix};
3908             return @{delete $entries{$cxix}};
3909 0 0       0 }
  0         0  
3910 0         0 else {
  0         0  
3911             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
3912             return shift @{$entries{$cxix}};
3913             }
3914 0         0 else {
3915 0         0 # return undef for EOL
3916 0         0 delete $iter{$cxix};
3917             delete $entries{$cxix};
3918             return undef;
3919             }
3920             }
3921             }
3922              
3923             #
3924             # old UTF-8 path globbing subroutine
3925             #
3926 0     0   0 sub _do_glob {
3927 0         0  
3928 0         0 my($cond,@expr) = @_;
3929             my @glob = ();
3930             my $fix_drive_relative_paths = 0;
3931 0         0  
3932 0 0       0 OUTER:
3933 0 0       0 for my $expr (@expr) {
3934             next OUTER if not defined $expr;
3935 0         0 next OUTER if $expr eq '';
3936 0         0  
3937 0         0 my @matched = ();
3938 0         0 my @globdir = ();
3939 0         0 my $head = '.';
3940             my $pathsep = '/';
3941             my $tail;
3942 0 0       0  
3943 0         0 # if argument is within quotes strip em and do no globbing
3944 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
3945 0 0       0 $expr = $1;
3946 0         0 if ($cond eq 'd') {
3947             if (-d $expr) {
3948             push @glob, $expr;
3949             }
3950 0 0       0 }
3951 0         0 else {
3952             if (-e $expr) {
3953             push @glob, $expr;
3954 0         0 }
3955             }
3956             next OUTER;
3957             }
3958              
3959 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
3960 0 0       0 # to h:./*.pm to expand correctly
3961 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
3962             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^\x80-\xFF/\\]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF]) #$1./$2#oxms) {
3963             $fix_drive_relative_paths = 1;
3964             }
3965 0 0       0 }
3966 0 0       0  
3967 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
3968 0         0 if ($tail eq '') {
3969             push @glob, $expr;
3970 0 0       0 next OUTER;
3971 0 0       0 }
3972 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
3973 0         0 if (@globdir = _do_glob('d', $head)) {
3974             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
3975             next OUTER;
3976 0 0 0     0 }
3977 0         0 }
3978             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
3979 0         0 $head .= $pathsep;
3980             }
3981             $expr = $tail;
3982             }
3983 0 0       0  
3984 0 0       0 # If file component has no wildcards, we can avoid opendir
3985 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
3986             if ($head eq '.') {
3987 0 0 0     0 $head = '';
3988 0         0 }
3989             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
3990 0         0 $head .= $pathsep;
3991 0 0       0 }
3992 0 0       0 $head .= $expr;
3993 0         0 if ($cond eq 'd') {
3994             if (-d $head) {
3995             push @glob, $head;
3996             }
3997 0 0       0 }
3998 0         0 else {
3999             if (-e $head) {
4000             push @glob, $head;
4001 0         0 }
4002             }
4003 0 0       0 next OUTER;
4004 0         0 }
4005 0         0 opendir(*DIR, $head) or next OUTER;
4006             my @leaf = readdir DIR;
4007 0 0       0 closedir DIR;
4008 0         0  
4009             if ($head eq '.') {
4010 0 0 0     0 $head = '';
4011 0         0 }
4012             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
4013             $head .= $pathsep;
4014 0         0 }
4015 0         0  
4016 0         0 my $pattern = '';
4017             while ($expr =~ / \G ($q_char) /oxgc) {
4018             my $char = $1;
4019              
4020             # 6.9. Matching Shell Globs as Regular Expressions
4021             # in Chapter 6. Pattern Matching
4022             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
4023 0 0       0 # (and so on)
    0          
    0          
4024 0         0  
4025             if ($char eq '*') {
4026             $pattern .= "(?:$your_char)*",
4027 0         0 }
4028             elsif ($char eq '?') {
4029             $pattern .= "(?:$your_char)?", # DOS style
4030             # $pattern .= "(?:$your_char)", # UNIX style
4031 0         0 }
4032             elsif ((my $fc = Eoldutf8::fc($char)) ne $char) {
4033             $pattern .= $fc;
4034 0         0 }
4035             else {
4036             $pattern .= quotemeta $char;
4037 0     0   0 }
  0         0  
4038             }
4039             my $matchsub = sub { Eoldutf8::fc($_[0]) =~ /\A $pattern \z/xms };
4040              
4041             # if ($@) {
4042             # print STDERR "$0: $@\n";
4043             # next OUTER;
4044             # }
4045 0         0  
4046 0 0 0     0 INNER:
4047 0         0 for my $leaf (@leaf) {
4048             if ($leaf eq '.' or $leaf eq '..') {
4049 0 0 0     0 next INNER;
4050 0         0 }
4051             if ($cond eq 'd' and not -d "$head$leaf") {
4052             next INNER;
4053 0 0       0 }
4054 0         0  
4055 0         0 if (&$matchsub($leaf)) {
4056             push @matched, "$head$leaf";
4057             next INNER;
4058             }
4059              
4060             # [DOS compatibility special case]
4061 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
4062              
4063             if (Eoldutf8::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
4064             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
4065 0 0       0 Eoldutf8::index($pattern,'\\.') != -1 # pattern has a dot.
4066 0         0 ) {
4067 0         0 if (&$matchsub("$leaf.")) {
4068             push @matched, "$head$leaf";
4069             next INNER;
4070             }
4071 0 0       0 }
4072 0         0 }
4073             if (@matched) {
4074             push @glob, @matched;
4075 0 0       0 }
4076 0         0 }
4077 0         0 if ($fix_drive_relative_paths) {
4078             for my $glob (@glob) {
4079             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
4080 0         0 }
4081             }
4082             return @glob;
4083             }
4084              
4085             #
4086             # old UTF-8 parse line
4087             #
4088 0     0   0 sub _parse_line {
4089              
4090 0         0 my($line) = @_;
4091 0         0  
4092 0         0 $line .= ' ';
4093             my @piece = ();
4094             while ($line =~ /
4095             " ( (?>(?: [^\x80-\xFF"] |(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] )* ) ) " (?>\s+) |
4096             ( (?>(?: [^\x80-\xFF"\s]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] )* ) ) (?>\s+)
4097 0 0       0 /oxmsg
4098             ) {
4099 0         0 push @piece, defined($1) ? $1 : $2;
4100             }
4101             return @piece;
4102             }
4103              
4104             #
4105             # old UTF-8 parse path
4106             #
4107 0     0   0 sub _parse_path {
4108              
4109 0         0 my($path,$pathsep) = @_;
4110 0         0  
4111 0         0 $path .= '/';
4112             my @subpath = ();
4113             while ($path =~ /
4114             ((?: [^\x80-\xFF\/\\]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] )+?) [\/\\]
4115 0         0 /oxmsg
4116             ) {
4117             push @subpath, $1;
4118 0         0 }
4119 0         0  
4120 0         0 my $tail = pop @subpath;
4121             my $head = join $pathsep, @subpath;
4122             return $head, $tail;
4123             }
4124              
4125             #
4126             # via File::HomeDir::Windows 1.00
4127             #
4128             sub my_home_MSWin32 {
4129              
4130             # A lot of unix people and unix-derived tools rely on
4131 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
4132 0         0 # so that they can replace raw HOME calls with File::HomeDir.
4133             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
4134             return $ENV{'HOME'};
4135             }
4136              
4137 0         0 # Do we have a user profile?
4138             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
4139             return $ENV{'USERPROFILE'};
4140             }
4141              
4142 0         0 # Some Windows use something like $ENV{'HOME'}
4143             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
4144             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
4145 0         0 }
4146              
4147             return undef;
4148             }
4149              
4150             #
4151             # via File::HomeDir::Unix 1.00
4152 0     0 0 0 #
4153             sub my_home {
4154 0 0 0     0 my $home;
    0 0        
4155 0         0  
4156             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
4157             $home = $ENV{'HOME'};
4158             }
4159              
4160             # This is from the original code, but I'm guessing
4161 0         0 # it means "login directory" and exists on some Unixes.
4162             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
4163             $home = $ENV{'LOGDIR'};
4164             }
4165              
4166             ### More-desperate methods
4167              
4168 0         0 # Light desperation on any (Unixish) platform
4169             else {
4170             $home = CORE::eval q{ (getpwuid($<))[7] };
4171             }
4172              
4173 0 0 0     0 # On Unix in general, a non-existant home means "no home"
4174 0         0 # For example, "nobody"-like users might use /nonexistant
4175             if (defined $home and ! -d($home)) {
4176 0         0 $home = undef;
4177             }
4178             return $home;
4179             }
4180              
4181             #
4182             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
4183 0     0 0 0 #
4184             sub Eoldutf8::PREMATCH {
4185             return $`;
4186             }
4187              
4188             #
4189             # ${^MATCH}, $MATCH, $& the string that matched
4190 0     0 0 0 #
4191             sub Eoldutf8::MATCH {
4192             return $&;
4193             }
4194              
4195             #
4196             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
4197 0     0 0 0 #
4198             sub Eoldutf8::POSTMATCH {
4199             return $';
4200             }
4201              
4202             #
4203             # old UTF-8 character to order (with parameter)
4204             #
4205 0 0   0 1 0 sub OldUTF8::ord(;$) {
4206              
4207 0 0       0 local $_ = shift if @_;
4208 0         0  
4209 0         0 if (/\A ($q_char) /oxms) {
4210 0         0 my @ord = unpack 'C*', $1;
4211 0         0 my $ord = 0;
4212             while (my $o = shift @ord) {
4213 0         0 $ord = $ord * 0x100 + $o;
4214             }
4215             return $ord;
4216 0         0 }
4217             else {
4218             return CORE::ord $_;
4219             }
4220             }
4221              
4222             #
4223             # old UTF-8 character to order (without parameter)
4224             #
4225 0 0   0 0 0 sub OldUTF8::ord_() {
4226 0         0  
4227 0         0 if (/\A ($q_char) /oxms) {
4228 0         0 my @ord = unpack 'C*', $1;
4229 0         0 my $ord = 0;
4230             while (my $o = shift @ord) {
4231 0         0 $ord = $ord * 0x100 + $o;
4232             }
4233             return $ord;
4234 0         0 }
4235             else {
4236             return CORE::ord $_;
4237             }
4238             }
4239              
4240             #
4241             # old UTF-8 reverse
4242             #
4243 0 0   0 0 0 sub OldUTF8::reverse(@) {
4244 0         0  
4245             if (wantarray) {
4246             return CORE::reverse @_;
4247             }
4248             else {
4249              
4250             # One of us once cornered Larry in an elevator and asked him what
4251             # problem he was solving with this, but he looked as far off into
4252             # the distance as he could in an elevator and said, "It seemed like
4253 0         0 # a good idea at the time."
4254              
4255             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
4256             }
4257             }
4258              
4259             #
4260             # old UTF-8 getc (with parameter, without parameter)
4261             #
4262 0     0 0 0 sub OldUTF8::getc(;*@) {
4263 0 0       0  
4264 0 0 0     0 my($package) = caller;
4265             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
4266 0         0 croak 'Too many arguments for OldUTF8::getc' if @_ and not wantarray;
  0         0  
4267 0         0  
4268 0         0 my @length = sort { $a <=> $b } keys %range_tr;
4269 0         0 my $getc = '';
4270 0 0       0 for my $length ($length[0] .. $length[-1]) {
4271 0 0       0 $getc .= CORE::getc($fh);
4272 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
4273             if ($getc =~ /\A ${Eoldutf8::dot_s} \z/oxms) {
4274             return wantarray ? ($getc,@_) : $getc;
4275             }
4276 0 0       0 }
4277             }
4278             return wantarray ? ($getc,@_) : $getc;
4279             }
4280              
4281             #
4282             # old UTF-8 length by character
4283             #
4284 0 0   0 1 0 sub OldUTF8::length(;$) {
4285              
4286 0         0 local $_ = shift if @_;
4287 0         0  
4288             local @_ = /\G ($q_char) /oxmsg;
4289             return scalar @_;
4290             }
4291              
4292             #
4293             # old UTF-8 substr by character
4294             #
4295             BEGIN {
4296              
4297             # P.232 The lvalue Attribute
4298             # in Chapter 6: Subroutines
4299             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4300              
4301             # P.336 The lvalue Attribute
4302             # in Chapter 7: Subroutines
4303             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4304              
4305             # P.144 8.4 Lvalue subroutines
4306             # in Chapter 8: perlsub: Perl subroutines
4307 306 50 0 306 1 348499 # 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  
4308              
4309             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
4310             # vv----------------------*******
4311             sub OldUTF8::substr($$;$$) %s {
4312              
4313             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
4314              
4315             # If the substring is beyond either end of the string, substr() returns the undefined
4316             # value and produces a warning. When used as an lvalue, specifying a substring that
4317             # is entirely outside the string raises an exception.
4318             # http://perldoc.perl.org/functions/substr.html
4319              
4320             # A return with no argument returns the scalar value undef in scalar context,
4321             # an empty list () in list context, and (naturally) nothing at all in void
4322             # context.
4323              
4324             my $offset = $_[1];
4325             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
4326             return;
4327             }
4328              
4329             # substr($string,$offset,$length,$replacement)
4330             if (@_ == 4) {
4331             my(undef,undef,$length,$replacement) = @_;
4332             my $substr = join '', splice(@char, $offset, $length, $replacement);
4333             $_[0] = join '', @char;
4334              
4335             # return $substr; this doesn't work, don't say "return"
4336             $substr;
4337             }
4338              
4339             # substr($string,$offset,$length)
4340             elsif (@_ == 3) {
4341             my(undef,undef,$length) = @_;
4342             my $octet_offset = 0;
4343             my $octet_length = 0;
4344             if ($offset == 0) {
4345             $octet_offset = 0;
4346             }
4347             elsif ($offset > 0) {
4348             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
4349             }
4350             else {
4351             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
4352             }
4353             if ($length == 0) {
4354             $octet_length = 0;
4355             }
4356             elsif ($length > 0) {
4357             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
4358             }
4359             else {
4360             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
4361             }
4362             CORE::substr($_[0], $octet_offset, $octet_length);
4363             }
4364              
4365             # substr($string,$offset)
4366             else {
4367             my $octet_offset = 0;
4368             if ($offset == 0) {
4369             $octet_offset = 0;
4370             }
4371             elsif ($offset > 0) {
4372             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
4373             }
4374             else {
4375             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
4376             }
4377             CORE::substr($_[0], $octet_offset);
4378             }
4379             }
4380             END
4381             }
4382              
4383             #
4384             # old UTF-8 index by character
4385             #
4386 0     0 1 0 sub OldUTF8::index($$;$) {
4387 0 0       0  
4388 0         0 my $index;
4389             if (@_ == 3) {
4390             $index = Eoldutf8::index($_[0], $_[1], CORE::length(OldUTF8::substr($_[0], 0, $_[2])));
4391 0         0 }
4392             else {
4393             $index = Eoldutf8::index($_[0], $_[1]);
4394 0 0       0 }
4395 0         0  
4396             if ($index == -1) {
4397             return -1;
4398 0         0 }
4399             else {
4400             return OldUTF8::length(CORE::substr $_[0], 0, $index);
4401             }
4402             }
4403              
4404             #
4405             # old UTF-8 rindex by character
4406             #
4407 0     0 1 0 sub OldUTF8::rindex($$;$) {
4408 0 0       0  
4409 0         0 my $rindex;
4410             if (@_ == 3) {
4411             $rindex = Eoldutf8::rindex($_[0], $_[1], CORE::length(OldUTF8::substr($_[0], 0, $_[2])));
4412 0         0 }
4413             else {
4414             $rindex = Eoldutf8::rindex($_[0], $_[1]);
4415 0 0       0 }
4416 0         0  
4417             if ($rindex == -1) {
4418             return -1;
4419 0         0 }
4420             else {
4421             return OldUTF8::length(CORE::substr $_[0], 0, $rindex);
4422             }
4423             }
4424              
4425 306     306   6699 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  306         2205  
  306         46905  
4426             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
4427             use vars qw($slash); $slash = 'm//';
4428              
4429             # ord() to ord() or OldUTF8::ord()
4430             my $function_ord = 'ord';
4431              
4432             # ord to ord or OldUTF8::ord_
4433             my $function_ord_ = 'ord';
4434              
4435             # reverse to reverse or OldUTF8::reverse
4436             my $function_reverse = 'reverse';
4437              
4438             # getc to getc or OldUTF8::getc
4439             my $function_getc = 'getc';
4440              
4441             # P.1023 Appendix W.9 Multibyte Anchoring
4442             # of ISBN 1-56592-224-7 CJKV Information Processing
4443              
4444 306     306   3996 my $anchor = '';
  306     0   551  
  306         20633001  
4445              
4446             use vars qw($nest);
4447              
4448             # regexp of nested parens in qqXX
4449              
4450             # P.340 Matching Nested Constructs with Embedded Code
4451             # in Chapter 7: Perl
4452             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
4453              
4454             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
4455             [^\x80-\xFF\\()] |
4456             \( (?{$nest++}) |
4457             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4458             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4459             \\ [^\x80-\xFFc] |
4460             \\c[\x40-\x5F] |
4461             \\ (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4462             [\x00-\xFF]
4463             }xms;
4464              
4465             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
4466             [^\x80-\xFF\\{}] |
4467             \{ (?{$nest++}) |
4468             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4469             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4470             \\ [^\x80-\xFFc] |
4471             \\c[\x40-\x5F] |
4472             \\ (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4473             [\x00-\xFF]
4474             }xms;
4475              
4476             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
4477             [^\x80-\xFF\\\[\]] |
4478             \[ (?{$nest++}) |
4479             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4480             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4481             \\ [^\x80-\xFFc] |
4482             \\c[\x40-\x5F] |
4483             \\ (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4484             [\x00-\xFF]
4485             }xms;
4486              
4487             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
4488             [^\x80-\xFF\\<>] |
4489             \< (?{$nest++}) |
4490             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4491             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4492             \\ [^\x80-\xFFc] |
4493             \\c[\x40-\x5F] |
4494             \\ (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4495             [\x00-\xFF]
4496             }xms;
4497              
4498             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
4499             (?: ::)? (?:
4500             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
4501             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
4502             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
4503             ))
4504             }xms;
4505              
4506             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
4507             (?: ::)? (?:
4508             (?>[0-9]+) |
4509             [^\x80-\xFFa-zA-Z_0-9\[\]] |
4510             ^[A-Z] |
4511             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
4512             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
4513             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
4514             ))
4515             }xms;
4516              
4517             my $qq_substr = qr{(?> Char::substr | OldUTF8::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
4518             }xms;
4519              
4520             # regexp of nested parens in qXX
4521             my $q_paren = qr{(?{local $nest=0}) (?>(?:
4522             [^\x80-\xFF()] |
4523             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4524             \( (?{$nest++}) |
4525             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4526             [\x00-\xFF]
4527             }xms;
4528              
4529             my $q_brace = qr{(?{local $nest=0}) (?>(?:
4530             [^\x80-\xFF\{\}] |
4531             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4532             \{ (?{$nest++}) |
4533             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4534             [\x00-\xFF]
4535             }xms;
4536              
4537             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
4538             [^\x80-\xFF\[\]] |
4539             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4540             \[ (?{$nest++}) |
4541             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4542             [\x00-\xFF]
4543             }xms;
4544              
4545             my $q_angle = qr{(?{local $nest=0}) (?>(?:
4546             [^\x80-\xFF<>] |
4547             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
4548             \< (?{$nest++}) |
4549             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
4550             [\x00-\xFF]
4551             }xms;
4552              
4553             my $matched = '';
4554             my $s_matched = '';
4555              
4556             my $tr_variable = ''; # variable of tr///
4557             my $sub_variable = ''; # variable of s///
4558             my $bind_operator = ''; # =~ or !~
4559              
4560             my @heredoc = (); # here document
4561             my @heredoc_delimiter = ();
4562             my $here_script = ''; # here script
4563              
4564             #
4565             # escape old UTF-8 script
4566 0 50   306 0 0 #
4567             sub OldUTF8::escape(;$) {
4568             local($_) = $_[0] if @_;
4569              
4570             # P.359 The Study Function
4571             # in Chapter 7: Perl
4572 306         1002 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
4573              
4574             study $_; # Yes, I studied study yesterday.
4575              
4576             # while all script
4577              
4578             # 6.14. Matching from Where the Last Pattern Left Off
4579             # in Chapter 6. Pattern Matching
4580             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
4581             # (and so on)
4582              
4583             # one member of Tag-team
4584             #
4585             # P.128 Start of match (or end of previous match): \G
4586             # P.130 Advanced Use of \G with Perl
4587             # in Chapter 3: Overview of Regular Expression Features and Flavors
4588             # P.255 Use leading anchors
4589             # P.256 Expose ^ and \G at the front expressions
4590             # in Chapter 6: Crafting an Efficient Expression
4591             # P.315 "Tag-team" matching with /gc
4592             # in Chapter 7: Perl
4593 306         614 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
4594 306         520  
4595 306         1166 my $e_script = '';
4596             while (not /\G \z/oxgc) { # member
4597             $e_script .= OldUTF8::escape_token();
4598 135644         258653 }
4599              
4600             return $e_script;
4601             }
4602              
4603             #
4604             # escape old UTF-8 token of script
4605             #
4606             sub OldUTF8::escape_token {
4607              
4608 306     135644 0 4864 # \n output here document
4609              
4610             my $ignore_modules = join('|', qw(
4611             utf8
4612             bytes
4613             charnames
4614             I18N::Japanese
4615             I18N::Collate
4616             I18N::JExt
4617             File::DosGlob
4618             Wild
4619             Wildcard
4620             Japanese
4621             ));
4622              
4623             # another member of Tag-team
4624             #
4625             # P.315 "Tag-team" matching with /gc
4626             # in Chapter 7: Perl
4627 135644 100 100     167839 # 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          
4628 135644         7733584  
4629 22128 100       28155 if (/\G ( \n ) /oxgc) { # another member (and so on)
4630 22128         40570 my $heredoc = '';
4631             if (scalar(@heredoc_delimiter) >= 1) {
4632 191         269 $slash = 'm//';
4633 191         447  
4634             $heredoc = join '', @heredoc;
4635             @heredoc = ();
4636 191         323  
4637 191         417 # skip here document
4638             for my $heredoc_delimiter (@heredoc_delimiter) {
4639 199         1302 /\G .*? \n $heredoc_delimiter \n/xmsgc;
4640             }
4641 191         340 @heredoc_delimiter = ();
4642              
4643 191         362 $here_script = '';
4644             }
4645             return "\n" . $heredoc;
4646             }
4647 22128         69093  
4648             # ignore space, comment
4649             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
4650              
4651             # if (, elsif (, unless (, while (, until (, given (, and when (
4652              
4653             # given, when
4654              
4655             # P.225 The given Statement
4656             # in Chapter 15: Smart Matching and given-when
4657             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4658              
4659             # P.133 The given Statement
4660             # in Chapter 4: Statements and Declarations
4661             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4662 36018         113703  
4663 2398         4042 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
4664             $slash = 'm//';
4665             return $1;
4666             }
4667              
4668             # scalar variable ($scalar = ...) =~ tr///;
4669             # scalar variable ($scalar = ...) =~ s///;
4670              
4671             # state
4672              
4673             # P.68 Persistent, Private Variables
4674             # in Chapter 4: Subroutines
4675             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4676              
4677             # P.160 Persistent Lexically Scoped Variables: state
4678             # in Chapter 4: Statements and Declarations
4679             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4680              
4681             # (and so on)
4682 2398         10156  
4683             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
4684 139 50       370 my $e_string = e_string($1);
    50          
4685 139         5704  
4686 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
4687 0         0 $tr_variable = $e_string . e_string($1);
4688 0         0 $bind_operator = $2;
4689             $slash = 'm//';
4690             return '';
4691 0         0 }
4692 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
4693 0         0 $sub_variable = $e_string . e_string($1);
4694 0         0 $bind_operator = $2;
4695             $slash = 'm//';
4696             return '';
4697 0         0 }
4698 139         276 else {
4699             $slash = 'div';
4700             return $e_string;
4701             }
4702             }
4703              
4704 139         500 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eoldutf8::PREMATCH()
4705 4         11 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4706             $slash = 'div';
4707             return q{Eoldutf8::PREMATCH()};
4708             }
4709              
4710 4         15 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eoldutf8::MATCH()
4711 28         163 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4712             $slash = 'div';
4713             return q{Eoldutf8::MATCH()};
4714             }
4715              
4716 28         89 # $', ${'} --> $', ${'}
4717 1         3 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
4718             $slash = 'div';
4719             return $1;
4720             }
4721              
4722 1         4 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eoldutf8::POSTMATCH()
4723 3         7 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4724             $slash = 'div';
4725             return q{Eoldutf8::POSTMATCH()};
4726             }
4727              
4728             # scalar variable $scalar =~ tr///;
4729             # scalar variable $scalar =~ s///;
4730             # substr() =~ tr///;
4731 3         11 # substr() =~ s///;
4732             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
4733 2318 100       5380 my $scalar = e_string($1);
    100          
4734 2318         11538  
4735 9         66 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
4736 9         17 $tr_variable = $scalar;
4737 9         12 $bind_operator = $1;
4738             $slash = 'm//';
4739             return '';
4740 9         28 }
4741 95         197 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
4742 95         200 $sub_variable = $scalar;
4743 95         212 $bind_operator = $1;
4744             $slash = 'm//';
4745             return '';
4746 95         401 }
4747 2214         3287 else {
4748             $slash = 'div';
4749             return $scalar;
4750             }
4751             }
4752              
4753 2214         5977 # end of statement
4754             elsif (/\G ( [,;] ) /oxgc) {
4755             $slash = 'm//';
4756 9208         14688  
4757             # clear tr/// variable
4758             $tr_variable = '';
4759 9208         11748  
4760             # clear s/// variable
4761 9208         11400 $sub_variable = '';
4762              
4763 9208         10812 $bind_operator = '';
4764              
4765             return $1;
4766             }
4767              
4768 9208         33788 # bareword
4769             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4770             return $1;
4771             }
4772              
4773 0         0 # $0 --> $0
4774 2         5 elsif (/\G ( \$ 0 ) /oxmsgc) {
4775             $slash = 'div';
4776             return $1;
4777 2         7 }
4778 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4779             $slash = 'div';
4780             return $1;
4781             }
4782              
4783 0         0 # $$ --> $$
4784 1         2 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4785             $slash = 'div';
4786             return $1;
4787             }
4788              
4789             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4790 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
4791 57         125 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4792             $slash = 'div';
4793             return e_capture($1);
4794 57         158 }
4795 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4796             $slash = 'div';
4797             return e_capture($1);
4798             }
4799              
4800 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4801 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4802             $slash = 'div';
4803             return e_capture($1.'->'.$2);
4804             }
4805              
4806 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4807 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4808             $slash = 'div';
4809             return e_capture($1.'->'.$2);
4810             }
4811              
4812 0         0 # $$foo
4813 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4814             $slash = 'div';
4815             return e_capture($1);
4816             }
4817              
4818 0         0 # ${ foo }
4819 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
4820             $slash = 'div';
4821             return '${' . $1 . '}';
4822             }
4823              
4824 0         0 # ${ ... }
4825 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4826             $slash = 'div';
4827             return e_capture($1);
4828             }
4829              
4830             # variable or function
4831 0         0 # $ @ % & * $ #
4832 27         48 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) {
4833             $slash = 'div';
4834             return $1;
4835             }
4836             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4837 27         88 # $ @ # \ ' " / ? ( ) [ ] < >
4838 90         187 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4839             $slash = 'div';
4840             return $1;
4841             }
4842              
4843 90         321 # while ()
4844             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
4845             return $1;
4846             }
4847              
4848             # while () --- glob
4849              
4850             # avoid "Error: Runtime exception" of perl version 5.005_03
4851 0         0  
4852             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^\x80-\xFF>\0\a\e\f\n\r\t]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])+?) > (?>\s*) \) \b /oxgc) {
4853             return 'while ($_ = Eoldutf8::glob("' . $1 . '"))';
4854             }
4855              
4856 0         0 # while (glob)
4857             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
4858             return 'while ($_ = Eoldutf8::glob_)';
4859             }
4860              
4861 0         0 # while (glob(WILDCARD))
4862             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
4863             return 'while ($_ = Eoldutf8::glob';
4864             }
4865 0         0  
  401         1156  
4866             # doit if, doit unless, doit while, doit until, doit for, doit when
4867             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
4868 401         1574  
  19         38  
4869 19         66 # subroutines of package Eoldutf8
  0         0  
4870 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         21  
4871 13         29 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
4872 0         0 elsif (/\G \b OldUTF8::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         177  
4873 114         442 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         4  
4874 2         5 elsif (/\G \b OldUTF8::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval OldUTF8::escape'; }
  2         5  
4875 2         7 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         4  
4876 2         5 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::chop'; }
  0         0  
4877 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  2         5  
4878 2         6 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  2         3  
4879 2         6 elsif (/\G \b OldUTF8::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'OldUTF8::index'; }
  2         5  
4880 2         5 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::index'; }
  0         0  
4881 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  2         5  
4882 2         6 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  2         13  
4883 2         9 elsif (/\G \b OldUTF8::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'OldUTF8::rindex'; }
  1         2  
4884 1         4 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::rindex'; }
  0         0  
4885 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eoldutf8::lc'; }
  0         0  
4886 0         0 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eoldutf8::lcfirst'; }
  0         0  
4887 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eoldutf8::uc'; }
  7         13  
4888             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eoldutf8::ucfirst'; }
4889             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eoldutf8::fc'; }
4890 7         24  
  0         0  
4891 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4892 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
4893 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
4894 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
4895 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
4896 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
4897             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
4898 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  
4899 0         0  
  0         0  
4900 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
4901 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
4902 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
4903 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
4904 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
4905             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
4906             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
4907 0         0  
  0         0  
4908 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
4909 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
4910 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
4911             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
4912 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         5  
4913 2         6  
  2         4  
4914 2         6 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         87  
4915 36         135 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         6  
4916 2         7 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eoldutf8::chr'; }
  2         4  
4917 2         7 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
4918 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
4919 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Eoldutf8::glob'; }
  0         0  
4920 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::lc_'; }
  0         0  
4921 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::lcfirst_'; }
  0         0  
4922 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::uc_'; }
  0         0  
4923 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::ucfirst_'; }
  0         0  
4924             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::fc_'; }
4925 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
4926 0         0  
  0         0  
4927 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
4928 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
4929 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::chr_'; }
  2         5  
4930 2         8 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
4931 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  4         11  
4932 4         18 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Eoldutf8::glob_'; }
  8         22  
4933             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
4934             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
4935 8         30 # split
4936             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4937 120         712 $slash = 'm//';
4938 120         203  
4939 120         439 my $e = '';
4940             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4941             $e .= $1;
4942             }
4943 117 100       444  
  120 100       11224  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
4944             # end of split
4945             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Eoldutf8::split' . $e; }
4946 3         14  
4947             # split scalar value
4948             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Eoldutf8::split' . $e . e_string($1); }
4949 1         6  
4950 0         0 # split literal space
4951 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Eoldutf8::split' . $e . qq {qq$1 $2}; }
4952 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; }
4953 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; }
4954 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; }
4955 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; }
4956 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; }
4957 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Eoldutf8::split' . $e . qq {q$1 $2}; }
4958 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Eoldutf8::split' . $e . qq {$1q$2 $3}; }
4959 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Eoldutf8::split' . $e . qq {$1q$2 $3}; }
4960 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Eoldutf8::split' . $e . qq {$1q$2 $3}; }
4961 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Eoldutf8::split' . $e . qq {$1q$2 $3}; }
4962 13         113 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Eoldutf8::split' . $e . qq {$1q$2 $3}; }
4963             elsif (/\G ' [ ] ' /oxgc) { return 'Eoldutf8::split' . $e . qq {' '}; }
4964             elsif (/\G " [ ] " /oxgc) { return 'Eoldutf8::split' . $e . qq {" "}; }
4965              
4966 2 0       9 # split qq//
  0         0  
4967             elsif (/\G \b (qq) \b /oxgc) {
4968 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
4969 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4970 0         0 while (not /\G \z/oxgc) {
4971 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
4972 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
4973 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
4974 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
4975 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
4976             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
4977 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
4978             }
4979             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4980             }
4981             }
4982              
4983 0 50       0 # split qr//
  12         573  
4984             elsif (/\G \b (qr) \b /oxgc) {
4985 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
4986 12 50       67 else {
  12 50       4921  
    50          
    50          
    50          
    50          
    50          
    50          
4987 0         0 while (not /\G \z/oxgc) {
4988 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
4989 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
4990 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
4991 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
4992 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
4993 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
4994             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
4995 12         81 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
4996             }
4997             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4998             }
4999             }
5000              
5001 0 0       0 # split q//
  0         0  
5002             elsif (/\G \b (q) \b /oxgc) {
5003 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
5004 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
5005 0         0 while (not /\G \z/oxgc) {
5006 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5007 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
5008 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
5009 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
5010 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
5011             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
5012 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
5013             }
5014             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5015             }
5016             }
5017              
5018 0 50       0 # split m//
  24         728  
5019             elsif (/\G \b (m) \b /oxgc) {
5020 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
5021 24 50       97 else {
  24 50       5740  
    50          
    50          
    50          
    50          
    50          
    50          
5022 0         0 while (not /\G \z/oxgc) {
5023 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5024 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
5025 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
5026 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
5027 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
5028 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
5029             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
5030 24         133 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
5031             }
5032             die __FILE__, ": Search pattern not terminated\n";
5033             }
5034             }
5035              
5036 0         0 # split ''
5037 0         0 elsif (/\G (\') /oxgc) {
5038 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
5039 0         0 while (not /\G \z/oxgc) {
5040 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5041 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
5042             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
5043 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5044             }
5045             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5046             }
5047              
5048 0         0 # split ""
5049 0         0 elsif (/\G (\") /oxgc) {
5050 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
5051 0         0 while (not /\G \z/oxgc) {
5052 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
5053 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
5054             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
5055 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
5056             }
5057             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5058             }
5059              
5060 0         0 # split //
5061 65         175 elsif (/\G (\/) /oxgc) {
5062 65 50       237 my $regexp = '';
  434 50       2237  
    100          
    50          
5063 0         0 while (not /\G \z/oxgc) {
5064 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
5065 65         302 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
5066             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
5067 369         819 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
5068             }
5069             die __FILE__, ": Search pattern not terminated\n";
5070             }
5071             }
5072              
5073             # tr/// or y///
5074              
5075             # about [cdsrbB]* (/B modifier)
5076             #
5077             # P.559 appendix C
5078             # of ISBN 4-89052-384-7 Programming perl
5079             # (Japanese title is: Perl puroguramingu)
5080 0         0  
5081             elsif (/\G \b ( tr | y ) \b /oxgc) {
5082             my $ope = $1;
5083 11 50       26  
5084 11         201 # $1 $2 $3 $4 $5 $6
5085 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
5086             my @tr = ($tr_variable,$2);
5087             return e_tr(@tr,'',$4,$6);
5088 0         0 }
5089 11         20 else {
5090 11 50       28 my $e = '';
  11 50       1194  
    50          
    50          
    50          
    50          
5091             while (not /\G \z/oxgc) {
5092 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5093 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
5094 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
5095 0         0 while (not /\G \z/oxgc) {
5096 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5097 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
5098 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
5099 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
5100             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
5101 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
5102             }
5103             die __FILE__, ": Transliteration replacement not terminated\n";
5104 0         0 }
5105 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
5106 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
5107 0         0 while (not /\G \z/oxgc) {
5108 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5109 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
5110 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
5111 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
5112             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
5113 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
5114             }
5115             die __FILE__, ": Transliteration replacement not terminated\n";
5116 0         0 }
5117 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
5118 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
5119 0         0 while (not /\G \z/oxgc) {
5120 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5121 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
5122 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
5123 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
5124             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
5125 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
5126             }
5127             die __FILE__, ": Transliteration replacement not terminated\n";
5128 0         0 }
5129 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
5130 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
5131 0         0 while (not /\G \z/oxgc) {
5132 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5133 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
5134 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
5135 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
5136             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
5137 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
5138             }
5139             die __FILE__, ": Transliteration replacement not terminated\n";
5140             }
5141 0         0 # $1 $2 $3 $4 $5 $6
5142 11         97 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
5143             my @tr = ($tr_variable,$2);
5144             return e_tr(@tr,'',$4,$6);
5145 11         82 }
5146             }
5147             die __FILE__, ": Transliteration pattern not terminated\n";
5148             }
5149             }
5150              
5151 0         0 # qq//
5152             elsif (/\G \b (qq) \b /oxgc) {
5153             my $ope = $1;
5154 3822 100       22735  
5155 3822         7568 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
5156 40         57 if (/\G (\#) /oxgc) { # qq# #
5157 40 100       88 my $qq_string = '';
  1948 50       5576  
    100          
    50          
5158 80         153 while (not /\G \z/oxgc) {
5159 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
5160 40         88 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
5161             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
5162 1828         3417 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5163             }
5164             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5165             }
5166 0         0  
5167 3782         5495 else {
5168 3782 50       29025 my $e = '';
  3782 50       16243  
    100          
    50          
    100          
    50          
5169             while (not /\G \z/oxgc) {
5170             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5171              
5172 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
5173 0         0 elsif (/\G (\() /oxgc) { # qq ( )
5174 0         0 my $qq_string = '';
5175 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
5176 0         0 while (not /\G \z/oxgc) {
5177 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
5178             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
5179 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
5180 0         0 elsif (/\G (\)) /oxgc) {
5181             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
5182 0         0 else { $qq_string .= $1; }
5183             }
5184 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5185             }
5186             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5187             }
5188              
5189 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
5190 3724         5656 elsif (/\G (\{) /oxgc) { # qq { }
5191 3724         5844 my $qq_string = '';
5192 3724 100       8442 local $nest = 1;
  155912 50       611666  
    100          
    100          
    50          
5193 792         1636 while (not /\G \z/oxgc) {
5194 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1384         2309  
5195             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
5196 1384 100       2688 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  5108         8387  
5197 3724         9684 elsif (/\G (\}) /oxgc) {
5198             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
5199 1384         2726 else { $qq_string .= $1; }
5200             }
5201 148628         315607 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5202             }
5203             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5204             }
5205              
5206 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
5207 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
5208 0         0 my $qq_string = '';
5209 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
5210 0         0 while (not /\G \z/oxgc) {
5211 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
5212             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
5213 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
5214 0         0 elsif (/\G (\]) /oxgc) {
5215             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
5216 0         0 else { $qq_string .= $1; }
5217             }
5218 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5219             }
5220             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5221             }
5222              
5223 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
5224 38         68 elsif (/\G (\<) /oxgc) { # qq < >
5225 38         63 my $qq_string = '';
5226 38 100       133 local $nest = 1;
  1418 50       5120  
    50          
    100          
    50          
5227 22         56 while (not /\G \z/oxgc) {
5228 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
5229             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
5230 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  38         85  
5231 38         95 elsif (/\G (\>) /oxgc) {
5232             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
5233 0         0 else { $qq_string .= $1; }
5234             }
5235 1358         2799 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5236             }
5237             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5238             }
5239              
5240 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
5241 20         30 elsif (/\G (\S) /oxgc) { # qq * *
5242 20         22 my $delimiter = $1;
5243 20 50       38 my $qq_string = '';
  840 50       2381  
    100          
    50          
5244 0         0 while (not /\G \z/oxgc) {
5245 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
5246 20         38 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
5247             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
5248 820         1463 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
5249             }
5250             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5251 0         0 }
5252             }
5253             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5254             }
5255             }
5256              
5257 0         0 # qr//
5258 36 50       86 elsif (/\G \b (qr) \b /oxgc) {
5259 36         333 my $ope = $1;
5260             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
5261             return e_qr($ope,$1,$3,$2,$4);
5262 0         0 }
5263 36         60 else {
5264 36 50       96 my $e = '';
  36 50       2900  
    100          
    50          
    50          
    100          
    50          
    50          
5265 0         0 while (not /\G \z/oxgc) {
5266 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5267 1         115 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
5268 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
5269 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
5270 2         19 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
5271 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
5272             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
5273 33         190 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
5274             }
5275             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5276             }
5277             }
5278              
5279 0         0 # qw//
5280 34 50       94 elsif (/\G \b (qw) \b /oxgc) {
5281 34         123 my $ope = $1;
5282             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
5283             return e_qw($ope,$1,$3,$2);
5284 0         0 }
5285 34         72 else {
5286 34 50       113 my $e = '';
  34 50       290  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5287             while (not /\G \z/oxgc) {
5288 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5289 34         121  
5290             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
5291 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
5292 0         0  
5293             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
5294 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
5295 0         0  
5296             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
5297 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
5298 0         0  
5299             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
5300 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
5301 0         0  
5302             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
5303 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
5304             }
5305             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5306             }
5307             }
5308              
5309 0         0 # qx//
5310 2 50       5 elsif (/\G \b (qx) \b /oxgc) {
5311 2         48 my $ope = $1;
5312             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
5313             return e_qq($ope,$1,$3,$2);
5314 0         0 }
5315 2         4 else {
5316 2 50       7 my $e = '';
  2 50       149  
    50          
    0          
    0          
    0          
    0          
5317 0         0 while (not /\G \z/oxgc) {
5318 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5319 2         7 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
5320 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
5321 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
5322 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
5323             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
5324 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
5325             }
5326             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5327             }
5328             }
5329              
5330 0         0 # q//
5331             elsif (/\G \b (q) \b /oxgc) {
5332             my $ope = $1;
5333              
5334             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
5335              
5336             # avoid "Error: Runtime exception" of perl version 5.005_03
5337 527 50       1973 # (and so on)
5338 527         1409  
5339 0         0 if (/\G (\#) /oxgc) { # q# #
5340 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
5341 0         0 while (not /\G \z/oxgc) {
5342 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5343 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
5344             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
5345 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5346             }
5347             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5348             }
5349 0         0  
5350 527         927 else {
5351 527 50       2414 my $e = '';
  527 50       3453  
    100          
    50          
    100          
    50          
5352             while (not /\G \z/oxgc) {
5353             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5354              
5355 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
5356 0         0 elsif (/\G (\() /oxgc) { # q ( )
5357 0         0 my $q_string = '';
5358 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
5359 0         0 while (not /\G \z/oxgc) {
5360 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5361 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
5362             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
5363 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
5364 0         0 elsif (/\G (\)) /oxgc) {
5365             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
5366 0         0 else { $q_string .= $1; }
5367             }
5368 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5369             }
5370             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5371             }
5372              
5373 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
5374 521         930 elsif (/\G (\{) /oxgc) { # q { }
5375 521         1065 my $q_string = '';
5376 521 50       1563 local $nest = 1;
  8167 50       54374  
    50          
    100          
    100          
    50          
5377 0         0 while (not /\G \z/oxgc) {
5378 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5379 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  114         397  
5380             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
5381 114 100       221 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  635         1732  
5382 521         1564 elsif (/\G (\}) /oxgc) {
5383             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
5384 114         235 else { $q_string .= $1; }
5385             }
5386 7418         15282 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5387             }
5388             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5389             }
5390              
5391 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
5392 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
5393 0         0 my $q_string = '';
5394 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
5395 0         0 while (not /\G \z/oxgc) {
5396 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5397 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
5398             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
5399 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
5400 0         0 elsif (/\G (\]) /oxgc) {
5401             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
5402 0         0 else { $q_string .= $1; }
5403             }
5404 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5405             }
5406             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5407             }
5408              
5409 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
5410 5         11 elsif (/\G (\<) /oxgc) { # q < >
5411 5         9 my $q_string = '';
5412 5 50       19 local $nest = 1;
  82 50       421  
    50          
    50          
    100          
    50          
5413 0         0 while (not /\G \z/oxgc) {
5414 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5415 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
5416             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
5417 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         15  
5418 5         15 elsif (/\G (\>) /oxgc) {
5419             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
5420 0         0 else { $q_string .= $1; }
5421             }
5422 77         161 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5423             }
5424             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5425             }
5426              
5427 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
5428 1         2 elsif (/\G (\S) /oxgc) { # q * *
5429 1         3 my $delimiter = $1;
5430 1 50       3 my $q_string = '';
  14 50       81  
    100          
    50          
5431 0         0 while (not /\G \z/oxgc) {
5432 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5433 1         3 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
5434             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
5435 13         28 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5436             }
5437             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5438 0         0 }
5439             }
5440             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5441             }
5442             }
5443              
5444 0         0 # m//
5445 269 50       802 elsif (/\G \b (m) \b /oxgc) {
5446 269         2271 my $ope = $1;
5447             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
5448             return e_qr($ope,$1,$3,$2,$4);
5449 0         0 }
5450 269         436 else {
5451 269 50       970 my $e = '';
  269 50       22716  
    50          
    50          
    50          
    100          
    100          
    50          
    50          
5452 0         0 while (not /\G \z/oxgc) {
5453 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5454 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
5455 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
5456 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
5457 18         71 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
5458 13         45 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
5459 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
5460             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
5461 238         818 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
5462             }
5463             die __FILE__, ": Search pattern not terminated\n";
5464             }
5465             }
5466              
5467             # s///
5468              
5469             # about [cegimosxpradlunbB]* (/cg modifier)
5470             #
5471             # P.67 Pattern-Matching Operators
5472             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
5473 0         0  
5474             elsif (/\G \b (s) \b /oxgc) {
5475             my $ope = $1;
5476 132 100       427  
5477 132         4881 # $1 $2 $3 $4 $5 $6
5478             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
5479             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
5480 1         5 }
5481 131         289 else {
5482 131 50       1177 my $e = '';
  131 50       33958  
    50          
    50          
    50          
    100          
    100          
    50          
    50          
5483             while (not /\G \z/oxgc) {
5484 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5485 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
5486 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5487             while (not /\G \z/oxgc) {
5488 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5489 0         0 # $1 $2 $3 $4
5490 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5491 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5492 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5493 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5494 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5495 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5496 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5497             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5498 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5499             }
5500             die __FILE__, ": Substitution replacement not terminated\n";
5501 0         0 }
5502 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
5503 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5504             while (not /\G \z/oxgc) {
5505 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5506 0         0 # $1 $2 $3 $4
5507 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5508 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5509 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5510 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5511 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5512 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5513 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5514             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5515 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5516             }
5517             die __FILE__, ": Substitution replacement not terminated\n";
5518 0         0 }
5519 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
5520 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
5521             while (not /\G \z/oxgc) {
5522 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5523 0         0 # $1 $2 $3 $4
5524 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5525 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5526 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5527 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5528 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5529             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5530 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5531             }
5532             die __FILE__, ": Substitution replacement not terminated\n";
5533 0         0 }
5534 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
5535 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5536             while (not /\G \z/oxgc) {
5537 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
5538 0         0 # $1 $2 $3 $4
5539 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5540 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5541 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5542 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5543 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5544 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5545 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5546             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5547 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
5548             }
5549             die __FILE__, ": Substitution replacement not terminated\n";
5550             }
5551 0         0 # $1 $2 $3 $4 $5 $6
5552             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
5553             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
5554             }
5555 22         76 # $1 $2 $3 $4 $5 $6
5556             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
5557             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
5558             }
5559 2         13 # $1 $2 $3 $4 $5 $6
5560             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
5561             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
5562             }
5563 0         0 # $1 $2 $3 $4 $5 $6
5564             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
5565             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
5566 107         577 }
5567             }
5568             die __FILE__, ": Substitution pattern not terminated\n";
5569             }
5570             }
5571 0         0  
5572 0         0 # require ignore module
5573 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
5574             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^\x80-\xFF#]) /oxmsgc) { return "# require$1\n$2"; }
5575             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
5576 0         0  
5577 43         359 # use strict; --> use strict; no strict qw(refs);
5578 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
5579             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^\x80-\xFF#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
5580             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
5581              
5582 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
5583 3         63 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
5584             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
5585             return "use $1; no strict qw(refs);";
5586 0         0 }
5587             else {
5588             return "use $1;";
5589             }
5590 3 0 0     19 }
      0        
5591 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
5592             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
5593             return "use $1; no strict qw(refs);";
5594 0         0 }
5595             else {
5596             return "use $1;";
5597             }
5598             }
5599 0         0  
5600 2         13 # ignore use module
5601 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
5602             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^\x80-\xFF#]) /oxmsgc) { return "# use$1\n$2"; }
5603             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
5604 0         0  
5605 0         0 # ignore no module
5606 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
5607             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^\x80-\xFF#]) /oxmsgc) { return "# no$1\n$2"; }
5608             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
5609 0         0  
5610             # use else
5611             elsif (/\G \b use \b /oxmsgc) { return "use"; }
5612 0         0  
5613             # use else
5614             elsif (/\G \b no \b /oxmsgc) { return "no"; }
5615              
5616 2         8 # ''
5617 1589         3514 elsif (/\G (?
5618 1589 100       4161 my $q_string = '';
  10597 100       45495  
    100          
    50          
5619 4         11 while (not /\G \z/oxgc) {
5620 48         141 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
5621 1589         5926 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
5622             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
5623 8956         25489 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
5624             }
5625             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5626             }
5627              
5628 0         0 # ""
5629 5587         10881 elsif (/\G (\") /oxgc) {
5630 5587 100       12954 my $qq_string = '';
  88088 100       295232  
    100          
    50          
5631 109         340 while (not /\G \z/oxgc) {
5632 12         27 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
5633 5587         11498 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
5634             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
5635 82380         166972 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
5636             }
5637             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5638             }
5639              
5640 0         0 # ``
5641 1         3 elsif (/\G (\`) /oxgc) {
5642 1 50       4 my $qx_string = '';
  19 50       89  
    100          
    50          
5643 0         0 while (not /\G \z/oxgc) {
5644 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
5645 1         3 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
5646             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
5647 18         35 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
5648             }
5649             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
5650             }
5651              
5652 0         0 # // --- not divide operator (num / num), not defined-or
5653 1069         2774 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
5654 1069 100       4289 my $regexp = '';
  10235 50       61814  
    100          
    50          
5655 1         4 while (not /\G \z/oxgc) {
5656 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
5657 1069         4904 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
5658             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
5659 9165         23089 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
5660             }
5661             die __FILE__, ": Search pattern not terminated\n";
5662             }
5663              
5664 0         0 # ?? --- not conditional operator (condition ? then : else)
5665 18         37 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
5666 18 50       52 my $regexp = '';
  82 50       394  
    100          
    50          
5667 0         0 while (not /\G \z/oxgc) {
5668 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
5669 18         51 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
5670             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
5671 64         144 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
5672             }
5673             die __FILE__, ": Search pattern not terminated\n";
5674             }
5675 0         0  
  0         0  
5676             # <<>> (a safer ARGV)
5677             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
5678 0         0  
  0         0  
5679             # << (bit shift) --- not here document
5680             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
5681              
5682 0         0 # <<~'HEREDOC'
5683 6         11 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
5684 6         10 $slash = 'm//';
5685             my $here_quote = $1;
5686             my $delimiter = $2;
5687 6 50       10  
5688 6         11 # get here document
5689 6         28 if ($here_script eq '') {
5690             $here_script = CORE::substr $_, pos $_;
5691 6 50       28 $here_script =~ s/.*?\n//oxm;
5692 6         61 }
5693 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5694 6         7 my $heredoc = $1;
5695 6         48 my $indent = $2;
5696 6         27 $heredoc =~ s{^$indent}{}msg; # no /ox
5697             push @heredoc, $heredoc . qq{\n$delimiter\n};
5698             push @heredoc_delimiter, qq{\\s*$delimiter};
5699 6         14 }
5700             else {
5701 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5702             }
5703             return qq{<<'$delimiter'};
5704             }
5705              
5706             # <<~\HEREDOC
5707              
5708             # P.66 2.6.6. "Here" Documents
5709             # in Chapter 2: Bits and Pieces
5710             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5711              
5712             # P.73 "Here" Documents
5713             # in Chapter 2: Bits and Pieces
5714             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5715 6         21  
5716 3         6 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
5717 3         6 $slash = 'm//';
5718             my $here_quote = $1;
5719             my $delimiter = $2;
5720 3 50       6  
5721 3         7 # get here document
5722 3         19 if ($here_script eq '') {
5723             $here_script = CORE::substr $_, pos $_;
5724 3 50       18 $here_script =~ s/.*?\n//oxm;
5725 3         49 }
5726 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5727 3         5 my $heredoc = $1;
5728 3         37 my $indent = $2;
5729 3         11 $heredoc =~ s{^$indent}{}msg; # no /ox
5730             push @heredoc, $heredoc . qq{\n$delimiter\n};
5731             push @heredoc_delimiter, qq{\\s*$delimiter};
5732 3         7 }
5733             else {
5734 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5735             }
5736             return qq{<<\\$delimiter};
5737             }
5738              
5739 3         11 # <<~"HEREDOC"
5740 6         11 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
5741 6         12 $slash = 'm//';
5742             my $here_quote = $1;
5743             my $delimiter = $2;
5744 6 50       9  
5745 6         13 # get here document
5746 6         18 if ($here_script eq '') {
5747             $here_script = CORE::substr $_, pos $_;
5748 6 50       31 $here_script =~ s/.*?\n//oxm;
5749 6         68 }
5750 6         15 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5751 6         7 my $heredoc = $1;
5752 6         48 my $indent = $2;
5753 6         16 $heredoc =~ s{^$indent}{}msg; # no /ox
5754             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5755             push @heredoc_delimiter, qq{\\s*$delimiter};
5756 6         53 }
5757             else {
5758 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5759             }
5760             return qq{<<"$delimiter"};
5761             }
5762              
5763 6         27 # <<~HEREDOC
5764 3         7 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
5765 3         7 $slash = 'm//';
5766             my $here_quote = $1;
5767             my $delimiter = $2;
5768 3 50       6  
5769 3         7 # get here document
5770 3         30 if ($here_script eq '') {
5771             $here_script = CORE::substr $_, pos $_;
5772 3 50       22 $here_script =~ s/.*?\n//oxm;
5773 3         53 }
5774 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5775 3         4 my $heredoc = $1;
5776 3         39 my $indent = $2;
5777 3         13 $heredoc =~ s{^$indent}{}msg; # no /ox
5778             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5779             push @heredoc_delimiter, qq{\\s*$delimiter};
5780 3         8 }
5781             else {
5782 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5783             }
5784             return qq{<<$delimiter};
5785             }
5786              
5787 3         13 # <<~`HEREDOC`
5788 6         12 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
5789 6         20 $slash = 'm//';
5790             my $here_quote = $1;
5791             my $delimiter = $2;
5792 6 50       10  
5793 6         12 # get here document
5794 6         16 if ($here_script eq '') {
5795             $here_script = CORE::substr $_, pos $_;
5796 6 50       32 $here_script =~ s/.*?\n//oxm;
5797 6         55 }
5798 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5799 6         9 my $heredoc = $1;
5800 6         45 my $indent = $2;
5801 6         16 $heredoc =~ s{^$indent}{}msg; # no /ox
5802             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5803             push @heredoc_delimiter, qq{\\s*$delimiter};
5804 6         13 }
5805             else {
5806 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5807             }
5808             return qq{<<`$delimiter`};
5809             }
5810              
5811 6         20 # <<'HEREDOC'
5812 80         250 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
5813 80         172 $slash = 'm//';
5814             my $here_quote = $1;
5815             my $delimiter = $2;
5816 80 100       139  
5817 80         294 # get here document
5818 77         2248 if ($here_script eq '') {
5819             $here_script = CORE::substr $_, pos $_;
5820 77 50       459 $here_script =~ s/.*?\n//oxm;
5821 80         868 }
5822 80         342 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5823             push @heredoc, $1 . qq{\n$delimiter\n};
5824             push @heredoc_delimiter, $delimiter;
5825 80         137 }
5826             else {
5827 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5828             }
5829             return $here_quote;
5830             }
5831              
5832             # <<\HEREDOC
5833              
5834             # P.66 2.6.6. "Here" Documents
5835             # in Chapter 2: Bits and Pieces
5836             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5837              
5838             # P.73 "Here" Documents
5839             # in Chapter 2: Bits and Pieces
5840             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5841 80         377  
5842 2         5 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5843 2         5 $slash = 'm//';
5844             my $here_quote = $1;
5845             my $delimiter = $2;
5846 2 100       4  
5847 2         5 # get here document
5848 1         6 if ($here_script eq '') {
5849             $here_script = CORE::substr $_, pos $_;
5850 1 50       6 $here_script =~ s/.*?\n//oxm;
5851 2         45 }
5852 2         9 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5853             push @heredoc, $1 . qq{\n$delimiter\n};
5854             push @heredoc_delimiter, $delimiter;
5855 2         4 }
5856             else {
5857 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5858             }
5859             return $here_quote;
5860             }
5861              
5862 2         9 # <<"HEREDOC"
5863 39         182 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5864 39         102 $slash = 'm//';
5865             my $here_quote = $1;
5866             my $delimiter = $2;
5867 39 100       73  
5868 39         101 # get here document
5869 38         202 if ($here_script eq '') {
5870             $here_script = CORE::substr $_, pos $_;
5871 38 50       264 $here_script =~ s/.*?\n//oxm;
5872 39         557 }
5873 39         306 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5874             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5875             push @heredoc_delimiter, $delimiter;
5876 39         96 }
5877             else {
5878 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5879             }
5880             return $here_quote;
5881             }
5882              
5883 39         158 # <
5884 54         132 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5885 54         120 $slash = 'm//';
5886             my $here_quote = $1;
5887             my $delimiter = $2;
5888 54 100       116  
5889 54         157 # get here document
5890 51         303 if ($here_script eq '') {
5891             $here_script = CORE::substr $_, pos $_;
5892 51 50       857 $here_script =~ s/.*?\n//oxm;
5893 54         768 }
5894 54         226 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5895             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5896             push @heredoc_delimiter, $delimiter;
5897 54         130 }
5898             else {
5899 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5900             }
5901             return $here_quote;
5902             }
5903              
5904 54         235 # <<`HEREDOC`
5905 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5906 0         0 $slash = 'm//';
5907             my $here_quote = $1;
5908             my $delimiter = $2;
5909 0 0       0  
5910 0         0 # get here document
5911 0         0 if ($here_script eq '') {
5912             $here_script = CORE::substr $_, pos $_;
5913 0 0       0 $here_script =~ s/.*?\n//oxm;
5914 0         0 }
5915 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5916             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5917             push @heredoc_delimiter, $delimiter;
5918 0         0 }
5919             else {
5920 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5921             }
5922             return $here_quote;
5923             }
5924              
5925 0         0 # <<= <=> <= < operator
5926             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
5927             return $1;
5928             }
5929              
5930 12         65 #
5931             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
5932             return $1;
5933             }
5934              
5935             # --- glob
5936              
5937             # avoid "Error: Runtime exception" of perl version 5.005_03
5938 0         0  
5939             elsif (/\G < ((?:[^\x80-\xFF>\0\a\e\f\n\r\t]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF])+?) > /oxgc) {
5940             return 'Eoldutf8::glob("' . $1 . '")';
5941             }
5942 0         0  
5943             # __DATA__
5944             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
5945 0         0  
5946             # __END__
5947             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
5948              
5949             # \cD Control-D
5950              
5951             # P.68 2.6.8. Other Literal Tokens
5952             # in Chapter 2: Bits and Pieces
5953             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5954              
5955             # P.76 Other Literal Tokens
5956             # in Chapter 2: Bits and Pieces
5957 306         2070 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5958              
5959             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
5960 0         0  
5961             # \cZ Control-Z
5962             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
5963              
5964             # any operator before div
5965             elsif (/\G (
5966             -- | \+\+ |
5967 0         0 [\)\}\]]
  8556         19446  
5968              
5969             ) /oxgc) { $slash = 'div'; return $1; }
5970              
5971             # yada-yada or triple-dot operator
5972             elsif (/\G (
5973 8556         41376 \.\.\.
  7         16  
5974              
5975             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
5976              
5977             # any operator before m//
5978              
5979             # //, //= (defined-or)
5980              
5981             # P.164 Logical Operators
5982             # in Chapter 10: More Control Structures
5983             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
5984              
5985             # P.119 C-Style Logical (Short-Circuit) Operators
5986             # in Chapter 3: Unary and Binary Operators
5987             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5988              
5989             # (and so on)
5990              
5991             # ~~
5992              
5993             # P.221 The Smart Match Operator
5994             # in Chapter 15: Smart Matching and given-when
5995             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
5996              
5997             # P.112 Smartmatch Operator
5998             # in Chapter 3: Unary and Binary Operators
5999             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6000              
6001             # (and so on)
6002              
6003             elsif (/\G ((?>
6004              
6005             !~~ | !~ | != | ! |
6006             %= | % |
6007             &&= | && | &= | &\.= | &\. | & |
6008             -= | -> | - |
6009             :(?>\s*)= |
6010             : |
6011             <<>> |
6012             <<= | <=> | <= | < |
6013             == | => | =~ | = |
6014             >>= | >> | >= | > |
6015             \*\*= | \*\* | \*= | \* |
6016             \+= | \+ |
6017             \.\. | \.= | \. |
6018             \/\/= | \/\/ |
6019             \/= | \/ |
6020             \? |
6021             \\ |
6022             \^= | \^\.= | \^\. | \^ |
6023             \b x= |
6024             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
6025             ~~ | ~\. | ~ |
6026             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
6027             \b(?: print )\b |
6028              
6029 7         26 [,;\(\{\[]
  16324         35446  
6030              
6031             )) /oxgc) { $slash = 'm//'; return $1; }
6032 16324         77893  
  23922         50583  
6033             # other any character
6034             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
6035              
6036 23922         131195 # system error
6037             else {
6038             die __FILE__, ": Oops, this shouldn't happen!\n";
6039             }
6040             }
6041              
6042 0     2512 0 0 # escape old UTF-8 string
6043 2512         7633 sub e_string {
6044             my($string) = @_;
6045 2512         4111 my $e_string = '';
6046              
6047             local $slash = 'm//';
6048              
6049             # P.1024 Appendix W.10 Multibyte Processing
6050             # of ISBN 1-56592-224-7 CJKV Information Processing
6051 2512         3710 # (and so on)
6052              
6053             my @char = $string =~ / \G (?>[^\x80-\xFF\\]|\\$q_char|$q_char) /oxmsg;
6054 2512 100 66     39103  
6055 2512 50       19522 # without { ... }
6056 2473         5690 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
6057             if ($string !~ /<
6058             return $string;
6059             }
6060             }
6061 2473         6304  
6062 39 50       131 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          
6063             while ($string !~ /\G \z/oxgc) {
6064             if (0) {
6065             }
6066 293         22663  
6067 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Eoldutf8::PREMATCH()]}
6068 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
6069             $e_string .= q{Eoldutf8::PREMATCH()};
6070             $slash = 'div';
6071             }
6072              
6073 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Eoldutf8::MATCH()]}
6074 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
6075             $e_string .= q{Eoldutf8::MATCH()};
6076             $slash = 'div';
6077             }
6078              
6079 0         0 # $', ${'} --> $', ${'}
6080 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
6081             $e_string .= $1;
6082             $slash = 'div';
6083             }
6084              
6085 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Eoldutf8::POSTMATCH()]}
6086 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
6087             $e_string .= q{Eoldutf8::POSTMATCH()};
6088             $slash = 'div';
6089             }
6090              
6091 0         0 # bareword
6092 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
6093             $e_string .= $1;
6094             $slash = 'div';
6095             }
6096              
6097 0         0 # $0 --> $0
6098 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
6099             $e_string .= $1;
6100             $slash = 'div';
6101 0         0 }
6102 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
6103             $e_string .= $1;
6104             $slash = 'div';
6105             }
6106              
6107 0         0 # $$ --> $$
6108 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
6109             $e_string .= $1;
6110             $slash = 'div';
6111             }
6112              
6113             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6114 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6115 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
6116             $e_string .= e_capture($1);
6117             $slash = 'div';
6118 0         0 }
6119 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
6120             $e_string .= e_capture($1);
6121             $slash = 'div';
6122             }
6123              
6124 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6125 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
6126             $e_string .= e_capture($1.'->'.$2);
6127             $slash = 'div';
6128             }
6129              
6130 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6131 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
6132             $e_string .= e_capture($1.'->'.$2);
6133             $slash = 'div';
6134             }
6135              
6136 0         0 # $$foo
6137 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
6138             $e_string .= e_capture($1);
6139             $slash = 'div';
6140             }
6141              
6142 0         0 # ${ foo }
6143 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
6144             $e_string .= '${' . $1 . '}';
6145             $slash = 'div';
6146             }
6147              
6148 0         0 # ${ ... }
6149 3         11 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
6150             $e_string .= e_capture($1);
6151             $slash = 'div';
6152             }
6153              
6154             # variable or function
6155 3         15 # $ @ % & * $ #
6156 1         5 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) {
6157             $e_string .= $1;
6158             $slash = 'div';
6159             }
6160             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
6161 1         7 # $ @ # \ ' " / ? ( ) [ ] < >
6162 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
6163             $e_string .= $1;
6164             $slash = 'div';
6165             }
6166 0         0  
  0         0  
6167 0         0 # subroutines of package Eoldutf8
  0         0  
6168 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
6169 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
6170 0         0 elsif ($string =~ /\G \b OldUTF8::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
6171 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
6172 0         0 elsif ($string =~ /\G \b OldUTF8::eval \b /oxgc) { $e_string .= 'eval OldUTF8::escape'; $slash = 'm//'; }
  0         0  
6173 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
6174 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Eoldutf8::chop'; $slash = 'm//'; }
  0         0  
6175 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
6176 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
6177 0         0 elsif ($string =~ /\G \b OldUTF8::index \b /oxgc) { $e_string .= 'OldUTF8::index'; $slash = 'm//'; }
  0         0  
6178 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Eoldutf8::index'; $slash = 'm//'; }
  0         0  
6179 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
6180 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
6181 0         0 elsif ($string =~ /\G \b OldUTF8::rindex \b /oxgc) { $e_string .= 'OldUTF8::rindex'; $slash = 'm//'; }
  0         0  
6182 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Eoldutf8::rindex'; $slash = 'm//'; }
  0         0  
6183 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eoldutf8::lc'; $slash = 'm//'; }
  0         0  
6184 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eoldutf8::lcfirst'; $slash = 'm//'; }
  0         0  
6185 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eoldutf8::uc'; $slash = 'm//'; }
  0         0  
6186             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eoldutf8::ucfirst'; $slash = 'm//'; }
6187             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eoldutf8::fc'; $slash = 'm//'; }
6188 0         0  
  0         0  
6189 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
6190 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
6191 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  
6192 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  
6193 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  
6194 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  
6195             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
6196 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  
6197 0         0  
  0         0  
6198 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
6199 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  
6200 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  
6201 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  
6202 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  
6203             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
6204             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
6205 0         0  
  0         0  
6206 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
6207 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
6208 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
6209             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
6210 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
6211 0         0  
  0         0  
6212 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
6213 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
6214 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eoldutf8::chr'; $slash = 'm//'; }
  0         0  
6215 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
6216 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
6217 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Eoldutf8::glob'; $slash = 'm//'; }
  0         0  
6218 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Eoldutf8::lc_'; $slash = 'm//'; }
  0         0  
6219 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Eoldutf8::lcfirst_'; $slash = 'm//'; }
  0         0  
6220 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Eoldutf8::uc_'; $slash = 'm//'; }
  0         0  
6221 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Eoldutf8::ucfirst_'; $slash = 'm//'; }
  0         0  
6222             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Eoldutf8::fc_'; $slash = 'm//'; }
6223 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
6224 0         0  
  0         0  
6225 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
6226 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
6227 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Eoldutf8::chr_'; $slash = 'm//'; }
  0         0  
6228 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
6229 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
6230 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Eoldutf8::glob_'; $slash = 'm//'; }
  0         0  
6231             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
6232             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
6233 0         0 # split
6234             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
6235 0         0 $slash = 'm//';
6236 0         0  
6237 0         0 my $e = '';
6238             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
6239             $e .= $1;
6240             }
6241 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          
6242             # end of split
6243             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Eoldutf8::split' . $e; }
6244 0         0  
  0         0  
6245             # split scalar value
6246             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . e_string($1); next E_STRING_LOOP; }
6247 0         0  
  0         0  
6248 0         0 # split literal space
  0         0  
6249 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
6250 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6251 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6252 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6253 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6254 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
6255 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
6256 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6257 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6258 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6259 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6260 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
6261             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq {' '}; next E_STRING_LOOP; }
6262             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Eoldutf8::split' . $e . qq {" "}; next E_STRING_LOOP; }
6263              
6264 0 0       0 # split qq//
  0         0  
  0         0  
6265             elsif ($string =~ /\G \b (qq) \b /oxgc) {
6266 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
6267 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6268 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6269 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
6270 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  
6271 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  
6272 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  
6273 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  
6274             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
6275 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 * *
6276             }
6277             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6278             }
6279             }
6280              
6281 0 0       0 # split qr//
  0         0  
  0         0  
6282             elsif ($string =~ /\G \b (qr) \b /oxgc) {
6283 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
6284 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
6285 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6286 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
6287 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  
6288 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  
6289 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  
6290 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  
6291 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  
6292             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
6293 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 * *
6294             }
6295             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6296             }
6297             }
6298              
6299 0 0       0 # split q//
  0         0  
  0         0  
6300             elsif ($string =~ /\G \b (q) \b /oxgc) {
6301 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
6302 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6303 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6304 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
6305 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  
6306 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  
6307 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  
6308 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  
6309             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
6310 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 * *
6311             }
6312             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6313             }
6314             }
6315              
6316 0 0       0 # split m//
  0         0  
  0         0  
6317             elsif ($string =~ /\G \b (m) \b /oxgc) {
6318 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 # #
6319 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
6320 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6321 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
6322 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  
6323 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  
6324 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  
6325 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  
6326 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  
6327             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
6328 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 * *
6329             }
6330             die __FILE__, ": Search pattern not terminated\n";
6331             }
6332             }
6333              
6334 0         0 # split ''
6335 0         0 elsif ($string =~ /\G (\') /oxgc) {
6336 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
6337 0         0 while ($string !~ /\G \z/oxgc) {
6338 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
6339 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
6340             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
6341 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
6342             }
6343             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6344             }
6345              
6346 0         0 # split ""
6347 0         0 elsif ($string =~ /\G (\") /oxgc) {
6348 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
6349 0         0 while ($string !~ /\G \z/oxgc) {
6350 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
6351 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
6352             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
6353 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
6354             }
6355             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6356             }
6357              
6358 0         0 # split //
6359 0         0 elsif ($string =~ /\G (\/) /oxgc) {
6360 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
6361 0         0 while ($string !~ /\G \z/oxgc) {
6362 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
6363 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
6364             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
6365 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
6366             }
6367             die __FILE__, ": Search pattern not terminated\n";
6368             }
6369             }
6370              
6371 0         0 # qq//
6372 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
6373 0         0 my $ope = $1;
6374             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
6375             $e_string .= e_qq($ope,$1,$3,$2);
6376 0         0 }
6377 0         0 else {
6378 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
6379 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6380 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
6381 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
6382 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
6383 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
6384             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
6385 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
6386             }
6387             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6388             }
6389             }
6390              
6391 0         0 # qx//
6392 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
6393 0         0 my $ope = $1;
6394             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
6395             $e_string .= e_qq($ope,$1,$3,$2);
6396 0         0 }
6397 0         0 else {
6398 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6399 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6400 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
6401 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
6402 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
6403 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
6404 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
6405             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
6406 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
6407             }
6408             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6409             }
6410             }
6411              
6412 0         0 # q//
6413 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
6414 0         0 my $ope = $1;
6415             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
6416             $e_string .= e_q($ope,$1,$3,$2);
6417 0         0 }
6418 0         0 else {
6419 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
6420 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
6421 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
6422 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
6423 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
6424 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
6425             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
6426 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 * *
6427             }
6428             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6429             }
6430             }
6431 0         0  
6432             # ''
6433             elsif ($string =~ /\G (?
6434 12         40  
6435             # ""
6436             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
6437 6         23  
6438             # ``
6439             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
6440 0         0  
6441             # <<>> (a safer ARGV)
6442             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
6443 0         0  
6444             # <<= <=> <= < operator
6445             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
6446 0         0  
6447             #
6448             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
6449              
6450 0         0 # --- glob
6451             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
6452             $e_string .= 'Eoldutf8::glob("' . $1 . '")';
6453             }
6454              
6455 0         0 # << (bit shift) --- not here document
6456 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
6457             $slash = 'm//';
6458             $e_string .= $1;
6459             }
6460              
6461 0         0 # <<~'HEREDOC'
6462 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
6463 0         0 $slash = 'm//';
6464             my $here_quote = $1;
6465             my $delimiter = $2;
6466 0 0       0  
6467 0         0 # get here document
6468 0         0 if ($here_script eq '') {
6469             $here_script = CORE::substr $_, pos $_;
6470 0 0       0 $here_script =~ s/.*?\n//oxm;
6471 0         0 }
6472 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6473 0         0 my $heredoc = $1;
6474 0         0 my $indent = $2;
6475 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6476             push @heredoc, $heredoc . qq{\n$delimiter\n};
6477             push @heredoc_delimiter, qq{\\s*$delimiter};
6478 0         0 }
6479             else {
6480 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6481             }
6482             $e_string .= qq{<<'$delimiter'};
6483             }
6484              
6485 0         0 # <<~\HEREDOC
6486 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
6487 0         0 $slash = 'm//';
6488             my $here_quote = $1;
6489             my $delimiter = $2;
6490 0 0       0  
6491 0         0 # get here document
6492 0         0 if ($here_script eq '') {
6493             $here_script = CORE::substr $_, pos $_;
6494 0 0       0 $here_script =~ s/.*?\n//oxm;
6495 0         0 }
6496 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6497 0         0 my $heredoc = $1;
6498 0         0 my $indent = $2;
6499 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6500             push @heredoc, $heredoc . qq{\n$delimiter\n};
6501             push @heredoc_delimiter, qq{\\s*$delimiter};
6502 0         0 }
6503             else {
6504 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6505             }
6506             $e_string .= qq{<<\\$delimiter};
6507             }
6508              
6509 0         0 # <<~"HEREDOC"
6510 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
6511 0         0 $slash = 'm//';
6512             my $here_quote = $1;
6513             my $delimiter = $2;
6514 0 0       0  
6515 0         0 # get here document
6516 0         0 if ($here_script eq '') {
6517             $here_script = CORE::substr $_, pos $_;
6518 0 0       0 $here_script =~ s/.*?\n//oxm;
6519 0         0 }
6520 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6521 0         0 my $heredoc = $1;
6522 0         0 my $indent = $2;
6523 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6524             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
6525             push @heredoc_delimiter, qq{\\s*$delimiter};
6526 0         0 }
6527             else {
6528 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6529             }
6530             $e_string .= qq{<<"$delimiter"};
6531             }
6532              
6533 0         0 # <<~HEREDOC
6534 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
6535 0         0 $slash = 'm//';
6536             my $here_quote = $1;
6537             my $delimiter = $2;
6538 0 0       0  
6539 0         0 # get here document
6540 0         0 if ($here_script eq '') {
6541             $here_script = CORE::substr $_, pos $_;
6542 0 0       0 $here_script =~ s/.*?\n//oxm;
6543 0         0 }
6544 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6545 0         0 my $heredoc = $1;
6546 0         0 my $indent = $2;
6547 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6548             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
6549             push @heredoc_delimiter, qq{\\s*$delimiter};
6550 0         0 }
6551             else {
6552 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6553             }
6554             $e_string .= qq{<<$delimiter};
6555             }
6556              
6557 0         0 # <<~`HEREDOC`
6558 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
6559 0         0 $slash = 'm//';
6560             my $here_quote = $1;
6561             my $delimiter = $2;
6562 0 0       0  
6563 0         0 # get here document
6564 0         0 if ($here_script eq '') {
6565             $here_script = CORE::substr $_, pos $_;
6566 0 0       0 $here_script =~ s/.*?\n//oxm;
6567 0         0 }
6568 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
6569 0         0 my $heredoc = $1;
6570 0         0 my $indent = $2;
6571 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
6572             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
6573             push @heredoc_delimiter, qq{\\s*$delimiter};
6574 0         0 }
6575             else {
6576 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6577             }
6578             $e_string .= qq{<<`$delimiter`};
6579             }
6580              
6581 0         0 # <<'HEREDOC'
6582 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
6583 0         0 $slash = 'm//';
6584             my $here_quote = $1;
6585             my $delimiter = $2;
6586 0 0       0  
6587 0         0 # get here document
6588 0         0 if ($here_script eq '') {
6589             $here_script = CORE::substr $_, pos $_;
6590 0 0       0 $here_script =~ s/.*?\n//oxm;
6591 0         0 }
6592 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6593             push @heredoc, $1 . qq{\n$delimiter\n};
6594             push @heredoc_delimiter, $delimiter;
6595 0         0 }
6596             else {
6597 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6598             }
6599             $e_string .= $here_quote;
6600             }
6601              
6602 0         0 # <<\HEREDOC
6603 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
6604 0         0 $slash = 'm//';
6605             my $here_quote = $1;
6606             my $delimiter = $2;
6607 0 0       0  
6608 0         0 # get here document
6609 0         0 if ($here_script eq '') {
6610             $here_script = CORE::substr $_, pos $_;
6611 0 0       0 $here_script =~ s/.*?\n//oxm;
6612 0         0 }
6613 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6614             push @heredoc, $1 . qq{\n$delimiter\n};
6615             push @heredoc_delimiter, $delimiter;
6616 0         0 }
6617             else {
6618 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6619             }
6620             $e_string .= $here_quote;
6621             }
6622              
6623 0         0 # <<"HEREDOC"
6624 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
6625 0         0 $slash = 'm//';
6626             my $here_quote = $1;
6627             my $delimiter = $2;
6628 0 0       0  
6629 0         0 # get here document
6630 0         0 if ($here_script eq '') {
6631             $here_script = CORE::substr $_, pos $_;
6632 0 0       0 $here_script =~ s/.*?\n//oxm;
6633 0         0 }
6634 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6635             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
6636             push @heredoc_delimiter, $delimiter;
6637 0         0 }
6638             else {
6639 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6640             }
6641             $e_string .= $here_quote;
6642             }
6643              
6644 0         0 # <
6645 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
6646 0         0 $slash = 'm//';
6647             my $here_quote = $1;
6648             my $delimiter = $2;
6649 0 0       0  
6650 0         0 # get here document
6651 0         0 if ($here_script eq '') {
6652             $here_script = CORE::substr $_, pos $_;
6653 0 0       0 $here_script =~ s/.*?\n//oxm;
6654 0         0 }
6655 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6656             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
6657             push @heredoc_delimiter, $delimiter;
6658 0         0 }
6659             else {
6660 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6661             }
6662             $e_string .= $here_quote;
6663             }
6664              
6665 0         0 # <<`HEREDOC`
6666 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
6667 0         0 $slash = 'm//';
6668             my $here_quote = $1;
6669             my $delimiter = $2;
6670 0 0       0  
6671 0         0 # get here document
6672 0         0 if ($here_script eq '') {
6673             $here_script = CORE::substr $_, pos $_;
6674 0 0       0 $here_script =~ s/.*?\n//oxm;
6675 0         0 }
6676 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
6677             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
6678             push @heredoc_delimiter, $delimiter;
6679 0         0 }
6680             else {
6681 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
6682             }
6683             $e_string .= $here_quote;
6684             }
6685              
6686             # any operator before div
6687             elsif ($string =~ /\G (
6688             -- | \+\+ |
6689 0         0 [\)\}\]]
  40         71  
6690              
6691             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
6692              
6693             # yada-yada or triple-dot operator
6694             elsif ($string =~ /\G (
6695 40         122 \.\.\.
  0         0  
6696              
6697             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
6698              
6699             # any operator before m//
6700             elsif ($string =~ /\G ((?>
6701              
6702             !~~ | !~ | != | ! |
6703             %= | % |
6704             &&= | && | &= | &\.= | &\. | & |
6705             -= | -> | - |
6706             :(?>\s*)= |
6707             : |
6708             <<>> |
6709             <<= | <=> | <= | < |
6710             == | => | =~ | = |
6711             >>= | >> | >= | > |
6712             \*\*= | \*\* | \*= | \* |
6713             \+= | \+ |
6714             \.\. | \.= | \. |
6715             \/\/= | \/\/ |
6716             \/= | \/ |
6717             \? |
6718             \\ |
6719             \^= | \^\.= | \^\. | \^ |
6720             \b x= |
6721             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
6722             ~~ | ~\. | ~ |
6723             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
6724             \b(?: print )\b |
6725              
6726 0         0 [,;\(\{\[]
  50         102  
6727              
6728             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
6729 50         176  
6730             # other any character
6731             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
6732              
6733 181         730 # system error
6734             else {
6735             die __FILE__, ": Oops, this shouldn't happen!\n";
6736             }
6737 0         0 }
6738              
6739             return $e_string;
6740             }
6741              
6742             #
6743             # character class
6744 39     2935 0 132 #
6745             sub character_class {
6746 2935 100       5524 my($char,$modifier) = @_;
6747 2935 100       4982  
6748 115         236 if ($char eq '.') {
6749             if ($modifier =~ /s/) {
6750             return '${Eoldutf8::dot_s}';
6751 23         54 }
6752             else {
6753             return '${Eoldutf8::dot}';
6754             }
6755 92         191 }
6756             else {
6757             return Eoldutf8::classic_character_class($char);
6758             }
6759             }
6760              
6761             #
6762             # escape capture ($1, $2, $3, ...)
6763             #
6764 2820     469 0 5668 sub e_capture {
6765              
6766             return join '', '${', $_[0], '}';
6767             }
6768              
6769             #
6770             # escape transliteration (tr/// or y///)
6771 469     11 0 1774 #
6772 11         62 sub e_tr {
6773 11   100     27 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
6774             my $e_tr = '';
6775 11         33 $modifier ||= '';
6776              
6777             $slash = 'div';
6778 11         16  
6779             # quote character class 1
6780             $charclass = q_tr($charclass);
6781 11         19  
6782             # quote character class 2
6783             $charclass2 = q_tr($charclass2);
6784 11 50       23  
6785 11 0       29 # /b /B modifier
6786 0         0 if ($modifier =~ tr/bB//d) {
6787             if ($variable eq '') {
6788             $e_tr = qq{tr$charclass$e$charclass2$modifier};
6789 0         0 }
6790             else {
6791             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
6792             }
6793 0 100       0 }
6794 11         30 else {
6795             if ($variable eq '') {
6796             $e_tr = qq{Eoldutf8::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
6797 2         8 }
6798             else {
6799             $e_tr = qq{Eoldutf8::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
6800             }
6801             }
6802 9         30  
6803 11         16 # clear tr/// variable
6804             $tr_variable = '';
6805 11         15 $bind_operator = '';
6806              
6807             return $e_tr;
6808             }
6809              
6810             #
6811             # quote for escape transliteration (tr/// or y///)
6812 11     22 0 68 #
6813             sub q_tr {
6814             my($charclass) = @_;
6815 22 50       32  
    0          
    0          
    0          
    0          
    0          
6816 22         46 # quote character class
6817             if ($charclass !~ /'/oxms) {
6818             return e_q('', "'", "'", $charclass); # --> q' '
6819 22         31 }
6820             elsif ($charclass !~ /\//oxms) {
6821             return e_q('q', '/', '/', $charclass); # --> q/ /
6822 0         0 }
6823             elsif ($charclass !~ /\#/oxms) {
6824             return e_q('q', '#', '#', $charclass); # --> q# #
6825 0         0 }
6826             elsif ($charclass !~ /[\<\>]/oxms) {
6827             return e_q('q', '<', '>', $charclass); # --> q< >
6828 0         0 }
6829             elsif ($charclass !~ /[\(\)]/oxms) {
6830             return e_q('q', '(', ')', $charclass); # --> q( )
6831 0         0 }
6832             elsif ($charclass !~ /[\{\}]/oxms) {
6833             return e_q('q', '{', '}', $charclass); # --> q{ }
6834 0         0 }
6835 0 0       0 else {
6836 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6837             if ($charclass !~ /\Q$char\E/xms) {
6838             return e_q('q', $char, $char, $charclass);
6839             }
6840             }
6841 0         0 }
6842              
6843             return e_q('q', '{', '}', $charclass);
6844             }
6845              
6846             #
6847             # escape q string (q//, '')
6848 0     2150 0 0 #
6849             sub e_q {
6850 2150         15148 my($ope,$delimiter,$end_delimiter,$string) = @_;
6851              
6852 2150         3218 $slash = 'div';
6853              
6854             return join '', $ope, $delimiter, $string, $end_delimiter;
6855             }
6856              
6857             #
6858             # escape qq string (qq//, "", qx//, ``)
6859 2150     9533 0 11144 #
6860             sub e_qq {
6861 9533         21260 my($ope,$delimiter,$end_delimiter,$string) = @_;
6862              
6863 9533         13411 $slash = 'div';
6864 9533         13904  
6865             my $left_e = 0;
6866             my $right_e = 0;
6867 9533         11110  
6868             # split regexp
6869             my @char = $string =~ /\G((?>
6870             [^\x80-\xFF\\\$]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
6871             \\x\{ (?>[0-9A-Fa-f]+) \} |
6872             \\o\{ (?>[0-7]+) \} |
6873             \\N\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
6874             \\ $q_char |
6875             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6876             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6877             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6878             \$ (?>\s* [0-9]+) |
6879             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6880             \$ \$ (?![\w\{]) |
6881             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6882             $q_char
6883 9533         397237 ))/oxmsg;
6884              
6885             for (my $i=0; $i <= $#char; $i++) {
6886 9533 50 66     31071  
    50 33        
    100          
    100          
    50          
6887 226917         808714 # "\L\u" --> "\u\L"
6888             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6889             @char[$i,$i+1] = @char[$i+1,$i];
6890             }
6891              
6892 0         0 # "\U\l" --> "\l\U"
6893             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6894             @char[$i,$i+1] = @char[$i+1,$i];
6895             }
6896              
6897 0         0 # octal escape sequence
6898             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6899             $char[$i] = Eoldutf8::octchr($1);
6900             }
6901              
6902 1         4 # hexadecimal escape sequence
6903             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6904             $char[$i] = Eoldutf8::hexchr($1);
6905             }
6906              
6907 1         5 # \N{CHARNAME} --> N{CHARNAME}
6908             elsif ($char[$i] =~ /\A \\ ( N\{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
6909             $char[$i] = $1;
6910 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          
6911              
6912             if (0) {
6913             }
6914              
6915             # \F
6916             #
6917             # P.69 Table 2-6. Translation escapes
6918             # in Chapter 2: Bits and Pieces
6919             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6920             # (and so on)
6921 226917         1929279  
6922 0 50       0 # \u \l \U \L \F \Q \E
6923 602         1278 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
6924             if ($right_e < $left_e) {
6925             $char[$i] = '\\' . $char[$i];
6926             }
6927             }
6928             elsif ($char[$i] eq '\u') {
6929              
6930             # "STRING @{[ LIST EXPR ]} MORE STRING"
6931              
6932             # P.257 Other Tricks You Can Do with Hard References
6933             # in Chapter 8: References
6934             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6935              
6936             # P.353 Other Tricks You Can Do with Hard References
6937             # in Chapter 8: References
6938             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6939              
6940 0         0 # (and so on)
6941 0         0  
6942             $char[$i] = '@{[Eoldutf8::ucfirst qq<';
6943             $left_e++;
6944 0         0 }
6945 0         0 elsif ($char[$i] eq '\l') {
6946             $char[$i] = '@{[Eoldutf8::lcfirst qq<';
6947             $left_e++;
6948 0         0 }
6949 0         0 elsif ($char[$i] eq '\U') {
6950             $char[$i] = '@{[Eoldutf8::uc qq<';
6951             $left_e++;
6952 0         0 }
6953 6         12 elsif ($char[$i] eq '\L') {
6954             $char[$i] = '@{[Eoldutf8::lc qq<';
6955             $left_e++;
6956 6         11 }
6957 23         39 elsif ($char[$i] eq '\F') {
6958             $char[$i] = '@{[Eoldutf8::fc qq<';
6959             $left_e++;
6960 23         38 }
6961 0         0 elsif ($char[$i] eq '\Q') {
6962             $char[$i] = '@{[CORE::quotemeta qq<';
6963             $left_e++;
6964 0 50       0 }
6965 26         50 elsif ($char[$i] eq '\E') {
6966 26         33 if ($right_e < $left_e) {
6967             $char[$i] = '>]}';
6968             $right_e++;
6969 26         44 }
6970             else {
6971             $char[$i] = '';
6972             }
6973 0         0 }
6974 0 0       0 elsif ($char[$i] eq '\Q') {
6975 0         0 while (1) {
6976             if (++$i > $#char) {
6977 0 0       0 last;
6978 0         0 }
6979             if ($char[$i] eq '\E') {
6980             last;
6981             }
6982             }
6983             }
6984             elsif ($char[$i] eq '\E') {
6985             }
6986              
6987             # $0 --> $0
6988             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6989             }
6990             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6991             }
6992              
6993             # $$ --> $$
6994             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6995             }
6996              
6997             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6998 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6999             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7000             $char[$i] = e_capture($1);
7001 409         876 }
7002             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7003             $char[$i] = e_capture($1);
7004             }
7005              
7006 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7007             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7008             $char[$i] = e_capture($1.'->'.$2);
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_brace)*? \} ) \z/oxms) {
7013             $char[$i] = e_capture($1.'->'.$2);
7014             }
7015              
7016 0         0 # $$foo
7017             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7018             $char[$i] = e_capture($1);
7019             }
7020              
7021 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eoldutf8::PREMATCH()
7022             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7023             $char[$i] = '@{[Eoldutf8::PREMATCH()]}';
7024             }
7025              
7026 44         123 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eoldutf8::MATCH()
7027             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7028             $char[$i] = '@{[Eoldutf8::MATCH()]}';
7029             }
7030              
7031 45         120 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eoldutf8::POSTMATCH()
7032             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7033             $char[$i] = '@{[Eoldutf8::POSTMATCH()]}';
7034             }
7035              
7036             # ${ foo } --> ${ foo }
7037             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
7038             }
7039              
7040 33         96 # ${ ... }
7041             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7042             $char[$i] = e_capture($1);
7043             }
7044             }
7045 0 100       0  
7046 9533         16689 # return string
7047             if ($left_e > $right_e) {
7048 3         20 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
7049             }
7050             return join '', $ope, $delimiter, @char, $end_delimiter;
7051             }
7052              
7053             #
7054             # escape qw string (qw//)
7055 9530     34 0 79825 #
7056             sub e_qw {
7057 34         180 my($ope,$delimiter,$end_delimiter,$string) = @_;
7058              
7059             $slash = 'div';
7060 34         71  
  34         431  
7061 856 50       1254 # choice again delimiter
    0          
    0          
    0          
    0          
7062 34         268 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
7063             if (not $octet{$end_delimiter}) {
7064             return join '', $ope, $delimiter, $string, $end_delimiter;
7065 34         245 }
7066             elsif (not $octet{')'}) {
7067             return join '', $ope, '(', $string, ')';
7068 0         0 }
7069             elsif (not $octet{'}'}) {
7070             return join '', $ope, '{', $string, '}';
7071 0         0 }
7072             elsif (not $octet{']'}) {
7073             return join '', $ope, '[', $string, ']';
7074 0         0 }
7075             elsif (not $octet{'>'}) {
7076             return join '', $ope, '<', $string, '>';
7077 0         0 }
7078 0 0       0 else {
7079 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7080             if (not $octet{$char}) {
7081             return join '', $ope, $char, $string, $char;
7082             }
7083             }
7084             }
7085 0         0  
7086 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
7087 0         0 my @string = CORE::split(/\s+/, $string);
7088 0         0 for my $string (@string) {
7089 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
7090 0         0 for my $octet (@octet) {
7091             if ($octet =~ /\A (['\\]) \z/oxms) {
7092             $octet = '\\' . $1;
7093 0         0 }
7094             }
7095 0         0 $string = join '', @octet;
  0         0  
7096             }
7097             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
7098             }
7099              
7100             #
7101             # escape here document (<<"HEREDOC", <
7102 0     108 0 0 #
7103             sub e_heredoc {
7104 108         314 my($string) = @_;
7105              
7106 108         190 $slash = 'm//';
7107              
7108 108         380 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
7109 108         217  
7110             my $left_e = 0;
7111             my $right_e = 0;
7112 108         149  
7113             # split regexp
7114             my @char = $string =~ /\G((?>
7115             [^\x80-\xFF\\\$]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
7116             \\x\{ (?>[0-9A-Fa-f]+) \} |
7117             \\o\{ (?>[0-7]+) \} |
7118             \\N\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
7119             \\ $q_char |
7120             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7121             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7122             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7123             \$ (?>\s* [0-9]+) |
7124             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7125             \$ \$ (?![\w\{]) |
7126             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7127             $q_char
7128 108         12702 ))/oxmsg;
7129              
7130             for (my $i=0; $i <= $#char; $i++) {
7131 108 50 66     574  
    50 33        
    100          
    100          
    50          
7132 3383         10965 # "\L\u" --> "\u\L"
7133             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7134             @char[$i,$i+1] = @char[$i+1,$i];
7135             }
7136              
7137 0         0 # "\U\l" --> "\l\U"
7138             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7139             @char[$i,$i+1] = @char[$i+1,$i];
7140             }
7141              
7142 0         0 # octal escape sequence
7143             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7144             $char[$i] = Eoldutf8::octchr($1);
7145             }
7146              
7147 1         3 # hexadecimal escape sequence
7148             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7149             $char[$i] = Eoldutf8::hexchr($1);
7150             }
7151              
7152 1         4 # \N{CHARNAME} --> N{CHARNAME}
7153             elsif ($char[$i] =~ /\A \\ ( N\{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
7154             $char[$i] = $1;
7155 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          
7156              
7157             if (0) {
7158             }
7159 3383         32082  
7160 0 50       0 # \u \l \U \L \F \Q \E
7161 72         132 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7162             if ($right_e < $left_e) {
7163             $char[$i] = '\\' . $char[$i];
7164             }
7165 0         0 }
7166 0         0 elsif ($char[$i] eq '\u') {
7167             $char[$i] = '@{[Eoldutf8::ucfirst qq<';
7168             $left_e++;
7169 0         0 }
7170 0         0 elsif ($char[$i] eq '\l') {
7171             $char[$i] = '@{[Eoldutf8::lcfirst qq<';
7172             $left_e++;
7173 0         0 }
7174 0         0 elsif ($char[$i] eq '\U') {
7175             $char[$i] = '@{[Eoldutf8::uc qq<';
7176             $left_e++;
7177 0         0 }
7178 6         9 elsif ($char[$i] eq '\L') {
7179             $char[$i] = '@{[Eoldutf8::lc qq<';
7180             $left_e++;
7181 6         11 }
7182 0         0 elsif ($char[$i] eq '\F') {
7183             $char[$i] = '@{[Eoldutf8::fc qq<';
7184             $left_e++;
7185 0         0 }
7186 0         0 elsif ($char[$i] eq '\Q') {
7187             $char[$i] = '@{[CORE::quotemeta qq<';
7188             $left_e++;
7189 0 50       0 }
7190 3         7 elsif ($char[$i] eq '\E') {
7191 3         5 if ($right_e < $left_e) {
7192             $char[$i] = '>]}';
7193             $right_e++;
7194 3         7 }
7195             else {
7196             $char[$i] = '';
7197             }
7198 0         0 }
7199 0 0       0 elsif ($char[$i] eq '\Q') {
7200 0         0 while (1) {
7201             if (++$i > $#char) {
7202 0 0       0 last;
7203 0         0 }
7204             if ($char[$i] eq '\E') {
7205             last;
7206             }
7207             }
7208             }
7209             elsif ($char[$i] eq '\E') {
7210             }
7211              
7212             # $0 --> $0
7213             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7214             }
7215             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7216             }
7217              
7218             # $$ --> $$
7219             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7220             }
7221              
7222             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7223 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7224             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7225             $char[$i] = e_capture($1);
7226 0         0 }
7227             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7228             $char[$i] = e_capture($1);
7229             }
7230              
7231 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7232             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7233             $char[$i] = e_capture($1.'->'.$2);
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_brace)*? \} ) \z/oxms) {
7238             $char[$i] = e_capture($1.'->'.$2);
7239             }
7240              
7241 0         0 # $$foo
7242             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7243             $char[$i] = e_capture($1);
7244             }
7245              
7246 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eoldutf8::PREMATCH()
7247             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7248             $char[$i] = '@{[Eoldutf8::PREMATCH()]}';
7249             }
7250              
7251 8         49 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eoldutf8::MATCH()
7252             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7253             $char[$i] = '@{[Eoldutf8::MATCH()]}';
7254             }
7255              
7256 8         55 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eoldutf8::POSTMATCH()
7257             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7258             $char[$i] = '@{[Eoldutf8::POSTMATCH()]}';
7259             }
7260              
7261             # ${ foo } --> ${ foo }
7262             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
7263             }
7264              
7265 6         39 # ${ ... }
7266             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7267             $char[$i] = e_capture($1);
7268             }
7269             }
7270 0 100       0  
7271 108         251 # return string
7272             if ($left_e > $right_e) {
7273 3         24 return join '', @char, '>]}' x ($left_e - $right_e);
7274             }
7275             return join '', @char;
7276             }
7277              
7278             #
7279             # escape regexp (m//, qr//)
7280 105     1377 0 830 #
7281 1377   100     7463 sub e_qr {
7282             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7283 1377         5220 $modifier ||= '';
7284 1377 50       2756  
7285 1377         4826 $modifier =~ tr/p//d;
7286 0         0 if ($modifier =~ /([adlu])/oxms) {
7287 0 0       0 my $line = 0;
7288 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7289 0         0 if ($filename ne __FILE__) {
7290             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7291             last;
7292 0         0 }
7293             }
7294             die qq{Unsupported modifier "$1" used at line $line.\n};
7295 0         0 }
7296              
7297             $slash = 'div';
7298 1377 100       2571  
    100          
7299 1377         6084 # literal null string pattern
7300 8         9 if ($string eq '') {
7301 8         13 $modifier =~ tr/bB//d;
7302             $modifier =~ tr/i//d;
7303             return join '', $ope, $delimiter, $end_delimiter, $modifier;
7304             }
7305              
7306             # /b /B modifier
7307             elsif ($modifier =~ tr/bB//d) {
7308 8 50       41  
7309 25         68 # choice again delimiter
7310 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
7311 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
7312 0         0 my %octet = map {$_ => 1} @char;
7313 0         0 if (not $octet{')'}) {
7314             $delimiter = '(';
7315             $end_delimiter = ')';
7316 0         0 }
7317 0         0 elsif (not $octet{'}'}) {
7318             $delimiter = '{';
7319             $end_delimiter = '}';
7320 0         0 }
7321 0         0 elsif (not $octet{']'}) {
7322             $delimiter = '[';
7323             $end_delimiter = ']';
7324 0         0 }
7325 0         0 elsif (not $octet{'>'}) {
7326             $delimiter = '<';
7327             $end_delimiter = '>';
7328 0         0 }
7329 0 0       0 else {
7330 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7331 0         0 if (not $octet{$char}) {
7332 0         0 $delimiter = $char;
7333             $end_delimiter = $char;
7334             last;
7335             }
7336             }
7337             }
7338 0 100 100     0 }
7339 25         148  
7340             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
7341             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
7342 4         26 }
7343             else {
7344             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
7345             }
7346 21 100       151 }
7347 1344         3346  
7348             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7349             my $metachar = qr/[\@\\|[\]{^]/oxms;
7350 1344         6600  
7351             # split regexp
7352             my @char = $string =~ /\G((?>
7353             [^\x80-\xFF\\\$\@\[\(]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
7354             \\x (?>[0-9A-Fa-f]{1,2}) |
7355             \\ (?>[0-7]{2,3}) |
7356             \\c [\x40-\x5F] |
7357             \\x\{ (?>[0-9A-Fa-f]+) \} |
7358             \\o\{ (?>[0-7]+) \} |
7359             \\[bBNpP]\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
7360             \\ $q_char |
7361             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7362             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7363             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7364             [\$\@] $qq_variable |
7365             \$ (?>\s* [0-9]+) |
7366             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7367             \$ \$ (?![\w\{]) |
7368             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7369             \[\^ |
7370             \[\: (?>[a-z]+) :\] |
7371             \[\:\^ (?>[a-z]+) :\] |
7372             \(\? |
7373             $q_char
7374             ))/oxmsg;
7375 1344 50       182325  
7376 1344         6408 # choice again delimiter
  0         0  
7377 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
7378 0         0 my %octet = map {$_ => 1} @char;
7379 0         0 if (not $octet{')'}) {
7380             $delimiter = '(';
7381             $end_delimiter = ')';
7382 0         0 }
7383 0         0 elsif (not $octet{'}'}) {
7384             $delimiter = '{';
7385             $end_delimiter = '}';
7386 0         0 }
7387 0         0 elsif (not $octet{']'}) {
7388             $delimiter = '[';
7389             $end_delimiter = ']';
7390 0         0 }
7391 0         0 elsif (not $octet{'>'}) {
7392             $delimiter = '<';
7393             $end_delimiter = '>';
7394 0         0 }
7395 0 0       0 else {
7396 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7397 0         0 if (not $octet{$char}) {
7398 0         0 $delimiter = $char;
7399             $end_delimiter = $char;
7400             last;
7401             }
7402             }
7403             }
7404 0         0 }
7405 1344         2228  
7406 1344         1767 my $left_e = 0;
7407             my $right_e = 0;
7408             for (my $i=0; $i <= $#char; $i++) {
7409 1344 50 66     3793  
    50 66        
    100          
    100          
    100          
    100          
7410 3231         18982 # "\L\u" --> "\u\L"
7411             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7412             @char[$i,$i+1] = @char[$i+1,$i];
7413             }
7414              
7415 0         0 # "\U\l" --> "\l\U"
7416             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7417             @char[$i,$i+1] = @char[$i+1,$i];
7418             }
7419              
7420 0         0 # octal escape sequence
7421             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7422             $char[$i] = Eoldutf8::octchr($1);
7423             }
7424              
7425 1         4 # hexadecimal escape sequence
7426             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7427             $char[$i] = Eoldutf8::hexchr($1);
7428             }
7429              
7430             # \b{...} --> b\{...}
7431             # \B{...} --> B\{...}
7432             # \N{CHARNAME} --> N\{CHARNAME}
7433             # \p{PROPERTY} --> p\{PROPERTY}
7434 1         5 # \P{PROPERTY} --> P\{PROPERTY}
7435             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
7436             $char[$i] = $1 . '\\' . $2;
7437             }
7438              
7439 6         20 # \p, \P, \X --> p, P, X
7440             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7441             $char[$i] = $1;
7442 4 100 100     14 }
    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          
7443              
7444             if (0) {
7445             }
7446 3231         11925  
7447 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
7448 6         79 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7449             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)) {
7450             $char[$i] .= join '', splice @char, $i+1, 3;
7451 0         0 }
7452             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)) {
7453             $char[$i] .= join '', splice @char, $i+1, 2;
7454 0         0 }
7455             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)) {
7456             $char[$i] .= join '', splice @char, $i+1, 1;
7457             }
7458             }
7459              
7460 0         0 # open character class [...]
7461             elsif ($char[$i] eq '[') {
7462             my $left = $i;
7463              
7464             # [] make die "Unmatched [] in regexp ...\n"
7465 598 100       850 # (and so on)
7466 598         1540  
7467             if ($char[$i+1] eq ']') {
7468             $i++;
7469 3         5 }
7470 598 50       829  
7471 2607         4128 while (1) {
7472             if (++$i > $#char) {
7473 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7474 2607         4445 }
7475             if ($char[$i] eq ']') {
7476             my $right = $i;
7477 598 100       1035  
7478 598         3482 # [...]
  90         235  
7479             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7480             splice @char, $left, $right-$left+1, sprintf(q{@{[Eoldutf8::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7481 270         451 }
7482             else {
7483             splice @char, $left, $right-$left+1, Eoldutf8::charlist_qr(@char[$left+1..$right-1], $modifier);
7484 508         2311 }
7485 598         1194  
7486             $i = $left;
7487             last;
7488             }
7489             }
7490             }
7491              
7492 598         3900 # open character class [^...]
7493             elsif ($char[$i] eq '[^') {
7494             my $left = $i;
7495              
7496             # [^] make die "Unmatched [] in regexp ...\n"
7497 328 100       585 # (and so on)
7498 328         769  
7499             if ($char[$i+1] eq ']') {
7500             $i++;
7501 5         10 }
7502 328 50       437  
7503 1447         2128 while (1) {
7504             if (++$i > $#char) {
7505 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7506 1447         2301 }
7507             if ($char[$i] eq ']') {
7508             my $right = $i;
7509 328 100       399  
7510 328         1595 # [^...]
  90         197  
7511             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7512             splice @char, $left, $right-$left+1, sprintf(q{@{[Eoldutf8::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7513 270         452 }
7514             else {
7515             splice @char, $left, $right-$left+1, Eoldutf8::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7516 238         886 }
7517 328         1709  
7518             $i = $left;
7519             last;
7520             }
7521             }
7522             }
7523              
7524 328         990 # rewrite character class or escape character
7525             elsif (my $char = character_class($char[$i],$modifier)) {
7526             $char[$i] = $char;
7527             }
7528              
7529 215 50       627 # /i modifier
7530 44         81 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eoldutf8::uc($char[$i]) ne Eoldutf8::fc($char[$i]))) {
7531             if (CORE::length(Eoldutf8::fc($char[$i])) == 1) {
7532             $char[$i] = '[' . Eoldutf8::uc($char[$i]) . Eoldutf8::fc($char[$i]) . ']';
7533 44         92 }
7534             else {
7535             $char[$i] = '(?:' . Eoldutf8::uc($char[$i]) . '|' . Eoldutf8::fc($char[$i]) . ')';
7536             }
7537             }
7538              
7539 0 50       0 # \u \l \U \L \F \Q \E
7540 1         4 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
7541             if ($right_e < $left_e) {
7542             $char[$i] = '\\' . $char[$i];
7543             }
7544 0         0 }
7545 0         0 elsif ($char[$i] eq '\u') {
7546             $char[$i] = '@{[Eoldutf8::ucfirst qq<';
7547             $left_e++;
7548 0         0 }
7549 0         0 elsif ($char[$i] eq '\l') {
7550             $char[$i] = '@{[Eoldutf8::lcfirst qq<';
7551             $left_e++;
7552 0         0 }
7553 1         3 elsif ($char[$i] eq '\U') {
7554             $char[$i] = '@{[Eoldutf8::uc qq<';
7555             $left_e++;
7556 1         3 }
7557 1         3 elsif ($char[$i] eq '\L') {
7558             $char[$i] = '@{[Eoldutf8::lc qq<';
7559             $left_e++;
7560 1         3 }
7561 16         26 elsif ($char[$i] eq '\F') {
7562             $char[$i] = '@{[Eoldutf8::fc qq<';
7563             $left_e++;
7564 16         35 }
7565 20         36 elsif ($char[$i] eq '\Q') {
7566             $char[$i] = '@{[CORE::quotemeta qq<';
7567             $left_e++;
7568 20 50       45 }
7569 38         78 elsif ($char[$i] eq '\E') {
7570 38         63 if ($right_e < $left_e) {
7571             $char[$i] = '>]}';
7572             $right_e++;
7573 38         82 }
7574             else {
7575             $char[$i] = '';
7576             }
7577 0         0 }
7578 0 0       0 elsif ($char[$i] eq '\Q') {
7579 0         0 while (1) {
7580             if (++$i > $#char) {
7581 0 0       0 last;
7582 0         0 }
7583             if ($char[$i] eq '\E') {
7584             last;
7585             }
7586             }
7587             }
7588             elsif ($char[$i] eq '\E') {
7589             }
7590              
7591 0 0       0 # $0 --> $0
7592 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7593             if ($ignorecase) {
7594             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7595             }
7596 0 0       0 }
7597 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7598             if ($ignorecase) {
7599             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7600             }
7601             }
7602              
7603             # $$ --> $$
7604             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7605             }
7606              
7607             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7608 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7609 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7610 0         0 $char[$i] = e_capture($1);
7611             if ($ignorecase) {
7612             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7613             }
7614 0         0 }
7615 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7616 0         0 $char[$i] = e_capture($1);
7617             if ($ignorecase) {
7618             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7619             }
7620             }
7621              
7622 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7623 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) {
7624 0         0 $char[$i] = e_capture($1.'->'.$2);
7625             if ($ignorecase) {
7626             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7627             }
7628             }
7629              
7630 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7631 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) {
7632 0         0 $char[$i] = e_capture($1.'->'.$2);
7633             if ($ignorecase) {
7634             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7635             }
7636             }
7637              
7638 0         0 # $$foo
7639 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7640 0         0 $char[$i] = e_capture($1);
7641             if ($ignorecase) {
7642             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7643             }
7644             }
7645              
7646 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eoldutf8::PREMATCH()
7647 8         149 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7648             if ($ignorecase) {
7649             $char[$i] = '@{[Eoldutf8::ignorecase(Eoldutf8::PREMATCH())]}';
7650 0         0 }
7651             else {
7652             $char[$i] = '@{[Eoldutf8::PREMATCH()]}';
7653             }
7654             }
7655              
7656 8 50       31 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eoldutf8::MATCH()
7657 8         157 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7658             if ($ignorecase) {
7659             $char[$i] = '@{[Eoldutf8::ignorecase(Eoldutf8::MATCH())]}';
7660 0         0 }
7661             else {
7662             $char[$i] = '@{[Eoldutf8::MATCH()]}';
7663             }
7664             }
7665              
7666 8 50       30 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eoldutf8::POSTMATCH()
7667 6         83 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7668             if ($ignorecase) {
7669             $char[$i] = '@{[Eoldutf8::ignorecase(Eoldutf8::POSTMATCH())]}';
7670 0         0 }
7671             else {
7672             $char[$i] = '@{[Eoldutf8::POSTMATCH()]}';
7673             }
7674             }
7675              
7676 6 0       21 # ${ foo }
7677 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) {
7678             if ($ignorecase) {
7679             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7680             }
7681             }
7682              
7683 0         0 # ${ ... }
7684 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7685 0         0 $char[$i] = e_capture($1);
7686             if ($ignorecase) {
7687             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7688             }
7689             }
7690              
7691 0         0 # $scalar or @array
7692 42 100       155 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7693 42         129 $char[$i] = e_string($char[$i]);
7694             if ($ignorecase) {
7695             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
7696             }
7697             }
7698              
7699 9 100 66     27 # quote character before ? + * {
    50          
7700             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7701             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7702 188         1439 }
7703 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
7704 0         0 my $char = $char[$i-1];
7705             if ($char[$i] eq '{') {
7706             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
7707 0         0 }
7708             else {
7709             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
7710             }
7711 0         0 }
7712             else {
7713             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7714             }
7715             }
7716             }
7717 187         728  
7718 1344 50       2665 # make regexp string
7719 1344 0 0     3108 $modifier =~ tr/i//d;
7720 0         0 if ($left_e > $right_e) {
7721             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
7722             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
7723 0         0 }
7724             else {
7725             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
7726 0 100 100     0 }
7727 1344         9143 }
7728             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
7729             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
7730 32         418 }
7731             else {
7732             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
7733             }
7734             }
7735              
7736             #
7737             # double quote stuff
7738 1312     540 0 12275 #
7739             sub qq_stuff {
7740             my($delimiter,$end_delimiter,$stuff) = @_;
7741 540 100       899  
7742 540         1091 # scalar variable or array variable
7743             if ($stuff =~ /\A [\$\@] /oxms) {
7744             return $stuff;
7745             }
7746 300         1481  
  240         685  
7747 320         851 # quote by delimiter
7748 240 50       604 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
7749 240 50       460 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7750 240 50       377 next if $char eq $delimiter;
7751 240         427 next if $char eq $end_delimiter;
7752             if (not $octet{$char}) {
7753             return join '', 'qq', $char, $stuff, $char;
7754 240         1186 }
7755             }
7756             return join '', 'qq', '<', $stuff, '>';
7757             }
7758              
7759             #
7760             # escape regexp (m'', qr'', and m''b, qr''b)
7761 0     15 0 0 #
7762 15   100     76 sub e_qr_q {
7763             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7764 15         69 $modifier ||= '';
7765 15 50       28  
7766 15         39 $modifier =~ tr/p//d;
7767 0         0 if ($modifier =~ /([adlu])/oxms) {
7768 0 0       0 my $line = 0;
7769 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7770 0         0 if ($filename ne __FILE__) {
7771             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7772             last;
7773 0         0 }
7774             }
7775             die qq{Unsupported modifier "$1" used at line $line.\n};
7776 0         0 }
7777              
7778             $slash = 'div';
7779 15 100       24  
    100          
7780 15         87 # literal null string pattern
7781 8         10 if ($string eq '') {
7782 8         12 $modifier =~ tr/bB//d;
7783             $modifier =~ tr/i//d;
7784             return join '', $ope, $delimiter, $end_delimiter, $modifier;
7785             }
7786              
7787 8         41 # with /b /B modifier
7788             elsif ($modifier =~ tr/bB//d) {
7789             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
7790             }
7791              
7792 3         13 # without /b /B modifier
7793             else {
7794             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
7795             }
7796             }
7797              
7798             #
7799             # escape regexp (m'', qr'')
7800 4     4 0 16 #
7801             sub e_qr_qt {
7802 4 50       16 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7803              
7804             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7805 4         11  
7806             # split regexp
7807             my @char = $string =~ /\G((?>
7808             [^\x80-\xFF\\\[\$\@\/] |
7809             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
7810             \[\^ |
7811             \[\: (?>[a-z]+) \:\] |
7812             \[\:\^ (?>[a-z]+) \:\] |
7813             [\$\@\/] |
7814             \\ (?:$q_char) |
7815             (?:$q_char)
7816             ))/oxmsg;
7817 4         300  
7818 4 50 33     30 # unescape character
    50 33        
    50 66        
    50          
    50          
    50          
7819             for (my $i=0; $i <= $#char; $i++) {
7820             if (0) {
7821             }
7822 5         37  
7823 0         0 # open character class [...]
7824 0 0       0 elsif ($char[$i] eq '[') {
7825 0         0 my $left = $i;
7826             if ($char[$i+1] eq ']') {
7827 0         0 $i++;
7828 0 0       0 }
7829 0         0 while (1) {
7830             if (++$i > $#char) {
7831 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7832 0         0 }
7833             if ($char[$i] eq ']') {
7834             my $right = $i;
7835 0         0  
7836             # [...]
7837 0         0 splice @char, $left, $right-$left+1, Eoldutf8::charlist_qr(@char[$left+1..$right-1], $modifier);
7838 0         0  
7839             $i = $left;
7840             last;
7841             }
7842             }
7843             }
7844              
7845 0         0 # open character class [^...]
7846 0 0       0 elsif ($char[$i] eq '[^') {
7847 0         0 my $left = $i;
7848             if ($char[$i+1] eq ']') {
7849 0         0 $i++;
7850 0 0       0 }
7851 0         0 while (1) {
7852             if (++$i > $#char) {
7853 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7854 0         0 }
7855             if ($char[$i] eq ']') {
7856             my $right = $i;
7857 0         0  
7858             # [^...]
7859 0         0 splice @char, $left, $right-$left+1, Eoldutf8::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7860 0         0  
7861             $i = $left;
7862             last;
7863             }
7864             }
7865             }
7866              
7867 0         0 # escape $ @ / and \
7868             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7869             $char[$i] = '\\' . $char[$i];
7870             }
7871              
7872 0         0 # rewrite character class or escape character
7873             elsif (my $char = character_class($char[$i],$modifier)) {
7874             $char[$i] = $char;
7875             }
7876              
7877 0 0       0 # /i modifier
7878 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eoldutf8::uc($char[$i]) ne Eoldutf8::fc($char[$i]))) {
7879             if (CORE::length(Eoldutf8::fc($char[$i])) == 1) {
7880             $char[$i] = '[' . Eoldutf8::uc($char[$i]) . Eoldutf8::fc($char[$i]) . ']';
7881 0         0 }
7882             else {
7883             $char[$i] = '(?:' . Eoldutf8::uc($char[$i]) . '|' . Eoldutf8::fc($char[$i]) . ')';
7884             }
7885             }
7886              
7887 0 0       0 # quote character before ? + * {
7888             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7889             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7890 0         0 }
7891             else {
7892             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7893             }
7894             }
7895 0         0 }
7896 4         14  
7897             $delimiter = '/';
7898 4         8 $end_delimiter = '/';
7899 4         7  
7900             $modifier =~ tr/i//d;
7901             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
7902             }
7903              
7904             #
7905             # escape regexp (m''b, qr''b)
7906 4     3 0 42 #
7907             sub e_qr_qb {
7908             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7909 3         8  
7910             # split regexp
7911             my @char = $string =~ /\G ((?>[^\\]|\\\\|[\x00-\xFF])) /oxmsg;
7912 3         15  
7913 3 50       11 # unescape character
    50          
7914             for (my $i=0; $i <= $#char; $i++) {
7915             if (0) {
7916             }
7917 9         31  
7918             # remain \\
7919             elsif ($char[$i] eq '\\\\') {
7920             }
7921              
7922 0         0 # escape $ @ / and \
7923             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7924             $char[$i] = '\\' . $char[$i];
7925             }
7926 0         0 }
7927 3         5  
7928 3         5 $delimiter = '/';
7929             $end_delimiter = '/';
7930             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
7931             }
7932              
7933             #
7934             # escape regexp (s/here//)
7935 3     110 0 19 #
7936 110   100     379 sub e_s1 {
7937             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7938 110         474 $modifier ||= '';
7939 110 50       187  
7940 110         335 $modifier =~ tr/p//d;
7941 0         0 if ($modifier =~ /([adlu])/oxms) {
7942 0 0       0 my $line = 0;
7943 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7944 0         0 if ($filename ne __FILE__) {
7945             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7946             last;
7947 0         0 }
7948             }
7949             die qq{Unsupported modifier "$1" used at line $line.\n};
7950 0         0 }
7951              
7952             $slash = 'div';
7953 110 100       241  
    100          
7954 110         486 # literal null string pattern
7955 8         10 if ($string eq '') {
7956 8         11 $modifier =~ tr/bB//d;
7957             $modifier =~ tr/i//d;
7958             return join '', $ope, $delimiter, $end_delimiter, $modifier;
7959             }
7960              
7961             # /b /B modifier
7962             elsif ($modifier =~ tr/bB//d) {
7963 8 50       79  
7964 1         3 # choice again delimiter
7965 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
7966 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
7967 0         0 my %octet = map {$_ => 1} @char;
7968 0         0 if (not $octet{')'}) {
7969             $delimiter = '(';
7970             $end_delimiter = ')';
7971 0         0 }
7972 0         0 elsif (not $octet{'}'}) {
7973             $delimiter = '{';
7974             $end_delimiter = '}';
7975 0         0 }
7976 0         0 elsif (not $octet{']'}) {
7977             $delimiter = '[';
7978             $end_delimiter = ']';
7979 0         0 }
7980 0         0 elsif (not $octet{'>'}) {
7981             $delimiter = '<';
7982             $end_delimiter = '>';
7983 0         0 }
7984 0 0       0 else {
7985 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7986 0         0 if (not $octet{$char}) {
7987 0         0 $delimiter = $char;
7988             $end_delimiter = $char;
7989             last;
7990             }
7991             }
7992             }
7993 0         0 }
7994 1         2  
7995             my $prematch = '';
7996             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
7997 1 100       11 }
7998 101         299  
7999             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
8000             my $metachar = qr/[\@\\|[\]{^]/oxms;
8001 101         666  
8002             # split regexp
8003             my @char = $string =~ /\G((?>
8004             [^\x80-\xFF\\\$\@\[\(]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
8005             \\ (?>[1-9][0-9]*) |
8006             \\g (?>\s*) (?>[1-9][0-9]*) |
8007             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
8008             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
8009             \\x (?>[0-9A-Fa-f]{1,2}) |
8010             \\ (?>[0-7]{2,3}) |
8011             \\c [\x40-\x5F] |
8012             \\x\{ (?>[0-9A-Fa-f]+) \} |
8013             \\o\{ (?>[0-7]+) \} |
8014             \\[bBNpP]\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
8015             \\ $q_char |
8016             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
8017             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
8018             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
8019             [\$\@] $qq_variable |
8020             \$ (?>\s* [0-9]+) |
8021             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
8022             \$ \$ (?![\w\{]) |
8023             \$ (?>\s*) \$ (?>\s*) $qq_variable |
8024             \[\^ |
8025             \[\: (?>[a-z]+) :\] |
8026             \[\:\^ (?>[a-z]+) :\] |
8027             \(\? |
8028             $q_char
8029             ))/oxmsg;
8030 101 50       63452  
8031 101         1294 # choice again delimiter
  0         0  
8032 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
8033 0         0 my %octet = map {$_ => 1} @char;
8034 0         0 if (not $octet{')'}) {
8035             $delimiter = '(';
8036             $end_delimiter = ')';
8037 0         0 }
8038 0         0 elsif (not $octet{'}'}) {
8039             $delimiter = '{';
8040             $end_delimiter = '}';
8041 0         0 }
8042 0         0 elsif (not $octet{']'}) {
8043             $delimiter = '[';
8044             $end_delimiter = ']';
8045 0         0 }
8046 0         0 elsif (not $octet{'>'}) {
8047             $delimiter = '<';
8048             $end_delimiter = '>';
8049 0         0 }
8050 0 0       0 else {
8051 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
8052 0         0 if (not $octet{$char}) {
8053 0         0 $delimiter = $char;
8054             $end_delimiter = $char;
8055             last;
8056             }
8057             }
8058             }
8059             }
8060 0         0  
  101         243  
8061             # count '('
8062 425         776 my $parens = grep { $_ eq '(' } @char;
8063 101         179  
8064 101         214 my $left_e = 0;
8065             my $right_e = 0;
8066             for (my $i=0; $i <= $#char; $i++) {
8067 101 50 33     341  
    50 33        
    100          
    100          
    50          
    50          
8068 346         2103 # "\L\u" --> "\u\L"
8069             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
8070             @char[$i,$i+1] = @char[$i+1,$i];
8071             }
8072              
8073 0         0 # "\U\l" --> "\l\U"
8074             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
8075             @char[$i,$i+1] = @char[$i+1,$i];
8076             }
8077              
8078 0         0 # octal escape sequence
8079             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
8080             $char[$i] = Eoldutf8::octchr($1);
8081             }
8082              
8083 1         3 # hexadecimal escape sequence
8084             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
8085             $char[$i] = Eoldutf8::hexchr($1);
8086             }
8087              
8088             # \b{...} --> b\{...}
8089             # \B{...} --> B\{...}
8090             # \N{CHARNAME} --> N\{CHARNAME}
8091             # \p{PROPERTY} --> p\{PROPERTY}
8092 1         5 # \P{PROPERTY} --> P\{PROPERTY}
8093             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
8094             $char[$i] = $1 . '\\' . $2;
8095             }
8096              
8097 0         0 # \p, \P, \X --> p, P, X
8098             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
8099             $char[$i] = $1;
8100 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          
8101              
8102             if (0) {
8103             }
8104 346         1357  
8105 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
8106 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
8107             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)) {
8108             $char[$i] .= join '', splice @char, $i+1, 3;
8109 0         0 }
8110             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)) {
8111             $char[$i] .= join '', splice @char, $i+1, 2;
8112 0         0 }
8113             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)) {
8114             $char[$i] .= join '', splice @char, $i+1, 1;
8115             }
8116             }
8117              
8118 0         0 # open character class [...]
8119 20 50       34 elsif ($char[$i] eq '[') {
8120 20         80 my $left = $i;
8121             if ($char[$i+1] eq ']') {
8122 0         0 $i++;
8123 20 50       41 }
8124 79         133 while (1) {
8125             if (++$i > $#char) {
8126 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
8127 79         243 }
8128             if ($char[$i] eq ']') {
8129             my $right = $i;
8130 20 50       42  
8131 20         133 # [...]
  0         0  
8132             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8133             splice @char, $left, $right-$left+1, sprintf(q{@{[Eoldutf8::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8134 0         0 }
8135             else {
8136             splice @char, $left, $right-$left+1, Eoldutf8::charlist_qr(@char[$left+1..$right-1], $modifier);
8137 20         97 }
8138 20         40  
8139             $i = $left;
8140             last;
8141             }
8142             }
8143             }
8144              
8145 20         55 # open character class [^...]
8146 0 0       0 elsif ($char[$i] eq '[^') {
8147 0         0 my $left = $i;
8148             if ($char[$i+1] eq ']') {
8149 0         0 $i++;
8150 0 0       0 }
8151 0         0 while (1) {
8152             if (++$i > $#char) {
8153 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
8154 0         0 }
8155             if ($char[$i] eq ']') {
8156             my $right = $i;
8157 0 0       0  
8158 0         0 # [^...]
  0         0  
8159             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8160             splice @char, $left, $right-$left+1, sprintf(q{@{[Eoldutf8::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8161 0         0 }
8162             else {
8163             splice @char, $left, $right-$left+1, Eoldutf8::charlist_not_qr(@char[$left+1..$right-1], $modifier);
8164 0         0 }
8165 0         0  
8166             $i = $left;
8167             last;
8168             }
8169             }
8170             }
8171              
8172 0         0 # rewrite character class or escape character
8173             elsif (my $char = character_class($char[$i],$modifier)) {
8174             $char[$i] = $char;
8175             }
8176              
8177 11 50       29 # /i modifier
8178 3         6 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eoldutf8::uc($char[$i]) ne Eoldutf8::fc($char[$i]))) {
8179             if (CORE::length(Eoldutf8::fc($char[$i])) == 1) {
8180             $char[$i] = '[' . Eoldutf8::uc($char[$i]) . Eoldutf8::fc($char[$i]) . ']';
8181 3         5 }
8182             else {
8183             $char[$i] = '(?:' . Eoldutf8::uc($char[$i]) . '|' . Eoldutf8::fc($char[$i]) . ')';
8184             }
8185             }
8186              
8187 0 50       0 # \u \l \U \L \F \Q \E
8188 8         25 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
8189             if ($right_e < $left_e) {
8190             $char[$i] = '\\' . $char[$i];
8191             }
8192 0         0 }
8193 0         0 elsif ($char[$i] eq '\u') {
8194             $char[$i] = '@{[Eoldutf8::ucfirst qq<';
8195             $left_e++;
8196 0         0 }
8197 0         0 elsif ($char[$i] eq '\l') {
8198             $char[$i] = '@{[Eoldutf8::lcfirst qq<';
8199             $left_e++;
8200 0         0 }
8201 0         0 elsif ($char[$i] eq '\U') {
8202             $char[$i] = '@{[Eoldutf8::uc qq<';
8203             $left_e++;
8204 0         0 }
8205 0         0 elsif ($char[$i] eq '\L') {
8206             $char[$i] = '@{[Eoldutf8::lc qq<';
8207             $left_e++;
8208 0         0 }
8209 0         0 elsif ($char[$i] eq '\F') {
8210             $char[$i] = '@{[Eoldutf8::fc qq<';
8211             $left_e++;
8212 0         0 }
8213 5         9 elsif ($char[$i] eq '\Q') {
8214             $char[$i] = '@{[CORE::quotemeta qq<';
8215             $left_e++;
8216 5 50       9 }
8217 5         10 elsif ($char[$i] eq '\E') {
8218 5         8 if ($right_e < $left_e) {
8219             $char[$i] = '>]}';
8220             $right_e++;
8221 5         8 }
8222             else {
8223             $char[$i] = '';
8224             }
8225 0         0 }
8226 0 0       0 elsif ($char[$i] eq '\Q') {
8227 0         0 while (1) {
8228             if (++$i > $#char) {
8229 0 0       0 last;
8230 0         0 }
8231             if ($char[$i] eq '\E') {
8232             last;
8233             }
8234             }
8235             }
8236             elsif ($char[$i] eq '\E') {
8237             }
8238              
8239             # \0 --> \0
8240             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
8241             }
8242              
8243             # \g{N}, \g{-N}
8244              
8245             # P.108 Using Simple Patterns
8246             # in Chapter 7: In the World of Regular Expressions
8247             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
8248              
8249             # P.221 Capturing
8250             # in Chapter 5: Pattern Matching
8251             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
8252              
8253             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
8254             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
8255             }
8256              
8257             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
8258             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
8259             }
8260              
8261             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
8262             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
8263             }
8264              
8265             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
8266             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
8267             }
8268              
8269 0 0       0 # $0 --> $0
8270 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
8271             if ($ignorecase) {
8272             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8273             }
8274 0 0       0 }
8275 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
8276             if ($ignorecase) {
8277             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8278             }
8279             }
8280              
8281             # $$ --> $$
8282             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
8283             }
8284              
8285             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
8286 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
8287 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
8288 0         0 $char[$i] = e_capture($1);
8289             if ($ignorecase) {
8290             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8291             }
8292 0         0 }
8293 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
8294 0         0 $char[$i] = e_capture($1);
8295             if ($ignorecase) {
8296             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8297             }
8298             }
8299              
8300 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
8301 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) {
8302 0         0 $char[$i] = e_capture($1.'->'.$2);
8303             if ($ignorecase) {
8304             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8305             }
8306             }
8307              
8308 0         0 # $$foo{ ... } --> $ $foo->{ ... }
8309 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) {
8310 0         0 $char[$i] = e_capture($1.'->'.$2);
8311             if ($ignorecase) {
8312             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8313             }
8314             }
8315              
8316 0         0 # $$foo
8317 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
8318 0         0 $char[$i] = e_capture($1);
8319             if ($ignorecase) {
8320             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8321             }
8322             }
8323              
8324 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eoldutf8::PREMATCH()
8325 4         16 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
8326             if ($ignorecase) {
8327             $char[$i] = '@{[Eoldutf8::ignorecase(Eoldutf8::PREMATCH())]}';
8328 0         0 }
8329             else {
8330             $char[$i] = '@{[Eoldutf8::PREMATCH()]}';
8331             }
8332             }
8333              
8334 4 50       16 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eoldutf8::MATCH()
8335 4         15 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
8336             if ($ignorecase) {
8337             $char[$i] = '@{[Eoldutf8::ignorecase(Eoldutf8::MATCH())]}';
8338 0         0 }
8339             else {
8340             $char[$i] = '@{[Eoldutf8::MATCH()]}';
8341             }
8342             }
8343              
8344 4 50       15 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eoldutf8::POSTMATCH()
8345 3         11 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
8346             if ($ignorecase) {
8347             $char[$i] = '@{[Eoldutf8::ignorecase(Eoldutf8::POSTMATCH())]}';
8348 0         0 }
8349             else {
8350             $char[$i] = '@{[Eoldutf8::POSTMATCH()]}';
8351             }
8352             }
8353              
8354 3 0       11 # ${ foo }
8355 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) {
8356             if ($ignorecase) {
8357             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8358             }
8359             }
8360              
8361 0         0 # ${ ... }
8362 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
8363 0         0 $char[$i] = e_capture($1);
8364             if ($ignorecase) {
8365             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8366             }
8367             }
8368              
8369 0         0 # $scalar or @array
8370 9 50       36 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
8371 9         45 $char[$i] = e_string($char[$i]);
8372             if ($ignorecase) {
8373             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
8374             }
8375             }
8376              
8377 0 50       0 # quote character before ? + * {
8378             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
8379             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
8380 23         139 }
8381             else {
8382             $char[$i-1] = '(?:' . $char[$i-1] . ')';
8383             }
8384             }
8385             }
8386 23         128  
8387 101         262 # make regexp string
8388 101 50       188 my $prematch = '';
8389 101         311 $modifier =~ tr/i//d;
8390             if ($left_e > $right_e) {
8391 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
8392             }
8393             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
8394             }
8395              
8396             #
8397             # escape regexp (s'here'' or s'here''b)
8398 101     22 0 1619 #
8399 22   100     58 sub e_s1_q {
8400             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8401 22         89 $modifier ||= '';
8402 22 50       32  
8403 22         52 $modifier =~ tr/p//d;
8404 0         0 if ($modifier =~ /([adlu])/oxms) {
8405 0 0       0 my $line = 0;
8406 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
8407 0         0 if ($filename ne __FILE__) {
8408             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
8409             last;
8410 0         0 }
8411             }
8412             die qq{Unsupported modifier "$1" used at line $line.\n};
8413 0         0 }
8414              
8415             $slash = 'div';
8416 22 100       41  
    100          
8417 22         76 # literal null string pattern
8418 8         9 if ($string eq '') {
8419 8         9 $modifier =~ tr/bB//d;
8420             $modifier =~ tr/i//d;
8421             return join '', $ope, $delimiter, $end_delimiter, $modifier;
8422             }
8423              
8424 8         48 # with /b /B modifier
8425             elsif ($modifier =~ tr/bB//d) {
8426             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
8427             }
8428              
8429 1         4 # without /b /B modifier
8430             else {
8431             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
8432             }
8433             }
8434              
8435             #
8436             # escape regexp (s'here'')
8437 13     13 0 35 #
8438             sub e_s1_qt {
8439 13 50       38 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8440              
8441             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
8442 13         30  
8443             # split regexp
8444             my @char = $string =~ /\G((?>
8445             [^\x80-\xFF\\\[\$\@\/] |
8446             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
8447             \[\^ |
8448             \[\: (?>[a-z]+) \:\] |
8449             \[\:\^ (?>[a-z]+) \:\] |
8450             [\$\@\/] |
8451             \\ (?:$q_char) |
8452             (?:$q_char)
8453             ))/oxmsg;
8454 13         316  
8455 13 50 33     57 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
8456             for (my $i=0; $i <= $#char; $i++) {
8457             if (0) {
8458             }
8459 25         577  
8460 0         0 # open character class [...]
8461 0 0       0 elsif ($char[$i] eq '[') {
8462 0         0 my $left = $i;
8463             if ($char[$i+1] eq ']') {
8464 0         0 $i++;
8465 0 0       0 }
8466 0         0 while (1) {
8467             if (++$i > $#char) {
8468 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
8469 0         0 }
8470             if ($char[$i] eq ']') {
8471             my $right = $i;
8472 0         0  
8473             # [...]
8474 0         0 splice @char, $left, $right-$left+1, Eoldutf8::charlist_qr(@char[$left+1..$right-1], $modifier);
8475 0         0  
8476             $i = $left;
8477             last;
8478             }
8479             }
8480             }
8481              
8482 0         0 # open character class [^...]
8483 0 0       0 elsif ($char[$i] eq '[^') {
8484 0         0 my $left = $i;
8485             if ($char[$i+1] eq ']') {
8486 0         0 $i++;
8487 0 0       0 }
8488 0         0 while (1) {
8489             if (++$i > $#char) {
8490 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
8491 0         0 }
8492             if ($char[$i] eq ']') {
8493             my $right = $i;
8494 0         0  
8495             # [^...]
8496 0         0 splice @char, $left, $right-$left+1, Eoldutf8::charlist_not_qr(@char[$left+1..$right-1], $modifier);
8497 0         0  
8498             $i = $left;
8499             last;
8500             }
8501             }
8502             }
8503              
8504 0         0 # escape $ @ / and \
8505             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
8506             $char[$i] = '\\' . $char[$i];
8507             }
8508              
8509 0         0 # rewrite character class or escape character
8510             elsif (my $char = character_class($char[$i],$modifier)) {
8511             $char[$i] = $char;
8512             }
8513              
8514 6 0       16 # /i modifier
8515 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eoldutf8::uc($char[$i]) ne Eoldutf8::fc($char[$i]))) {
8516             if (CORE::length(Eoldutf8::fc($char[$i])) == 1) {
8517             $char[$i] = '[' . Eoldutf8::uc($char[$i]) . Eoldutf8::fc($char[$i]) . ']';
8518 0         0 }
8519             else {
8520             $char[$i] = '(?:' . Eoldutf8::uc($char[$i]) . '|' . Eoldutf8::fc($char[$i]) . ')';
8521             }
8522             }
8523              
8524 0 0       0 # quote character before ? + * {
8525             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
8526             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
8527 0         0 }
8528             else {
8529             $char[$i-1] = '(?:' . $char[$i-1] . ')';
8530             }
8531             }
8532 0         0 }
8533 13         27  
8534 13         21 $modifier =~ tr/i//d;
8535 13         24 $delimiter = '/';
8536 13         20 $end_delimiter = '/';
8537             my $prematch = '';
8538             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
8539             }
8540              
8541             #
8542             # escape regexp (s'here''b)
8543 13     1 0 172 #
8544             sub e_s1_qb {
8545             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8546 1         3  
8547             # split regexp
8548             my @char = $string =~ /\G (?>[^\\]|\\\\|[\x00-\xFF]) /oxmsg;
8549 1         6  
8550 1 50       3 # unescape character
    50          
8551             for (my $i=0; $i <= $#char; $i++) {
8552             if (0) {
8553             }
8554 3         12  
8555             # remain \\
8556             elsif ($char[$i] eq '\\\\') {
8557             }
8558              
8559 0         0 # escape $ @ / and \
8560             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
8561             $char[$i] = '\\' . $char[$i];
8562             }
8563 0         0 }
8564 1         3  
8565 1         2 $delimiter = '/';
8566 1         1 $end_delimiter = '/';
8567             my $prematch = '';
8568             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
8569             }
8570              
8571             #
8572             # escape regexp (s''here')
8573 1     17 0 9 #
8574             sub e_s2_q {
8575 17         72 my($ope,$delimiter,$end_delimiter,$string) = @_;
8576              
8577 17         31 $slash = 'div';
8578 17         221  
8579 17 100       58 my @char = $string =~ / \G (?>[^\x80-\xFF\\]|\\\\|$q_char) /oxmsg;
    100          
8580             for (my $i=0; $i <= $#char; $i++) {
8581             if (0) {
8582             }
8583 9         38  
8584             # not escape \\
8585             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
8586             }
8587              
8588 0         0 # escape $ @ / and \
8589             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
8590             $char[$i] = '\\' . $char[$i];
8591             }
8592 5         19 }
8593              
8594             return join '', $ope, $delimiter, @char, $end_delimiter;
8595             }
8596              
8597             #
8598             # escape regexp (s/here/and here/modifier)
8599 17     132 0 58 #
8600 132   100     1291 sub e_sub {
8601             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
8602 132         634 $modifier ||= '';
8603 132 50       286  
8604 132         409 $modifier =~ tr/p//d;
8605 0         0 if ($modifier =~ /([adlu])/oxms) {
8606 0 0       0 my $line = 0;
8607 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
8608 0         0 if ($filename ne __FILE__) {
8609             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
8610             last;
8611 0         0 }
8612             }
8613             die qq{Unsupported modifier "$1" used at line $line.\n};
8614 0 100       0 }
8615 132         398  
8616 37         61 if ($variable eq '') {
8617             $variable = '$_';
8618             $bind_operator = ' =~ ';
8619 37         53 }
8620              
8621             $slash = 'div';
8622              
8623             # P.128 Start of match (or end of previous match): \G
8624             # P.130 Advanced Use of \G with Perl
8625             # in Chapter 3: Overview of Regular Expression Features and Flavors
8626             # P.312 Iterative Matching: Scalar Context, with /g
8627             # in Chapter 7: Perl
8628             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
8629              
8630             # P.181 Where You Left Off: The \G Assertion
8631             # in Chapter 5: Pattern Matching
8632             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
8633              
8634             # P.220 Where You Left Off: The \G Assertion
8635             # in Chapter 5: Pattern Matching
8636 132         440 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
8637 132         235  
8638             my $e_modifier = $modifier =~ tr/e//d;
8639 132         219 my $r_modifier = $modifier =~ tr/r//d;
8640 132 50       219  
8641 132         544 my $my = '';
8642 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
8643 0         0 $my = $variable;
8644             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
8645             $variable =~ s/ = .+ \z//oxms;
8646 0         0 }
8647 132         429  
8648             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
8649             $variable_basename =~ s/ \s+ \z//oxms;
8650 132         275  
8651 132 100       238 # quote replacement string
8652 132         336 my $e_replacement = '';
8653 17         40 if ($e_modifier >= 1) {
8654             $e_replacement = e_qq('', '', '', $replacement);
8655             $e_modifier--;
8656 17 100       27 }
8657 115         300 else {
8658             if ($delimiter2 eq "'") {
8659             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
8660 17         42 }
8661             else {
8662             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
8663             }
8664 98         393 }
8665              
8666             my $sub = '';
8667 132 100       271  
8668 132 100       367 # with /r
8669             if ($r_modifier) {
8670             if (0) {
8671             }
8672 8         21  
8673 0 50       0 # s///gr without multibyte anchoring
8674             elsif ($modifier =~ /g/oxms) {
8675             $sub = sprintf(
8676             # 1 2 3 4 5
8677             q,
8678              
8679             $variable, # 1
8680             ($delimiter1 eq "'") ? # 2
8681             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
8682             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
8683             $s_matched, # 3
8684             $e_replacement, # 4
8685             '$Eoldutf8::re_r=CORE::eval $Eoldutf8::re_r; ' x $e_modifier, # 5
8686             );
8687             }
8688              
8689             # s///r
8690 4         22 else {
8691              
8692 4 50       8 my $prematch = q{$`};
8693              
8694             $sub = sprintf(
8695             # 1 2 3 4 5 6 7
8696             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Eoldutf8::re_r=%s; %s"%s$Eoldutf8::re_r$'" } : %s>,
8697              
8698             $variable, # 1
8699             ($delimiter1 eq "'") ? # 2
8700             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
8701             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
8702             $s_matched, # 3
8703             $e_replacement, # 4
8704             '$Eoldutf8::re_r=CORE::eval $Eoldutf8::re_r; ' x $e_modifier, # 5
8705             $prematch, # 6
8706             $variable, # 7
8707             );
8708             }
8709 4 50       108  
8710 8         35 # $var !~ s///r doesn't make sense
8711             if ($bind_operator =~ / !~ /oxms) {
8712             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
8713             }
8714             }
8715              
8716 0 100       0 # without /r
8717             else {
8718             if (0) {
8719             }
8720 124         343  
8721 0 100       0 # s///g without multibyte anchoring
    100          
8722             elsif ($modifier =~ /g/oxms) {
8723             $sub = sprintf(
8724             # 1 2 3 4 5 6 7 8
8725             q,
8726              
8727             $variable, # 1
8728             ($delimiter1 eq "'") ? # 2
8729             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
8730             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
8731             $s_matched, # 3
8732             $e_replacement, # 4
8733             '$Eoldutf8::re_r=CORE::eval $Eoldutf8::re_r; ' x $e_modifier, # 5
8734             $variable, # 6
8735             $variable, # 7
8736             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
8737             );
8738             }
8739              
8740             # s///
8741 29         8282 else {
8742              
8743 95 100       184 my $prematch = q{$`};
    100          
8744              
8745             $sub = sprintf(
8746              
8747             ($bind_operator =~ / =~ /oxms) ?
8748              
8749             # 1 2 3 4 5 6 7 8
8750             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Eoldutf8::re_r=%s; %s%s="%s$Eoldutf8::re_r$'"; 1 } : undef> :
8751              
8752             # 1 2 3 4 5 6 7 8
8753             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Eoldutf8::re_r=%s; %s%s="%s$Eoldutf8::re_r$'"; undef }>,
8754              
8755             $variable, # 1
8756             $bind_operator, # 2
8757             ($delimiter1 eq "'") ? # 3
8758             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
8759             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
8760             $s_matched, # 4
8761             $e_replacement, # 5
8762             '$Eoldutf8::re_r=CORE::eval $Eoldutf8::re_r; ' x $e_modifier, # 6
8763             $variable, # 7
8764             $prematch, # 8
8765             );
8766             }
8767             }
8768 95 50       722  
8769 132         479 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
8770             if ($my ne '') {
8771             $sub = "($my, $sub)[1]";
8772             }
8773 0         0  
8774 132         299 # clear s/// variable
8775             $sub_variable = '';
8776 132         264 $bind_operator = '';
8777              
8778             return $sub;
8779             }
8780              
8781             #
8782             # escape regexp of split qr//
8783 132     101 0 1507 #
8784 101   100     455 sub e_split {
8785             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8786 101         461 $modifier ||= '';
8787 101 50       175  
8788 101         369 $modifier =~ tr/p//d;
8789 0         0 if ($modifier =~ /([adlu])/oxms) {
8790 0 0       0 my $line = 0;
8791 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
8792 0         0 if ($filename ne __FILE__) {
8793             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
8794             last;
8795 0         0 }
8796             }
8797             die qq{Unsupported modifier "$1" used at line $line.\n};
8798 0         0 }
8799              
8800             $slash = 'div';
8801 101 50       172  
8802 101         236 # /b /B modifier
8803             if ($modifier =~ tr/bB//d) {
8804             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
8805 0 50       0 }
8806 101         266  
8807             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
8808             my $metachar = qr/[\@\\|[\]{^]/oxms;
8809 101         398  
8810             # split regexp
8811             my @char = $string =~ /\G((?>
8812             [^\x80-\xFF\\\$\@\[\(]|(?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
8813             \\x (?>[0-9A-Fa-f]{1,2}) |
8814             \\ (?>[0-7]{2,3}) |
8815             \\c [\x40-\x5F] |
8816             \\x\{ (?>[0-9A-Fa-f]+) \} |
8817             \\o\{ (?>[0-7]+) \} |
8818             \\[bBNpP]\{ (?>[^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} |
8819             \\ $q_char |
8820             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
8821             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
8822             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
8823             [\$\@] $qq_variable |
8824             \$ (?>\s* [0-9]+) |
8825             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
8826             \$ \$ (?![\w\{]) |
8827             \$ (?>\s*) \$ (?>\s*) $qq_variable |
8828             \[\^ |
8829             \[\: (?>[a-z]+) :\] |
8830             \[\:\^ (?>[a-z]+) :\] |
8831             \(\? |
8832             $q_char
8833 101         18623 ))/oxmsg;
8834 101         507  
8835 101         158 my $left_e = 0;
8836             my $right_e = 0;
8837             for (my $i=0; $i <= $#char; $i++) {
8838 101 50 33     295  
    50 33        
    100          
    100          
    50          
    50          
8839 284         1486 # "\L\u" --> "\u\L"
8840             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
8841             @char[$i,$i+1] = @char[$i+1,$i];
8842             }
8843              
8844 0         0 # "\U\l" --> "\l\U"
8845             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
8846             @char[$i,$i+1] = @char[$i+1,$i];
8847             }
8848              
8849 0         0 # octal escape sequence
8850             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
8851             $char[$i] = Eoldutf8::octchr($1);
8852             }
8853              
8854 1         4 # hexadecimal escape sequence
8855             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
8856             $char[$i] = Eoldutf8::hexchr($1);
8857             }
8858              
8859             # \b{...} --> b\{...}
8860             # \B{...} --> B\{...}
8861             # \N{CHARNAME} --> N\{CHARNAME}
8862             # \p{PROPERTY} --> p\{PROPERTY}
8863 1         4 # \P{PROPERTY} --> P\{PROPERTY}
8864             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x80-\xFF0-9\}][^\x80-\xFF\}]*) \} ) \z/oxms) {
8865             $char[$i] = $1 . '\\' . $2;
8866             }
8867              
8868 0         0 # \p, \P, \X --> p, P, X
8869             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
8870             $char[$i] = $1;
8871 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          
8872              
8873             if (0) {
8874             }
8875 284         1066  
8876 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
8877 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
8878             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)) {
8879             $char[$i] .= join '', splice @char, $i+1, 3;
8880 0         0 }
8881             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)) {
8882             $char[$i] .= join '', splice @char, $i+1, 2;
8883 0         0 }
8884             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)) {
8885             $char[$i] .= join '', splice @char, $i+1, 1;
8886             }
8887             }
8888              
8889 0         0 # open character class [...]
8890 3 50       6 elsif ($char[$i] eq '[') {
8891 3         9 my $left = $i;
8892             if ($char[$i+1] eq ']') {
8893 0         0 $i++;
8894 3 50       6 }
8895 7         11 while (1) {
8896             if (++$i > $#char) {
8897 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
8898 7         13 }
8899             if ($char[$i] eq ']') {
8900             my $right = $i;
8901 3 50       6  
8902 3         17 # [...]
  0         0  
8903             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8904             splice @char, $left, $right-$left+1, sprintf(q{@{[Eoldutf8::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8905 0         0 }
8906             else {
8907             splice @char, $left, $right-$left+1, Eoldutf8::charlist_qr(@char[$left+1..$right-1], $modifier);
8908 3         17 }
8909 3         6  
8910             $i = $left;
8911             last;
8912             }
8913             }
8914             }
8915              
8916 3         7 # open character class [^...]
8917 1 50       1 elsif ($char[$i] eq '[^') {
8918 1         4 my $left = $i;
8919             if ($char[$i+1] eq ']') {
8920 0         0 $i++;
8921 1 50       2 }
8922 2         5 while (1) {
8923             if (++$i > $#char) {
8924 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
8925 2         6 }
8926             if ($char[$i] eq ']') {
8927             my $right = $i;
8928 1 50       2  
8929 1         7 # [^...]
  0         0  
8930             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8931             splice @char, $left, $right-$left+1, sprintf(q{@{[Eoldutf8::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8932 0         0 }
8933             else {
8934             splice @char, $left, $right-$left+1, Eoldutf8::charlist_not_qr(@char[$left+1..$right-1], $modifier);
8935 1         6 }
8936 1         3  
8937             $i = $left;
8938             last;
8939             }
8940             }
8941             }
8942              
8943 1         3 # rewrite character class or escape character
8944             elsif (my $char = character_class($char[$i],$modifier)) {
8945             $char[$i] = $char;
8946             }
8947              
8948             # P.794 29.2.161. split
8949             # in Chapter 29: Functions
8950             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
8951              
8952             # P.951 split
8953             # in Chapter 27: Functions
8954             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
8955              
8956             # said "The //m modifier is assumed when you split on the pattern /^/",
8957             # but perl5.008 is not so. Therefore, this software adds //m.
8958             # (and so on)
8959              
8960 5         17 # split(m/^/) --> split(m/^/m)
8961             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
8962             $modifier .= 'm';
8963             }
8964              
8965 11 0       35 # /i modifier
8966 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eoldutf8::uc($char[$i]) ne Eoldutf8::fc($char[$i]))) {
8967             if (CORE::length(Eoldutf8::fc($char[$i])) == 1) {
8968             $char[$i] = '[' . Eoldutf8::uc($char[$i]) . Eoldutf8::fc($char[$i]) . ']';
8969 0         0 }
8970             else {
8971             $char[$i] = '(?:' . Eoldutf8::uc($char[$i]) . '|' . Eoldutf8::fc($char[$i]) . ')';
8972             }
8973             }
8974              
8975 0 50       0 # \u \l \U \L \F \Q \E
8976 2         8 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
8977             if ($right_e < $left_e) {
8978             $char[$i] = '\\' . $char[$i];
8979             }
8980 0         0 }
8981 0         0 elsif ($char[$i] eq '\u') {
8982             $char[$i] = '@{[Eoldutf8::ucfirst qq<';
8983             $left_e++;
8984 0         0 }
8985 0         0 elsif ($char[$i] eq '\l') {
8986             $char[$i] = '@{[Eoldutf8::lcfirst qq<';
8987             $left_e++;
8988 0         0 }
8989 0         0 elsif ($char[$i] eq '\U') {
8990             $char[$i] = '@{[Eoldutf8::uc qq<';
8991             $left_e++;
8992 0         0 }
8993 0         0 elsif ($char[$i] eq '\L') {
8994             $char[$i] = '@{[Eoldutf8::lc qq<';
8995             $left_e++;
8996 0         0 }
8997 0         0 elsif ($char[$i] eq '\F') {
8998             $char[$i] = '@{[Eoldutf8::fc qq<';
8999             $left_e++;
9000 0         0 }
9001 0         0 elsif ($char[$i] eq '\Q') {
9002             $char[$i] = '@{[CORE::quotemeta qq<';
9003             $left_e++;
9004 0 0       0 }
9005 0         0 elsif ($char[$i] eq '\E') {
9006 0         0 if ($right_e < $left_e) {
9007             $char[$i] = '>]}';
9008             $right_e++;
9009 0         0 }
9010             else {
9011             $char[$i] = '';
9012             }
9013 0         0 }
9014 0 0       0 elsif ($char[$i] eq '\Q') {
9015 0         0 while (1) {
9016             if (++$i > $#char) {
9017 0 0       0 last;
9018 0         0 }
9019             if ($char[$i] eq '\E') {
9020             last;
9021             }
9022             }
9023             }
9024             elsif ($char[$i] eq '\E') {
9025             }
9026              
9027 0 0       0 # $0 --> $0
9028 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
9029             if ($ignorecase) {
9030             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
9031             }
9032 0 0       0 }
9033 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
9034             if ($ignorecase) {
9035             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
9036             }
9037             }
9038              
9039             # $$ --> $$
9040             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
9041             }
9042              
9043             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
9044 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
9045 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
9046 0         0 $char[$i] = e_capture($1);
9047             if ($ignorecase) {
9048             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
9049             }
9050 0         0 }
9051 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
9052 0         0 $char[$i] = e_capture($1);
9053             if ($ignorecase) {
9054             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
9055             }
9056             }
9057              
9058 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
9059 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) {
9060 0         0 $char[$i] = e_capture($1.'->'.$2);
9061             if ($ignorecase) {
9062             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
9063             }
9064             }
9065              
9066 0         0 # $$foo{ ... } --> $ $foo->{ ... }
9067 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) {
9068 0         0 $char[$i] = e_capture($1.'->'.$2);
9069             if ($ignorecase) {
9070             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
9071             }
9072             }
9073              
9074 0         0 # $$foo
9075 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
9076 0         0 $char[$i] = e_capture($1);
9077             if ($ignorecase) {
9078             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
9079             }
9080             }
9081              
9082 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Eoldutf8::PREMATCH()
9083 12         33 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
9084             if ($ignorecase) {
9085             $char[$i] = '@{[Eoldutf8::ignorecase(Eoldutf8::PREMATCH())]}';
9086 0         0 }
9087             else {
9088             $char[$i] = '@{[Eoldutf8::PREMATCH()]}';
9089             }
9090             }
9091              
9092 12 50       61 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Eoldutf8::MATCH()
9093 12         40 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
9094             if ($ignorecase) {
9095             $char[$i] = '@{[Eoldutf8::ignorecase(Eoldutf8::MATCH())]}';
9096 0         0 }
9097             else {
9098             $char[$i] = '@{[Eoldutf8::MATCH()]}';
9099             }
9100             }
9101              
9102 12 50       61 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Eoldutf8::POSTMATCH()
9103 9         36 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
9104             if ($ignorecase) {
9105             $char[$i] = '@{[Eoldutf8::ignorecase(Eoldutf8::POSTMATCH())]}';
9106 0         0 }
9107             else {
9108             $char[$i] = '@{[Eoldutf8::POSTMATCH()]}';
9109             }
9110             }
9111              
9112 9 0       48 # ${ foo }
9113 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) {
9114             if ($ignorecase) {
9115             $char[$i] = '@{[Eoldutf8::ignorecase(' . $1 . ')]}';
9116             }
9117             }
9118              
9119 0         0 # ${ ... }
9120 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
9121 0         0 $char[$i] = e_capture($1);
9122             if ($ignorecase) {
9123             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
9124             }
9125             }
9126              
9127 0         0 # $scalar or @array
9128 3 50       8 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
9129 3         15 $char[$i] = e_string($char[$i]);
9130             if ($ignorecase) {
9131             $char[$i] = '@{[Eoldutf8::ignorecase(' . $char[$i] . ')]}';
9132             }
9133             }
9134              
9135 0 100       0 # quote character before ? + * {
9136             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
9137             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
9138 7         41 }
9139             else {
9140             $char[$i-1] = '(?:' . $char[$i-1] . ')';
9141             }
9142             }
9143             }
9144 4         25  
9145 101 50       202 # make regexp string
9146 101         261 $modifier =~ tr/i//d;
9147             if ($left_e > $right_e) {
9148 0         0 return join '', 'Eoldutf8::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
9149             }
9150             return join '', 'Eoldutf8::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
9151             }
9152              
9153             #
9154             # escape regexp of split qr''
9155 101     0 0 1153 #
9156 0   0       sub e_split_q {
9157             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
9158 0           $modifier ||= '';
9159 0 0          
9160 0           $modifier =~ tr/p//d;
9161 0           if ($modifier =~ /([adlu])/oxms) {
9162 0 0         my $line = 0;
9163 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
9164 0           if ($filename ne __FILE__) {
9165             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
9166             last;
9167 0           }
9168             }
9169             die qq{Unsupported modifier "$1" used at line $line.\n};
9170 0           }
9171              
9172             $slash = 'div';
9173 0 0          
9174 0           # /b /B modifier
9175             if ($modifier =~ tr/bB//d) {
9176             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
9177 0 0         }
9178              
9179             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
9180 0            
9181             # split regexp
9182             my @char = $string =~ /\G((?>
9183             [^\x80-\xFF\\\[] |
9184             (?:[\xC0-\xDF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF][\x80-\xBF])[\x80-\xBF] |
9185             \[\^ |
9186             \[\: (?>[a-z]+) \:\] |
9187             \[\:\^ (?>[a-z]+) \:\] |
9188             \\ (?:$q_char) |
9189             (?:$q_char)
9190             ))/oxmsg;
9191 0            
9192 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
9193             for (my $i=0; $i <= $#char; $i++) {
9194             if (0) {
9195             }
9196 0            
9197 0           # open character class [...]
9198 0 0         elsif ($char[$i] eq '[') {
9199 0           my $left = $i;
9200             if ($char[$i+1] eq ']') {
9201 0           $i++;
9202 0 0         }
9203 0           while (1) {
9204             if (++$i > $#char) {
9205 0 0         die __FILE__, ": Unmatched [] in regexp\n";
9206 0           }
9207             if ($char[$i] eq ']') {
9208             my $right = $i;
9209 0            
9210             # [...]
9211 0           splice @char, $left, $right-$left+1, Eoldutf8::charlist_qr(@char[$left+1..$right-1], $modifier);
9212 0            
9213             $i = $left;
9214             last;
9215             }
9216             }
9217             }
9218              
9219 0           # open character class [^...]
9220 0 0         elsif ($char[$i] eq '[^') {
9221 0           my $left = $i;
9222             if ($char[$i+1] eq ']') {
9223 0           $i++;
9224 0 0         }
9225 0           while (1) {
9226             if (++$i > $#char) {
9227 0 0         die __FILE__, ": Unmatched [] in regexp\n";
9228 0           }
9229             if ($char[$i] eq ']') {
9230             my $right = $i;
9231 0            
9232             # [^...]
9233 0           splice @char, $left, $right-$left+1, Eoldutf8::charlist_not_qr(@char[$left+1..$right-1], $modifier);
9234 0            
9235             $i = $left;
9236             last;
9237             }
9238             }
9239             }
9240              
9241 0           # rewrite character class or escape character
9242             elsif (my $char = character_class($char[$i],$modifier)) {
9243             $char[$i] = $char;
9244             }
9245              
9246 0           # split(m/^/) --> split(m/^/m)
9247             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
9248             $modifier .= 'm';
9249             }
9250              
9251 0 0         # /i modifier
9252 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Eoldutf8::uc($char[$i]) ne Eoldutf8::fc($char[$i]))) {
9253             if (CORE::length(Eoldutf8::fc($char[$i])) == 1) {
9254             $char[$i] = '[' . Eoldutf8::uc($char[$i]) . Eoldutf8::fc($char[$i]) . ']';
9255 0           }
9256             else {
9257             $char[$i] = '(?:' . Eoldutf8::uc($char[$i]) . '|' . Eoldutf8::fc($char[$i]) . ')';
9258             }
9259             }
9260              
9261 0 0         # quote character before ? + * {
9262             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
9263             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
9264 0           }
9265             else {
9266             $char[$i-1] = '(?:' . $char[$i-1] . ')';
9267             }
9268             }
9269 0           }
9270 0            
9271             $modifier =~ tr/i//d;
9272             return join '', 'Eoldutf8::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
9273             }
9274              
9275             #
9276             # instead of Carp::carp
9277 0     0 0   #
9278 0           sub carp {
9279             my($package,$filename,$line) = caller(1);
9280             print STDERR "@_ at $filename line $line.\n";
9281             }
9282              
9283             #
9284             # instead of Carp::croak
9285 0     0 0   #
9286 0           sub croak {
9287 0           my($package,$filename,$line) = caller(1);
9288             print STDERR "@_ at $filename line $line.\n";
9289             die "\n";
9290             }
9291              
9292             #
9293             # instead of Carp::cluck
9294 0     0 0   #
9295 0           sub cluck {
9296 0           my $i = 0;
9297 0           my @cluck = ();
9298 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
9299             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
9300 0           $i++;
9301 0           }
9302 0           print STDERR CORE::reverse @cluck;
9303             print STDERR "\n";
9304             print STDERR @_;
9305             }
9306              
9307             #
9308             # instead of Carp::confess
9309 0     0 0   #
9310 0           sub confess {
9311 0           my $i = 0;
9312 0           my @confess = ();
9313 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
9314             push @confess, "[$i] $filename($line) $package::$subroutine\n";
9315 0           $i++;
9316 0           }
9317 0           print STDERR CORE::reverse @confess;
9318 0           print STDERR "\n";
9319             print STDERR @_;
9320             die "\n";
9321             }
9322              
9323             1;
9324              
9325             __END__