File Coverage

blib/lib/Ekoi8u.pm
Criterion Covered Total %
statement 905 3196 28.3
branch 968 2742 35.3
condition 98 355 27.6
subroutine 52 110 47.2
pod 7 74 9.4
total 2030 6477 31.3


line stmt bran cond sub pod time code
1             package Ekoi8u;
2 204     204   1197 use strict;
  204         412  
  204         6177  
3             ######################################################################
4             #
5             # Ekoi8u - Run-time routines for KOI8U.pm
6             #
7             # http://search.cpan.org/dist/Char-KOI8U/
8             #
9             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
10             ######################################################################
11              
12 204     204   2598 use 5.00503; # Galapagos Consensus 1998 for primetools
  204         598  
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 204     204   941 use vars qw($VERSION);
  204         390  
  204         25804  
28             $VERSION = '1.15';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 204 50   204   1491 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 204         395 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 204         25293 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 204     204   13384 CORE::eval q{
  204     204   1245  
  204     88   408  
  204         21072  
  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 204 50       69723 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 (Ekoi8u::index($name,'::') >= 0) {
83 0         0 return $name;
84             }
85             elsif (Ekoi8u::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 204     204   1403 no strict qw(refs);
  204         377  
  204         13141  
118 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
119             }
120             else {
121 204     204   1142 no strict qw(refs);
  204     0   359  
  204         33827  
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{[\x00-\xFF]};
153 204     204   1231 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  204         367  
  204         11963  
154 204     204   1158 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  204         426  
  204         311798  
155              
156             #
157             # KOI8-U character range per length
158             #
159             my %range_tr = ();
160              
161             #
162             # KOI8-U 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 Ekoi8u \z/oxms) {
178             %range_tr = (
179             1 => [ [0x00..0xFF],
180             ],
181             );
182              
183             %lc = (%lc,
184             "\xB3" => "\xA3", # CYRILLIC LETTER IO
185             "\xB4" => "\xA4", # CYRILLIC LETTER UKRAINIAN IE
186             "\xB6" => "\xA6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
187             "\xB7" => "\xA7", # CYRILLIC LETTER YI (UKRAINIAN)
188             "\xBD" => "\xAD", # CYRILLIC LETTER GHE WITH UPTURN
189             "\xE0" => "\xC0", # CYRILLIC LETTER YU
190             "\xE1" => "\xC1", # CYRILLIC LETTER A
191             "\xE2" => "\xC2", # CYRILLIC LETTER BE
192             "\xE3" => "\xC3", # CYRILLIC LETTER TSE
193             "\xE4" => "\xC4", # CYRILLIC LETTER DE
194             "\xE5" => "\xC5", # CYRILLIC LETTER IE
195             "\xE6" => "\xC6", # CYRILLIC LETTER EF
196             "\xE7" => "\xC7", # CYRILLIC LETTER GHE
197             "\xE8" => "\xC8", # CYRILLIC LETTER KHA
198             "\xE9" => "\xC9", # CYRILLIC LETTER I
199             "\xEA" => "\xCA", # CYRILLIC LETTER SHORT I
200             "\xEB" => "\xCB", # CYRILLIC LETTER KA
201             "\xEC" => "\xCC", # CYRILLIC LETTER EL
202             "\xED" => "\xCD", # CYRILLIC LETTER EM
203             "\xEE" => "\xCE", # CYRILLIC LETTER EN
204             "\xEF" => "\xCF", # CYRILLIC LETTER O
205             "\xF0" => "\xD0", # CYRILLIC LETTER PE
206             "\xF1" => "\xD1", # CYRILLIC LETTER YA
207             "\xF2" => "\xD2", # CYRILLIC LETTER ER
208             "\xF3" => "\xD3", # CYRILLIC LETTER ES
209             "\xF4" => "\xD4", # CYRILLIC LETTER TE
210             "\xF5" => "\xD5", # CYRILLIC LETTER U
211             "\xF6" => "\xD6", # CYRILLIC LETTER ZHE
212             "\xF7" => "\xD7", # CYRILLIC LETTER VE
213             "\xF8" => "\xD8", # CYRILLIC LETTER SOFT SIGN
214             "\xF9" => "\xD9", # CYRILLIC LETTER YERU
215             "\xFA" => "\xDA", # CYRILLIC LETTER ZE
216             "\xFB" => "\xDB", # CYRILLIC LETTER SHA
217             "\xFC" => "\xDC", # CYRILLIC LETTER E
218             "\xFD" => "\xDD", # CYRILLIC LETTER SHCHA
219             "\xFE" => "\xDE", # CYRILLIC LETTER CHE
220             "\xFF" => "\xDF", # CYRILLIC LETTER HARD SIGN
221             );
222              
223             %uc = (%uc,
224             "\xA3" => "\xB3", # CYRILLIC LETTER IO
225             "\xA4" => "\xB4", # CYRILLIC LETTER UKRAINIAN IE
226             "\xA6" => "\xB6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
227             "\xA7" => "\xB7", # CYRILLIC LETTER YI (UKRAINIAN)
228             "\xAD" => "\xBD", # CYRILLIC LETTER GHE WITH UPTURN
229             "\xC0" => "\xE0", # CYRILLIC LETTER YU
230             "\xC1" => "\xE1", # CYRILLIC LETTER A
231             "\xC2" => "\xE2", # CYRILLIC LETTER BE
232             "\xC3" => "\xE3", # CYRILLIC LETTER TSE
233             "\xC4" => "\xE4", # CYRILLIC LETTER DE
234             "\xC5" => "\xE5", # CYRILLIC LETTER IE
235             "\xC6" => "\xE6", # CYRILLIC LETTER EF
236             "\xC7" => "\xE7", # CYRILLIC LETTER GHE
237             "\xC8" => "\xE8", # CYRILLIC LETTER KHA
238             "\xC9" => "\xE9", # CYRILLIC LETTER I
239             "\xCA" => "\xEA", # CYRILLIC LETTER SHORT I
240             "\xCB" => "\xEB", # CYRILLIC LETTER KA
241             "\xCC" => "\xEC", # CYRILLIC LETTER EL
242             "\xCD" => "\xED", # CYRILLIC LETTER EM
243             "\xCE" => "\xEE", # CYRILLIC LETTER EN
244             "\xCF" => "\xEF", # CYRILLIC LETTER O
245             "\xD0" => "\xF0", # CYRILLIC LETTER PE
246             "\xD1" => "\xF1", # CYRILLIC LETTER YA
247             "\xD2" => "\xF2", # CYRILLIC LETTER ER
248             "\xD3" => "\xF3", # CYRILLIC LETTER ES
249             "\xD4" => "\xF4", # CYRILLIC LETTER TE
250             "\xD5" => "\xF5", # CYRILLIC LETTER U
251             "\xD6" => "\xF6", # CYRILLIC LETTER ZHE
252             "\xD7" => "\xF7", # CYRILLIC LETTER VE
253             "\xD8" => "\xF8", # CYRILLIC LETTER SOFT SIGN
254             "\xD9" => "\xF9", # CYRILLIC LETTER YERU
255             "\xDA" => "\xFA", # CYRILLIC LETTER ZE
256             "\xDB" => "\xFB", # CYRILLIC LETTER SHA
257             "\xDC" => "\xFC", # CYRILLIC LETTER E
258             "\xDD" => "\xFD", # CYRILLIC LETTER SHCHA
259             "\xDE" => "\xFE", # CYRILLIC LETTER CHE
260             "\xDF" => "\xFF", # CYRILLIC LETTER HARD SIGN
261             );
262              
263             %fc = (%fc,
264             "\xB3" => "\xA3", # CYRILLIC CAPITAL LETTER IO --> CYRILLIC SMALL LETTER IO
265             "\xB4" => "\xA4", # CYRILLIC CAPITAL LETTER UKRAINIAN IE --> CYRILLIC SMALL LETTER UKRAINIAN IE
266             "\xB6" => "\xA6", # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I --> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
267             "\xB7" => "\xA7", # CYRILLIC CAPITAL LETTER YI --> CYRILLIC SMALL LETTER YI
268             "\xBD" => "\xAD", # CYRILLIC CAPITAL LETTER GHE WITH UPTURN --> CYRILLIC SMALL LETTER GHE WITH UPTURN
269             "\xE0" => "\xC0", # CYRILLIC CAPITAL LETTER YU --> CYRILLIC SMALL LETTER YU
270             "\xE1" => "\xC1", # CYRILLIC CAPITAL LETTER A --> CYRILLIC SMALL LETTER A
271             "\xE2" => "\xC2", # CYRILLIC CAPITAL LETTER BE --> CYRILLIC SMALL LETTER BE
272             "\xE3" => "\xC3", # CYRILLIC CAPITAL LETTER TSE --> CYRILLIC SMALL LETTER TSE
273             "\xE4" => "\xC4", # CYRILLIC CAPITAL LETTER DE --> CYRILLIC SMALL LETTER DE
274             "\xE5" => "\xC5", # CYRILLIC CAPITAL LETTER IE --> CYRILLIC SMALL LETTER IE
275             "\xE6" => "\xC6", # CYRILLIC CAPITAL LETTER EF --> CYRILLIC SMALL LETTER EF
276             "\xE7" => "\xC7", # CYRILLIC CAPITAL LETTER GHE --> CYRILLIC SMALL LETTER GHE
277             "\xE8" => "\xC8", # CYRILLIC CAPITAL LETTER HA --> CYRILLIC SMALL LETTER HA
278             "\xE9" => "\xC9", # CYRILLIC CAPITAL LETTER I --> CYRILLIC SMALL LETTER I
279             "\xEA" => "\xCA", # CYRILLIC CAPITAL LETTER SHORT I --> CYRILLIC SMALL LETTER SHORT I
280             "\xEB" => "\xCB", # CYRILLIC CAPITAL LETTER KA --> CYRILLIC SMALL LETTER KA
281             "\xEC" => "\xCC", # CYRILLIC CAPITAL LETTER EL --> CYRILLIC SMALL LETTER EL
282             "\xED" => "\xCD", # CYRILLIC CAPITAL LETTER EM --> CYRILLIC SMALL LETTER EM
283             "\xEE" => "\xCE", # CYRILLIC CAPITAL LETTER EN --> CYRILLIC SMALL LETTER EN
284             "\xEF" => "\xCF", # CYRILLIC CAPITAL LETTER O --> CYRILLIC SMALL LETTER O
285             "\xF0" => "\xD0", # CYRILLIC CAPITAL LETTER PE --> CYRILLIC SMALL LETTER PE
286             "\xF1" => "\xD1", # CYRILLIC CAPITAL LETTER YA --> CYRILLIC SMALL LETTER YA
287             "\xF2" => "\xD2", # CYRILLIC CAPITAL LETTER ER --> CYRILLIC SMALL LETTER ER
288             "\xF3" => "\xD3", # CYRILLIC CAPITAL LETTER ES --> CYRILLIC SMALL LETTER ES
289             "\xF4" => "\xD4", # CYRILLIC CAPITAL LETTER TE --> CYRILLIC SMALL LETTER TE
290             "\xF5" => "\xD5", # CYRILLIC CAPITAL LETTER U --> CYRILLIC SMALL LETTER U
291             "\xF6" => "\xD6", # CYRILLIC CAPITAL LETTER ZHE --> CYRILLIC SMALL LETTER ZHE
292             "\xF7" => "\xD7", # CYRILLIC CAPITAL LETTER VE --> CYRILLIC SMALL LETTER VE
293             "\xF8" => "\xD8", # CYRILLIC CAPITAL LETTER SOFT SIGN --> CYRILLIC SMALL LETTER SOFT SIGN
294             "\xF9" => "\xD9", # CYRILLIC CAPITAL LETTER YERU --> CYRILLIC SMALL LETTER YERU
295             "\xFA" => "\xDA", # CYRILLIC CAPITAL LETTER ZE --> CYRILLIC SMALL LETTER ZE
296             "\xFB" => "\xDB", # CYRILLIC CAPITAL LETTER SHA --> CYRILLIC SMALL LETTER SHA
297             "\xFC" => "\xDC", # CYRILLIC CAPITAL LETTER E --> CYRILLIC SMALL LETTER E
298             "\xFD" => "\xDD", # CYRILLIC CAPITAL LETTER SHCHA --> CYRILLIC SMALL LETTER SHCHA
299             "\xFE" => "\xDE", # CYRILLIC CAPITAL LETTER CHE --> CYRILLIC SMALL LETTER CHE
300             "\xFF" => "\xDF", # CYRILLIC CAPITAL LETTER HARD SIGN --> CYRILLIC SMALL LETTER HARD SIGN
301             );
302             }
303              
304             else {
305             croak "Don't know my package name '@{[__PACKAGE__]}'";
306             }
307              
308             #
309             # @ARGV wildcard globbing
310             #
311             sub import {
312              
313 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
314 0         0 my @argv = ();
315 0         0 for (@ARGV) {
316              
317             # has space
318 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
319 0 0       0 if (my @glob = Ekoi8u::glob(qq{"$_"})) {
320 0         0 push @argv, @glob;
321             }
322             else {
323 0         0 push @argv, $_;
324             }
325             }
326              
327             # has wildcard metachar
328             elsif (/\A (?:$q_char)*? [*?] /oxms) {
329 0 0       0 if (my @glob = Ekoi8u::glob($_)) {
330 0         0 push @argv, @glob;
331             }
332             else {
333 0         0 push @argv, $_;
334             }
335             }
336              
337             # no wildcard globbing
338             else {
339 0         0 push @argv, $_;
340             }
341             }
342 0         0 @ARGV = @argv;
343             }
344              
345 0         0 *Char::ord = \&KOI8U::ord;
346 0         0 *Char::ord_ = \&KOI8U::ord_;
347 0         0 *Char::reverse = \&KOI8U::reverse;
348 0         0 *Char::getc = \&KOI8U::getc;
349 0         0 *Char::length = \&KOI8U::length;
350 0         0 *Char::substr = \&KOI8U::substr;
351 0         0 *Char::index = \&KOI8U::index;
352 0         0 *Char::rindex = \&KOI8U::rindex;
353 0         0 *Char::eval = \&KOI8U::eval;
354 0         0 *Char::escape = \&KOI8U::escape;
355 0         0 *Char::escape_token = \&KOI8U::escape_token;
356 0         0 *Char::escape_script = \&KOI8U::escape_script;
357             }
358              
359             # P.230 Care with Prototypes
360             # in Chapter 6: Subroutines
361             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
362             #
363             # If you aren't careful, you can get yourself into trouble with prototypes.
364             # But if you are careful, you can do a lot of neat things with them. This is
365             # all very powerful, of course, and should only be used in moderation to make
366             # the world a better place.
367              
368             # P.332 Care with Prototypes
369             # in Chapter 7: Subroutines
370             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
371             #
372             # If you aren't careful, you can get yourself into trouble with prototypes.
373             # But if you are careful, you can do a lot of neat things with them. This is
374             # all very powerful, of course, and should only be used in moderation to make
375             # the world a better place.
376              
377             #
378             # Prototypes of subroutines
379             #
380       0     sub unimport {}
381             sub Ekoi8u::split(;$$$);
382             sub Ekoi8u::tr($$$$;$);
383             sub Ekoi8u::chop(@);
384             sub Ekoi8u::index($$;$);
385             sub Ekoi8u::rindex($$;$);
386             sub Ekoi8u::lcfirst(@);
387             sub Ekoi8u::lcfirst_();
388             sub Ekoi8u::lc(@);
389             sub Ekoi8u::lc_();
390             sub Ekoi8u::ucfirst(@);
391             sub Ekoi8u::ucfirst_();
392             sub Ekoi8u::uc(@);
393             sub Ekoi8u::uc_();
394             sub Ekoi8u::fc(@);
395             sub Ekoi8u::fc_();
396             sub Ekoi8u::ignorecase;
397             sub Ekoi8u::classic_character_class;
398             sub Ekoi8u::capture;
399             sub Ekoi8u::chr(;$);
400             sub Ekoi8u::chr_();
401             sub Ekoi8u::glob($);
402             sub Ekoi8u::glob_();
403              
404             sub KOI8U::ord(;$);
405             sub KOI8U::ord_();
406             sub KOI8U::reverse(@);
407             sub KOI8U::getc(;*@);
408             sub KOI8U::length(;$);
409             sub KOI8U::substr($$;$$);
410             sub KOI8U::index($$;$);
411             sub KOI8U::rindex($$;$);
412             sub KOI8U::escape(;$);
413              
414             #
415             # Regexp work
416             #
417 204         16787 use vars qw(
418             $re_a
419             $re_t
420             $re_n
421             $re_r
422 204     204   1492 );
  204         407  
423              
424             #
425             # Character class
426             #
427 204         1707835 use vars qw(
428             $dot
429             $dot_s
430             $eD
431             $eS
432             $eW
433             $eH
434             $eV
435             $eR
436             $eN
437             $not_alnum
438             $not_alpha
439             $not_ascii
440             $not_blank
441             $not_cntrl
442             $not_digit
443             $not_graph
444             $not_lower
445             $not_lower_i
446             $not_print
447             $not_punct
448             $not_space
449             $not_upper
450             $not_upper_i
451             $not_word
452             $not_xdigit
453             $eb
454             $eB
455 204     204   1228 );
  204         362  
456              
457             ${Ekoi8u::dot} = qr{(?>[^\x0A])};
458             ${Ekoi8u::dot_s} = qr{(?>[\x00-\xFF])};
459             ${Ekoi8u::eD} = qr{(?>[^0-9])};
460              
461             # Vertical tabs are now whitespace
462             # \s in a regex now matches a vertical tab in all circumstances.
463             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
464             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
465             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
466             ${Ekoi8u::eS} = qr{(?>[^\s])};
467              
468             ${Ekoi8u::eW} = qr{(?>[^0-9A-Z_a-z])};
469             ${Ekoi8u::eH} = qr{(?>[^\x09\x20])};
470             ${Ekoi8u::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
471             ${Ekoi8u::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
472             ${Ekoi8u::eN} = qr{(?>[^\x0A])};
473             ${Ekoi8u::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
474             ${Ekoi8u::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
475             ${Ekoi8u::not_ascii} = qr{(?>[^\x00-\x7F])};
476             ${Ekoi8u::not_blank} = qr{(?>[^\x09\x20])};
477             ${Ekoi8u::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
478             ${Ekoi8u::not_digit} = qr{(?>[^\x30-\x39])};
479             ${Ekoi8u::not_graph} = qr{(?>[^\x21-\x7F])};
480             ${Ekoi8u::not_lower} = qr{(?>[^\x61-\x7A])};
481             ${Ekoi8u::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
482             # ${Ekoi8u::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
483             ${Ekoi8u::not_print} = qr{(?>[^\x20-\x7F])};
484             ${Ekoi8u::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
485             ${Ekoi8u::not_space} = qr{(?>[^\s\x0B])};
486             ${Ekoi8u::not_upper} = qr{(?>[^\x41-\x5A])};
487             ${Ekoi8u::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
488             # ${Ekoi8u::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
489             ${Ekoi8u::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
490             ${Ekoi8u::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
491             ${Ekoi8u::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))};
492             ${Ekoi8u::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]))};
493              
494             # avoid: Name "Ekoi8u::foo" used only once: possible typo at here.
495             ${Ekoi8u::dot} = ${Ekoi8u::dot};
496             ${Ekoi8u::dot_s} = ${Ekoi8u::dot_s};
497             ${Ekoi8u::eD} = ${Ekoi8u::eD};
498             ${Ekoi8u::eS} = ${Ekoi8u::eS};
499             ${Ekoi8u::eW} = ${Ekoi8u::eW};
500             ${Ekoi8u::eH} = ${Ekoi8u::eH};
501             ${Ekoi8u::eV} = ${Ekoi8u::eV};
502             ${Ekoi8u::eR} = ${Ekoi8u::eR};
503             ${Ekoi8u::eN} = ${Ekoi8u::eN};
504             ${Ekoi8u::not_alnum} = ${Ekoi8u::not_alnum};
505             ${Ekoi8u::not_alpha} = ${Ekoi8u::not_alpha};
506             ${Ekoi8u::not_ascii} = ${Ekoi8u::not_ascii};
507             ${Ekoi8u::not_blank} = ${Ekoi8u::not_blank};
508             ${Ekoi8u::not_cntrl} = ${Ekoi8u::not_cntrl};
509             ${Ekoi8u::not_digit} = ${Ekoi8u::not_digit};
510             ${Ekoi8u::not_graph} = ${Ekoi8u::not_graph};
511             ${Ekoi8u::not_lower} = ${Ekoi8u::not_lower};
512             ${Ekoi8u::not_lower_i} = ${Ekoi8u::not_lower_i};
513             ${Ekoi8u::not_print} = ${Ekoi8u::not_print};
514             ${Ekoi8u::not_punct} = ${Ekoi8u::not_punct};
515             ${Ekoi8u::not_space} = ${Ekoi8u::not_space};
516             ${Ekoi8u::not_upper} = ${Ekoi8u::not_upper};
517             ${Ekoi8u::not_upper_i} = ${Ekoi8u::not_upper_i};
518             ${Ekoi8u::not_word} = ${Ekoi8u::not_word};
519             ${Ekoi8u::not_xdigit} = ${Ekoi8u::not_xdigit};
520             ${Ekoi8u::eb} = ${Ekoi8u::eb};
521             ${Ekoi8u::eB} = ${Ekoi8u::eB};
522              
523             #
524             # KOI8-U split
525             #
526             sub Ekoi8u::split(;$$$) {
527              
528             # P.794 29.2.161. split
529             # in Chapter 29: Functions
530             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
531              
532             # P.951 split
533             # in Chapter 27: Functions
534             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
535              
536 0     0 0 0 my $pattern = $_[0];
537 0         0 my $string = $_[1];
538 0         0 my $limit = $_[2];
539              
540             # if $pattern is also omitted or is the literal space, " "
541 0 0       0 if (not defined $pattern) {
542 0         0 $pattern = ' ';
543             }
544              
545             # if $string is omitted, the function splits the $_ string
546 0 0       0 if (not defined $string) {
547 0 0       0 if (defined $_) {
548 0         0 $string = $_;
549             }
550             else {
551 0         0 $string = '';
552             }
553             }
554              
555 0         0 my @split = ();
556              
557             # when string is empty
558 0 0       0 if ($string eq '') {
    0          
559              
560             # resulting list value in list context
561 0 0       0 if (wantarray) {
562 0         0 return @split;
563             }
564              
565             # count of substrings in scalar context
566             else {
567 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
568 0         0 @_ = @split;
569 0         0 return scalar @_;
570             }
571             }
572              
573             # split's first argument is more consistently interpreted
574             #
575             # After some changes earlier in v5.17, split's behavior has been simplified:
576             # if the PATTERN argument evaluates to a string containing one space, it is
577             # treated the way that a literal string containing one space once was.
578             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
579              
580             # if $pattern is also omitted or is the literal space, " ", the function splits
581             # on whitespace, /\s+/, after skipping any leading whitespace
582             # (and so on)
583              
584             elsif ($pattern eq ' ') {
585 0 0       0 if (not defined $limit) {
586 0         0 return CORE::split(' ', $string);
587             }
588             else {
589 0         0 return CORE::split(' ', $string, $limit);
590             }
591             }
592              
593             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
594 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
595              
596             # a pattern capable of matching either the null string or something longer than the
597             # null string will split the value of $string into separate characters wherever it
598             # matches the null string between characters
599             # (and so on)
600              
601 0 0       0 if ('' =~ / \A $pattern \z /xms) {
602 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
603 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
604              
605             # P.1024 Appendix W.10 Multibyte Processing
606             # of ISBN 1-56592-224-7 CJKV Information Processing
607             # (and so on)
608              
609             # the //m modifier is assumed when you split on the pattern /^/
610             # (and so on)
611              
612             # V
613 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
614              
615             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
616             # is included in the resulting list, interspersed with the fields that are ordinarily returned
617             # (and so on)
618              
619 0         0 local $@;
620 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
621 0         0 push @split, CORE::eval('$' . $digit);
622             }
623             }
624             }
625              
626             else {
627 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
628              
629             # V
630 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
631 0         0 local $@;
632 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
633 0         0 push @split, CORE::eval('$' . $digit);
634             }
635             }
636             }
637             }
638              
639             elsif ($limit > 0) {
640 0 0       0 if ('' =~ / \A $pattern \z /xms) {
641 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
642 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
643              
644             # V
645 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
646 0         0 local $@;
647 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
648 0         0 push @split, CORE::eval('$' . $digit);
649             }
650             }
651             }
652             }
653             else {
654 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
655 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
656              
657             # V
658 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
659 0         0 local $@;
660 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
661 0         0 push @split, CORE::eval('$' . $digit);
662             }
663             }
664             }
665             }
666             }
667              
668 0 0       0 if (CORE::length($string) > 0) {
669 0         0 push @split, $string;
670             }
671              
672             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
673 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
674 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
675 0         0 pop @split;
676             }
677             }
678              
679             # resulting list value in list context
680 0 0       0 if (wantarray) {
681 0         0 return @split;
682             }
683              
684             # count of substrings in scalar context
685             else {
686 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
687 0         0 @_ = @split;
688 0         0 return scalar @_;
689             }
690             }
691              
692             #
693             # get last subexpression offsets
694             #
695             sub _last_subexpression_offsets {
696 0     0   0 my $pattern = $_[0];
697              
698             # remove comment
699 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
700              
701 0         0 my $modifier = '';
702 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
703 0         0 $modifier = $1;
704 0         0 $modifier =~ s/-[A-Za-z]*//;
705             }
706              
707             # with /x modifier
708 0         0 my @char = ();
709 0 0       0 if ($modifier =~ /x/oxms) {
710 0         0 @char = $pattern =~ /\G((?>
711             [^\\\#\[\(] |
712             \\ $q_char |
713             \# (?>[^\n]*) $ |
714             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
715             \(\? |
716             $q_char
717             ))/oxmsg;
718             }
719              
720             # without /x modifier
721             else {
722 0         0 @char = $pattern =~ /\G((?>
723             [^\\\[\(] |
724             \\ $q_char |
725             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
726             \(\? |
727             $q_char
728             ))/oxmsg;
729             }
730              
731 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
732             }
733              
734             #
735             # KOI8-U transliteration (tr///)
736             #
737             sub Ekoi8u::tr($$$$;$) {
738              
739 0     0 0 0 my $bind_operator = $_[1];
740 0         0 my $searchlist = $_[2];
741 0         0 my $replacementlist = $_[3];
742 0   0     0 my $modifier = $_[4] || '';
743              
744 0 0       0 if ($modifier =~ /r/oxms) {
745 0 0       0 if ($bind_operator =~ / !~ /oxms) {
746 0         0 croak "Using !~ with tr///r doesn't make sense";
747             }
748             }
749              
750 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
751 0         0 my @searchlist = _charlist_tr($searchlist);
752 0         0 my @replacementlist = _charlist_tr($replacementlist);
753              
754 0         0 my %tr = ();
755 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
756 0 0       0 if (not exists $tr{$searchlist[$i]}) {
757 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
758 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
759             }
760             elsif ($modifier =~ /d/oxms) {
761 0         0 $tr{$searchlist[$i]} = '';
762             }
763             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
764 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
765             }
766             else {
767 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
768             }
769             }
770             }
771              
772 0         0 my $tr = 0;
773 0         0 my $replaced = '';
774 0 0       0 if ($modifier =~ /c/oxms) {
775 0         0 while (defined(my $char = shift @char)) {
776 0 0       0 if (not exists $tr{$char}) {
777 0 0       0 if (defined $replacementlist[0]) {
778 0         0 $replaced .= $replacementlist[0];
779             }
780 0         0 $tr++;
781 0 0       0 if ($modifier =~ /s/oxms) {
782 0   0     0 while (@char and (not exists $tr{$char[0]})) {
783 0         0 shift @char;
784 0         0 $tr++;
785             }
786             }
787             }
788             else {
789 0         0 $replaced .= $char;
790             }
791             }
792             }
793             else {
794 0         0 while (defined(my $char = shift @char)) {
795 0 0       0 if (exists $tr{$char}) {
796 0         0 $replaced .= $tr{$char};
797 0         0 $tr++;
798 0 0       0 if ($modifier =~ /s/oxms) {
799 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
800 0         0 shift @char;
801 0         0 $tr++;
802             }
803             }
804             }
805             else {
806 0         0 $replaced .= $char;
807             }
808             }
809             }
810              
811 0 0       0 if ($modifier =~ /r/oxms) {
812 0         0 return $replaced;
813             }
814             else {
815 0         0 $_[0] = $replaced;
816 0 0       0 if ($bind_operator =~ / !~ /oxms) {
817 0         0 return not $tr;
818             }
819             else {
820 0         0 return $tr;
821             }
822             }
823             }
824              
825             #
826             # KOI8-U chop
827             #
828             sub Ekoi8u::chop(@) {
829              
830 0     0 0 0 my $chop;
831 0 0       0 if (@_ == 0) {
832 0         0 my @char = /\G (?>$q_char) /oxmsg;
833 0         0 $chop = pop @char;
834 0         0 $_ = join '', @char;
835             }
836             else {
837 0         0 for (@_) {
838 0         0 my @char = /\G (?>$q_char) /oxmsg;
839 0         0 $chop = pop @char;
840 0         0 $_ = join '', @char;
841             }
842             }
843 0         0 return $chop;
844             }
845              
846             #
847             # KOI8-U index by octet
848             #
849             sub Ekoi8u::index($$;$) {
850              
851 0     0 1 0 my($str,$substr,$position) = @_;
852 0   0     0 $position ||= 0;
853 0         0 my $pos = 0;
854              
855 0         0 while ($pos < CORE::length($str)) {
856 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
857 0 0       0 if ($pos >= $position) {
858 0         0 return $pos;
859             }
860             }
861 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
862 0         0 $pos += CORE::length($1);
863             }
864             else {
865 0         0 $pos += 1;
866             }
867             }
868 0         0 return -1;
869             }
870              
871             #
872             # KOI8-U reverse index
873             #
874             sub Ekoi8u::rindex($$;$) {
875              
876 0     0 0 0 my($str,$substr,$position) = @_;
877 0   0     0 $position ||= CORE::length($str) - 1;
878 0         0 my $pos = 0;
879 0         0 my $rindex = -1;
880              
881 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
882 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
883 0         0 $rindex = $pos;
884             }
885 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
886 0         0 $pos += CORE::length($1);
887             }
888             else {
889 0         0 $pos += 1;
890             }
891             }
892 0         0 return $rindex;
893             }
894              
895             #
896             # KOI8-U lower case first with parameter
897             #
898             sub Ekoi8u::lcfirst(@) {
899 0 0   0 0 0 if (@_) {
900 0         0 my $s = shift @_;
901 0 0 0     0 if (@_ and wantarray) {
902 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
903             }
904             else {
905 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
906             }
907             }
908             else {
909 0         0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
910             }
911             }
912              
913             #
914             # KOI8-U lower case first without parameter
915             #
916             sub Ekoi8u::lcfirst_() {
917 0     0 0 0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
918             }
919              
920             #
921             # KOI8-U lower case with parameter
922             #
923             sub Ekoi8u::lc(@) {
924 0 0   0 0 0 if (@_) {
925 0         0 my $s = shift @_;
926 0 0 0     0 if (@_ and wantarray) {
927 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
928             }
929             else {
930 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
931             }
932             }
933             else {
934 0         0 return Ekoi8u::lc_();
935             }
936             }
937              
938             #
939             # KOI8-U lower case without parameter
940             #
941             sub Ekoi8u::lc_() {
942 0     0 0 0 my $s = $_;
943 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
944             }
945              
946             #
947             # KOI8-U upper case first with parameter
948             #
949             sub Ekoi8u::ucfirst(@) {
950 0 0   0 0 0 if (@_) {
951 0         0 my $s = shift @_;
952 0 0 0     0 if (@_ and wantarray) {
953 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
954             }
955             else {
956 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
957             }
958             }
959             else {
960 0         0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
961             }
962             }
963              
964             #
965             # KOI8-U upper case first without parameter
966             #
967             sub Ekoi8u::ucfirst_() {
968 0     0 0 0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
969             }
970              
971             #
972             # KOI8-U upper case with parameter
973             #
974             sub Ekoi8u::uc(@) {
975 0 50   174 0 0 if (@_) {
976 174         280 my $s = shift @_;
977 174 50 33     217 if (@_ and wantarray) {
978 174 0       310 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
979             }
980             else {
981 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         537  
982             }
983             }
984             else {
985 174         614 return Ekoi8u::uc_();
986             }
987             }
988              
989             #
990             # KOI8-U upper case without parameter
991             #
992             sub Ekoi8u::uc_() {
993 0     0 0 0 my $s = $_;
994 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
995             }
996              
997             #
998             # KOI8-U fold case with parameter
999             #
1000             sub Ekoi8u::fc(@) {
1001 0 50   197 0 0 if (@_) {
1002 197         282 my $s = shift @_;
1003 197 50 33     239 if (@_ and wantarray) {
1004 197 0       358 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1005             }
1006             else {
1007 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         510  
1008             }
1009             }
1010             else {
1011 197         1079 return Ekoi8u::fc_();
1012             }
1013             }
1014              
1015             #
1016             # KOI8-U fold case without parameter
1017             #
1018             sub Ekoi8u::fc_() {
1019 0     0 0 0 my $s = $_;
1020 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1021             }
1022              
1023             #
1024             # KOI8-U regexp capture
1025             #
1026             {
1027             sub Ekoi8u::capture {
1028 0     0 1 0 return $_[0];
1029             }
1030             }
1031              
1032             #
1033             # KOI8-U regexp ignore case modifier
1034             #
1035             sub Ekoi8u::ignorecase {
1036              
1037 0     0 0 0 my @string = @_;
1038 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1039              
1040             # ignore case of $scalar or @array
1041 0         0 for my $string (@string) {
1042              
1043             # split regexp
1044 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1045              
1046             # unescape character
1047 0         0 for (my $i=0; $i <= $#char; $i++) {
1048 0 0       0 next if not defined $char[$i];
1049              
1050             # open character class [...]
1051 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1052 0         0 my $left = $i;
1053              
1054             # [] make die "unmatched [] in regexp ...\n"
1055              
1056 0 0       0 if ($char[$i+1] eq ']') {
1057 0         0 $i++;
1058             }
1059              
1060 0         0 while (1) {
1061 0 0       0 if (++$i > $#char) {
1062 0         0 croak "Unmatched [] in regexp";
1063             }
1064 0 0       0 if ($char[$i] eq ']') {
1065 0         0 my $right = $i;
1066 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1067              
1068             # escape character
1069 0         0 for my $char (@charlist) {
1070 0 0       0 if (0) {
1071             }
1072              
1073 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1074 0         0 $char = '\\' . $char;
1075             }
1076             }
1077              
1078             # [...]
1079 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1080              
1081 0         0 $i = $left;
1082 0         0 last;
1083             }
1084             }
1085             }
1086              
1087             # open character class [^...]
1088             elsif ($char[$i] eq '[^') {
1089 0         0 my $left = $i;
1090              
1091             # [^] make die "unmatched [] in regexp ...\n"
1092              
1093 0 0       0 if ($char[$i+1] eq ']') {
1094 0         0 $i++;
1095             }
1096              
1097 0         0 while (1) {
1098 0 0       0 if (++$i > $#char) {
1099 0         0 croak "Unmatched [] in regexp";
1100             }
1101 0 0       0 if ($char[$i] eq ']') {
1102 0         0 my $right = $i;
1103 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1104              
1105             # escape character
1106 0         0 for my $char (@charlist) {
1107 0 0       0 if (0) {
1108             }
1109              
1110 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1111 0         0 $char = '\\' . $char;
1112             }
1113             }
1114              
1115             # [^...]
1116 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1117              
1118 0         0 $i = $left;
1119 0         0 last;
1120             }
1121             }
1122             }
1123              
1124             # rewrite classic character class or escape character
1125             elsif (my $char = classic_character_class($char[$i])) {
1126 0         0 $char[$i] = $char;
1127             }
1128              
1129             # with /i modifier
1130             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1131 0         0 my $uc = Ekoi8u::uc($char[$i]);
1132 0         0 my $fc = Ekoi8u::fc($char[$i]);
1133 0 0       0 if ($uc ne $fc) {
1134 0 0       0 if (CORE::length($fc) == 1) {
1135 0         0 $char[$i] = '[' . $uc . $fc . ']';
1136             }
1137             else {
1138 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1139             }
1140             }
1141             }
1142             }
1143              
1144             # characterize
1145 0         0 for (my $i=0; $i <= $#char; $i++) {
1146 0 0       0 next if not defined $char[$i];
1147              
1148 0 0       0 if (0) {
1149             }
1150              
1151             # quote character before ? + * {
1152 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1153 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1154 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1155             }
1156             }
1157             }
1158              
1159 0         0 $string = join '', @char;
1160             }
1161              
1162             # make regexp string
1163 0         0 return @string;
1164             }
1165              
1166             #
1167             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1168             #
1169             sub Ekoi8u::classic_character_class {
1170 0     1867 0 0 my($char) = @_;
1171              
1172             return {
1173             '\D' => '${Ekoi8u::eD}',
1174             '\S' => '${Ekoi8u::eS}',
1175             '\W' => '${Ekoi8u::eW}',
1176             '\d' => '[0-9]',
1177              
1178             # Before Perl 5.6, \s only matched the five whitespace characters
1179             # tab, newline, form-feed, carriage return, and the space character
1180             # itself, which, taken together, is the character class [\t\n\f\r ].
1181              
1182             # Vertical tabs are now whitespace
1183             # \s in a regex now matches a vertical tab in all circumstances.
1184             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1185             # \t \n \v \f \r space
1186             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1187             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1188             '\s' => '\s',
1189              
1190             '\w' => '[0-9A-Z_a-z]',
1191             '\C' => '[\x00-\xFF]',
1192             '\X' => 'X',
1193              
1194             # \h \v \H \V
1195              
1196             # P.114 Character Class Shortcuts
1197             # in Chapter 7: In the World of Regular Expressions
1198             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1199              
1200             # P.357 13.2.3 Whitespace
1201             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1202             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1203             #
1204             # 0x00009 CHARACTER TABULATION h s
1205             # 0x0000a LINE FEED (LF) vs
1206             # 0x0000b LINE TABULATION v
1207             # 0x0000c FORM FEED (FF) vs
1208             # 0x0000d CARRIAGE RETURN (CR) vs
1209             # 0x00020 SPACE h s
1210              
1211             # P.196 Table 5-9. Alphanumeric regex metasymbols
1212             # in Chapter 5. Pattern Matching
1213             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1214              
1215             # (and so on)
1216              
1217             '\H' => '${Ekoi8u::eH}',
1218             '\V' => '${Ekoi8u::eV}',
1219             '\h' => '[\x09\x20]',
1220             '\v' => '[\x0A\x0B\x0C\x0D]',
1221             '\R' => '${Ekoi8u::eR}',
1222              
1223             # \N
1224             #
1225             # http://perldoc.perl.org/perlre.html
1226             # Character Classes and other Special Escapes
1227             # Any character but \n (experimental). Not affected by /s modifier
1228              
1229             '\N' => '${Ekoi8u::eN}',
1230              
1231             # \b \B
1232              
1233             # P.180 Boundaries: The \b and \B Assertions
1234             # in Chapter 5: Pattern Matching
1235             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1236              
1237             # P.219 Boundaries: The \b and \B Assertions
1238             # in Chapter 5: Pattern Matching
1239             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1240              
1241             # \b really means (?:(?<=\w)(?!\w)|(?
1242             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1243             '\b' => '${Ekoi8u::eb}',
1244              
1245             # \B really means (?:(?<=\w)(?=\w)|(?
1246             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1247             '\B' => '${Ekoi8u::eB}',
1248              
1249 1867   100     2653 }->{$char} || '';
1250             }
1251              
1252             #
1253             # prepare KOI8-U characters per length
1254             #
1255              
1256             # 1 octet characters
1257             my @chars1 = ();
1258             sub chars1 {
1259 1867 0   0 0 64271 if (@chars1) {
1260 0         0 return @chars1;
1261             }
1262 0 0       0 if (exists $range_tr{1}) {
1263 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1264 0         0 while (my @range = splice(@ranges,0,1)) {
1265 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1266 0         0 push @chars1, pack 'C', $oct0;
1267             }
1268             }
1269             }
1270 0         0 return @chars1;
1271             }
1272              
1273             # 2 octets characters
1274             my @chars2 = ();
1275             sub chars2 {
1276 0 0   0 0 0 if (@chars2) {
1277 0         0 return @chars2;
1278             }
1279 0 0       0 if (exists $range_tr{2}) {
1280 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1281 0         0 while (my @range = splice(@ranges,0,2)) {
1282 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1283 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1284 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1285             }
1286             }
1287             }
1288             }
1289 0         0 return @chars2;
1290             }
1291              
1292             # 3 octets characters
1293             my @chars3 = ();
1294             sub chars3 {
1295 0 0   0 0 0 if (@chars3) {
1296 0         0 return @chars3;
1297             }
1298 0 0       0 if (exists $range_tr{3}) {
1299 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1300 0         0 while (my @range = splice(@ranges,0,3)) {
1301 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1302 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1303 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1304 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1305             }
1306             }
1307             }
1308             }
1309             }
1310 0         0 return @chars3;
1311             }
1312              
1313             # 4 octets characters
1314             my @chars4 = ();
1315             sub chars4 {
1316 0 0   0 0 0 if (@chars4) {
1317 0         0 return @chars4;
1318             }
1319 0 0       0 if (exists $range_tr{4}) {
1320 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1321 0         0 while (my @range = splice(@ranges,0,4)) {
1322 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1323 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1324 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1325 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1326 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1327             }
1328             }
1329             }
1330             }
1331             }
1332             }
1333 0         0 return @chars4;
1334             }
1335              
1336             #
1337             # KOI8-U open character list for tr
1338             #
1339             sub _charlist_tr {
1340              
1341 0     0   0 local $_ = shift @_;
1342              
1343             # unescape character
1344 0         0 my @char = ();
1345 0         0 while (not /\G \z/oxmsgc) {
1346 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1347 0         0 push @char, '\-';
1348             }
1349             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1350 0         0 push @char, CORE::chr(oct $1);
1351             }
1352             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1353 0         0 push @char, CORE::chr(hex $1);
1354             }
1355             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1356 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1357             }
1358             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1359             push @char, {
1360             '\0' => "\0",
1361             '\n' => "\n",
1362             '\r' => "\r",
1363             '\t' => "\t",
1364             '\f' => "\f",
1365             '\b' => "\x08", # \b means backspace in character class
1366             '\a' => "\a",
1367             '\e' => "\e",
1368 0         0 }->{$1};
1369             }
1370             elsif (/\G \\ ($q_char) /oxmsgc) {
1371 0         0 push @char, $1;
1372             }
1373             elsif (/\G ($q_char) /oxmsgc) {
1374 0         0 push @char, $1;
1375             }
1376             }
1377              
1378             # join separated multiple-octet
1379 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1380              
1381             # unescape '-'
1382 0         0 my @i = ();
1383 0         0 for my $i (0 .. $#char) {
1384 0 0       0 if ($char[$i] eq '\-') {
    0          
1385 0         0 $char[$i] = '-';
1386             }
1387             elsif ($char[$i] eq '-') {
1388 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1389 0         0 push @i, $i;
1390             }
1391             }
1392             }
1393              
1394             # open character list (reverse for splice)
1395 0         0 for my $i (CORE::reverse @i) {
1396 0         0 my @range = ();
1397              
1398             # range error
1399 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1400 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1401             }
1402              
1403             # range of multiple-octet code
1404 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1405 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1406 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1407             }
1408             elsif (CORE::length($char[$i+1]) == 2) {
1409 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1410 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1411             }
1412             elsif (CORE::length($char[$i+1]) == 3) {
1413 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1414 0         0 push @range, chars2();
1415 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1416             }
1417             elsif (CORE::length($char[$i+1]) == 4) {
1418 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1419 0         0 push @range, chars2();
1420 0         0 push @range, chars3();
1421 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1422             }
1423             else {
1424 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1425             }
1426             }
1427             elsif (CORE::length($char[$i-1]) == 2) {
1428 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1429 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1430             }
1431             elsif (CORE::length($char[$i+1]) == 3) {
1432 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1433 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1434             }
1435             elsif (CORE::length($char[$i+1]) == 4) {
1436 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1437 0         0 push @range, chars3();
1438 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1439             }
1440             else {
1441 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1442             }
1443             }
1444             elsif (CORE::length($char[$i-1]) == 3) {
1445 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1446 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1447             }
1448             elsif (CORE::length($char[$i+1]) == 4) {
1449 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1450 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1451             }
1452             else {
1453 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1454             }
1455             }
1456             elsif (CORE::length($char[$i-1]) == 4) {
1457 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1458 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1459             }
1460             else {
1461 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1462             }
1463             }
1464             else {
1465 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1466             }
1467              
1468 0         0 splice @char, $i-1, 3, @range;
1469             }
1470              
1471 0         0 return @char;
1472             }
1473              
1474             #
1475             # KOI8-U open character class
1476             #
1477             sub _cc {
1478 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1479 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1480             }
1481             elsif (scalar(@_) == 1) {
1482 0         0 return sprintf('\x%02X',$_[0]);
1483             }
1484             elsif (scalar(@_) == 2) {
1485 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1486 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1487             }
1488             elsif ($_[0] == $_[1]) {
1489 0         0 return sprintf('\x%02X',$_[0]);
1490             }
1491             elsif (($_[0]+1) == $_[1]) {
1492 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1493             }
1494             else {
1495 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1496             }
1497             }
1498             else {
1499 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1500             }
1501             }
1502              
1503             #
1504             # KOI8-U octet range
1505             #
1506             sub _octets {
1507 0     182   0 my $length = shift @_;
1508              
1509 182 50       295 if ($length == 1) {
1510 182         378 my($a1) = unpack 'C', $_[0];
1511 182         667 my($z1) = unpack 'C', $_[1];
1512              
1513 182 50       320 if ($a1 > $z1) {
1514 182         350 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1515             }
1516              
1517 0 50       0 if ($a1 == $z1) {
    50          
1518 182         411 return sprintf('\x%02X',$a1);
1519             }
1520             elsif (($a1+1) == $z1) {
1521 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1522             }
1523             else {
1524 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1525             }
1526             }
1527             else {
1528 182         1222 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1529             }
1530             }
1531              
1532             #
1533             # KOI8-U range regexp
1534             #
1535             sub _range_regexp {
1536 0     182   0 my($length,$first,$last) = @_;
1537              
1538 182         391 my @range_regexp = ();
1539 182 50       303 if (not exists $range_tr{$length}) {
1540 182         434 return @range_regexp;
1541             }
1542              
1543 0         0 my @ranges = @{ $range_tr{$length} };
  182         277  
1544 182         415 while (my @range = splice(@ranges,0,$length)) {
1545 182         637 my $min = '';
1546 182         272 my $max = '';
1547 182         241 for (my $i=0; $i < $length; $i++) {
1548 182         486 $min .= pack 'C', $range[$i][0];
1549 182         686 $max .= pack 'C', $range[$i][-1];
1550             }
1551              
1552             # min___max
1553             # FIRST_____________LAST
1554             # (nothing)
1555              
1556 182 50 33     436 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1557             }
1558              
1559             # **********
1560             # min_________max
1561             # FIRST_____________LAST
1562             # **********
1563              
1564             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1565 182         1983 push @range_regexp, _octets($length,$first,$max,$min,$max);
1566             }
1567              
1568             # **********************
1569             # min________________max
1570             # FIRST_____________LAST
1571             # **********************
1572              
1573             elsif (($min eq $first) and ($max eq $last)) {
1574 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1575             }
1576              
1577             # *********
1578             # min___max
1579             # FIRST_____________LAST
1580             # *********
1581              
1582             elsif (($first le $min) and ($max le $last)) {
1583 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1584             }
1585              
1586             # **********************
1587             # min__________________________max
1588             # FIRST_____________LAST
1589             # **********************
1590              
1591             elsif (($min le $first) and ($last le $max)) {
1592 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1593             }
1594              
1595             # *********
1596             # min________max
1597             # FIRST_____________LAST
1598             # *********
1599              
1600             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1601 182         454 push @range_regexp, _octets($length,$min,$last,$min,$max);
1602             }
1603              
1604             # min___max
1605             # FIRST_____________LAST
1606             # (nothing)
1607              
1608             elsif ($last lt $min) {
1609             }
1610              
1611             else {
1612 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1613             }
1614             }
1615              
1616 0         0 return @range_regexp;
1617             }
1618              
1619             #
1620             # KOI8-U open character list for qr and not qr
1621             #
1622             sub _charlist {
1623              
1624 182     358   409 my $modifier = pop @_;
1625 358         553 my @char = @_;
1626              
1627 358 100       765 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1628              
1629             # unescape character
1630 358         897 for (my $i=0; $i <= $#char; $i++) {
1631              
1632             # escape - to ...
1633 358 100 100     1330 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1634 1125 100 100     8362 if ((0 < $i) and ($i < $#char)) {
1635 206         1762 $char[$i] = '...';
1636             }
1637             }
1638              
1639             # octal escape sequence
1640             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1641 182         394 $char[$i] = octchr($1);
1642             }
1643              
1644             # hexadecimal escape sequence
1645             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1646 0         0 $char[$i] = hexchr($1);
1647             }
1648              
1649             # \b{...} --> b\{...}
1650             # \B{...} --> B\{...}
1651             # \N{CHARNAME} --> N\{CHARNAME}
1652             # \p{PROPERTY} --> p\{PROPERTY}
1653             # \P{PROPERTY} --> P\{PROPERTY}
1654             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1655 0         0 $char[$i] = $1 . '\\' . $2;
1656             }
1657              
1658             # \p, \P, \X --> p, P, X
1659             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1660 0         0 $char[$i] = $1;
1661             }
1662              
1663             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1664 0         0 $char[$i] = CORE::chr oct $1;
1665             }
1666             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1667 0         0 $char[$i] = CORE::chr hex $1;
1668             }
1669             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1670 22         100 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1671             }
1672             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1673             $char[$i] = {
1674             '\0' => "\0",
1675             '\n' => "\n",
1676             '\r' => "\r",
1677             '\t' => "\t",
1678             '\f' => "\f",
1679             '\b' => "\x08", # \b means backspace in character class
1680             '\a' => "\a",
1681             '\e' => "\e",
1682             '\d' => '[0-9]',
1683              
1684             # Vertical tabs are now whitespace
1685             # \s in a regex now matches a vertical tab in all circumstances.
1686             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1687             # \t \n \v \f \r space
1688             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1689             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1690             '\s' => '\s',
1691              
1692             '\w' => '[0-9A-Z_a-z]',
1693             '\D' => '${Ekoi8u::eD}',
1694             '\S' => '${Ekoi8u::eS}',
1695             '\W' => '${Ekoi8u::eW}',
1696              
1697             '\H' => '${Ekoi8u::eH}',
1698             '\V' => '${Ekoi8u::eV}',
1699             '\h' => '[\x09\x20]',
1700             '\v' => '[\x0A\x0B\x0C\x0D]',
1701             '\R' => '${Ekoi8u::eR}',
1702              
1703 0         0 }->{$1};
1704             }
1705              
1706             # POSIX-style character classes
1707             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1708             $char[$i] = {
1709              
1710             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1711             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1712             '[:^lower:]' => '${Ekoi8u::not_lower_i}',
1713             '[:^upper:]' => '${Ekoi8u::not_upper_i}',
1714              
1715 25         409 }->{$1};
1716             }
1717             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1718             $char[$i] = {
1719              
1720             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1721             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1722             '[:ascii:]' => '[\x00-\x7F]',
1723             '[:blank:]' => '[\x09\x20]',
1724             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1725             '[:digit:]' => '[\x30-\x39]',
1726             '[:graph:]' => '[\x21-\x7F]',
1727             '[:lower:]' => '[\x61-\x7A]',
1728             '[:print:]' => '[\x20-\x7F]',
1729             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1730              
1731             # P.174 POSIX-Style Character Classes
1732             # in Chapter 5: Pattern Matching
1733             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1734              
1735             # P.311 11.2.4 Character Classes and other Special Escapes
1736             # in Chapter 11: perlre: Perl regular expressions
1737             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1738              
1739             # P.210 POSIX-Style Character Classes
1740             # in Chapter 5: Pattern Matching
1741             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1742              
1743             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1744              
1745             '[:upper:]' => '[\x41-\x5A]',
1746             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1747             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1748             '[:^alnum:]' => '${Ekoi8u::not_alnum}',
1749             '[:^alpha:]' => '${Ekoi8u::not_alpha}',
1750             '[:^ascii:]' => '${Ekoi8u::not_ascii}',
1751             '[:^blank:]' => '${Ekoi8u::not_blank}',
1752             '[:^cntrl:]' => '${Ekoi8u::not_cntrl}',
1753             '[:^digit:]' => '${Ekoi8u::not_digit}',
1754             '[:^graph:]' => '${Ekoi8u::not_graph}',
1755             '[:^lower:]' => '${Ekoi8u::not_lower}',
1756             '[:^print:]' => '${Ekoi8u::not_print}',
1757             '[:^punct:]' => '${Ekoi8u::not_punct}',
1758             '[:^space:]' => '${Ekoi8u::not_space}',
1759             '[:^upper:]' => '${Ekoi8u::not_upper}',
1760             '[:^word:]' => '${Ekoi8u::not_word}',
1761             '[:^xdigit:]' => '${Ekoi8u::not_xdigit}',
1762              
1763 8         72 }->{$1};
1764             }
1765             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1766 70         1366 $char[$i] = $1;
1767             }
1768             }
1769              
1770             # open character list
1771 7         30 my @singleoctet = ();
1772 358         607 my @multipleoctet = ();
1773 358         509 for (my $i=0; $i <= $#char; ) {
1774              
1775             # escaped -
1776 358 100 100     839 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1777 943         4075 $i += 1;
1778 182         246 next;
1779             }
1780              
1781             # make range regexp
1782             elsif ($char[$i] eq '...') {
1783              
1784             # range error
1785 182 50       410 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1786 182         763 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1787             }
1788             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1789 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1790 182         454 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1791             }
1792             }
1793              
1794             # make range regexp per length
1795 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1796 182         544 my @regexp = ();
1797              
1798             # is first and last
1799 182 50 33     281 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1800 182         592 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1801             }
1802              
1803             # is first
1804             elsif ($length == CORE::length($char[$i-1])) {
1805 182         453 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1806             }
1807              
1808             # is inside in first and last
1809             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1810 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1811             }
1812              
1813             # is last
1814             elsif ($length == CORE::length($char[$i+1])) {
1815 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1816             }
1817              
1818             else {
1819 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1820             }
1821              
1822 0 50       0 if ($length == 1) {
1823 182         405 push @singleoctet, @regexp;
1824             }
1825             else {
1826 182         434 push @multipleoctet, @regexp;
1827             }
1828             }
1829              
1830 0         0 $i += 2;
1831             }
1832              
1833             # with /i modifier
1834             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1835 182 100       1088 if ($modifier =~ /i/oxms) {
1836 493         786 my $uc = Ekoi8u::uc($char[$i]);
1837 24         45 my $fc = Ekoi8u::fc($char[$i]);
1838 24 100       49 if ($uc ne $fc) {
1839 24 50       43 if (CORE::length($fc) == 1) {
1840 12         29 push @singleoctet, $uc, $fc;
1841             }
1842             else {
1843 12         22 push @singleoctet, $uc;
1844 0         0 push @multipleoctet, $fc;
1845             }
1846             }
1847             else {
1848 0         0 push @singleoctet, $char[$i];
1849             }
1850             }
1851             else {
1852 12         26 push @singleoctet, $char[$i];
1853             }
1854 469         802 $i += 1;
1855             }
1856              
1857             # single character of single octet code
1858             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1859 493         913 push @singleoctet, "\t", "\x20";
1860 0         0 $i += 1;
1861             }
1862             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1863 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1864 0         0 $i += 1;
1865             }
1866             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1867 0         0 push @singleoctet, $char[$i];
1868 2         6 $i += 1;
1869             }
1870              
1871             # single character of multiple-octet code
1872             else {
1873 2         10 push @multipleoctet, $char[$i];
1874 84         192 $i += 1;
1875             }
1876             }
1877              
1878             # quote metachar
1879 84         172 for (@singleoctet) {
1880 358 50       748 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1881 689         3272 $_ = '-';
1882             }
1883             elsif (/\A \n \z/oxms) {
1884 0         0 $_ = '\n';
1885             }
1886             elsif (/\A \r \z/oxms) {
1887 8         17 $_ = '\r';
1888             }
1889             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1890 8         17 $_ = sprintf('\x%02X', CORE::ord $1);
1891             }
1892             elsif (/\A [\x00-\xFF] \z/oxms) {
1893 60         199 $_ = quotemeta $_;
1894             }
1895             }
1896              
1897             # return character list
1898 429         752 return \@singleoctet, \@multipleoctet;
1899             }
1900              
1901             #
1902             # KOI8-U octal escape sequence
1903             #
1904             sub octchr {
1905 358     5 0 1217 my($octdigit) = @_;
1906              
1907 5         14 my @binary = ();
1908 5         7 for my $octal (split(//,$octdigit)) {
1909             push @binary, {
1910             '0' => '000',
1911             '1' => '001',
1912             '2' => '010',
1913             '3' => '011',
1914             '4' => '100',
1915             '5' => '101',
1916             '6' => '110',
1917             '7' => '111',
1918 5         28 }->{$octal};
1919             }
1920 50         169 my $binary = join '', @binary;
1921              
1922             my $octchr = {
1923             # 1234567
1924             1 => pack('B*', "0000000$binary"),
1925             2 => pack('B*', "000000$binary"),
1926             3 => pack('B*', "00000$binary"),
1927             4 => pack('B*', "0000$binary"),
1928             5 => pack('B*', "000$binary"),
1929             6 => pack('B*', "00$binary"),
1930             7 => pack('B*', "0$binary"),
1931             0 => pack('B*', "$binary"),
1932              
1933 5         15 }->{CORE::length($binary) % 8};
1934              
1935 5         54 return $octchr;
1936             }
1937              
1938             #
1939             # KOI8-U hexadecimal escape sequence
1940             #
1941             sub hexchr {
1942 5     5 0 18 my($hexdigit) = @_;
1943              
1944             my $hexchr = {
1945             1 => pack('H*', "0$hexdigit"),
1946             0 => pack('H*', "$hexdigit"),
1947              
1948 5         13 }->{CORE::length($_[0]) % 2};
1949              
1950 5         40 return $hexchr;
1951             }
1952              
1953             #
1954             # KOI8-U open character list for qr
1955             #
1956             sub charlist_qr {
1957              
1958 5     314 0 18 my $modifier = pop @_;
1959 314         617 my @char = @_;
1960              
1961 314         799 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1962 314         935 my @singleoctet = @$singleoctet;
1963 314         696 my @multipleoctet = @$multipleoctet;
1964              
1965             # return character list
1966 314 100       528 if (scalar(@singleoctet) >= 1) {
1967              
1968             # with /i modifier
1969 314 100       1136 if ($modifier =~ m/i/oxms) {
1970 236         477 my %singleoctet_ignorecase = ();
1971 22         32 for (@singleoctet) {
1972 22   100     40 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1973 46         210 for my $ord (hex($1) .. hex($2)) {
1974 46         131 my $char = CORE::chr($ord);
1975 66         102 my $uc = Ekoi8u::uc($char);
1976 66         91 my $fc = Ekoi8u::fc($char);
1977 66 100       111 if ($uc eq $fc) {
1978 66         110 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1979             }
1980             else {
1981 12 50       87 if (CORE::length($fc) == 1) {
1982 54         70 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1983 54         115 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1984             }
1985             else {
1986 54         193 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1987 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1988             }
1989             }
1990             }
1991             }
1992 0 50       0 if ($_ ne '') {
1993 46         93 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1994             }
1995             }
1996 0         0 my $i = 0;
1997 22         26 my @singleoctet_ignorecase = ();
1998 22         32 for my $ord (0 .. 255) {
1999 22 100       39 if (exists $singleoctet_ignorecase{$ord}) {
2000 5632         6299 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         88  
2001             }
2002             else {
2003 96         206 $i++;
2004             }
2005             }
2006 5536         5381 @singleoctet = ();
2007 22         63 for my $range (@singleoctet_ignorecase) {
2008 22 100       61 if (ref $range) {
2009 3648 100       5494 if (scalar(@{$range}) == 1) {
  56 50       55  
2010 56         93 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         40  
2011             }
2012 36         114 elsif (scalar(@{$range}) == 2) {
2013 20         27 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2014             }
2015             else {
2016 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         23  
  20         22  
2017             }
2018             }
2019             }
2020             }
2021              
2022 20         100 my $not_anchor = '';
2023              
2024 236         376 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2025             }
2026 236 100       686 if (scalar(@multipleoctet) >= 2) {
2027 314         654 return '(?:' . join('|', @multipleoctet) . ')';
2028             }
2029             else {
2030 6         30 return $multipleoctet[0];
2031             }
2032             }
2033              
2034             #
2035             # KOI8-U open character list for not qr
2036             #
2037             sub charlist_not_qr {
2038              
2039 308     44 0 1323 my $modifier = pop @_;
2040 44         82 my @char = @_;
2041              
2042 44         96 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2043 44         114 my @singleoctet = @$singleoctet;
2044 44         91 my @multipleoctet = @$multipleoctet;
2045              
2046             # with /i modifier
2047 44 100       65 if ($modifier =~ m/i/oxms) {
2048 44         114 my %singleoctet_ignorecase = ();
2049 10         13 for (@singleoctet) {
2050 10   66     13 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2051 10         41 for my $ord (hex($1) .. hex($2)) {
2052 10         32 my $char = CORE::chr($ord);
2053 30         41 my $uc = Ekoi8u::uc($char);
2054 30         49 my $fc = Ekoi8u::fc($char);
2055 30 50       42 if ($uc eq $fc) {
2056 30         45 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2057             }
2058             else {
2059 0 50       0 if (CORE::length($fc) == 1) {
2060 30         36 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2061 30         66 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2062             }
2063             else {
2064 30         94 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2065 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2066             }
2067             }
2068             }
2069             }
2070 0 50       0 if ($_ ne '') {
2071 10         23 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2072             }
2073             }
2074 0         0 my $i = 0;
2075 10         15 my @singleoctet_ignorecase = ();
2076 10         12 for my $ord (0 .. 255) {
2077 10 100       13 if (exists $singleoctet_ignorecase{$ord}) {
2078 2560         2865 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         52  
2079             }
2080             else {
2081 60         97 $i++;
2082             }
2083             }
2084 2500         2483 @singleoctet = ();
2085 10         15 for my $range (@singleoctet_ignorecase) {
2086 10 100       23 if (ref $range) {
2087 960 50       1456 if (scalar(@{$range}) == 1) {
  20 50       21  
2088 20         33 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2089             }
2090 0         0 elsif (scalar(@{$range}) == 2) {
2091 20         22 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2092             }
2093             else {
2094 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         27  
  20         30  
2095             }
2096             }
2097             }
2098             }
2099              
2100             # return character list
2101 20 50       83 if (scalar(@multipleoctet) >= 1) {
2102 44 0       93 if (scalar(@singleoctet) >= 1) {
2103              
2104             # any character other than multiple-octet and single octet character class
2105 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2106             }
2107             else {
2108              
2109             # any character other than multiple-octet character class
2110 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2111             }
2112             }
2113             else {
2114 0 50       0 if (scalar(@singleoctet) >= 1) {
2115              
2116             # any character other than single octet character class
2117 44         119 return '(?:[^' . join('', @singleoctet) . '])';
2118             }
2119             else {
2120              
2121             # any character
2122 44         241 return "(?:$your_char)";
2123             }
2124             }
2125             }
2126              
2127             #
2128             # open file in read mode
2129             #
2130             sub _open_r {
2131 0     408   0 my(undef,$file) = @_;
2132 204     204   1926 use Fcntl qw(O_RDONLY);
  204         476  
  204         25674  
2133 408         1109 return CORE::sysopen($_[0], $file, &O_RDONLY);
2134             }
2135              
2136             #
2137             # open file in append mode
2138             #
2139             sub _open_a {
2140 408     204   17253 my(undef,$file) = @_;
2141 204     204   1514 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  204         464  
  204         538199  
2142 204         630 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2143             }
2144              
2145             #
2146             # safe system
2147             #
2148             sub _systemx {
2149              
2150             # P.707 29.2.33. exec
2151             # in Chapter 29: Functions
2152             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2153             #
2154             # Be aware that in older releases of Perl, exec (and system) did not flush
2155             # your output buffer, so you needed to enable command buffering by setting $|
2156             # on one or more filehandles to avoid lost output in the case of exec, or
2157             # misordererd output in the case of system. This situation was largely remedied
2158             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2159              
2160             # P.855 exec
2161             # in Chapter 27: Functions
2162             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2163             #
2164             # In very old release of Perl (before v5.6), exec (and system) did not flush
2165             # your output buffer, so you needed to enable command buffering by setting $|
2166             # on one or more filehandles to avoid lost output with exec or misordered
2167             # output with system.
2168              
2169 204     204   23995 $| = 1;
2170              
2171             # P.565 23.1.2. Cleaning Up Your Environment
2172             # in Chapter 23: Security
2173             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2174              
2175             # P.656 Cleaning Up Your Environment
2176             # in Chapter 20: Security
2177             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2178              
2179             # local $ENV{'PATH'} = '.';
2180 204         658 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2181              
2182             # P.707 29.2.33. exec
2183             # in Chapter 29: Functions
2184             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2185             #
2186             # As we mentioned earlier, exec treats a discrete list of arguments as an
2187             # indication that it should bypass shell processing. However, there is one
2188             # place where you might still get tripped up. The exec call (and system, too)
2189             # will not distinguish between a single scalar argument and an array containing
2190             # only one element.
2191             #
2192             # @args = ("echo surprise"); # just one element in list
2193             # exec @args # still subject to shell escapes
2194             # or die "exec: $!"; # because @args == 1
2195             #
2196             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2197             # first argument as the pathname, which forces the rest of the arguments to be
2198             # interpreted as a list, even if there is only one of them:
2199             #
2200             # exec { $args[0] } @args # safe even with one-argument list
2201             # or die "can't exec @args: $!";
2202              
2203             # P.855 exec
2204             # in Chapter 27: Functions
2205             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2206             #
2207             # As we mentioned earlier, exec treats a discrete list of arguments as a
2208             # directive to bypass shell processing. However, there is one place where
2209             # you might still get tripped up. The exec call (and system, too) cannot
2210             # distinguish between a single scalar argument and an array containing
2211             # only one element.
2212             #
2213             # @args = ("echo surprise"); # just one element in list
2214             # exec @args # still subject to shell escapes
2215             # || die "exec: $!"; # because @args == 1
2216             #
2217             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2218             # argument as the pathname, which forces the rest of the arguments to be
2219             # interpreted as a list, even if there is only one of them:
2220             #
2221             # exec { $args[0] } @args # safe even with one-argument list
2222             # || die "can't exec @args: $!";
2223              
2224 204         1635 return CORE::system { $_[0] } @_; # safe even with one-argument list
  204         418  
2225             }
2226              
2227             #
2228             # KOI8-U order to character (with parameter)
2229             #
2230             sub Ekoi8u::chr(;$) {
2231              
2232 204 0   0 0 14450720 my $c = @_ ? $_[0] : $_;
2233              
2234 0 0       0 if ($c == 0x00) {
2235 0         0 return "\x00";
2236             }
2237             else {
2238 0         0 my @chr = ();
2239 0         0 while ($c > 0) {
2240 0         0 unshift @chr, ($c % 0x100);
2241 0         0 $c = int($c / 0x100);
2242             }
2243 0         0 return pack 'C*', @chr;
2244             }
2245             }
2246              
2247             #
2248             # KOI8-U order to character (without parameter)
2249             #
2250             sub Ekoi8u::chr_() {
2251              
2252 0     0 0 0 my $c = $_;
2253              
2254 0 0       0 if ($c == 0x00) {
2255 0         0 return "\x00";
2256             }
2257             else {
2258 0         0 my @chr = ();
2259 0         0 while ($c > 0) {
2260 0         0 unshift @chr, ($c % 0x100);
2261 0         0 $c = int($c / 0x100);
2262             }
2263 0         0 return pack 'C*', @chr;
2264             }
2265             }
2266              
2267             #
2268             # KOI8-U path globbing (with parameter)
2269             #
2270             sub Ekoi8u::glob($) {
2271              
2272 0 0   0 0 0 if (wantarray) {
2273 0         0 my @glob = _DOS_like_glob(@_);
2274 0         0 for my $glob (@glob) {
2275 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2276             }
2277 0         0 return @glob;
2278             }
2279             else {
2280 0         0 my $glob = _DOS_like_glob(@_);
2281 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2282 0         0 return $glob;
2283             }
2284             }
2285              
2286             #
2287             # KOI8-U path globbing (without parameter)
2288             #
2289             sub Ekoi8u::glob_() {
2290              
2291 0 0   0 0 0 if (wantarray) {
2292 0         0 my @glob = _DOS_like_glob();
2293 0         0 for my $glob (@glob) {
2294 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2295             }
2296 0         0 return @glob;
2297             }
2298             else {
2299 0         0 my $glob = _DOS_like_glob();
2300 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2301 0         0 return $glob;
2302             }
2303             }
2304              
2305             #
2306             # KOI8-U path globbing via File::DosGlob 1.10
2307             #
2308             # Often I confuse "_dosglob" and "_doglob".
2309             # So, I renamed "_dosglob" to "_DOS_like_glob".
2310             #
2311             my %iter;
2312             my %entries;
2313             sub _DOS_like_glob {
2314              
2315             # context (keyed by second cxix argument provided by core)
2316 0     0   0 my($expr,$cxix) = @_;
2317              
2318             # glob without args defaults to $_
2319 0 0       0 $expr = $_ if not defined $expr;
2320              
2321             # represents the current user's home directory
2322             #
2323             # 7.3. Expanding Tildes in Filenames
2324             # in Chapter 7. File Access
2325             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2326             #
2327             # and File::HomeDir, File::HomeDir::Windows module
2328              
2329             # DOS-like system
2330 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2331 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2332             { my_home_MSWin32() }oxmse;
2333             }
2334              
2335             # UNIX-like system
2336 0 0 0     0 else {
  0         0  
2337             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2338             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2339             }
2340 0 0       0  
2341 0 0       0 # assume global context if not provided one
2342             $cxix = '_G_' if not defined $cxix;
2343             $iter{$cxix} = 0 if not exists $iter{$cxix};
2344 0 0       0  
2345 0         0 # if we're just beginning, do it all first
2346             if ($iter{$cxix} == 0) {
2347             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2348             }
2349 0 0       0  
2350 0         0 # chuck it all out, quick or slow
2351 0         0 if (wantarray) {
  0         0  
2352             delete $iter{$cxix};
2353             return @{delete $entries{$cxix}};
2354 0 0       0 }
  0         0  
2355 0         0 else {
  0         0  
2356             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2357             return shift @{$entries{$cxix}};
2358             }
2359 0         0 else {
2360 0         0 # return undef for EOL
2361 0         0 delete $iter{$cxix};
2362             delete $entries{$cxix};
2363             return undef;
2364             }
2365             }
2366             }
2367              
2368             #
2369             # KOI8-U path globbing subroutine
2370             #
2371 0     0   0 sub _do_glob {
2372 0         0  
2373 0         0 my($cond,@expr) = @_;
2374             my @glob = ();
2375             my $fix_drive_relative_paths = 0;
2376 0         0  
2377 0 0       0 OUTER:
2378 0 0       0 for my $expr (@expr) {
2379             next OUTER if not defined $expr;
2380 0         0 next OUTER if $expr eq '';
2381 0         0  
2382 0         0 my @matched = ();
2383 0         0 my @globdir = ();
2384 0         0 my $head = '.';
2385             my $pathsep = '/';
2386             my $tail;
2387 0 0       0  
2388 0         0 # if argument is within quotes strip em and do no globbing
2389 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2390 0 0       0 $expr = $1;
2391 0         0 if ($cond eq 'd') {
2392             if (-d $expr) {
2393             push @glob, $expr;
2394             }
2395 0 0       0 }
2396 0         0 else {
2397             if (-e $expr) {
2398             push @glob, $expr;
2399 0         0 }
2400             }
2401             next OUTER;
2402             }
2403              
2404 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2405 0 0       0 # to h:./*.pm to expand correctly
2406 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2407             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2408             $fix_drive_relative_paths = 1;
2409             }
2410 0 0       0 }
2411 0 0       0  
2412 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2413 0         0 if ($tail eq '') {
2414             push @glob, $expr;
2415 0 0       0 next OUTER;
2416 0 0       0 }
2417 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2418 0         0 if (@globdir = _do_glob('d', $head)) {
2419             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2420             next OUTER;
2421 0 0 0     0 }
2422 0         0 }
2423             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2424 0         0 $head .= $pathsep;
2425             }
2426             $expr = $tail;
2427             }
2428 0 0       0  
2429 0 0       0 # If file component has no wildcards, we can avoid opendir
2430 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2431             if ($head eq '.') {
2432 0 0 0     0 $head = '';
2433 0         0 }
2434             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2435 0         0 $head .= $pathsep;
2436 0 0       0 }
2437 0 0       0 $head .= $expr;
2438 0         0 if ($cond eq 'd') {
2439             if (-d $head) {
2440             push @glob, $head;
2441             }
2442 0 0       0 }
2443 0         0 else {
2444             if (-e $head) {
2445             push @glob, $head;
2446 0         0 }
2447             }
2448 0 0       0 next OUTER;
2449 0         0 }
2450 0         0 opendir(*DIR, $head) or next OUTER;
2451             my @leaf = readdir DIR;
2452 0 0       0 closedir DIR;
2453 0         0  
2454             if ($head eq '.') {
2455 0 0 0     0 $head = '';
2456 0         0 }
2457             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2458             $head .= $pathsep;
2459 0         0 }
2460 0         0  
2461 0         0 my $pattern = '';
2462             while ($expr =~ / \G ($q_char) /oxgc) {
2463             my $char = $1;
2464              
2465             # 6.9. Matching Shell Globs as Regular Expressions
2466             # in Chapter 6. Pattern Matching
2467             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2468 0 0       0 # (and so on)
    0          
    0          
2469 0         0  
2470             if ($char eq '*') {
2471             $pattern .= "(?:$your_char)*",
2472 0         0 }
2473             elsif ($char eq '?') {
2474             $pattern .= "(?:$your_char)?", # DOS style
2475             # $pattern .= "(?:$your_char)", # UNIX style
2476 0         0 }
2477             elsif ((my $fc = Ekoi8u::fc($char)) ne $char) {
2478             $pattern .= $fc;
2479 0         0 }
2480             else {
2481             $pattern .= quotemeta $char;
2482 0     0   0 }
  0         0  
2483             }
2484             my $matchsub = sub { Ekoi8u::fc($_[0]) =~ /\A $pattern \z/xms };
2485              
2486             # if ($@) {
2487             # print STDERR "$0: $@\n";
2488             # next OUTER;
2489             # }
2490 0         0  
2491 0 0 0     0 INNER:
2492 0         0 for my $leaf (@leaf) {
2493             if ($leaf eq '.' or $leaf eq '..') {
2494 0 0 0     0 next INNER;
2495 0         0 }
2496             if ($cond eq 'd' and not -d "$head$leaf") {
2497             next INNER;
2498 0 0       0 }
2499 0         0  
2500 0         0 if (&$matchsub($leaf)) {
2501             push @matched, "$head$leaf";
2502             next INNER;
2503             }
2504              
2505             # [DOS compatibility special case]
2506 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2507              
2508             if (Ekoi8u::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2509             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2510 0 0       0 Ekoi8u::index($pattern,'\\.') != -1 # pattern has a dot.
2511 0         0 ) {
2512 0         0 if (&$matchsub("$leaf.")) {
2513             push @matched, "$head$leaf";
2514             next INNER;
2515             }
2516 0 0       0 }
2517 0         0 }
2518             if (@matched) {
2519             push @glob, @matched;
2520 0 0       0 }
2521 0         0 }
2522 0         0 if ($fix_drive_relative_paths) {
2523             for my $glob (@glob) {
2524             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2525 0         0 }
2526             }
2527             return @glob;
2528             }
2529              
2530             #
2531             # KOI8-U parse line
2532             #
2533 0     0   0 sub _parse_line {
2534              
2535 0         0 my($line) = @_;
2536 0         0  
2537 0         0 $line .= ' ';
2538             my @piece = ();
2539             while ($line =~ /
2540             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2541             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2542 0 0       0 /oxmsg
2543             ) {
2544 0         0 push @piece, defined($1) ? $1 : $2;
2545             }
2546             return @piece;
2547             }
2548              
2549             #
2550             # KOI8-U parse path
2551             #
2552 0     0   0 sub _parse_path {
2553              
2554 0         0 my($path,$pathsep) = @_;
2555 0         0  
2556 0         0 $path .= '/';
2557             my @subpath = ();
2558             while ($path =~ /
2559             ((?: [^\/\\] )+?) [\/\\]
2560 0         0 /oxmsg
2561             ) {
2562             push @subpath, $1;
2563 0         0 }
2564 0         0  
2565 0         0 my $tail = pop @subpath;
2566             my $head = join $pathsep, @subpath;
2567             return $head, $tail;
2568             }
2569              
2570             #
2571             # via File::HomeDir::Windows 1.00
2572             #
2573             sub my_home_MSWin32 {
2574              
2575             # A lot of unix people and unix-derived tools rely on
2576 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2577 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2578             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2579             return $ENV{'HOME'};
2580             }
2581              
2582 0         0 # Do we have a user profile?
2583             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2584             return $ENV{'USERPROFILE'};
2585             }
2586              
2587 0         0 # Some Windows use something like $ENV{'HOME'}
2588             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2589             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2590 0         0 }
2591              
2592             return undef;
2593             }
2594              
2595             #
2596             # via File::HomeDir::Unix 1.00
2597 0     0 0 0 #
2598             sub my_home {
2599 0 0 0     0 my $home;
    0 0        
2600 0         0  
2601             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2602             $home = $ENV{'HOME'};
2603             }
2604              
2605             # This is from the original code, but I'm guessing
2606 0         0 # it means "login directory" and exists on some Unixes.
2607             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2608             $home = $ENV{'LOGDIR'};
2609             }
2610              
2611             ### More-desperate methods
2612              
2613 0         0 # Light desperation on any (Unixish) platform
2614             else {
2615             $home = CORE::eval q{ (getpwuid($<))[7] };
2616             }
2617              
2618 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2619 0         0 # For example, "nobody"-like users might use /nonexistant
2620             if (defined $home and ! -d($home)) {
2621 0         0 $home = undef;
2622             }
2623             return $home;
2624             }
2625              
2626             #
2627             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2628 0     0 0 0 #
2629             sub Ekoi8u::PREMATCH {
2630             return $`;
2631             }
2632              
2633             #
2634             # ${^MATCH}, $MATCH, $& the string that matched
2635 0     0 0 0 #
2636             sub Ekoi8u::MATCH {
2637             return $&;
2638             }
2639              
2640             #
2641             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2642 0     0 0 0 #
2643             sub Ekoi8u::POSTMATCH {
2644             return $';
2645             }
2646              
2647             #
2648             # KOI8-U character to order (with parameter)
2649             #
2650 0 0   0 1 0 sub KOI8U::ord(;$) {
2651              
2652 0 0       0 local $_ = shift if @_;
2653 0         0  
2654 0         0 if (/\A ($q_char) /oxms) {
2655 0         0 my @ord = unpack 'C*', $1;
2656 0         0 my $ord = 0;
2657             while (my $o = shift @ord) {
2658 0         0 $ord = $ord * 0x100 + $o;
2659             }
2660             return $ord;
2661 0         0 }
2662             else {
2663             return CORE::ord $_;
2664             }
2665             }
2666              
2667             #
2668             # KOI8-U character to order (without parameter)
2669             #
2670 0 0   0 0 0 sub KOI8U::ord_() {
2671 0         0  
2672 0         0 if (/\A ($q_char) /oxms) {
2673 0         0 my @ord = unpack 'C*', $1;
2674 0         0 my $ord = 0;
2675             while (my $o = shift @ord) {
2676 0         0 $ord = $ord * 0x100 + $o;
2677             }
2678             return $ord;
2679 0         0 }
2680             else {
2681             return CORE::ord $_;
2682             }
2683             }
2684              
2685             #
2686             # KOI8-U reverse
2687             #
2688 0 0   0 0 0 sub KOI8U::reverse(@) {
2689 0         0  
2690             if (wantarray) {
2691             return CORE::reverse @_;
2692             }
2693             else {
2694              
2695             # One of us once cornered Larry in an elevator and asked him what
2696             # problem he was solving with this, but he looked as far off into
2697             # the distance as he could in an elevator and said, "It seemed like
2698 0         0 # a good idea at the time."
2699              
2700             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2701             }
2702             }
2703              
2704             #
2705             # KOI8-U getc (with parameter, without parameter)
2706             #
2707 0     0 0 0 sub KOI8U::getc(;*@) {
2708 0 0       0  
2709 0 0 0     0 my($package) = caller;
2710             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2711 0         0 croak 'Too many arguments for KOI8U::getc' if @_ and not wantarray;
  0         0  
2712 0         0  
2713 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2714 0         0 my $getc = '';
2715 0 0       0 for my $length ($length[0] .. $length[-1]) {
2716 0 0       0 $getc .= CORE::getc($fh);
2717 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2718             if ($getc =~ /\A ${Ekoi8u::dot_s} \z/oxms) {
2719             return wantarray ? ($getc,@_) : $getc;
2720             }
2721 0 0       0 }
2722             }
2723             return wantarray ? ($getc,@_) : $getc;
2724             }
2725              
2726             #
2727             # KOI8-U length by character
2728             #
2729 0 0   0 1 0 sub KOI8U::length(;$) {
2730              
2731 0         0 local $_ = shift if @_;
2732 0         0  
2733             local @_ = /\G ($q_char) /oxmsg;
2734             return scalar @_;
2735             }
2736              
2737             #
2738             # KOI8-U substr by character
2739             #
2740             BEGIN {
2741              
2742             # P.232 The lvalue Attribute
2743             # in Chapter 6: Subroutines
2744             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2745              
2746             # P.336 The lvalue Attribute
2747             # in Chapter 7: Subroutines
2748             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2749              
2750             # P.144 8.4 Lvalue subroutines
2751             # in Chapter 8: perlsub: Perl subroutines
2752 204 50 0 204 1 110842 # 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  
2753              
2754             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2755             # vv----------------------*******
2756             sub KOI8U::substr($$;$$) %s {
2757              
2758             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2759              
2760             # If the substring is beyond either end of the string, substr() returns the undefined
2761             # value and produces a warning. When used as an lvalue, specifying a substring that
2762             # is entirely outside the string raises an exception.
2763             # http://perldoc.perl.org/functions/substr.html
2764              
2765             # A return with no argument returns the scalar value undef in scalar context,
2766             # an empty list () in list context, and (naturally) nothing at all in void
2767             # context.
2768              
2769             my $offset = $_[1];
2770             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2771             return;
2772             }
2773              
2774             # substr($string,$offset,$length,$replacement)
2775             if (@_ == 4) {
2776             my(undef,undef,$length,$replacement) = @_;
2777             my $substr = join '', splice(@char, $offset, $length, $replacement);
2778             $_[0] = join '', @char;
2779              
2780             # return $substr; this doesn't work, don't say "return"
2781             $substr;
2782             }
2783              
2784             # substr($string,$offset,$length)
2785             elsif (@_ == 3) {
2786             my(undef,undef,$length) = @_;
2787             my $octet_offset = 0;
2788             my $octet_length = 0;
2789             if ($offset == 0) {
2790             $octet_offset = 0;
2791             }
2792             elsif ($offset > 0) {
2793             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2794             }
2795             else {
2796             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2797             }
2798             if ($length == 0) {
2799             $octet_length = 0;
2800             }
2801             elsif ($length > 0) {
2802             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2803             }
2804             else {
2805             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2806             }
2807             CORE::substr($_[0], $octet_offset, $octet_length);
2808             }
2809              
2810             # substr($string,$offset)
2811             else {
2812             my $octet_offset = 0;
2813             if ($offset == 0) {
2814             $octet_offset = 0;
2815             }
2816             elsif ($offset > 0) {
2817             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2818             }
2819             else {
2820             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2821             }
2822             CORE::substr($_[0], $octet_offset);
2823             }
2824             }
2825             END
2826             }
2827              
2828             #
2829             # KOI8-U index by character
2830             #
2831 0     0 1 0 sub KOI8U::index($$;$) {
2832 0 0       0  
2833 0         0 my $index;
2834             if (@_ == 3) {
2835             $index = Ekoi8u::index($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2836 0         0 }
2837             else {
2838             $index = Ekoi8u::index($_[0], $_[1]);
2839 0 0       0 }
2840 0         0  
2841             if ($index == -1) {
2842             return -1;
2843 0         0 }
2844             else {
2845             return KOI8U::length(CORE::substr $_[0], 0, $index);
2846             }
2847             }
2848              
2849             #
2850             # KOI8-U rindex by character
2851             #
2852 0     0 1 0 sub KOI8U::rindex($$;$) {
2853 0 0       0  
2854 0         0 my $rindex;
2855             if (@_ == 3) {
2856             $rindex = Ekoi8u::rindex($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2857 0         0 }
2858             else {
2859             $rindex = Ekoi8u::rindex($_[0], $_[1]);
2860 0 0       0 }
2861 0         0  
2862             if ($rindex == -1) {
2863             return -1;
2864 0         0 }
2865             else {
2866             return KOI8U::length(CORE::substr $_[0], 0, $rindex);
2867             }
2868             }
2869              
2870 204     204   1535 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  204         430  
  204         20625  
2871             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2872             use vars qw($slash); $slash = 'm//';
2873              
2874             # ord() to ord() or KOI8U::ord()
2875             my $function_ord = 'ord';
2876              
2877             # ord to ord or KOI8U::ord_
2878             my $function_ord_ = 'ord';
2879              
2880             # reverse to reverse or KOI8U::reverse
2881             my $function_reverse = 'reverse';
2882              
2883             # getc to getc or KOI8U::getc
2884             my $function_getc = 'getc';
2885              
2886             # P.1023 Appendix W.9 Multibyte Anchoring
2887             # of ISBN 1-56592-224-7 CJKV Information Processing
2888              
2889 204     204   1460 my $anchor = '';
  204     0   488  
  204         8294360  
2890              
2891             use vars qw($nest);
2892              
2893             # regexp of nested parens in qqXX
2894              
2895             # P.340 Matching Nested Constructs with Embedded Code
2896             # in Chapter 7: Perl
2897             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2898              
2899             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2900             [^\\()] |
2901             \( (?{$nest++}) |
2902             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2903             \\ [^c] |
2904             \\c[\x40-\x5F] |
2905             [\x00-\xFF]
2906             }xms;
2907              
2908             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2909             [^\\{}] |
2910             \{ (?{$nest++}) |
2911             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2912             \\ [^c] |
2913             \\c[\x40-\x5F] |
2914             [\x00-\xFF]
2915             }xms;
2916              
2917             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2918             [^\\\[\]] |
2919             \[ (?{$nest++}) |
2920             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2921             \\ [^c] |
2922             \\c[\x40-\x5F] |
2923             [\x00-\xFF]
2924             }xms;
2925              
2926             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2927             [^\\<>] |
2928             \< (?{$nest++}) |
2929             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2930             \\ [^c] |
2931             \\c[\x40-\x5F] |
2932             [\x00-\xFF]
2933             }xms;
2934              
2935             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2936             (?: ::)? (?:
2937             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2938             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2939             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2940             ))
2941             }xms;
2942              
2943             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2944             (?: ::)? (?:
2945             (?>[0-9]+) |
2946             [^a-zA-Z_0-9\[\]] |
2947             ^[A-Z] |
2948             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2949             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2950             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2951             ))
2952             }xms;
2953              
2954             my $qq_substr = qr{(?> Char::substr | KOI8U::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2955             }xms;
2956              
2957             # regexp of nested parens in qXX
2958             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2959             [^()] |
2960             \( (?{$nest++}) |
2961             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2962             [\x00-\xFF]
2963             }xms;
2964              
2965             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2966             [^\{\}] |
2967             \{ (?{$nest++}) |
2968             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2969             [\x00-\xFF]
2970             }xms;
2971              
2972             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2973             [^\[\]] |
2974             \[ (?{$nest++}) |
2975             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2976             [\x00-\xFF]
2977             }xms;
2978              
2979             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2980             [^<>] |
2981             \< (?{$nest++}) |
2982             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2983             [\x00-\xFF]
2984             }xms;
2985              
2986             my $matched = '';
2987             my $s_matched = '';
2988              
2989             my $tr_variable = ''; # variable of tr///
2990             my $sub_variable = ''; # variable of s///
2991             my $bind_operator = ''; # =~ or !~
2992              
2993             my @heredoc = (); # here document
2994             my @heredoc_delimiter = ();
2995             my $here_script = ''; # here script
2996              
2997             #
2998             # escape KOI8-U script
2999 0 50   204 0 0 #
3000             sub KOI8U::escape(;$) {
3001             local($_) = $_[0] if @_;
3002              
3003             # P.359 The Study Function
3004             # in Chapter 7: Perl
3005 204         641 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3006              
3007             study $_; # Yes, I studied study yesterday.
3008              
3009             # while all script
3010              
3011             # 6.14. Matching from Where the Last Pattern Left Off
3012             # in Chapter 6. Pattern Matching
3013             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3014             # (and so on)
3015              
3016             # one member of Tag-team
3017             #
3018             # P.128 Start of match (or end of previous match): \G
3019             # P.130 Advanced Use of \G with Perl
3020             # in Chapter 3: Overview of Regular Expression Features and Flavors
3021             # P.255 Use leading anchors
3022             # P.256 Expose ^ and \G at the front expressions
3023             # in Chapter 6: Crafting an Efficient Expression
3024             # P.315 "Tag-team" matching with /gc
3025             # in Chapter 7: Perl
3026 204         411 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3027 204         354  
3028 204         764 my $e_script = '';
3029             while (not /\G \z/oxgc) { # member
3030             $e_script .= KOI8U::escape_token();
3031 74753         113223 }
3032              
3033             return $e_script;
3034             }
3035              
3036             #
3037             # escape KOI8-U token of script
3038             #
3039             sub KOI8U::escape_token {
3040              
3041 204     74753 0 2627 # \n output here document
3042              
3043             my $ignore_modules = join('|', qw(
3044             utf8
3045             bytes
3046             charnames
3047             I18N::Japanese
3048             I18N::Collate
3049             I18N::JExt
3050             File::DosGlob
3051             Wild
3052             Wildcard
3053             Japanese
3054             ));
3055              
3056             # another member of Tag-team
3057             #
3058             # P.315 "Tag-team" matching with /gc
3059             # in Chapter 7: Perl
3060 74753 100 100     87676 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
    100 66        
    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          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    100          
    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          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
3061 74753         2762387  
3062 12522 100       15354 if (/\G ( \n ) /oxgc) { # another member (and so on)
3063 12522         20992 my $heredoc = '';
3064             if (scalar(@heredoc_delimiter) >= 1) {
3065 174         217 $slash = 'm//';
3066 174         332  
3067             $heredoc = join '', @heredoc;
3068             @heredoc = ();
3069 174         296  
3070 174         312 # skip here document
3071             for my $heredoc_delimiter (@heredoc_delimiter) {
3072 174         1082 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3073             }
3074 174         304 @heredoc_delimiter = ();
3075              
3076 174         234 $here_script = '';
3077             }
3078             return "\n" . $heredoc;
3079             }
3080 12522         36005  
3081             # ignore space, comment
3082             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3083              
3084             # if (, elsif (, unless (, while (, until (, given (, and when (
3085              
3086             # given, when
3087              
3088             # P.225 The given Statement
3089             # in Chapter 15: Smart Matching and given-when
3090             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3091              
3092             # P.133 The given Statement
3093             # in Chapter 4: Statements and Declarations
3094             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3095 17974         54957  
3096 1401         2142 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3097             $slash = 'm//';
3098             return $1;
3099             }
3100              
3101             # scalar variable ($scalar = ...) =~ tr///;
3102             # scalar variable ($scalar = ...) =~ s///;
3103              
3104             # state
3105              
3106             # P.68 Persistent, Private Variables
3107             # in Chapter 4: Subroutines
3108             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3109              
3110             # P.160 Persistent Lexically Scoped Variables: state
3111             # in Chapter 4: Statements and Declarations
3112             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3113              
3114             # (and so on)
3115 1401         4316  
3116             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3117 86 50       197 my $e_string = e_string($1);
    50          
3118 86         2149  
3119 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3120 0         0 $tr_variable = $e_string . e_string($1);
3121 0         0 $bind_operator = $2;
3122             $slash = 'm//';
3123             return '';
3124 0         0 }
3125 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3126 0         0 $sub_variable = $e_string . e_string($1);
3127 0         0 $bind_operator = $2;
3128             $slash = 'm//';
3129             return '';
3130 0         0 }
3131 86         167 else {
3132             $slash = 'div';
3133             return $e_string;
3134             }
3135             }
3136              
3137 86         309 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
3138 4         9 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3139             $slash = 'div';
3140             return q{Ekoi8u::PREMATCH()};
3141             }
3142              
3143 4         13 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
3144 28         57 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3145             $slash = 'div';
3146             return q{Ekoi8u::MATCH()};
3147             }
3148              
3149 28         79 # $', ${'} --> $', ${'}
3150 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3151             $slash = 'div';
3152             return $1;
3153             }
3154              
3155 1         3 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
3156 3         6 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3157             $slash = 'div';
3158             return q{Ekoi8u::POSTMATCH()};
3159             }
3160              
3161             # scalar variable $scalar =~ tr///;
3162             # scalar variable $scalar =~ s///;
3163             # substr() =~ tr///;
3164 3         10 # substr() =~ s///;
3165             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3166 1671 100       3575 my $scalar = e_string($1);
    100          
3167 1671         6320  
3168 1         2 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3169 1         2 $tr_variable = $scalar;
3170 1         2 $bind_operator = $1;
3171             $slash = 'm//';
3172             return '';
3173 1         3 }
3174 61         119 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3175 61         112 $sub_variable = $scalar;
3176 61         93 $bind_operator = $1;
3177             $slash = 'm//';
3178             return '';
3179 61         169 }
3180 1609         2334 else {
3181             $slash = 'div';
3182             return $scalar;
3183             }
3184             }
3185              
3186 1609         4233 # end of statement
3187             elsif (/\G ( [,;] ) /oxgc) {
3188             $slash = 'm//';
3189 4998         7266  
3190             # clear tr/// variable
3191             $tr_variable = '';
3192 4998         5946  
3193             # clear s/// variable
3194 4998         5617 $sub_variable = '';
3195              
3196 4998         5506 $bind_operator = '';
3197              
3198             return $1;
3199             }
3200              
3201 4998         16233 # bareword
3202             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3203             return $1;
3204             }
3205              
3206 0         0 # $0 --> $0
3207 2         4 elsif (/\G ( \$ 0 ) /oxmsgc) {
3208             $slash = 'div';
3209             return $1;
3210 2         7 }
3211 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3212             $slash = 'div';
3213             return $1;
3214             }
3215              
3216 0         0 # $$ --> $$
3217 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3218             $slash = 'div';
3219             return $1;
3220             }
3221              
3222             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3223 1         5 # $1, $2, $3 --> $1, $2, $3 otherwise
3224 4         8 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3225             $slash = 'div';
3226             return e_capture($1);
3227 4         8 }
3228 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3229             $slash = 'div';
3230             return e_capture($1);
3231             }
3232              
3233 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3234 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3235             $slash = 'div';
3236             return e_capture($1.'->'.$2);
3237             }
3238              
3239 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3240 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3241             $slash = 'div';
3242             return e_capture($1.'->'.$2);
3243             }
3244              
3245 0         0 # $$foo
3246 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3247             $slash = 'div';
3248             return e_capture($1);
3249             }
3250              
3251 0         0 # ${ foo }
3252 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3253             $slash = 'div';
3254             return '${' . $1 . '}';
3255             }
3256              
3257 0         0 # ${ ... }
3258 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3259             $slash = 'div';
3260             return e_capture($1);
3261             }
3262              
3263             # variable or function
3264 0         0 # $ @ % & * $ #
3265 42         70 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) {
3266             $slash = 'div';
3267             return $1;
3268             }
3269             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3270 42         135 # $ @ # \ ' " / ? ( ) [ ] < >
3271 62         122 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3272             $slash = 'div';
3273             return $1;
3274             }
3275              
3276 62         223 # while ()
3277             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3278             return $1;
3279             }
3280              
3281             # while () --- glob
3282              
3283             # avoid "Error: Runtime exception" of perl version 5.005_03
3284 0         0  
3285             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3286             return 'while ($_ = Ekoi8u::glob("' . $1 . '"))';
3287             }
3288              
3289 0         0 # while (glob)
3290             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3291             return 'while ($_ = Ekoi8u::glob_)';
3292             }
3293              
3294 0         0 # while (glob(WILDCARD))
3295             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3296             return 'while ($_ = Ekoi8u::glob';
3297             }
3298 0         0  
  248         553  
3299             # doit if, doit unless, doit while, doit until, doit for, doit when
3300             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3301 248         893  
  19         34  
3302 19         61 # subroutines of package Ekoi8u
  0         0  
3303 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         16  
3304 13         30 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3305 0         0 elsif (/\G \b KOI8U::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         159  
3306 114         327 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         5  
3307 2         7 elsif (/\G \b KOI8U::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval KOI8U::escape'; }
  0         0  
3308 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         6  
3309 2         7 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chop'; }
  0         0  
3310 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3311 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3312 0         0 elsif (/\G \b KOI8U::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::index'; }
  2         6  
3313 2         6 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::index'; }
  0         0  
3314 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3315 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3316 0         0 elsif (/\G \b KOI8U::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::rindex'; }
  1         2  
3317 1         3 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::rindex'; }
  0         0  
3318 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc'; }
  1         2  
3319 1         4 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst'; }
  0         0  
3320 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc'; }
  6         13  
3321             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst'; }
3322             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc'; }
3323 6         21  
  0         0  
3324 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3325 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3326 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3327 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3328 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3329 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3330             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3331 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  
3332 0         0  
  0         0  
3333 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3334 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3335 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3336 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3337 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3338             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3339             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3340 0         0  
  0         0  
3341 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3342 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3343 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3344             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3345 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         4  
3346 2         9  
  2         4  
3347 2         8 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         76  
3348 36         126 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         6  
3349 2         10 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr'; }
  8         15  
3350 8         25 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3351 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3352 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob'; }
  0         0  
3353 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc_'; }
  0         0  
3354 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst_'; }
  0         0  
3355 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc_'; }
  0         0  
3356 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst_'; }
  0         0  
3357             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc_'; }
3358 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3359 0         0  
  0         0  
3360 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3361 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3362 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr_'; }
  0         0  
3363 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3364 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3365 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob_'; }
  8         22  
3366             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3367             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3368 8         31 # split
3369             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3370 87         183 $slash = 'm//';
3371 87         144  
3372 87         316 my $e = '';
3373             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3374             $e .= $1;
3375             }
3376 85 100       322  
  87 100       5688  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3377             # end of split
3378             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8u::split' . $e; }
3379 2         8  
3380             # split scalar value
3381             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Ekoi8u::split' . $e . e_string($1); }
3382 1         6  
3383 0         0 # split literal space
3384 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {qq$1 $2}; }
3385 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3386 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3387 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3388 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3389 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3390 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {q$1 $2}; }
3391 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3392 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3393 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3394 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3395 10         47 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3396             elsif (/\G ' [ ] ' /oxgc) { return 'Ekoi8u::split' . $e . qq {' '}; }
3397             elsif (/\G " [ ] " /oxgc) { return 'Ekoi8u::split' . $e . qq {" "}; }
3398              
3399 0 0       0 # split qq//
  0         0  
3400             elsif (/\G \b (qq) \b /oxgc) {
3401 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3402 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3403 0         0 while (not /\G \z/oxgc) {
3404 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3405 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3406 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3407 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3408 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3409             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3410 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3411             }
3412             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3413             }
3414             }
3415              
3416 0 50       0 # split qr//
  12         434  
3417             elsif (/\G \b (qr) \b /oxgc) {
3418 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3419 12 50       78 else {
  12 50       3298  
    50          
    50          
    50          
    50          
    50          
    50          
3420 0         0 while (not /\G \z/oxgc) {
3421 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3422 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3423 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3424 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3425 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3426 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3427             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3428 12         89 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3429             }
3430             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3431             }
3432             }
3433              
3434 0 0       0 # split q//
  0         0  
3435             elsif (/\G \b (q) \b /oxgc) {
3436 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3437 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3438 0         0 while (not /\G \z/oxgc) {
3439 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3440 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3441 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3442 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3443 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3444             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3445 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3446             }
3447             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3448             }
3449             }
3450              
3451 0 50       0 # split m//
  18         512  
3452             elsif (/\G \b (m) \b /oxgc) {
3453 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3454 18 50       77 else {
  18 50       3966  
    50          
    50          
    50          
    50          
    50          
    50          
3455 0         0 while (not /\G \z/oxgc) {
3456 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3457 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3458 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3459 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3460 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3461 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3462             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3463 18         99 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3464             }
3465             die __FILE__, ": Search pattern not terminated\n";
3466             }
3467             }
3468              
3469 0         0 # split ''
3470 0         0 elsif (/\G (\') /oxgc) {
3471 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3472 0         0 while (not /\G \z/oxgc) {
3473 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3474 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3475             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3476 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3477             }
3478             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3479             }
3480              
3481 0         0 # split ""
3482 0         0 elsif (/\G (\") /oxgc) {
3483 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3484 0         0 while (not /\G \z/oxgc) {
3485 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3486 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3487             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3488 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3489             }
3490             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3491             }
3492              
3493 0         0 # split //
3494 44         112 elsif (/\G (\/) /oxgc) {
3495 44 50       158 my $regexp = '';
  381 50       1495  
    100          
    50          
3496 0         0 while (not /\G \z/oxgc) {
3497 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3498 44         192 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3499             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3500 337         682 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3501             }
3502             die __FILE__, ": Search pattern not terminated\n";
3503             }
3504             }
3505              
3506             # tr/// or y///
3507              
3508             # about [cdsrbB]* (/B modifier)
3509             #
3510             # P.559 appendix C
3511             # of ISBN 4-89052-384-7 Programming perl
3512             # (Japanese title is: Perl puroguramingu)
3513 0         0  
3514             elsif (/\G \b ( tr | y ) \b /oxgc) {
3515             my $ope = $1;
3516 3 50       7  
3517 3         39 # $1 $2 $3 $4 $5 $6
3518 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3519             my @tr = ($tr_variable,$2);
3520             return e_tr(@tr,'',$4,$6);
3521 0         0 }
3522 3         6 else {
3523 3 50       8 my $e = '';
  3 50       234  
    50          
    50          
    50          
    50          
3524             while (not /\G \z/oxgc) {
3525 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3526 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3527 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3528 0         0 while (not /\G \z/oxgc) {
3529 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3530 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3531 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3532 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3533             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3534 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3535             }
3536             die __FILE__, ": Transliteration replacement not terminated\n";
3537 0         0 }
3538 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3539 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3540 0         0 while (not /\G \z/oxgc) {
3541 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3542 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3543 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3544 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3545             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3546 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3547             }
3548             die __FILE__, ": Transliteration replacement not terminated\n";
3549 0         0 }
3550 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3551 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3552 0         0 while (not /\G \z/oxgc) {
3553 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3554 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3555 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3556 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3557             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3558 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3559             }
3560             die __FILE__, ": Transliteration replacement not terminated\n";
3561 0         0 }
3562 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3563 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3564 0         0 while (not /\G \z/oxgc) {
3565 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3566 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3567 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3568 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3569             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3570 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3571             }
3572             die __FILE__, ": Transliteration replacement not terminated\n";
3573             }
3574 0         0 # $1 $2 $3 $4 $5 $6
3575 3         11 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3576             my @tr = ($tr_variable,$2);
3577             return e_tr(@tr,'',$4,$6);
3578 3         10 }
3579             }
3580             die __FILE__, ": Transliteration pattern not terminated\n";
3581             }
3582             }
3583              
3584 0         0 # qq//
3585             elsif (/\G \b (qq) \b /oxgc) {
3586             my $ope = $1;
3587 2180 50       4745  
3588 2180         3973 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3589 0         0 if (/\G (\#) /oxgc) { # qq# #
3590 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3591 0         0 while (not /\G \z/oxgc) {
3592 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3593 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3594             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3595 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3596             }
3597             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3598             }
3599 0         0  
3600 2180         2888 else {
3601 2180 50       4914 my $e = '';
  2180 50       7895  
    100          
    50          
    50          
    0          
3602             while (not /\G \z/oxgc) {
3603             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3604              
3605 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3606 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3607 0         0 my $qq_string = '';
3608 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3609 0         0 while (not /\G \z/oxgc) {
3610 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3611             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3612 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3613 0         0 elsif (/\G (\)) /oxgc) {
3614             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3615 0         0 else { $qq_string .= $1; }
3616             }
3617 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3618             }
3619             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3620             }
3621              
3622 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3623 2150         2882 elsif (/\G (\{) /oxgc) { # qq { }
3624 2150         2994 my $qq_string = '';
3625 2150 100       4596 local $nest = 1;
  83993 50       256666  
    100          
    100          
    50          
3626 722         1523 while (not /\G \z/oxgc) {
3627 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         1506  
3628             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3629 1153 100       1980 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         4833  
3630 2150         4310 elsif (/\G (\}) /oxgc) {
3631             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3632 1153         2309 else { $qq_string .= $1; }
3633             }
3634 78815         153625 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3635             }
3636             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3637             }
3638              
3639 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3640 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3641 0         0 my $qq_string = '';
3642 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3643 0         0 while (not /\G \z/oxgc) {
3644 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3645             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3646 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3647 0         0 elsif (/\G (\]) /oxgc) {
3648             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3649 0         0 else { $qq_string .= $1; }
3650             }
3651 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3652             }
3653             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3654             }
3655              
3656 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3657 30         60 elsif (/\G (\<) /oxgc) { # qq < >
3658 30         49 my $qq_string = '';
3659 30 100       97 local $nest = 1;
  1166 50       3762  
    50          
    100          
    50          
3660 22         50 while (not /\G \z/oxgc) {
3661 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3662             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3663 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         63  
3664 30         67 elsif (/\G (\>) /oxgc) {
3665             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3666 0         0 else { $qq_string .= $1; }
3667             }
3668 1114         2089 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3669             }
3670             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3671             }
3672              
3673 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3674 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3675 0         0 my $delimiter = $1;
3676 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3677 0         0 while (not /\G \z/oxgc) {
3678 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3679 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3680             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3681 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3682             }
3683             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3684 0         0 }
3685             }
3686             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3687             }
3688             }
3689              
3690 0         0 # qr//
3691 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3692 0         0 my $ope = $1;
3693             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3694             return e_qr($ope,$1,$3,$2,$4);
3695 0         0 }
3696 0         0 else {
3697 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3698 0         0 while (not /\G \z/oxgc) {
3699 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3700 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3701 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3702 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3703 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3704 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3705             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3706 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3707             }
3708             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3709             }
3710             }
3711              
3712 0         0 # qw//
3713 16 50       48 elsif (/\G \b (qw) \b /oxgc) {
3714 16         92 my $ope = $1;
3715             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3716             return e_qw($ope,$1,$3,$2);
3717 0         0 }
3718 16         28 else {
3719 16 50       54 my $e = '';
  16 50       113  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3720             while (not /\G \z/oxgc) {
3721 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3722 16         55  
3723             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3724 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3725 0         0  
3726             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3727 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3728 0         0  
3729             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3730 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3731 0         0  
3732             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3733 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3734 0         0  
3735             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3736 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3737             }
3738             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3739             }
3740             }
3741              
3742 0         0 # qx//
3743 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3744 0         0 my $ope = $1;
3745             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3746             return e_qq($ope,$1,$3,$2);
3747 0         0 }
3748 0         0 else {
3749 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3750 0         0 while (not /\G \z/oxgc) {
3751 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3752 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3753 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3754 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3755 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3756             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3757 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3758             }
3759             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3760             }
3761             }
3762              
3763 0         0 # q//
3764             elsif (/\G \b (q) \b /oxgc) {
3765             my $ope = $1;
3766              
3767             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3768              
3769             # avoid "Error: Runtime exception" of perl version 5.005_03
3770 410 50       1056 # (and so on)
3771 410         978  
3772 0         0 if (/\G (\#) /oxgc) { # q# #
3773 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3774 0         0 while (not /\G \z/oxgc) {
3775 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3776 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3777             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3778 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3779             }
3780             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3781             }
3782 0         0  
3783 410         655 else {
3784 410 50       1171 my $e = '';
  410 50       2019  
    100          
    50          
    100          
    50          
3785             while (not /\G \z/oxgc) {
3786             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3787              
3788 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3789 0         0 elsif (/\G (\() /oxgc) { # q ( )
3790 0         0 my $q_string = '';
3791 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3792 0         0 while (not /\G \z/oxgc) {
3793 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3794 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3795             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3796 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3797 0         0 elsif (/\G (\)) /oxgc) {
3798             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3799 0         0 else { $q_string .= $1; }
3800             }
3801 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3802             }
3803             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3804             }
3805              
3806 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3807 404         661 elsif (/\G (\{) /oxgc) { # q { }
3808 404         644 my $q_string = '';
3809 404 50       989 local $nest = 1;
  6757 50       23796  
    50          
    100          
    100          
    50          
3810 0         0 while (not /\G \z/oxgc) {
3811 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3812 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         153  
3813             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3814 107 100       178 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         1112  
3815 404         1001 elsif (/\G (\}) /oxgc) {
3816             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3817 107         203 else { $q_string .= $1; }
3818             }
3819 6139         11194 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3820             }
3821             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3822             }
3823              
3824 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3825 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3826 0         0 my $q_string = '';
3827 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3828 0         0 while (not /\G \z/oxgc) {
3829 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3830 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3831             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3832 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3833 0         0 elsif (/\G (\]) /oxgc) {
3834             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3835 0         0 else { $q_string .= $1; }
3836             }
3837 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3838             }
3839             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3840             }
3841              
3842 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3843 5         12 elsif (/\G (\<) /oxgc) { # q < >
3844 5         11 my $q_string = '';
3845 5 50       16 local $nest = 1;
  88 50       364  
    50          
    50          
    100          
    50          
3846 0         0 while (not /\G \z/oxgc) {
3847 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3848 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3849             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3850 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         25  
3851 5         14 elsif (/\G (\>) /oxgc) {
3852             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3853 0         0 else { $q_string .= $1; }
3854             }
3855 83         172 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3856             }
3857             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3858             }
3859              
3860 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3861 1         3 elsif (/\G (\S) /oxgc) { # q * *
3862 1         2 my $delimiter = $1;
3863 1 50       4 my $q_string = '';
  14 50       61  
    100          
    50          
3864 0         0 while (not /\G \z/oxgc) {
3865 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3866 1         2 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3867             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3868 13         28 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3869             }
3870             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3871 0         0 }
3872             }
3873             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3874             }
3875             }
3876              
3877 0         0 # m//
3878 209 50       542 elsif (/\G \b (m) \b /oxgc) {
3879 209         1288 my $ope = $1;
3880             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3881             return e_qr($ope,$1,$3,$2,$4);
3882 0         0 }
3883 209         319 else {
3884 209 50       540 my $e = '';
  209 50       10256  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3885 0         0 while (not /\G \z/oxgc) {
3886 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3887 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3888 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3889 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3890 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3891 10         28 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3892 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3893             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3894 199         617 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3895             }
3896             die __FILE__, ": Search pattern not terminated\n";
3897             }
3898             }
3899              
3900             # s///
3901              
3902             # about [cegimosxpradlunbB]* (/cg modifier)
3903             #
3904             # P.67 Pattern-Matching Operators
3905             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3906 0         0  
3907             elsif (/\G \b (s) \b /oxgc) {
3908             my $ope = $1;
3909 97 100       246  
3910 97         1745 # $1 $2 $3 $4 $5 $6
3911             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3912             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3913 1         4 }
3914 96         173 else {
3915 96 50       325 my $e = '';
  96 50       13430  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3916             while (not /\G \z/oxgc) {
3917 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3918 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3919 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3920             while (not /\G \z/oxgc) {
3921 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3922 0         0 # $1 $2 $3 $4
3923 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3924 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3925 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3926 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3927 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3928 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3929 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3930             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3931 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3932             }
3933             die __FILE__, ": Substitution replacement not terminated\n";
3934 0         0 }
3935 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3936 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3937             while (not /\G \z/oxgc) {
3938 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3939 0         0 # $1 $2 $3 $4
3940 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3941 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3942 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3943 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3944 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3945 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3946 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3947             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3948 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3949             }
3950             die __FILE__, ": Substitution replacement not terminated\n";
3951 0         0 }
3952 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3953 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3954             while (not /\G \z/oxgc) {
3955 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3956 0         0 # $1 $2 $3 $4
3957 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3958 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3960 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3961 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3962             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3963 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3964             }
3965             die __FILE__, ": Substitution replacement not terminated\n";
3966 0         0 }
3967 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3968 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3969             while (not /\G \z/oxgc) {
3970 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3971 0         0 # $1 $2 $3 $4
3972 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3973 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3974 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3975 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3976 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3977 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3978 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3979             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3980 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3981             }
3982             die __FILE__, ": Substitution replacement not terminated\n";
3983             }
3984 0         0 # $1 $2 $3 $4 $5 $6
3985             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3986             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3987             }
3988 21         62 # $1 $2 $3 $4 $5 $6
3989             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3990             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3991             }
3992 0         0 # $1 $2 $3 $4 $5 $6
3993             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3994             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3995             }
3996 0         0 # $1 $2 $3 $4 $5 $6
3997             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3998             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3999 75         333 }
4000             }
4001             die __FILE__, ": Substitution pattern not terminated\n";
4002             }
4003             }
4004 0         0  
4005 0         0 # require ignore module
4006 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
4007             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
4008             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4009 0         0  
4010 37         302 # use strict; --> use strict; no strict qw(refs);
4011 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4012             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4013             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4014              
4015 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
4016 2         23 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4017             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4018             return "use $1; no strict qw(refs);";
4019 0         0 }
4020             else {
4021             return "use $1;";
4022             }
4023 2 0 0     12 }
      0        
4024 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4025             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4026             return "use $1; no strict qw(refs);";
4027 0         0 }
4028             else {
4029             return "use $1;";
4030             }
4031             }
4032 0         0  
4033 2         18 # ignore use module
4034 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4035             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4036             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4037 0         0  
4038 0         0 # ignore no module
4039 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4040             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4041             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4042 0         0  
4043             # use else
4044             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4045 0         0  
4046             # use else
4047             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4048              
4049 2         8 # ''
4050 848         1729 elsif (/\G (?
4051 848 100       2221 my $q_string = '';
  8241 100       24967  
    100          
    50          
4052 4         10 while (not /\G \z/oxgc) {
4053 48         84 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4054 848         1930 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4055             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4056 7341         14397 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4057             }
4058             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4059             }
4060              
4061 0         0 # ""
4062 1804         3439 elsif (/\G (\") /oxgc) {
4063 1804 100       4304 my $qq_string = '';
  34992 100       98307  
    100          
    50          
4064 67         165 while (not /\G \z/oxgc) {
4065 12         25 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4066 1804         3829 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4067             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4068 33109         63714 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4069             }
4070             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4071             }
4072              
4073 0         0 # ``
4074 1         3 elsif (/\G (\`) /oxgc) {
4075 1 50       4 my $qx_string = '';
  19 50       108  
    100          
    50          
4076 0         0 while (not /\G \z/oxgc) {
4077 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4078 1         3 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4079             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4080 18         43 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4081             }
4082             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4083             }
4084              
4085 0         0 # // --- not divide operator (num / num), not defined-or
4086 453         1461 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4087 453 50       1288 my $regexp = '';
  4496 50       15309  
    100          
    50          
4088 0         0 while (not /\G \z/oxgc) {
4089 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4090 453         1493 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4091             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4092 4043         8584 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4093             }
4094             die __FILE__, ": Search pattern not terminated\n";
4095             }
4096              
4097 0         0 # ?? --- not conditional operator (condition ? then : else)
4098 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4099 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4100 0         0 while (not /\G \z/oxgc) {
4101 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4102 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4103             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4104 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4105             }
4106             die __FILE__, ": Search pattern not terminated\n";
4107             }
4108 0         0  
  0         0  
4109             # <<>> (a safer ARGV)
4110             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4111 0         0  
  0         0  
4112             # << (bit shift) --- not here document
4113             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4114              
4115 0         0 # <<~'HEREDOC'
4116 6         13 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4117 6         11 $slash = 'm//';
4118             my $here_quote = $1;
4119             my $delimiter = $2;
4120 6 50       9  
4121 6         12 # get here document
4122 6         28 if ($here_script eq '') {
4123             $here_script = CORE::substr $_, pos $_;
4124 6 50       29 $here_script =~ s/.*?\n//oxm;
4125 6         53 }
4126 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4127 6         8 my $heredoc = $1;
4128 6         44 my $indent = $2;
4129 6         19 $heredoc =~ s{^$indent}{}msg; # no /ox
4130             push @heredoc, $heredoc . qq{\n$delimiter\n};
4131             push @heredoc_delimiter, qq{\\s*$delimiter};
4132 6         10 }
4133             else {
4134 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4135             }
4136             return qq{<<'$delimiter'};
4137             }
4138              
4139             # <<~\HEREDOC
4140              
4141             # P.66 2.6.6. "Here" Documents
4142             # in Chapter 2: Bits and Pieces
4143             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4144              
4145             # P.73 "Here" Documents
4146             # in Chapter 2: Bits and Pieces
4147             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4148 6         23  
4149 3         7 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4150 3         6 $slash = 'm//';
4151             my $here_quote = $1;
4152             my $delimiter = $2;
4153 3 50       4  
4154 3         7 # get here document
4155 3         12 if ($here_script eq '') {
4156             $here_script = CORE::substr $_, pos $_;
4157 3 50       22 $here_script =~ s/.*?\n//oxm;
4158 3         36 }
4159 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4160 3         5 my $heredoc = $1;
4161 3         40 my $indent = $2;
4162 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
4163             push @heredoc, $heredoc . qq{\n$delimiter\n};
4164             push @heredoc_delimiter, qq{\\s*$delimiter};
4165 3         7 }
4166             else {
4167 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4168             }
4169             return qq{<<\\$delimiter};
4170             }
4171              
4172 3         13 # <<~"HEREDOC"
4173 6         12 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4174 6         8 $slash = 'm//';
4175             my $here_quote = $1;
4176             my $delimiter = $2;
4177 6 50       11  
4178 6         11 # get here document
4179 6         24 if ($here_script eq '') {
4180             $here_script = CORE::substr $_, pos $_;
4181 6 50       28 $here_script =~ s/.*?\n//oxm;
4182 6         64 }
4183 6         15 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4184 6         8 my $heredoc = $1;
4185 6         44 my $indent = $2;
4186 6         13 $heredoc =~ s{^$indent}{}msg; # no /ox
4187             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4188             push @heredoc_delimiter, qq{\\s*$delimiter};
4189 6         11 }
4190             else {
4191 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4192             }
4193             return qq{<<"$delimiter"};
4194             }
4195              
4196 6         21 # <<~HEREDOC
4197 3         7 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4198 3         4 $slash = 'm//';
4199             my $here_quote = $1;
4200             my $delimiter = $2;
4201 3 50       6  
4202 3         5 # get here document
4203 3         11 if ($here_script eq '') {
4204             $here_script = CORE::substr $_, pos $_;
4205 3 50       23 $here_script =~ s/.*?\n//oxm;
4206 3         42 }
4207 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4208 3         4 my $heredoc = $1;
4209 3         35 my $indent = $2;
4210 3         8 $heredoc =~ s{^$indent}{}msg; # no /ox
4211             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4212             push @heredoc_delimiter, qq{\\s*$delimiter};
4213 3         7 }
4214             else {
4215 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4216             }
4217             return qq{<<$delimiter};
4218             }
4219              
4220 3         11 # <<~`HEREDOC`
4221 6         9 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4222 6         13 $slash = 'm//';
4223             my $here_quote = $1;
4224             my $delimiter = $2;
4225 6 50       9  
4226 6         12 # get here document
4227 6         15 if ($here_script eq '') {
4228             $here_script = CORE::substr $_, pos $_;
4229 6 50       27 $here_script =~ s/.*?\n//oxm;
4230 6         50 }
4231 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4232 6         10 my $heredoc = $1;
4233 6         53 my $indent = $2;
4234 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4235             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4236             push @heredoc_delimiter, qq{\\s*$delimiter};
4237 6         14 }
4238             else {
4239 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4240             }
4241             return qq{<<`$delimiter`};
4242             }
4243              
4244 6         20 # <<'HEREDOC'
4245 72         141 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4246 72         142 $slash = 'm//';
4247             my $here_quote = $1;
4248             my $delimiter = $2;
4249 72 50       115  
4250 72         125 # get here document
4251 72         357 if ($here_script eq '') {
4252             $here_script = CORE::substr $_, pos $_;
4253 72 50       360 $here_script =~ s/.*?\n//oxm;
4254 72         514 }
4255 72         224 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4256             push @heredoc, $1 . qq{\n$delimiter\n};
4257             push @heredoc_delimiter, $delimiter;
4258 72         130 }
4259             else {
4260 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4261             }
4262             return $here_quote;
4263             }
4264              
4265             # <<\HEREDOC
4266              
4267             # P.66 2.6.6. "Here" Documents
4268             # in Chapter 2: Bits and Pieces
4269             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4270              
4271             # P.73 "Here" Documents
4272             # in Chapter 2: Bits and Pieces
4273             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4274 72         258  
4275 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4276 0         0 $slash = 'm//';
4277             my $here_quote = $1;
4278             my $delimiter = $2;
4279 0 0       0  
4280 0         0 # get here document
4281 0         0 if ($here_script eq '') {
4282             $here_script = CORE::substr $_, pos $_;
4283 0 0       0 $here_script =~ s/.*?\n//oxm;
4284 0         0 }
4285 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4286             push @heredoc, $1 . qq{\n$delimiter\n};
4287             push @heredoc_delimiter, $delimiter;
4288 0         0 }
4289             else {
4290 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4291             }
4292             return $here_quote;
4293             }
4294              
4295 0         0 # <<"HEREDOC"
4296 36         87 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4297 36         85 $slash = 'm//';
4298             my $here_quote = $1;
4299             my $delimiter = $2;
4300 36 50       64  
4301 36         90 # get here document
4302 36         252 if ($here_script eq '') {
4303             $here_script = CORE::substr $_, pos $_;
4304 36 50       210 $here_script =~ s/.*?\n//oxm;
4305 36         503 }
4306 36         114 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4307             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4308             push @heredoc_delimiter, $delimiter;
4309 36         80 }
4310             else {
4311 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4312             }
4313             return $here_quote;
4314             }
4315              
4316 36         140 # <
4317 42         102 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4318 42         91 $slash = 'm//';
4319             my $here_quote = $1;
4320             my $delimiter = $2;
4321 42 50       129  
4322 42         105 # get here document
4323 42         284 if ($here_script eq '') {
4324             $here_script = CORE::substr $_, pos $_;
4325 42 50       332 $here_script =~ s/.*?\n//oxm;
4326 42         748 }
4327 42         146 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4328             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4329             push @heredoc_delimiter, $delimiter;
4330 42         93 }
4331             else {
4332 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4333             }
4334             return $here_quote;
4335             }
4336              
4337 42         170 # <<`HEREDOC`
4338 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4339 0         0 $slash = 'm//';
4340             my $here_quote = $1;
4341             my $delimiter = $2;
4342 0 0       0  
4343 0         0 # get here document
4344 0         0 if ($here_script eq '') {
4345             $here_script = CORE::substr $_, pos $_;
4346 0 0       0 $here_script =~ s/.*?\n//oxm;
4347 0         0 }
4348 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4349             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4350             push @heredoc_delimiter, $delimiter;
4351 0         0 }
4352             else {
4353 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4354             }
4355             return $here_quote;
4356             }
4357              
4358 0         0 # <<= <=> <= < operator
4359             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4360             return $1;
4361             }
4362              
4363 12         67 #
4364             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4365             return $1;
4366             }
4367              
4368             # --- glob
4369              
4370             # avoid "Error: Runtime exception" of perl version 5.005_03
4371 0         0  
4372             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4373             return 'Ekoi8u::glob("' . $1 . '")';
4374             }
4375 0         0  
4376             # __DATA__
4377             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4378 0         0  
4379             # __END__
4380             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4381              
4382             # \cD Control-D
4383              
4384             # P.68 2.6.8. Other Literal Tokens
4385             # in Chapter 2: Bits and Pieces
4386             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4387              
4388             # P.76 Other Literal Tokens
4389             # in Chapter 2: Bits and Pieces
4390 204         1406 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4391              
4392             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4393 0         0  
4394             # \cZ Control-Z
4395             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4396              
4397             # any operator before div
4398             elsif (/\G (
4399             -- | \+\+ |
4400 0         0 [\)\}\]]
  5081         9810  
4401              
4402             ) /oxgc) { $slash = 'div'; return $1; }
4403              
4404             # yada-yada or triple-dot operator
4405             elsif (/\G (
4406 5081         22865 \.\.\.
  7         13  
4407              
4408             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4409              
4410             # any operator before m//
4411              
4412             # //, //= (defined-or)
4413              
4414             # P.164 Logical Operators
4415             # in Chapter 10: More Control Structures
4416             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4417              
4418             # P.119 C-Style Logical (Short-Circuit) Operators
4419             # in Chapter 3: Unary and Binary Operators
4420             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4421              
4422             # (and so on)
4423              
4424             # ~~
4425              
4426             # P.221 The Smart Match Operator
4427             # in Chapter 15: Smart Matching and given-when
4428             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4429              
4430             # P.112 Smartmatch Operator
4431             # in Chapter 3: Unary and Binary Operators
4432             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4433              
4434             # (and so on)
4435              
4436             elsif (/\G ((?>
4437              
4438             !~~ | !~ | != | ! |
4439             %= | % |
4440             &&= | && | &= | &\.= | &\. | & |
4441             -= | -> | - |
4442             :(?>\s*)= |
4443             : |
4444             <<>> |
4445             <<= | <=> | <= | < |
4446             == | => | =~ | = |
4447             >>= | >> | >= | > |
4448             \*\*= | \*\* | \*= | \* |
4449             \+= | \+ |
4450             \.\. | \.= | \. |
4451             \/\/= | \/\/ |
4452             \/= | \/ |
4453             \? |
4454             \\ |
4455             \^= | \^\.= | \^\. | \^ |
4456             \b x= |
4457             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4458             ~~ | ~\. | ~ |
4459             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4460             \b(?: print )\b |
4461              
4462 7         25 [,;\(\{\[]
  8846         17018  
4463              
4464             )) /oxgc) { $slash = 'm//'; return $1; }
4465 8846         38168  
  15013         27515  
4466             # other any character
4467             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4468              
4469 15013         66354 # system error
4470             else {
4471             die __FILE__, ": Oops, this shouldn't happen!\n";
4472             }
4473             }
4474              
4475 0     1786 0 0 # escape KOI8-U string
4476 1786         4144 sub e_string {
4477             my($string) = @_;
4478 1786         2615 my $e_string = '';
4479              
4480             local $slash = 'm//';
4481              
4482             # P.1024 Appendix W.10 Multibyte Processing
4483             # of ISBN 1-56592-224-7 CJKV Information Processing
4484 1786         2633 # (and so on)
4485              
4486             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4487 1786 100 66     14833  
4488 1786 50       7620 # without { ... }
4489 1769         4110 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4490             if ($string !~ /<
4491             return $string;
4492             }
4493             }
4494 1769         4369  
4495 17 50       71 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          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
4496             while ($string !~ /\G \z/oxgc) {
4497             if (0) {
4498             }
4499 190         12268  
4500 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Ekoi8u::PREMATCH()]}
4501 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4502             $e_string .= q{Ekoi8u::PREMATCH()};
4503             $slash = 'div';
4504             }
4505              
4506 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Ekoi8u::MATCH()]}
4507 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4508             $e_string .= q{Ekoi8u::MATCH()};
4509             $slash = 'div';
4510             }
4511              
4512 0         0 # $', ${'} --> $', ${'}
4513 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4514             $e_string .= $1;
4515             $slash = 'div';
4516             }
4517              
4518 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Ekoi8u::POSTMATCH()]}
4519 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4520             $e_string .= q{Ekoi8u::POSTMATCH()};
4521             $slash = 'div';
4522             }
4523              
4524 0         0 # bareword
4525 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4526             $e_string .= $1;
4527             $slash = 'div';
4528             }
4529              
4530 0         0 # $0 --> $0
4531 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4532             $e_string .= $1;
4533             $slash = 'div';
4534 0         0 }
4535 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4536             $e_string .= $1;
4537             $slash = 'div';
4538             }
4539              
4540 0         0 # $$ --> $$
4541 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4542             $e_string .= $1;
4543             $slash = 'div';
4544             }
4545              
4546             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4547 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4548 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4549             $e_string .= e_capture($1);
4550             $slash = 'div';
4551 0         0 }
4552 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4553             $e_string .= e_capture($1);
4554             $slash = 'div';
4555             }
4556              
4557 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4558 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4559             $e_string .= e_capture($1.'->'.$2);
4560             $slash = 'div';
4561             }
4562              
4563 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4564 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4565             $e_string .= e_capture($1.'->'.$2);
4566             $slash = 'div';
4567             }
4568              
4569 0         0 # $$foo
4570 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4571             $e_string .= e_capture($1);
4572             $slash = 'div';
4573             }
4574              
4575 0         0 # ${ foo }
4576 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4577             $e_string .= '${' . $1 . '}';
4578             $slash = 'div';
4579             }
4580              
4581 0         0 # ${ ... }
4582 3         10 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4583             $e_string .= e_capture($1);
4584             $slash = 'div';
4585             }
4586              
4587             # variable or function
4588 3         16 # $ @ % & * $ #
4589 7         21 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) {
4590             $e_string .= $1;
4591             $slash = 'div';
4592             }
4593             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4594 7         22 # $ @ # \ ' " / ? ( ) [ ] < >
4595 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4596             $e_string .= $1;
4597             $slash = 'div';
4598             }
4599 0         0  
  0         0  
4600 0         0 # subroutines of package Ekoi8u
  0         0  
4601 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4602 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4603 0         0 elsif ($string =~ /\G \b KOI8U::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4604 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4605 0         0 elsif ($string =~ /\G \b KOI8U::eval \b /oxgc) { $e_string .= 'eval KOI8U::escape'; $slash = 'm//'; }
  0         0  
4606 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4607 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Ekoi8u::chop'; $slash = 'm//'; }
  0         0  
4608 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4609 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4610 0         0 elsif ($string =~ /\G \b KOI8U::index \b /oxgc) { $e_string .= 'KOI8U::index'; $slash = 'm//'; }
  0         0  
4611 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Ekoi8u::index'; $slash = 'm//'; }
  0         0  
4612 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4613 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4614 0         0 elsif ($string =~ /\G \b KOI8U::rindex \b /oxgc) { $e_string .= 'KOI8U::rindex'; $slash = 'm//'; }
  0         0  
4615 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Ekoi8u::rindex'; $slash = 'm//'; }
  0         0  
4616 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::lc'; $slash = 'm//'; }
  0         0  
4617 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::lcfirst'; $slash = 'm//'; }
  0         0  
4618 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::uc'; $slash = 'm//'; }
  0         0  
4619             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::ucfirst'; $slash = 'm//'; }
4620             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::fc'; $slash = 'm//'; }
4621 0         0  
  0         0  
4622 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4623 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4624 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  
4625 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  
4626 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  
4627 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  
4628             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
4629 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  
4630 0         0  
  0         0  
4631 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4632 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  
4633 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  
4634 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  
4635 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  
4636             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4637             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4638 0         0  
  0         0  
4639 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
4640 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4641 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4642             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
4643 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4644 0         0  
  0         0  
4645 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4646 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4647 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::chr'; $slash = 'm//'; }
  0         0  
4648 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4649 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4650 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::glob'; $slash = 'm//'; }
  0         0  
4651 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Ekoi8u::lc_'; $slash = 'm//'; }
  0         0  
4652 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Ekoi8u::lcfirst_'; $slash = 'm//'; }
  0         0  
4653 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Ekoi8u::uc_'; $slash = 'm//'; }
  0         0  
4654 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Ekoi8u::ucfirst_'; $slash = 'm//'; }
  0         0  
4655             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Ekoi8u::fc_'; $slash = 'm//'; }
4656 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4657 0         0  
  0         0  
4658 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4659 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4660 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Ekoi8u::chr_'; $slash = 'm//'; }
  0         0  
4661 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4662 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4663 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Ekoi8u::glob_'; $slash = 'm//'; }
  0         0  
4664             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
4665             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
4666 0         0 # split
4667             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4668 0         0 $slash = 'm//';
4669 0         0  
4670 0         0 my $e = '';
4671             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4672             $e .= $1;
4673             }
4674 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          
4675             # end of split
4676             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8u::split' . $e; }
4677 0         0  
  0         0  
4678             # split scalar value
4679             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . e_string($1); next E_STRING_LOOP; }
4680 0         0  
  0         0  
4681 0         0 # split literal space
  0         0  
4682 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4683 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4684 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4685 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4686 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4687 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4688 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4689 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4690 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4691 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4692 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4693 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4694             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {' '}; next E_STRING_LOOP; }
4695             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {" "}; next E_STRING_LOOP; }
4696              
4697 0 0       0 # split qq//
  0         0  
  0         0  
4698             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4699 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
4700 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4701 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4702 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4703 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  
4704 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  
4705 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  
4706 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  
4707             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
4708 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 * *
4709             }
4710             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4711             }
4712             }
4713              
4714 0 0       0 # split qr//
  0         0  
  0         0  
4715             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4716 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
4717 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4718 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4719 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4720 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  
4721 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  
4722 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  
4723 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  
4724 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  
4725             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
4726 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 * *
4727             }
4728             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4729             }
4730             }
4731              
4732 0 0       0 # split q//
  0         0  
  0         0  
4733             elsif ($string =~ /\G \b (q) \b /oxgc) {
4734 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
4735 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4736 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4737 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4738 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  
4739 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  
4740 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  
4741 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  
4742             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
4743 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 * *
4744             }
4745             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4746             }
4747             }
4748              
4749 0 0       0 # split m//
  0         0  
  0         0  
4750             elsif ($string =~ /\G \b (m) \b /oxgc) {
4751 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 # #
4752 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4753 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4754 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4755 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  
4756 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  
4757 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  
4758 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  
4759 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  
4760             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
4761 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 * *
4762             }
4763             die __FILE__, ": Search pattern not terminated\n";
4764             }
4765             }
4766              
4767 0         0 # split ''
4768 0         0 elsif ($string =~ /\G (\') /oxgc) {
4769 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
4770 0         0 while ($string !~ /\G \z/oxgc) {
4771 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
4772 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4773             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
4774 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4775             }
4776             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4777             }
4778              
4779 0         0 # split ""
4780 0         0 elsif ($string =~ /\G (\") /oxgc) {
4781 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
4782 0         0 while ($string !~ /\G \z/oxgc) {
4783 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
4784 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4785             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
4786 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4787             }
4788             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4789             }
4790              
4791 0         0 # split //
4792 0         0 elsif ($string =~ /\G (\/) /oxgc) {
4793 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4794 0         0 while ($string !~ /\G \z/oxgc) {
4795 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
4796 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4797             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
4798 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4799             }
4800             die __FILE__, ": Search pattern not terminated\n";
4801             }
4802             }
4803              
4804 0         0 # qq//
4805 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4806 0         0 my $ope = $1;
4807             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4808             $e_string .= e_qq($ope,$1,$3,$2);
4809 0         0 }
4810 0         0 else {
4811 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4812 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4813 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4814 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4815 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4816 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4817             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4818 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4819             }
4820             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4821             }
4822             }
4823              
4824 0         0 # qx//
4825 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4826 0         0 my $ope = $1;
4827             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4828             $e_string .= e_qq($ope,$1,$3,$2);
4829 0         0 }
4830 0         0 else {
4831 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4832 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4833 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4834 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4835 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4836 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4837 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4838             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4839 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4840             }
4841             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4842             }
4843             }
4844              
4845 0         0 # q//
4846 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4847 0         0 my $ope = $1;
4848             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4849             $e_string .= e_q($ope,$1,$3,$2);
4850 0         0 }
4851 0         0 else {
4852 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4853 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4854 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4855 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4856 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4857 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4858             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4859 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 * *
4860             }
4861             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4862             }
4863             }
4864 0         0  
4865             # ''
4866             elsif ($string =~ /\G (?
4867 0         0  
4868             # ""
4869             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4870 0         0  
4871             # ``
4872             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4873 0         0  
4874             # <<>> (a safer ARGV)
4875             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4876 0         0  
4877             # <<= <=> <= < operator
4878             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4879 0         0  
4880             #
4881             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4882              
4883 0         0 # --- glob
4884             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4885             $e_string .= 'Ekoi8u::glob("' . $1 . '")';
4886             }
4887              
4888 0         0 # << (bit shift) --- not here document
4889 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
4890             $slash = 'm//';
4891             $e_string .= $1;
4892             }
4893              
4894 0         0 # <<~'HEREDOC'
4895 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4896 0         0 $slash = 'm//';
4897             my $here_quote = $1;
4898             my $delimiter = $2;
4899 0 0       0  
4900 0         0 # get here document
4901 0         0 if ($here_script eq '') {
4902             $here_script = CORE::substr $_, pos $_;
4903 0 0       0 $here_script =~ s/.*?\n//oxm;
4904 0         0 }
4905 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4906 0         0 my $heredoc = $1;
4907 0         0 my $indent = $2;
4908 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4909             push @heredoc, $heredoc . qq{\n$delimiter\n};
4910             push @heredoc_delimiter, qq{\\s*$delimiter};
4911 0         0 }
4912             else {
4913 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4914             }
4915             $e_string .= qq{<<'$delimiter'};
4916             }
4917              
4918 0         0 # <<~\HEREDOC
4919 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4920 0         0 $slash = 'm//';
4921             my $here_quote = $1;
4922             my $delimiter = $2;
4923 0 0       0  
4924 0         0 # get here document
4925 0         0 if ($here_script eq '') {
4926             $here_script = CORE::substr $_, pos $_;
4927 0 0       0 $here_script =~ s/.*?\n//oxm;
4928 0         0 }
4929 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4930 0         0 my $heredoc = $1;
4931 0         0 my $indent = $2;
4932 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4933             push @heredoc, $heredoc . qq{\n$delimiter\n};
4934             push @heredoc_delimiter, qq{\\s*$delimiter};
4935 0         0 }
4936             else {
4937 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4938             }
4939             $e_string .= qq{<<\\$delimiter};
4940             }
4941              
4942 0         0 # <<~"HEREDOC"
4943 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4944 0         0 $slash = 'm//';
4945             my $here_quote = $1;
4946             my $delimiter = $2;
4947 0 0       0  
4948 0         0 # get here document
4949 0         0 if ($here_script eq '') {
4950             $here_script = CORE::substr $_, pos $_;
4951 0 0       0 $here_script =~ s/.*?\n//oxm;
4952 0         0 }
4953 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4954 0         0 my $heredoc = $1;
4955 0         0 my $indent = $2;
4956 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4957             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4958             push @heredoc_delimiter, qq{\\s*$delimiter};
4959 0         0 }
4960             else {
4961 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4962             }
4963             $e_string .= qq{<<"$delimiter"};
4964             }
4965              
4966 0         0 # <<~HEREDOC
4967 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4968 0         0 $slash = 'm//';
4969             my $here_quote = $1;
4970             my $delimiter = $2;
4971 0 0       0  
4972 0         0 # get here document
4973 0         0 if ($here_script eq '') {
4974             $here_script = CORE::substr $_, pos $_;
4975 0 0       0 $here_script =~ s/.*?\n//oxm;
4976 0         0 }
4977 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4978 0         0 my $heredoc = $1;
4979 0         0 my $indent = $2;
4980 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4981             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4982             push @heredoc_delimiter, qq{\\s*$delimiter};
4983 0         0 }
4984             else {
4985 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4986             }
4987             $e_string .= qq{<<$delimiter};
4988             }
4989              
4990 0         0 # <<~`HEREDOC`
4991 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4992 0         0 $slash = 'm//';
4993             my $here_quote = $1;
4994             my $delimiter = $2;
4995 0 0       0  
4996 0         0 # get here document
4997 0         0 if ($here_script eq '') {
4998             $here_script = CORE::substr $_, pos $_;
4999 0 0       0 $here_script =~ s/.*?\n//oxm;
5000 0         0 }
5001 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5002 0         0 my $heredoc = $1;
5003 0         0 my $indent = $2;
5004 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
5005             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5006             push @heredoc_delimiter, qq{\\s*$delimiter};
5007 0         0 }
5008             else {
5009 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5010             }
5011             $e_string .= qq{<<`$delimiter`};
5012             }
5013              
5014 0         0 # <<'HEREDOC'
5015 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
5016 0         0 $slash = 'm//';
5017             my $here_quote = $1;
5018             my $delimiter = $2;
5019 0 0       0  
5020 0         0 # get here document
5021 0         0 if ($here_script eq '') {
5022             $here_script = CORE::substr $_, pos $_;
5023 0 0       0 $here_script =~ s/.*?\n//oxm;
5024 0         0 }
5025 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5026             push @heredoc, $1 . qq{\n$delimiter\n};
5027             push @heredoc_delimiter, $delimiter;
5028 0         0 }
5029             else {
5030 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5031             }
5032             $e_string .= $here_quote;
5033             }
5034              
5035 0         0 # <<\HEREDOC
5036 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5037 0         0 $slash = 'm//';
5038             my $here_quote = $1;
5039             my $delimiter = $2;
5040 0 0       0  
5041 0         0 # get here document
5042 0         0 if ($here_script eq '') {
5043             $here_script = CORE::substr $_, pos $_;
5044 0 0       0 $here_script =~ s/.*?\n//oxm;
5045 0         0 }
5046 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5047             push @heredoc, $1 . qq{\n$delimiter\n};
5048             push @heredoc_delimiter, $delimiter;
5049 0         0 }
5050             else {
5051 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5052             }
5053             $e_string .= $here_quote;
5054             }
5055              
5056 0         0 # <<"HEREDOC"
5057 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5058 0         0 $slash = 'm//';
5059             my $here_quote = $1;
5060             my $delimiter = $2;
5061 0 0       0  
5062 0         0 # get here document
5063 0         0 if ($here_script eq '') {
5064             $here_script = CORE::substr $_, pos $_;
5065 0 0       0 $here_script =~ s/.*?\n//oxm;
5066 0         0 }
5067 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5068             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5069             push @heredoc_delimiter, $delimiter;
5070 0         0 }
5071             else {
5072 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5073             }
5074             $e_string .= $here_quote;
5075             }
5076              
5077 0         0 # <
5078 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5079 0         0 $slash = 'm//';
5080             my $here_quote = $1;
5081             my $delimiter = $2;
5082 0 0       0  
5083 0         0 # get here document
5084 0         0 if ($here_script eq '') {
5085             $here_script = CORE::substr $_, pos $_;
5086 0 0       0 $here_script =~ s/.*?\n//oxm;
5087 0         0 }
5088 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5089             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5090             push @heredoc_delimiter, $delimiter;
5091 0         0 }
5092             else {
5093 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5094             }
5095             $e_string .= $here_quote;
5096             }
5097              
5098 0         0 # <<`HEREDOC`
5099 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5100 0         0 $slash = 'm//';
5101             my $here_quote = $1;
5102             my $delimiter = $2;
5103 0 0       0  
5104 0         0 # get here document
5105 0         0 if ($here_script eq '') {
5106             $here_script = CORE::substr $_, pos $_;
5107 0 0       0 $here_script =~ s/.*?\n//oxm;
5108 0         0 }
5109 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5110             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5111             push @heredoc_delimiter, $delimiter;
5112 0         0 }
5113             else {
5114 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5115             }
5116             $e_string .= $here_quote;
5117             }
5118              
5119             # any operator before div
5120             elsif ($string =~ /\G (
5121             -- | \+\+ |
5122 0         0 [\)\}\]]
  18         36  
5123              
5124             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
5125              
5126             # yada-yada or triple-dot operator
5127             elsif ($string =~ /\G (
5128 18         54 \.\.\.
  0         0  
5129              
5130             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
5131              
5132             # any operator before m//
5133             elsif ($string =~ /\G ((?>
5134              
5135             !~~ | !~ | != | ! |
5136             %= | % |
5137             &&= | && | &= | &\.= | &\. | & |
5138             -= | -> | - |
5139             :(?>\s*)= |
5140             : |
5141             <<>> |
5142             <<= | <=> | <= | < |
5143             == | => | =~ | = |
5144             >>= | >> | >= | > |
5145             \*\*= | \*\* | \*= | \* |
5146             \+= | \+ |
5147             \.\. | \.= | \. |
5148             \/\/= | \/\/ |
5149             \/= | \/ |
5150             \? |
5151             \\ |
5152             \^= | \^\.= | \^\. | \^ |
5153             \b x= |
5154             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
5155             ~~ | ~\. | ~ |
5156             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
5157             \b(?: print )\b |
5158              
5159 0         0 [,;\(\{\[]
  31         64  
5160              
5161             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
5162 31         114  
5163             # other any character
5164             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
5165              
5166 131         397 # system error
5167             else {
5168             die __FILE__, ": Oops, this shouldn't happen!\n";
5169             }
5170 0         0 }
5171              
5172             return $e_string;
5173             }
5174              
5175             #
5176             # character class
5177 17     1919 0 75 #
5178             sub character_class {
5179 1919 100       3349 my($char,$modifier) = @_;
5180 1919 100       2929  
5181 52         105 if ($char eq '.') {
5182             if ($modifier =~ /s/) {
5183             return '${Ekoi8u::dot_s}';
5184 17         44 }
5185             else {
5186             return '${Ekoi8u::dot}';
5187             }
5188 35         87 }
5189             else {
5190             return Ekoi8u::classic_character_class($char);
5191             }
5192             }
5193              
5194             #
5195             # escape capture ($1, $2, $3, ...)
5196             #
5197 1867     212 0 3141 sub e_capture {
5198              
5199             return join '', '${', $_[0], '}';
5200             }
5201              
5202             #
5203             # escape transliteration (tr/// or y///)
5204 212     3 0 869 #
5205 3         44 sub e_tr {
5206 3   50     11 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
5207             my $e_tr = '';
5208 3         9 $modifier ||= '';
5209              
5210             $slash = 'div';
5211 3         5  
5212             # quote character class 1
5213             $charclass = q_tr($charclass);
5214 3         8  
5215             # quote character class 2
5216             $charclass2 = q_tr($charclass2);
5217 3 50       6  
5218 3 0       11 # /b /B modifier
5219 0         0 if ($modifier =~ tr/bB//d) {
5220             if ($variable eq '') {
5221             $e_tr = qq{tr$charclass$e$charclass2$modifier};
5222 0         0 }
5223             else {
5224             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
5225             }
5226 0 100       0 }
5227 3         8 else {
5228             if ($variable eq '') {
5229             $e_tr = qq{Ekoi8u::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
5230 2         9 }
5231             else {
5232             $e_tr = qq{Ekoi8u::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
5233             }
5234             }
5235 1         4  
5236 3         5 # clear tr/// variable
5237             $tr_variable = '';
5238 3         3 $bind_operator = '';
5239              
5240             return $e_tr;
5241             }
5242              
5243             #
5244             # quote for escape transliteration (tr/// or y///)
5245 3     6 0 17 #
5246             sub q_tr {
5247             my($charclass) = @_;
5248 6 50       9  
    0          
    0          
    0          
    0          
    0          
5249 6         13 # quote character class
5250             if ($charclass !~ /'/oxms) {
5251             return e_q('', "'", "'", $charclass); # --> q' '
5252 6         10 }
5253             elsif ($charclass !~ /\//oxms) {
5254             return e_q('q', '/', '/', $charclass); # --> q/ /
5255 0         0 }
5256             elsif ($charclass !~ /\#/oxms) {
5257             return e_q('q', '#', '#', $charclass); # --> q# #
5258 0         0 }
5259             elsif ($charclass !~ /[\<\>]/oxms) {
5260             return e_q('q', '<', '>', $charclass); # --> q< >
5261 0         0 }
5262             elsif ($charclass !~ /[\(\)]/oxms) {
5263             return e_q('q', '(', ')', $charclass); # --> q( )
5264 0         0 }
5265             elsif ($charclass !~ /[\{\}]/oxms) {
5266             return e_q('q', '{', '}', $charclass); # --> q{ }
5267 0         0 }
5268 0 0       0 else {
5269 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5270             if ($charclass !~ /\Q$char\E/xms) {
5271             return e_q('q', $char, $char, $charclass);
5272             }
5273             }
5274 0         0 }
5275              
5276             return e_q('q', '{', '}', $charclass);
5277             }
5278              
5279             #
5280             # escape q string (q//, '')
5281 0     1264 0 0 #
5282             sub e_q {
5283 1264         2829 my($ope,$delimiter,$end_delimiter,$string) = @_;
5284              
5285 1264         1670 $slash = 'div';
5286              
5287             return join '', $ope, $delimiter, $string, $end_delimiter;
5288             }
5289              
5290             #
5291             # escape qq string (qq//, "", qx//, ``)
5292 1264     4066 0 5997 #
5293             sub e_qq {
5294 4066         8583 my($ope,$delimiter,$end_delimiter,$string) = @_;
5295              
5296 4066         5147 $slash = 'div';
5297 4066         4731  
5298             my $left_e = 0;
5299             my $right_e = 0;
5300 4066         4396  
5301             # split regexp
5302             my @char = $string =~ /\G((?>
5303             [^\\\$] |
5304             \\x\{ (?>[0-9A-Fa-f]+) \} |
5305             \\o\{ (?>[0-7]+) \} |
5306             \\N\{ (?>[^0-9\}][^\}]*) \} |
5307             \\ $q_char |
5308             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5309             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5310             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5311             \$ (?>\s* [0-9]+) |
5312             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5313             \$ \$ (?![\w\{]) |
5314             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5315             $q_char
5316 4066         131978 ))/oxmsg;
5317              
5318             for (my $i=0; $i <= $#char; $i++) {
5319 4066 50 33     12167  
    50 33        
    100          
    100          
    50          
5320 113632         352698 # "\L\u" --> "\u\L"
5321             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5322             @char[$i,$i+1] = @char[$i+1,$i];
5323             }
5324              
5325 0         0 # "\U\l" --> "\l\U"
5326             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5327             @char[$i,$i+1] = @char[$i+1,$i];
5328             }
5329              
5330 0         0 # octal escape sequence
5331             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5332             $char[$i] = Ekoi8u::octchr($1);
5333             }
5334              
5335 1         3 # hexadecimal escape sequence
5336             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5337             $char[$i] = Ekoi8u::hexchr($1);
5338             }
5339              
5340 1         3 # \N{CHARNAME} --> N{CHARNAME}
5341             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5342             $char[$i] = $1;
5343 0 100       0 }
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5344              
5345             if (0) {
5346             }
5347              
5348             # \F
5349             #
5350             # P.69 Table 2-6. Translation escapes
5351             # in Chapter 2: Bits and Pieces
5352             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5353             # (and so on)
5354 113632         871645  
5355 0 50       0 # \u \l \U \L \F \Q \E
5356 484         1132 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5357             if ($right_e < $left_e) {
5358             $char[$i] = '\\' . $char[$i];
5359             }
5360             }
5361             elsif ($char[$i] eq '\u') {
5362              
5363             # "STRING @{[ LIST EXPR ]} MORE STRING"
5364              
5365             # P.257 Other Tricks You Can Do with Hard References
5366             # in Chapter 8: References
5367             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5368              
5369             # P.353 Other Tricks You Can Do with Hard References
5370             # in Chapter 8: References
5371             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5372              
5373 0         0 # (and so on)
5374 0         0  
5375             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5376             $left_e++;
5377 0         0 }
5378 0         0 elsif ($char[$i] eq '\l') {
5379             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5380             $left_e++;
5381 0         0 }
5382 0         0 elsif ($char[$i] eq '\U') {
5383             $char[$i] = '@{[Ekoi8u::uc qq<';
5384             $left_e++;
5385 0         0 }
5386 0         0 elsif ($char[$i] eq '\L') {
5387             $char[$i] = '@{[Ekoi8u::lc qq<';
5388             $left_e++;
5389 0         0 }
5390 24         45 elsif ($char[$i] eq '\F') {
5391             $char[$i] = '@{[Ekoi8u::fc qq<';
5392             $left_e++;
5393 24         51 }
5394 0         0 elsif ($char[$i] eq '\Q') {
5395             $char[$i] = '@{[CORE::quotemeta qq<';
5396             $left_e++;
5397 0 50       0 }
5398 24         48 elsif ($char[$i] eq '\E') {
5399 24         31 if ($right_e < $left_e) {
5400             $char[$i] = '>]}';
5401             $right_e++;
5402 24         69 }
5403             else {
5404             $char[$i] = '';
5405             }
5406 0         0 }
5407 0 0       0 elsif ($char[$i] eq '\Q') {
5408 0         0 while (1) {
5409             if (++$i > $#char) {
5410 0 0       0 last;
5411 0         0 }
5412             if ($char[$i] eq '\E') {
5413             last;
5414             }
5415             }
5416             }
5417             elsif ($char[$i] eq '\E') {
5418             }
5419              
5420             # $0 --> $0
5421             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5422             }
5423             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5424             }
5425              
5426             # $$ --> $$
5427             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5428             }
5429              
5430             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5431 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5432             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5433             $char[$i] = e_capture($1);
5434 205         417 }
5435             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5436             $char[$i] = e_capture($1);
5437             }
5438              
5439 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5440             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5441             $char[$i] = e_capture($1.'->'.$2);
5442             }
5443              
5444 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5445             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5446             $char[$i] = e_capture($1.'->'.$2);
5447             }
5448              
5449 0         0 # $$foo
5450             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5451             $char[$i] = e_capture($1);
5452             }
5453              
5454 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5455             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5456             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5457             }
5458              
5459 44         119 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5460             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5461             $char[$i] = '@{[Ekoi8u::MATCH()]}';
5462             }
5463              
5464 45         121 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5465             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5466             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5467             }
5468              
5469             # ${ foo } --> ${ foo }
5470             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5471             }
5472              
5473 33         100 # ${ ... }
5474             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5475             $char[$i] = e_capture($1);
5476             }
5477             }
5478 0 50       0  
5479 4066         7366 # return string
5480             if ($left_e > $right_e) {
5481 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5482             }
5483             return join '', $ope, $delimiter, @char, $end_delimiter;
5484             }
5485              
5486             #
5487             # escape qw string (qw//)
5488 4066     16 0 31387 #
5489             sub e_qw {
5490 16         82 my($ope,$delimiter,$end_delimiter,$string) = @_;
5491              
5492             $slash = 'div';
5493 16         36  
  16         211  
5494 483 50       822 # choice again delimiter
    0          
    0          
    0          
    0          
5495 16         136 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5496             if (not $octet{$end_delimiter}) {
5497             return join '', $ope, $delimiter, $string, $end_delimiter;
5498 16         155 }
5499             elsif (not $octet{')'}) {
5500             return join '', $ope, '(', $string, ')';
5501 0         0 }
5502             elsif (not $octet{'}'}) {
5503             return join '', $ope, '{', $string, '}';
5504 0         0 }
5505             elsif (not $octet{']'}) {
5506             return join '', $ope, '[', $string, ']';
5507 0         0 }
5508             elsif (not $octet{'>'}) {
5509             return join '', $ope, '<', $string, '>';
5510 0         0 }
5511 0 0       0 else {
5512 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5513             if (not $octet{$char}) {
5514             return join '', $ope, $char, $string, $char;
5515             }
5516             }
5517             }
5518 0         0  
5519 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5520 0         0 my @string = CORE::split(/\s+/, $string);
5521 0         0 for my $string (@string) {
5522 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5523 0         0 for my $octet (@octet) {
5524             if ($octet =~ /\A (['\\]) \z/oxms) {
5525             $octet = '\\' . $1;
5526 0         0 }
5527             }
5528 0         0 $string = join '', @octet;
  0         0  
5529             }
5530             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5531             }
5532              
5533             #
5534             # escape here document (<<"HEREDOC", <
5535 0     93 0 0 #
5536             sub e_heredoc {
5537 93         234 my($string) = @_;
5538              
5539 93         152 $slash = 'm//';
5540              
5541 93         274 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5542 93         143  
5543             my $left_e = 0;
5544             my $right_e = 0;
5545 93         109  
5546             # split regexp
5547             my @char = $string =~ /\G((?>
5548             [^\\\$] |
5549             \\x\{ (?>[0-9A-Fa-f]+) \} |
5550             \\o\{ (?>[0-7]+) \} |
5551             \\N\{ (?>[^0-9\}][^\}]*) \} |
5552             \\ $q_char |
5553             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5554             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5555             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5556             \$ (?>\s* [0-9]+) |
5557             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5558             \$ \$ (?![\w\{]) |
5559             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5560             $q_char
5561 93         8089 ))/oxmsg;
5562              
5563             for (my $i=0; $i <= $#char; $i++) {
5564 93 50 33     413  
    50 33        
    100          
    100          
    50          
5565 3151         9291 # "\L\u" --> "\u\L"
5566             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5567             @char[$i,$i+1] = @char[$i+1,$i];
5568             }
5569              
5570 0         0 # "\U\l" --> "\l\U"
5571             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5572             @char[$i,$i+1] = @char[$i+1,$i];
5573             }
5574              
5575 0         0 # octal escape sequence
5576             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5577             $char[$i] = Ekoi8u::octchr($1);
5578             }
5579              
5580 1         3 # hexadecimal escape sequence
5581             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5582             $char[$i] = Ekoi8u::hexchr($1);
5583             }
5584              
5585 1         3 # \N{CHARNAME} --> N{CHARNAME}
5586             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5587             $char[$i] = $1;
5588 0 50       0 }
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5589              
5590             if (0) {
5591             }
5592 3151         25032  
5593 0 0       0 # \u \l \U \L \F \Q \E
5594 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5595             if ($right_e < $left_e) {
5596             $char[$i] = '\\' . $char[$i];
5597             }
5598 0         0 }
5599 0         0 elsif ($char[$i] eq '\u') {
5600             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5601             $left_e++;
5602 0         0 }
5603 0         0 elsif ($char[$i] eq '\l') {
5604             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5605             $left_e++;
5606 0         0 }
5607 0         0 elsif ($char[$i] eq '\U') {
5608             $char[$i] = '@{[Ekoi8u::uc qq<';
5609             $left_e++;
5610 0         0 }
5611 0         0 elsif ($char[$i] eq '\L') {
5612             $char[$i] = '@{[Ekoi8u::lc qq<';
5613             $left_e++;
5614 0         0 }
5615 0         0 elsif ($char[$i] eq '\F') {
5616             $char[$i] = '@{[Ekoi8u::fc qq<';
5617             $left_e++;
5618 0         0 }
5619 0         0 elsif ($char[$i] eq '\Q') {
5620             $char[$i] = '@{[CORE::quotemeta qq<';
5621             $left_e++;
5622 0 0       0 }
5623 0         0 elsif ($char[$i] eq '\E') {
5624 0         0 if ($right_e < $left_e) {
5625             $char[$i] = '>]}';
5626             $right_e++;
5627 0         0 }
5628             else {
5629             $char[$i] = '';
5630             }
5631 0         0 }
5632 0 0       0 elsif ($char[$i] eq '\Q') {
5633 0         0 while (1) {
5634             if (++$i > $#char) {
5635 0 0       0 last;
5636 0         0 }
5637             if ($char[$i] eq '\E') {
5638             last;
5639             }
5640             }
5641             }
5642             elsif ($char[$i] eq '\E') {
5643             }
5644              
5645             # $0 --> $0
5646             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5647             }
5648             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5649             }
5650              
5651             # $$ --> $$
5652             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5653             }
5654              
5655             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5656 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5657             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5658             $char[$i] = e_capture($1);
5659 0         0 }
5660             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5661             $char[$i] = e_capture($1);
5662             }
5663              
5664 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5665             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5666             $char[$i] = e_capture($1.'->'.$2);
5667             }
5668              
5669 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5670             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5671             $char[$i] = e_capture($1.'->'.$2);
5672             }
5673              
5674 0         0 # $$foo
5675             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5676             $char[$i] = e_capture($1);
5677             }
5678              
5679 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5680             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5681             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5682             }
5683              
5684 8         48 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5685             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5686             $char[$i] = '@{[Ekoi8u::MATCH()]}';
5687             }
5688              
5689 8         45 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5690             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5691             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5692             }
5693              
5694             # ${ foo } --> ${ foo }
5695             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5696             }
5697              
5698 6         208 # ${ ... }
5699             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5700             $char[$i] = e_capture($1);
5701             }
5702             }
5703 0 50       0  
5704 93         216 # return string
5705             if ($left_e > $right_e) {
5706 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5707             }
5708             return join '', @char;
5709             }
5710              
5711             #
5712             # escape regexp (m//, qr//)
5713 93     652 0 689 #
5714 652   100     2716 sub e_qr {
5715             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5716 652         2562 $modifier ||= '';
5717 652 50       1176  
5718 652         1672 $modifier =~ tr/p//d;
5719 0         0 if ($modifier =~ /([adlu])/oxms) {
5720 0 0       0 my $line = 0;
5721 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5722 0         0 if ($filename ne __FILE__) {
5723             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5724             last;
5725 0         0 }
5726             }
5727             die qq{Unsupported modifier "$1" used at line $line.\n};
5728 0         0 }
5729              
5730             $slash = 'div';
5731 652 100       998  
    100          
5732 652         1892 # literal null string pattern
5733 8         10 if ($string eq '') {
5734 8         11 $modifier =~ tr/bB//d;
5735             $modifier =~ tr/i//d;
5736             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5737             }
5738              
5739             # /b /B modifier
5740             elsif ($modifier =~ tr/bB//d) {
5741 8 50       35  
5742 2         6 # choice again delimiter
5743 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5744 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5745 0         0 my %octet = map {$_ => 1} @char;
5746 0         0 if (not $octet{')'}) {
5747             $delimiter = '(';
5748             $end_delimiter = ')';
5749 0         0 }
5750 0         0 elsif (not $octet{'}'}) {
5751             $delimiter = '{';
5752             $end_delimiter = '}';
5753 0         0 }
5754 0         0 elsif (not $octet{']'}) {
5755             $delimiter = '[';
5756             $end_delimiter = ']';
5757 0         0 }
5758 0         0 elsif (not $octet{'>'}) {
5759             $delimiter = '<';
5760             $end_delimiter = '>';
5761 0         0 }
5762 0 0       0 else {
5763 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5764 0         0 if (not $octet{$char}) {
5765 0         0 $delimiter = $char;
5766             $end_delimiter = $char;
5767             last;
5768             }
5769             }
5770             }
5771 0 50 33     0 }
5772 2         10  
5773             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5774             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5775 0         0 }
5776             else {
5777             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5778             }
5779 2 100       13 }
5780 642         1465  
5781             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5782             my $metachar = qr/[\@\\|[\]{^]/oxms;
5783 642         2221  
5784             # split regexp
5785             my @char = $string =~ /\G((?>
5786             [^\\\$\@\[\(] |
5787             \\x (?>[0-9A-Fa-f]{1,2}) |
5788             \\ (?>[0-7]{2,3}) |
5789             \\c [\x40-\x5F] |
5790             \\x\{ (?>[0-9A-Fa-f]+) \} |
5791             \\o\{ (?>[0-7]+) \} |
5792             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5793             \\ $q_char |
5794             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5795             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5796             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5797             [\$\@] $qq_variable |
5798             \$ (?>\s* [0-9]+) |
5799             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5800             \$ \$ (?![\w\{]) |
5801             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5802             \[\^ |
5803             \[\: (?>[a-z]+) :\] |
5804             \[\:\^ (?>[a-z]+) :\] |
5805             \(\? |
5806             $q_char
5807             ))/oxmsg;
5808 642 50       60738  
5809 642         2699 # choice again delimiter
  0         0  
5810 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5811 0         0 my %octet = map {$_ => 1} @char;
5812 0         0 if (not $octet{')'}) {
5813             $delimiter = '(';
5814             $end_delimiter = ')';
5815 0         0 }
5816 0         0 elsif (not $octet{'}'}) {
5817             $delimiter = '{';
5818             $end_delimiter = '}';
5819 0         0 }
5820 0         0 elsif (not $octet{']'}) {
5821             $delimiter = '[';
5822             $end_delimiter = ']';
5823 0         0 }
5824 0         0 elsif (not $octet{'>'}) {
5825             $delimiter = '<';
5826             $end_delimiter = '>';
5827 0         0 }
5828 0 0       0 else {
5829 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5830 0         0 if (not $octet{$char}) {
5831 0         0 $delimiter = $char;
5832             $end_delimiter = $char;
5833             last;
5834             }
5835             }
5836             }
5837 0         0 }
5838 642         974  
5839 642         845 my $left_e = 0;
5840             my $right_e = 0;
5841             for (my $i=0; $i <= $#char; $i++) {
5842 642 50 66     1587  
    50 66        
    100          
    100          
    100          
    100          
5843 1872         9819 # "\L\u" --> "\u\L"
5844             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5845             @char[$i,$i+1] = @char[$i+1,$i];
5846             }
5847              
5848 0         0 # "\U\l" --> "\l\U"
5849             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5850             @char[$i,$i+1] = @char[$i+1,$i];
5851             }
5852              
5853 0         0 # octal escape sequence
5854             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5855             $char[$i] = Ekoi8u::octchr($1);
5856             }
5857              
5858 1         3 # hexadecimal escape sequence
5859             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5860             $char[$i] = Ekoi8u::hexchr($1);
5861             }
5862              
5863             # \b{...} --> b\{...}
5864             # \B{...} --> B\{...}
5865             # \N{CHARNAME} --> N\{CHARNAME}
5866             # \p{PROPERTY} --> p\{PROPERTY}
5867 1         3 # \P{PROPERTY} --> P\{PROPERTY}
5868             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5869             $char[$i] = $1 . '\\' . $2;
5870             }
5871              
5872 6         22 # \p, \P, \X --> p, P, X
5873             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5874             $char[$i] = $1;
5875 4 100 100     15 }
    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          
5876              
5877             if (0) {
5878             }
5879 1872         5336  
5880 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5881 6         75 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5882             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)) {
5883             $char[$i] .= join '', splice @char, $i+1, 3;
5884 0         0 }
5885             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)) {
5886             $char[$i] .= join '', splice @char, $i+1, 2;
5887 0         0 }
5888             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)) {
5889             $char[$i] .= join '', splice @char, $i+1, 1;
5890             }
5891             }
5892              
5893 0         0 # open character class [...]
5894             elsif ($char[$i] eq '[') {
5895             my $left = $i;
5896              
5897             # [] make die "Unmatched [] in regexp ...\n"
5898 328 100       450 # (and so on)
5899 328         737  
5900             if ($char[$i+1] eq ']') {
5901             $i++;
5902 3         6 }
5903 328 50       448  
5904 1379         2142 while (1) {
5905             if (++$i > $#char) {
5906 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5907 1379         2209 }
5908             if ($char[$i] eq ']') {
5909             my $right = $i;
5910 328 100       427  
5911 328         1626 # [...]
  30         64  
5912             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5913             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5914 90         127 }
5915             else {
5916             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
5917 298         1064 }
5918 328         622  
5919             $i = $left;
5920             last;
5921             }
5922             }
5923             }
5924              
5925 328         855 # open character class [^...]
5926             elsif ($char[$i] eq '[^') {
5927             my $left = $i;
5928              
5929             # [^] make die "Unmatched [] in regexp ...\n"
5930 74 100       104 # (and so on)
5931 74         162  
5932             if ($char[$i+1] eq ']') {
5933             $i++;
5934 4         7 }
5935 74 50       81  
5936 272         394 while (1) {
5937             if (++$i > $#char) {
5938 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5939 272         377 }
5940             if ($char[$i] eq ']') {
5941             my $right = $i;
5942 74 100       86  
5943 74         359 # [^...]
  30         83  
5944             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5945             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5946 90         128 }
5947             else {
5948             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5949 44         151 }
5950 74         130  
5951             $i = $left;
5952             last;
5953             }
5954             }
5955             }
5956              
5957 74         192 # rewrite character class or escape character
5958             elsif (my $char = character_class($char[$i],$modifier)) {
5959             $char[$i] = $char;
5960             }
5961              
5962 139 50       360 # /i modifier
5963 20         42 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
5964             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
5965             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
5966 20         37 }
5967             else {
5968             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
5969             }
5970             }
5971              
5972 0 50       0 # \u \l \U \L \F \Q \E
5973 1         4 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5974             if ($right_e < $left_e) {
5975             $char[$i] = '\\' . $char[$i];
5976             }
5977 0         0 }
5978 0         0 elsif ($char[$i] eq '\u') {
5979             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5980             $left_e++;
5981 0         0 }
5982 0         0 elsif ($char[$i] eq '\l') {
5983             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5984             $left_e++;
5985 0         0 }
5986 1         3 elsif ($char[$i] eq '\U') {
5987             $char[$i] = '@{[Ekoi8u::uc qq<';
5988             $left_e++;
5989 1         4 }
5990 1         4 elsif ($char[$i] eq '\L') {
5991             $char[$i] = '@{[Ekoi8u::lc qq<';
5992             $left_e++;
5993 1         4 }
5994 18         38 elsif ($char[$i] eq '\F') {
5995             $char[$i] = '@{[Ekoi8u::fc qq<';
5996             $left_e++;
5997 18         52 }
5998 1         3 elsif ($char[$i] eq '\Q') {
5999             $char[$i] = '@{[CORE::quotemeta qq<';
6000             $left_e++;
6001 1 50       3 }
6002 21         55 elsif ($char[$i] eq '\E') {
6003 21         36 if ($right_e < $left_e) {
6004             $char[$i] = '>]}';
6005             $right_e++;
6006 21         54 }
6007             else {
6008             $char[$i] = '';
6009             }
6010 0         0 }
6011 0 0       0 elsif ($char[$i] eq '\Q') {
6012 0         0 while (1) {
6013             if (++$i > $#char) {
6014 0 0       0 last;
6015 0         0 }
6016             if ($char[$i] eq '\E') {
6017             last;
6018             }
6019             }
6020             }
6021             elsif ($char[$i] eq '\E') {
6022             }
6023              
6024 0 0       0 # $0 --> $0
6025 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6026             if ($ignorecase) {
6027             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6028             }
6029 0 0       0 }
6030 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6031             if ($ignorecase) {
6032             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6033             }
6034             }
6035              
6036             # $$ --> $$
6037             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6038             }
6039              
6040             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6041 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6042 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6043 0         0 $char[$i] = e_capture($1);
6044             if ($ignorecase) {
6045             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6046             }
6047 0         0 }
6048 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6049 0         0 $char[$i] = e_capture($1);
6050             if ($ignorecase) {
6051             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6052             }
6053             }
6054              
6055 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6056 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) {
6057 0         0 $char[$i] = e_capture($1.'->'.$2);
6058             if ($ignorecase) {
6059             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6060             }
6061             }
6062              
6063 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6064 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) {
6065 0         0 $char[$i] = e_capture($1.'->'.$2);
6066             if ($ignorecase) {
6067             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6068             }
6069             }
6070              
6071 0         0 # $$foo
6072 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6073 0         0 $char[$i] = e_capture($1);
6074             if ($ignorecase) {
6075             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6076             }
6077             }
6078              
6079 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
6080 8         25 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6081             if ($ignorecase) {
6082             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
6083 0         0 }
6084             else {
6085             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
6086             }
6087             }
6088              
6089 8 50       22 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
6090 8         22 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6091             if ($ignorecase) {
6092             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
6093 0         0 }
6094             else {
6095             $char[$i] = '@{[Ekoi8u::MATCH()]}';
6096             }
6097             }
6098              
6099 8 50       26 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
6100 6         18 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6101             if ($ignorecase) {
6102             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
6103 0         0 }
6104             else {
6105             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
6106             }
6107             }
6108              
6109 6 0       21 # ${ foo }
6110 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) {
6111             if ($ignorecase) {
6112             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6113             }
6114             }
6115              
6116 0         0 # ${ ... }
6117 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6118 0         0 $char[$i] = e_capture($1);
6119             if ($ignorecase) {
6120             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6121             }
6122             }
6123              
6124 0         0 # $scalar or @array
6125 21 100       64 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6126 21         117 $char[$i] = e_string($char[$i]);
6127             if ($ignorecase) {
6128             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6129             }
6130             }
6131              
6132 11 100 33     40 # quote character before ? + * {
    50          
6133             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6134             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6135 138         953 }
6136 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6137 0         0 my $char = $char[$i-1];
6138             if ($char[$i] eq '{') {
6139             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
6140 0         0 }
6141             else {
6142             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
6143             }
6144 0         0 }
6145             else {
6146             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6147             }
6148             }
6149             }
6150 127         476  
6151 642 50       1154 # make regexp string
6152 642 0 0     1336 $modifier =~ tr/i//d;
6153 0         0 if ($left_e > $right_e) {
6154             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6155             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
6156 0         0 }
6157             else {
6158             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6159 0 50 33     0 }
6160 642         3318 }
6161             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6162             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
6163 0         0 }
6164             else {
6165             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6166             }
6167             }
6168              
6169             #
6170             # double quote stuff
6171 642     180 0 5114 #
6172             sub qq_stuff {
6173             my($delimiter,$end_delimiter,$stuff) = @_;
6174 180 100       272  
6175 180         333 # scalar variable or array variable
6176             if ($stuff =~ /\A [\$\@] /oxms) {
6177             return $stuff;
6178             }
6179 100         323  
  80         165  
6180 80         214 # quote by delimiter
6181 80 50       189 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
6182 80 50       126 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6183 80 50       114 next if $char eq $delimiter;
6184 80         161 next if $char eq $end_delimiter;
6185             if (not $octet{$char}) {
6186             return join '', 'qq', $char, $stuff, $char;
6187 80         317 }
6188             }
6189             return join '', 'qq', '<', $stuff, '>';
6190             }
6191              
6192             #
6193             # escape regexp (m'', qr'', and m''b, qr''b)
6194 0     10 0 0 #
6195 10   50     46 sub e_qr_q {
6196             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6197 10         36 $modifier ||= '';
6198 10 50       18  
6199 10         16 $modifier =~ tr/p//d;
6200 0         0 if ($modifier =~ /([adlu])/oxms) {
6201 0 0       0 my $line = 0;
6202 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6203 0         0 if ($filename ne __FILE__) {
6204             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6205             last;
6206 0         0 }
6207             }
6208             die qq{Unsupported modifier "$1" used at line $line.\n};
6209 0         0 }
6210              
6211             $slash = 'div';
6212 10 100       17  
    50          
6213 10         19 # literal null string pattern
6214 8         33 if ($string eq '') {
6215 8         8 $modifier =~ tr/bB//d;
6216             $modifier =~ tr/i//d;
6217             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6218             }
6219              
6220 8         40 # with /b /B modifier
6221             elsif ($modifier =~ tr/bB//d) {
6222             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6223             }
6224              
6225 0         0 # without /b /B modifier
6226             else {
6227             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6228             }
6229             }
6230              
6231             #
6232             # escape regexp (m'', qr'')
6233 2     2 0 6 #
6234             sub e_qr_qt {
6235 2 50       6 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6236              
6237             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6238 2         5  
6239             # split regexp
6240             my @char = $string =~ /\G((?>
6241             [^\\\[\$\@\/] |
6242             [\x00-\xFF] |
6243             \[\^ |
6244             \[\: (?>[a-z]+) \:\] |
6245             \[\:\^ (?>[a-z]+) \:\] |
6246             [\$\@\/] |
6247             \\ (?:$q_char) |
6248             (?:$q_char)
6249             ))/oxmsg;
6250 2         60  
6251 2 50 33     10 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
6252             for (my $i=0; $i <= $#char; $i++) {
6253             if (0) {
6254             }
6255 2         26  
6256 0         0 # open character class [...]
6257 0 0       0 elsif ($char[$i] eq '[') {
6258 0         0 my $left = $i;
6259             if ($char[$i+1] eq ']') {
6260 0         0 $i++;
6261 0 0       0 }
6262 0         0 while (1) {
6263             if (++$i > $#char) {
6264 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6265 0         0 }
6266             if ($char[$i] eq ']') {
6267             my $right = $i;
6268 0         0  
6269             # [...]
6270 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6271 0         0  
6272             $i = $left;
6273             last;
6274             }
6275             }
6276             }
6277              
6278 0         0 # open character class [^...]
6279 0 0       0 elsif ($char[$i] eq '[^') {
6280 0         0 my $left = $i;
6281             if ($char[$i+1] eq ']') {
6282 0         0 $i++;
6283 0 0       0 }
6284 0         0 while (1) {
6285             if (++$i > $#char) {
6286 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6287 0         0 }
6288             if ($char[$i] eq ']') {
6289             my $right = $i;
6290 0         0  
6291             # [^...]
6292 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6293 0         0  
6294             $i = $left;
6295             last;
6296             }
6297             }
6298             }
6299              
6300 0         0 # escape $ @ / and \
6301             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6302             $char[$i] = '\\' . $char[$i];
6303             }
6304              
6305 0         0 # rewrite character class or escape character
6306             elsif (my $char = character_class($char[$i],$modifier)) {
6307             $char[$i] = $char;
6308             }
6309              
6310 0 0       0 # /i modifier
6311 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6312             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6313             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6314 0         0 }
6315             else {
6316             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6317             }
6318             }
6319              
6320 0 0       0 # quote character before ? + * {
6321             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6322             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6323 0         0 }
6324             else {
6325             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6326             }
6327             }
6328 0         0 }
6329 2         6  
6330             $delimiter = '/';
6331 2         3 $end_delimiter = '/';
6332 2         4  
6333             $modifier =~ tr/i//d;
6334             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6335             }
6336              
6337             #
6338             # escape regexp (m''b, qr''b)
6339 2     0 0 17 #
6340             sub e_qr_qb {
6341             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6342 0         0  
6343             # split regexp
6344             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6345 0         0  
6346 0 0       0 # unescape character
    0          
6347             for (my $i=0; $i <= $#char; $i++) {
6348             if (0) {
6349             }
6350 0         0  
6351             # remain \\
6352             elsif ($char[$i] eq '\\\\') {
6353             }
6354              
6355 0         0 # escape $ @ / and \
6356             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6357             $char[$i] = '\\' . $char[$i];
6358             }
6359 0         0 }
6360 0         0  
6361 0         0 $delimiter = '/';
6362             $end_delimiter = '/';
6363             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6364             }
6365              
6366             #
6367             # escape regexp (s/here//)
6368 0     76 0 0 #
6369 76   100     227 sub e_s1 {
6370             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6371 76         354 $modifier ||= '';
6372 76 50       117  
6373 76         202 $modifier =~ tr/p//d;
6374 0         0 if ($modifier =~ /([adlu])/oxms) {
6375 0 0       0 my $line = 0;
6376 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6377 0         0 if ($filename ne __FILE__) {
6378             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6379             last;
6380 0         0 }
6381             }
6382             die qq{Unsupported modifier "$1" used at line $line.\n};
6383 0         0 }
6384              
6385             $slash = 'div';
6386 76 100       140  
    50          
6387 76         261 # literal null string pattern
6388 8         10 if ($string eq '') {
6389 8         9 $modifier =~ tr/bB//d;
6390             $modifier =~ tr/i//d;
6391             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6392             }
6393              
6394             # /b /B modifier
6395             elsif ($modifier =~ tr/bB//d) {
6396 8 0       48  
6397 0         0 # choice again delimiter
6398 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
6399 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
6400 0         0 my %octet = map {$_ => 1} @char;
6401 0         0 if (not $octet{')'}) {
6402             $delimiter = '(';
6403             $end_delimiter = ')';
6404 0         0 }
6405 0         0 elsif (not $octet{'}'}) {
6406             $delimiter = '{';
6407             $end_delimiter = '}';
6408 0         0 }
6409 0         0 elsif (not $octet{']'}) {
6410             $delimiter = '[';
6411             $end_delimiter = ']';
6412 0         0 }
6413 0         0 elsif (not $octet{'>'}) {
6414             $delimiter = '<';
6415             $end_delimiter = '>';
6416 0         0 }
6417 0 0       0 else {
6418 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6419 0         0 if (not $octet{$char}) {
6420 0         0 $delimiter = $char;
6421             $end_delimiter = $char;
6422             last;
6423             }
6424             }
6425             }
6426 0         0 }
6427 0         0  
6428             my $prematch = '';
6429             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6430 0 100       0 }
6431 68         187  
6432             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6433             my $metachar = qr/[\@\\|[\]{^]/oxms;
6434 68         271  
6435             # split regexp
6436             my @char = $string =~ /\G((?>
6437             [^\\\$\@\[\(] |
6438             \\ (?>[1-9][0-9]*) |
6439             \\g (?>\s*) (?>[1-9][0-9]*) |
6440             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6441             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6442             \\x (?>[0-9A-Fa-f]{1,2}) |
6443             \\ (?>[0-7]{2,3}) |
6444             \\c [\x40-\x5F] |
6445             \\x\{ (?>[0-9A-Fa-f]+) \} |
6446             \\o\{ (?>[0-7]+) \} |
6447             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6448             \\ $q_char |
6449             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6450             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6451             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6452             [\$\@] $qq_variable |
6453             \$ (?>\s* [0-9]+) |
6454             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6455             \$ \$ (?![\w\{]) |
6456             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6457             \[\^ |
6458             \[\: (?>[a-z]+) :\] |
6459             \[\:\^ (?>[a-z]+) :\] |
6460             \(\? |
6461             $q_char
6462             ))/oxmsg;
6463 68 50       17351  
6464 68         458 # choice again delimiter
  0         0  
6465 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
6466 0         0 my %octet = map {$_ => 1} @char;
6467 0         0 if (not $octet{')'}) {
6468             $delimiter = '(';
6469             $end_delimiter = ')';
6470 0         0 }
6471 0         0 elsif (not $octet{'}'}) {
6472             $delimiter = '{';
6473             $end_delimiter = '}';
6474 0         0 }
6475 0         0 elsif (not $octet{']'}) {
6476             $delimiter = '[';
6477             $end_delimiter = ']';
6478 0         0 }
6479 0         0 elsif (not $octet{'>'}) {
6480             $delimiter = '<';
6481             $end_delimiter = '>';
6482 0         0 }
6483 0 0       0 else {
6484 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6485 0         0 if (not $octet{$char}) {
6486 0         0 $delimiter = $char;
6487             $end_delimiter = $char;
6488             last;
6489             }
6490             }
6491             }
6492             }
6493 0         0  
  68         145  
6494             # count '('
6495 253         511 my $parens = grep { $_ eq '(' } @char;
6496 68         100  
6497 68         98 my $left_e = 0;
6498             my $right_e = 0;
6499             for (my $i=0; $i <= $#char; $i++) {
6500 68 50 33     201  
    50 33        
    100          
    100          
    50          
    50          
6501 195         1147 # "\L\u" --> "\u\L"
6502             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6503             @char[$i,$i+1] = @char[$i+1,$i];
6504             }
6505              
6506 0         0 # "\U\l" --> "\l\U"
6507             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6508             @char[$i,$i+1] = @char[$i+1,$i];
6509             }
6510              
6511 0         0 # octal escape sequence
6512             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6513             $char[$i] = Ekoi8u::octchr($1);
6514             }
6515              
6516 1         2 # hexadecimal escape sequence
6517             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6518             $char[$i] = Ekoi8u::hexchr($1);
6519             }
6520              
6521             # \b{...} --> b\{...}
6522             # \B{...} --> B\{...}
6523             # \N{CHARNAME} --> N\{CHARNAME}
6524             # \p{PROPERTY} --> p\{PROPERTY}
6525 1         3 # \P{PROPERTY} --> P\{PROPERTY}
6526             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6527             $char[$i] = $1 . '\\' . $2;
6528             }
6529              
6530 0         0 # \p, \P, \X --> p, P, X
6531             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6532             $char[$i] = $1;
6533 0 50 66     0 }
    100 66        
    50 100        
    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          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
6534              
6535             if (0) {
6536             }
6537 195         705  
6538 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6539 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6540             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)) {
6541             $char[$i] .= join '', splice @char, $i+1, 3;
6542 0         0 }
6543             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)) {
6544             $char[$i] .= join '', splice @char, $i+1, 2;
6545 0         0 }
6546             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)) {
6547             $char[$i] .= join '', splice @char, $i+1, 1;
6548             }
6549             }
6550              
6551 0         0 # open character class [...]
6552 13 50       19 elsif ($char[$i] eq '[') {
6553 13         54 my $left = $i;
6554             if ($char[$i+1] eq ']') {
6555 0         0 $i++;
6556 13 50       21 }
6557 58         115 while (1) {
6558             if (++$i > $#char) {
6559 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6560 58         137 }
6561             if ($char[$i] eq ']') {
6562             my $right = $i;
6563 13 50       24  
6564 13         86 # [...]
  0         0  
6565             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6566             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6567 0         0 }
6568             else {
6569             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6570 13         59 }
6571 13         26  
6572             $i = $left;
6573             last;
6574             }
6575             }
6576             }
6577              
6578 13         37 # open character class [^...]
6579 0 0       0 elsif ($char[$i] eq '[^') {
6580 0         0 my $left = $i;
6581             if ($char[$i+1] eq ']') {
6582 0         0 $i++;
6583 0 0       0 }
6584 0         0 while (1) {
6585             if (++$i > $#char) {
6586 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6587 0         0 }
6588             if ($char[$i] eq ']') {
6589             my $right = $i;
6590 0 0       0  
6591 0         0 # [^...]
  0         0  
6592             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6593             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6594 0         0 }
6595             else {
6596             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6597 0         0 }
6598 0         0  
6599             $i = $left;
6600             last;
6601             }
6602             }
6603             }
6604              
6605 0         0 # rewrite character class or escape character
6606             elsif (my $char = character_class($char[$i],$modifier)) {
6607             $char[$i] = $char;
6608             }
6609              
6610 7 50       14 # /i modifier
6611 3         5 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6612             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6613             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6614 3         5 }
6615             else {
6616             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6617             }
6618             }
6619              
6620 0 0       0 # \u \l \U \L \F \Q \E
6621 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6622             if ($right_e < $left_e) {
6623             $char[$i] = '\\' . $char[$i];
6624             }
6625 0         0 }
6626 0         0 elsif ($char[$i] eq '\u') {
6627             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
6628             $left_e++;
6629 0         0 }
6630 0         0 elsif ($char[$i] eq '\l') {
6631             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
6632             $left_e++;
6633 0         0 }
6634 0         0 elsif ($char[$i] eq '\U') {
6635             $char[$i] = '@{[Ekoi8u::uc qq<';
6636             $left_e++;
6637 0         0 }
6638 0         0 elsif ($char[$i] eq '\L') {
6639             $char[$i] = '@{[Ekoi8u::lc qq<';
6640             $left_e++;
6641 0         0 }
6642 0         0 elsif ($char[$i] eq '\F') {
6643             $char[$i] = '@{[Ekoi8u::fc qq<';
6644             $left_e++;
6645 0         0 }
6646 0         0 elsif ($char[$i] eq '\Q') {
6647             $char[$i] = '@{[CORE::quotemeta qq<';
6648             $left_e++;
6649 0 0       0 }
6650 0         0 elsif ($char[$i] eq '\E') {
6651 0         0 if ($right_e < $left_e) {
6652             $char[$i] = '>]}';
6653             $right_e++;
6654 0         0 }
6655             else {
6656             $char[$i] = '';
6657             }
6658 0         0 }
6659 0 0       0 elsif ($char[$i] eq '\Q') {
6660 0         0 while (1) {
6661             if (++$i > $#char) {
6662 0 0       0 last;
6663 0         0 }
6664             if ($char[$i] eq '\E') {
6665             last;
6666             }
6667             }
6668             }
6669             elsif ($char[$i] eq '\E') {
6670             }
6671              
6672             # \0 --> \0
6673             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6674             }
6675              
6676             # \g{N}, \g{-N}
6677              
6678             # P.108 Using Simple Patterns
6679             # in Chapter 7: In the World of Regular Expressions
6680             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6681              
6682             # P.221 Capturing
6683             # in Chapter 5: Pattern Matching
6684             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6685              
6686             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6687             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6688             }
6689              
6690             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6691             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6692             }
6693              
6694             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6695             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6696             }
6697              
6698             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6699             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6700             }
6701              
6702 0 0       0 # $0 --> $0
6703 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6704             if ($ignorecase) {
6705             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6706             }
6707 0 0       0 }
6708 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6709             if ($ignorecase) {
6710             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6711             }
6712             }
6713              
6714             # $$ --> $$
6715             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6716             }
6717              
6718             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6719 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6720 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6721 0         0 $char[$i] = e_capture($1);
6722             if ($ignorecase) {
6723             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6724             }
6725 0         0 }
6726 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6727 0         0 $char[$i] = e_capture($1);
6728             if ($ignorecase) {
6729             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6730             }
6731             }
6732              
6733 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6734 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) {
6735 0         0 $char[$i] = e_capture($1.'->'.$2);
6736             if ($ignorecase) {
6737             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6738             }
6739             }
6740              
6741 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6742 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) {
6743 0         0 $char[$i] = e_capture($1.'->'.$2);
6744             if ($ignorecase) {
6745             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6746             }
6747             }
6748              
6749 0         0 # $$foo
6750 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6751 0         0 $char[$i] = e_capture($1);
6752             if ($ignorecase) {
6753             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6754             }
6755             }
6756              
6757 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
6758 4         14 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6759             if ($ignorecase) {
6760             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
6761 0         0 }
6762             else {
6763             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
6764             }
6765             }
6766              
6767 4 50       15 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
6768 4         14 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6769             if ($ignorecase) {
6770             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
6771 0         0 }
6772             else {
6773             $char[$i] = '@{[Ekoi8u::MATCH()]}';
6774             }
6775             }
6776              
6777 4 50       14 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
6778 3         13 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6779             if ($ignorecase) {
6780             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
6781 0         0 }
6782             else {
6783             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
6784             }
6785             }
6786              
6787 3 0       11 # ${ foo }
6788 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) {
6789             if ($ignorecase) {
6790             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6791             }
6792             }
6793              
6794 0         0 # ${ ... }
6795 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6796 0         0 $char[$i] = e_capture($1);
6797             if ($ignorecase) {
6798             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6799             }
6800             }
6801              
6802 0         0 # $scalar or @array
6803 4 50       20 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6804 4         19 $char[$i] = e_string($char[$i]);
6805             if ($ignorecase) {
6806             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6807             }
6808             }
6809              
6810 0 50       0 # quote character before ? + * {
6811             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6812             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6813 13         72 }
6814             else {
6815             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6816             }
6817             }
6818             }
6819 13         66  
6820 68         150 # make regexp string
6821 68 50       106 my $prematch = '';
6822 68         189 $modifier =~ tr/i//d;
6823             if ($left_e > $right_e) {
6824 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6825             }
6826             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6827             }
6828              
6829             #
6830             # escape regexp (s'here'' or s'here''b)
6831 68     21 0 808 #
6832 21   100     47 sub e_s1_q {
6833             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6834 21         70 $modifier ||= '';
6835 21 50       27  
6836 21         43 $modifier =~ tr/p//d;
6837 0         0 if ($modifier =~ /([adlu])/oxms) {
6838 0 0       0 my $line = 0;
6839 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6840 0         0 if ($filename ne __FILE__) {
6841             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6842             last;
6843 0         0 }
6844             }
6845             die qq{Unsupported modifier "$1" used at line $line.\n};
6846 0         0 }
6847              
6848             $slash = 'div';
6849 21 100       30  
    50          
6850 21         56 # literal null string pattern
6851 8         9 if ($string eq '') {
6852 8         10 $modifier =~ tr/bB//d;
6853             $modifier =~ tr/i//d;
6854             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6855             }
6856              
6857 8         40 # with /b /B modifier
6858             elsif ($modifier =~ tr/bB//d) {
6859             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6860             }
6861              
6862 0         0 # without /b /B modifier
6863             else {
6864             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6865             }
6866             }
6867              
6868             #
6869             # escape regexp (s'here'')
6870 13     13 0 33 #
6871             sub e_s1_qt {
6872 13 50       28 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6873              
6874             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6875 13         25  
6876             # split regexp
6877             my @char = $string =~ /\G((?>
6878             [^\\\[\$\@\/] |
6879             [\x00-\xFF] |
6880             \[\^ |
6881             \[\: (?>[a-z]+) \:\] |
6882             \[\:\^ (?>[a-z]+) \:\] |
6883             [\$\@\/] |
6884             \\ (?:$q_char) |
6885             (?:$q_char)
6886             ))/oxmsg;
6887 13         194  
6888 13 50 33     44 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6889             for (my $i=0; $i <= $#char; $i++) {
6890             if (0) {
6891             }
6892 25         105  
6893 0         0 # open character class [...]
6894 0 0       0 elsif ($char[$i] eq '[') {
6895 0         0 my $left = $i;
6896             if ($char[$i+1] eq ']') {
6897 0         0 $i++;
6898 0 0       0 }
6899 0         0 while (1) {
6900             if (++$i > $#char) {
6901 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6902 0         0 }
6903             if ($char[$i] eq ']') {
6904             my $right = $i;
6905 0         0  
6906             # [...]
6907 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6908 0         0  
6909             $i = $left;
6910             last;
6911             }
6912             }
6913             }
6914              
6915 0         0 # open character class [^...]
6916 0 0       0 elsif ($char[$i] eq '[^') {
6917 0         0 my $left = $i;
6918             if ($char[$i+1] eq ']') {
6919 0         0 $i++;
6920 0 0       0 }
6921 0         0 while (1) {
6922             if (++$i > $#char) {
6923 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6924 0         0 }
6925             if ($char[$i] eq ']') {
6926             my $right = $i;
6927 0         0  
6928             # [^...]
6929 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6930 0         0  
6931             $i = $left;
6932             last;
6933             }
6934             }
6935             }
6936              
6937 0         0 # escape $ @ / and \
6938             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6939             $char[$i] = '\\' . $char[$i];
6940             }
6941              
6942 0         0 # rewrite character class or escape character
6943             elsif (my $char = character_class($char[$i],$modifier)) {
6944             $char[$i] = $char;
6945             }
6946              
6947 6 0       12 # /i modifier
6948 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6949             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6950             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6951 0         0 }
6952             else {
6953             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6954             }
6955             }
6956              
6957 0 0       0 # quote character before ? + * {
6958             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6959             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6960 0         0 }
6961             else {
6962             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6963             }
6964             }
6965 0         0 }
6966 13         20  
6967 13         23 $modifier =~ tr/i//d;
6968 13         15 $delimiter = '/';
6969 13         20 $end_delimiter = '/';
6970             my $prematch = '';
6971             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6972             }
6973              
6974             #
6975             # escape regexp (s'here''b)
6976 13     0 0 99 #
6977             sub e_s1_qb {
6978             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6979 0         0  
6980             # split regexp
6981             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6982 0         0  
6983 0 0       0 # unescape character
    0          
6984             for (my $i=0; $i <= $#char; $i++) {
6985             if (0) {
6986             }
6987 0         0  
6988             # remain \\
6989             elsif ($char[$i] eq '\\\\') {
6990             }
6991              
6992 0         0 # escape $ @ / and \
6993             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6994             $char[$i] = '\\' . $char[$i];
6995             }
6996 0         0 }
6997 0         0  
6998 0         0 $delimiter = '/';
6999 0         0 $end_delimiter = '/';
7000             my $prematch = '';
7001             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
7002             }
7003              
7004             #
7005             # escape regexp (s''here')
7006 0     16 0 0 #
7007             sub e_s2_q {
7008 16         38 my($ope,$delimiter,$end_delimiter,$string) = @_;
7009              
7010 16         22 $slash = 'div';
7011 16         109  
7012 16 100       74 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
7013             for (my $i=0; $i <= $#char; $i++) {
7014             if (0) {
7015             }
7016 9         38  
7017             # not escape \\
7018             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
7019             }
7020              
7021 0         0 # escape $ @ / and \
7022             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7023             $char[$i] = '\\' . $char[$i];
7024             }
7025 5         29 }
7026              
7027             return join '', $ope, $delimiter, @char, $end_delimiter;
7028             }
7029              
7030             #
7031             # escape regexp (s/here/and here/modifier)
7032 16     97 0 53 #
7033 97   100     720 sub e_sub {
7034             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
7035 97         425 $modifier ||= '';
7036 97 50       199  
7037 97         278 $modifier =~ tr/p//d;
7038 0         0 if ($modifier =~ /([adlu])/oxms) {
7039 0 0       0 my $line = 0;
7040 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7041 0         0 if ($filename ne __FILE__) {
7042             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7043             last;
7044 0         0 }
7045             }
7046             die qq{Unsupported modifier "$1" used at line $line.\n};
7047 0 100       0 }
7048 97         246  
7049 36         71 if ($variable eq '') {
7050             $variable = '$_';
7051             $bind_operator = ' =~ ';
7052 36         50 }
7053              
7054             $slash = 'div';
7055              
7056             # P.128 Start of match (or end of previous match): \G
7057             # P.130 Advanced Use of \G with Perl
7058             # in Chapter 3: Overview of Regular Expression Features and Flavors
7059             # P.312 Iterative Matching: Scalar Context, with /g
7060             # in Chapter 7: Perl
7061             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
7062              
7063             # P.181 Where You Left Off: The \G Assertion
7064             # in Chapter 5: Pattern Matching
7065             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7066              
7067             # P.220 Where You Left Off: The \G Assertion
7068             # in Chapter 5: Pattern Matching
7069 97         159 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7070 97         148  
7071             my $e_modifier = $modifier =~ tr/e//d;
7072 97         146 my $r_modifier = $modifier =~ tr/r//d;
7073 97 50       144  
7074 97         262 my $my = '';
7075 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
7076 0         0 $my = $variable;
7077             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
7078             $variable =~ s/ = .+ \z//oxms;
7079 0         0 }
7080 97         237  
7081             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
7082             $variable_basename =~ s/ \s+ \z//oxms;
7083 97         176  
7084 97 100       150 # quote replacement string
7085 97         215 my $e_replacement = '';
7086 17         35 if ($e_modifier >= 1) {
7087             $e_replacement = e_qq('', '', '', $replacement);
7088             $e_modifier--;
7089 17 100       25 }
7090 80         184 else {
7091             if ($delimiter2 eq "'") {
7092             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
7093 16         34 }
7094             else {
7095             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
7096             }
7097 64         146 }
7098              
7099             my $sub = '';
7100 97 100       158  
7101 97 100       1766 # with /r
7102             if ($r_modifier) {
7103             if (0) {
7104             }
7105 8         15  
7106 0 50       0 # s///gr without multibyte anchoring
7107             elsif ($modifier =~ /g/oxms) {
7108             $sub = sprintf(
7109             # 1 2 3 4 5
7110             q,
7111              
7112             $variable, # 1
7113             ($delimiter1 eq "'") ? # 2
7114             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7115             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7116             $s_matched, # 3
7117             $e_replacement, # 4
7118             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
7119             );
7120             }
7121              
7122             # s///r
7123 4         11 else {
7124              
7125 4 50       6 my $prematch = q{$`};
7126              
7127             $sub = sprintf(
7128             # 1 2 3 4 5 6 7
7129             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s"%s$Ekoi8u::re_r$'" } : %s>,
7130              
7131             $variable, # 1
7132             ($delimiter1 eq "'") ? # 2
7133             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7134             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7135             $s_matched, # 3
7136             $e_replacement, # 4
7137             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
7138             $prematch, # 6
7139             $variable, # 7
7140             );
7141             }
7142 4 50       16  
7143 8         19 # $var !~ s///r doesn't make sense
7144             if ($bind_operator =~ / !~ /oxms) {
7145             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
7146             }
7147             }
7148              
7149 0 100       0 # without /r
7150             else {
7151             if (0) {
7152             }
7153 89         222  
7154 0 100       0 # s///g without multibyte anchoring
    100          
7155             elsif ($modifier =~ /g/oxms) {
7156             $sub = sprintf(
7157             # 1 2 3 4 5 6 7 8
7158             q,
7159              
7160             $variable, # 1
7161             ($delimiter1 eq "'") ? # 2
7162             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7163             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7164             $s_matched, # 3
7165             $e_replacement, # 4
7166             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
7167             $variable, # 6
7168             $variable, # 7
7169             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
7170             );
7171             }
7172              
7173             # s///
7174 22         73 else {
7175              
7176 67 100       157 my $prematch = q{$`};
    100          
7177              
7178             $sub = sprintf(
7179              
7180             ($bind_operator =~ / =~ /oxms) ?
7181              
7182             # 1 2 3 4 5 6 7 8
7183             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s%s="%s$Ekoi8u::re_r$'"; 1 } : undef> :
7184              
7185             # 1 2 3 4 5 6 7 8
7186             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s%s="%s$Ekoi8u::re_r$'"; undef }>,
7187              
7188             $variable, # 1
7189             $bind_operator, # 2
7190             ($delimiter1 eq "'") ? # 3
7191             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7192             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7193             $s_matched, # 4
7194             $e_replacement, # 5
7195             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 6
7196             $variable, # 7
7197             $prematch, # 8
7198             );
7199             }
7200             }
7201 67 50       442  
7202 97         277 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
7203             if ($my ne '') {
7204             $sub = "($my, $sub)[1]";
7205             }
7206 0         0  
7207 97         148 # clear s/// variable
7208             $sub_variable = '';
7209 97         128 $bind_operator = '';
7210              
7211             return $sub;
7212             }
7213              
7214             #
7215             # escape regexp of split qr//
7216 97     74 0 691 #
7217 74   100     322 sub e_split {
7218             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7219 74         364 $modifier ||= '';
7220 74 50       132  
7221 74         204 $modifier =~ tr/p//d;
7222 0         0 if ($modifier =~ /([adlu])/oxms) {
7223 0 0       0 my $line = 0;
7224 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7225 0         0 if ($filename ne __FILE__) {
7226             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7227             last;
7228 0         0 }
7229             }
7230             die qq{Unsupported modifier "$1" used at line $line.\n};
7231 0         0 }
7232              
7233             $slash = 'div';
7234 74 50       121  
7235 74         189 # /b /B modifier
7236             if ($modifier =~ tr/bB//d) {
7237             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7238 0 50       0 }
7239 74         189  
7240             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7241             my $metachar = qr/[\@\\|[\]{^]/oxms;
7242 74         251  
7243             # split regexp
7244             my @char = $string =~ /\G((?>
7245             [^\\\$\@\[\(] |
7246             \\x (?>[0-9A-Fa-f]{1,2}) |
7247             \\ (?>[0-7]{2,3}) |
7248             \\c [\x40-\x5F] |
7249             \\x\{ (?>[0-9A-Fa-f]+) \} |
7250             \\o\{ (?>[0-7]+) \} |
7251             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7252             \\ $q_char |
7253             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7254             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7255             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7256             [\$\@] $qq_variable |
7257             \$ (?>\s* [0-9]+) |
7258             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7259             \$ \$ (?![\w\{]) |
7260             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7261             \[\^ |
7262             \[\: (?>[a-z]+) :\] |
7263             \[\:\^ (?>[a-z]+) :\] |
7264             \(\? |
7265             $q_char
7266 74         8974 ))/oxmsg;
7267 74         321  
7268 74         99 my $left_e = 0;
7269             my $right_e = 0;
7270             for (my $i=0; $i <= $#char; $i++) {
7271 74 50 33     363  
    50 33        
    100          
    100          
    50          
    50          
7272 249         1203 # "\L\u" --> "\u\L"
7273             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7274             @char[$i,$i+1] = @char[$i+1,$i];
7275             }
7276              
7277 0         0 # "\U\l" --> "\l\U"
7278             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7279             @char[$i,$i+1] = @char[$i+1,$i];
7280             }
7281              
7282 0         0 # octal escape sequence
7283             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7284             $char[$i] = Ekoi8u::octchr($1);
7285             }
7286              
7287 1         3 # hexadecimal escape sequence
7288             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7289             $char[$i] = Ekoi8u::hexchr($1);
7290             }
7291              
7292             # \b{...} --> b\{...}
7293             # \B{...} --> B\{...}
7294             # \N{CHARNAME} --> N\{CHARNAME}
7295             # \p{PROPERTY} --> p\{PROPERTY}
7296 1         3 # \P{PROPERTY} --> P\{PROPERTY}
7297             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7298             $char[$i] = $1 . '\\' . $2;
7299             }
7300              
7301 0         0 # \p, \P, \X --> p, P, X
7302             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7303             $char[$i] = $1;
7304 0 50 100     0 }
    100 33        
    50 33        
    100 100        
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
7305              
7306             if (0) {
7307             }
7308 249         809  
7309 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
7310 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7311             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)) {
7312             $char[$i] .= join '', splice @char, $i+1, 3;
7313 0         0 }
7314             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)) {
7315             $char[$i] .= join '', splice @char, $i+1, 2;
7316 0         0 }
7317             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)) {
7318             $char[$i] .= join '', splice @char, $i+1, 1;
7319             }
7320             }
7321              
7322 0         0 # open character class [...]
7323 3 50       4 elsif ($char[$i] eq '[') {
7324 3         6 my $left = $i;
7325             if ($char[$i+1] eq ']') {
7326 0         0 $i++;
7327 3 50       5 }
7328 7         12 while (1) {
7329             if (++$i > $#char) {
7330 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7331 7         11 }
7332             if ($char[$i] eq ']') {
7333             my $right = $i;
7334 3 50       6  
7335 3         16 # [...]
  0         0  
7336             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7337             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7338 0         0 }
7339             else {
7340             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
7341 3         28 }
7342 3         4  
7343             $i = $left;
7344             last;
7345             }
7346             }
7347             }
7348              
7349 3         7 # open character class [^...]
7350 0 0       0 elsif ($char[$i] eq '[^') {
7351 0         0 my $left = $i;
7352             if ($char[$i+1] eq ']') {
7353 0         0 $i++;
7354 0 0       0 }
7355 0         0 while (1) {
7356             if (++$i > $#char) {
7357 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7358 0         0 }
7359             if ($char[$i] eq ']') {
7360             my $right = $i;
7361 0 0       0  
7362 0         0 # [^...]
  0         0  
7363             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7364             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7365 0         0 }
7366             else {
7367             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7368 0         0 }
7369 0         0  
7370             $i = $left;
7371             last;
7372             }
7373             }
7374             }
7375              
7376 0         0 # rewrite character class or escape character
7377             elsif (my $char = character_class($char[$i],$modifier)) {
7378             $char[$i] = $char;
7379             }
7380              
7381             # P.794 29.2.161. split
7382             # in Chapter 29: Functions
7383             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7384              
7385             # P.951 split
7386             # in Chapter 27: Functions
7387             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7388              
7389             # said "The //m modifier is assumed when you split on the pattern /^/",
7390             # but perl5.008 is not so. Therefore, this software adds //m.
7391             # (and so on)
7392              
7393 1         2 # split(m/^/) --> split(m/^/m)
7394             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7395             $modifier .= 'm';
7396             }
7397              
7398 7 0       21 # /i modifier
7399 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
7400             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
7401             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
7402 0         0 }
7403             else {
7404             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
7405             }
7406             }
7407              
7408 0 0       0 # \u \l \U \L \F \Q \E
7409 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7410             if ($right_e < $left_e) {
7411             $char[$i] = '\\' . $char[$i];
7412             }
7413 0         0 }
7414 0         0 elsif ($char[$i] eq '\u') {
7415             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
7416             $left_e++;
7417 0         0 }
7418 0         0 elsif ($char[$i] eq '\l') {
7419             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
7420             $left_e++;
7421 0         0 }
7422 0         0 elsif ($char[$i] eq '\U') {
7423             $char[$i] = '@{[Ekoi8u::uc qq<';
7424             $left_e++;
7425 0         0 }
7426 0         0 elsif ($char[$i] eq '\L') {
7427             $char[$i] = '@{[Ekoi8u::lc qq<';
7428             $left_e++;
7429 0         0 }
7430 0         0 elsif ($char[$i] eq '\F') {
7431             $char[$i] = '@{[Ekoi8u::fc qq<';
7432             $left_e++;
7433 0         0 }
7434 0         0 elsif ($char[$i] eq '\Q') {
7435             $char[$i] = '@{[CORE::quotemeta qq<';
7436             $left_e++;
7437 0 0       0 }
7438 0         0 elsif ($char[$i] eq '\E') {
7439 0         0 if ($right_e < $left_e) {
7440             $char[$i] = '>]}';
7441             $right_e++;
7442 0         0 }
7443             else {
7444             $char[$i] = '';
7445             }
7446 0         0 }
7447 0 0       0 elsif ($char[$i] eq '\Q') {
7448 0         0 while (1) {
7449             if (++$i > $#char) {
7450 0 0       0 last;
7451 0         0 }
7452             if ($char[$i] eq '\E') {
7453             last;
7454             }
7455             }
7456             }
7457             elsif ($char[$i] eq '\E') {
7458             }
7459              
7460 0 0       0 # $0 --> $0
7461 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7462             if ($ignorecase) {
7463             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7464             }
7465 0 0       0 }
7466 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7467             if ($ignorecase) {
7468             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7469             }
7470             }
7471              
7472             # $$ --> $$
7473             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7474             }
7475              
7476             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7477 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7478 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7479 0         0 $char[$i] = e_capture($1);
7480             if ($ignorecase) {
7481             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7482             }
7483 0         0 }
7484 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7485 0         0 $char[$i] = e_capture($1);
7486             if ($ignorecase) {
7487             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7488             }
7489             }
7490              
7491 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7492 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) {
7493 0         0 $char[$i] = e_capture($1.'->'.$2);
7494             if ($ignorecase) {
7495             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7496             }
7497             }
7498              
7499 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7500 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) {
7501 0         0 $char[$i] = e_capture($1.'->'.$2);
7502             if ($ignorecase) {
7503             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7504             }
7505             }
7506              
7507 0         0 # $$foo
7508 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7509 0         0 $char[$i] = e_capture($1);
7510             if ($ignorecase) {
7511             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7512             }
7513             }
7514              
7515 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
7516 12         34 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7517             if ($ignorecase) {
7518             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
7519 0         0 }
7520             else {
7521             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
7522             }
7523             }
7524              
7525 12 50       53 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
7526 12         31 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7527             if ($ignorecase) {
7528             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
7529 0         0 }
7530             else {
7531             $char[$i] = '@{[Ekoi8u::MATCH()]}';
7532             }
7533             }
7534              
7535 12 50       55 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
7536 9         33 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7537             if ($ignorecase) {
7538             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
7539 0         0 }
7540             else {
7541             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
7542             }
7543             }
7544              
7545 9 0       42 # ${ foo }
7546 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) {
7547             if ($ignorecase) {
7548             $char[$i] = '@{[Ekoi8u::ignorecase(' . $1 . ')]}';
7549             }
7550             }
7551              
7552 0         0 # ${ ... }
7553 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7554 0         0 $char[$i] = e_capture($1);
7555             if ($ignorecase) {
7556             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7557             }
7558             }
7559              
7560 0         0 # $scalar or @array
7561 3 50       10 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7562 3         12 $char[$i] = e_string($char[$i]);
7563             if ($ignorecase) {
7564             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7565             }
7566             }
7567              
7568 0 50       0 # quote character before ? + * {
7569             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7570             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7571 1         6 }
7572             else {
7573             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7574             }
7575             }
7576             }
7577 0         0  
7578 74 50       204 # make regexp string
7579 74         155 $modifier =~ tr/i//d;
7580             if ($left_e > $right_e) {
7581 0         0 return join '', 'Ekoi8u::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7582             }
7583             return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7584             }
7585              
7586             #
7587             # escape regexp of split qr''
7588 74     0 0 798 #
7589 0   0       sub e_split_q {
7590             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7591 0           $modifier ||= '';
7592 0 0          
7593 0           $modifier =~ tr/p//d;
7594 0           if ($modifier =~ /([adlu])/oxms) {
7595 0 0         my $line = 0;
7596 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7597 0           if ($filename ne __FILE__) {
7598             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7599             last;
7600 0           }
7601             }
7602             die qq{Unsupported modifier "$1" used at line $line.\n};
7603 0           }
7604              
7605             $slash = 'div';
7606 0 0          
7607 0           # /b /B modifier
7608             if ($modifier =~ tr/bB//d) {
7609             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7610 0 0         }
7611              
7612             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7613 0            
7614             # split regexp
7615             my @char = $string =~ /\G((?>
7616             [^\\\[] |
7617             [\x00-\xFF] |
7618             \[\^ |
7619             \[\: (?>[a-z]+) \:\] |
7620             \[\:\^ (?>[a-z]+) \:\] |
7621             \\ (?:$q_char) |
7622             (?:$q_char)
7623             ))/oxmsg;
7624 0            
7625 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7626             for (my $i=0; $i <= $#char; $i++) {
7627             if (0) {
7628             }
7629 0            
7630 0           # open character class [...]
7631 0 0         elsif ($char[$i] eq '[') {
7632 0           my $left = $i;
7633             if ($char[$i+1] eq ']') {
7634 0           $i++;
7635 0 0         }
7636 0           while (1) {
7637             if (++$i > $#char) {
7638 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7639 0           }
7640             if ($char[$i] eq ']') {
7641             my $right = $i;
7642 0            
7643             # [...]
7644 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
7645 0            
7646             $i = $left;
7647             last;
7648             }
7649             }
7650             }
7651              
7652 0           # open character class [^...]
7653 0 0         elsif ($char[$i] eq '[^') {
7654 0           my $left = $i;
7655             if ($char[$i+1] eq ']') {
7656 0           $i++;
7657 0 0         }
7658 0           while (1) {
7659             if (++$i > $#char) {
7660 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7661 0           }
7662             if ($char[$i] eq ']') {
7663             my $right = $i;
7664 0            
7665             # [^...]
7666 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7667 0            
7668             $i = $left;
7669             last;
7670             }
7671             }
7672             }
7673              
7674 0           # rewrite character class or escape character
7675             elsif (my $char = character_class($char[$i],$modifier)) {
7676             $char[$i] = $char;
7677             }
7678              
7679 0           # split(m/^/) --> split(m/^/m)
7680             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7681             $modifier .= 'm';
7682             }
7683              
7684 0 0         # /i modifier
7685 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
7686             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
7687             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
7688 0           }
7689             else {
7690             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
7691             }
7692             }
7693              
7694 0 0         # quote character before ? + * {
7695             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7696             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7697 0           }
7698             else {
7699             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7700             }
7701             }
7702 0           }
7703 0            
7704             $modifier =~ tr/i//d;
7705             return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7706             }
7707              
7708             #
7709             # instead of Carp::carp
7710 0     0 0   #
7711 0           sub carp {
7712             my($package,$filename,$line) = caller(1);
7713             print STDERR "@_ at $filename line $line.\n";
7714             }
7715              
7716             #
7717             # instead of Carp::croak
7718 0     0 0   #
7719 0           sub croak {
7720 0           my($package,$filename,$line) = caller(1);
7721             print STDERR "@_ at $filename line $line.\n";
7722             die "\n";
7723             }
7724              
7725             #
7726             # instead of Carp::cluck
7727 0     0 0   #
7728 0           sub cluck {
7729 0           my $i = 0;
7730 0           my @cluck = ();
7731 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7732             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7733 0           $i++;
7734 0           }
7735 0           print STDERR CORE::reverse @cluck;
7736             print STDERR "\n";
7737             print STDERR @_;
7738             }
7739              
7740             #
7741             # instead of Carp::confess
7742 0     0 0   #
7743 0           sub confess {
7744 0           my $i = 0;
7745 0           my @confess = ();
7746 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7747             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7748 0           $i++;
7749 0           }
7750 0           print STDERR CORE::reverse @confess;
7751 0           print STDERR "\n";
7752             print STDERR @_;
7753             die "\n";
7754             }
7755              
7756             1;
7757              
7758             __END__