File Coverage

blib/lib/Ekoi8r.pm
Criterion Covered Total %
statement 905 3194 28.3
branch 968 2740 35.3
condition 98 355 27.6
subroutine 52 110 47.2
pod 7 74 9.4
total 2030 6473 31.3


line stmt bran cond sub pod time code
1             package Ekoi8r;
2 204     204   1472 use strict;
  204         372  
  204         16305  
3             ######################################################################
4             #
5             # Ekoi8r - Run-time routines for KOI8R.pm
6             #
7             # http://search.cpan.org/dist/Char-KOI8R/
8             #
9             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
10             ######################################################################
11              
12 204     204   3417 use 5.00503; # Galapagos Consensus 1998 for primetools
  204         681  
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   1042 use vars qw($VERSION);
  204         2067  
  204         30414  
28             $VERSION = '1.13';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 204 50   204   1601 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 204         350 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 204         28690 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   14344 CORE::eval q{
  204     204   1434  
  204     48   398  
  204         25512  
  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       92620 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 return \do { local *_ };
  0         0  
69             }
70              
71             sub qualify ($$) {
72 0     0 0 0 my($name) = @_;
73              
74 0 0       0 if (ref $name) {
    0          
    0          
    0          
    0          
    0          
    0          
75 0         0 return $name;
76             }
77             elsif (Ekoi8r::index($name,'::') >= 0) {
78 0         0 return $name;
79             }
80             elsif (Ekoi8r::index($name,"'") >= 0) {
81 0         0 return $name;
82             }
83              
84             # special character, "^xyz"
85             elsif ($name =~ /\A \^ [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+ \z/x) {
86              
87             # RGS 2001-11-05 : translate leading ^X to control-char
88 0         0 $name =~ s{\A \^ ([ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]) }{'qq(\c'.$1.')'}xee;
  0         0  
89 0         0 return 'main::' . $name;
90             }
91              
92             # Global names
93             elsif ($name =~ /\A (?: ARGV | ARGVOUT | ENV | INC | SIG | STDERR | STDIN | STDOUT ) \z/x) {
94 0         0 return 'main::' . $name;
95             }
96              
97             # or other
98             elsif ($name =~ /\A [^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz] \z/x) {
99 0         0 return 'main::' . $name;
100             }
101              
102             elsif (defined $_[1]) {
103 0         0 return $_[1] . '::' . $name;
104             }
105             else {
106 0         0 return (caller)[0] . '::' . $name;
107             }
108             }
109              
110             sub qualify_to_ref ($;$) {
111 0 0   0 0 0 if (defined $_[1]) {
112 204     204   1525 no strict qw(refs);
  204         535  
  204         15234  
113 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
114             }
115             else {
116 204     204   1254 no strict qw(refs);
  204     0   380  
  204         35919  
117 0         0 return \*{ qualify $_[0], (caller)[0] };
  0         0  
118             }
119             }
120             }
121              
122             # P.714 29.2.39. flock
123             # in Chapter 29: Functions
124             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
125              
126             # P.863 flock
127             # in Chapter 27: Functions
128             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
129              
130             sub LOCK_SH() {1}
131             sub LOCK_EX() {2}
132             sub LOCK_UN() {8}
133             sub LOCK_NB() {4}
134              
135             # instead of Carp.pm
136             sub carp;
137             sub croak;
138             sub cluck;
139             sub confess;
140              
141             # 6.18. Matching Multiple-Byte Characters
142             # in Chapter 6. Pattern Matching
143             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
144             # (and so on)
145              
146             # regexp of character
147             my $your_char = q{[\x00-\xFF]};
148 204     204   1288 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  204         360  
  204         15078  
149 204     204   1387 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  204         351  
  204         374007  
150              
151             #
152             # KOI8-R character range per length
153             #
154             my %range_tr = ();
155              
156             #
157             # KOI8-R case conversion
158             #
159             my %lc = ();
160             @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)} =
161             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);
162             my %uc = ();
163             @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)} =
164             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);
165             my %fc = ();
166             @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)} =
167             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);
168              
169             if (0) {
170             }
171              
172             elsif (__PACKAGE__ =~ / \b Ekoi8r \z/oxms) {
173             %range_tr = (
174             1 => [ [0x00..0xFF],
175             ],
176             );
177              
178             %lc = (%lc,
179             "\xB3" => "\xA3", # CYRILLIC LETTER IO
180             "\xE0" => "\xC0", # CYRILLIC LETTER IU
181             "\xE1" => "\xC1", # CYRILLIC LETTER A
182             "\xE2" => "\xC2", # CYRILLIC LETTER BE
183             "\xE3" => "\xC3", # CYRILLIC LETTER TSE
184             "\xE4" => "\xC4", # CYRILLIC LETTER DE
185             "\xE5" => "\xC5", # CYRILLIC LETTER IE
186             "\xE6" => "\xC6", # CYRILLIC LETTER EF
187             "\xE7" => "\xC7", # CYRILLIC LETTER GE
188             "\xE8" => "\xC8", # CYRILLIC LETTER KHA
189             "\xE9" => "\xC9", # CYRILLIC LETTER II
190             "\xEA" => "\xCA", # CYRILLIC LETTER SHORT II
191             "\xEB" => "\xCB", # CYRILLIC LETTER KA
192             "\xEC" => "\xCC", # CYRILLIC LETTER EL
193             "\xED" => "\xCD", # CYRILLIC LETTER EM
194             "\xEE" => "\xCE", # CYRILLIC LETTER EN
195             "\xEF" => "\xCF", # CYRILLIC LETTER O
196             "\xF0" => "\xD0", # CYRILLIC LETTER PE
197             "\xF1" => "\xD1", # CYRILLIC LETTER IA
198             "\xF2" => "\xD2", # CYRILLIC LETTER ER
199             "\xF3" => "\xD3", # CYRILLIC LETTER ES
200             "\xF4" => "\xD4", # CYRILLIC LETTER TE
201             "\xF5" => "\xD5", # CYRILLIC LETTER U
202             "\xF6" => "\xD6", # CYRILLIC LETTER ZHE
203             "\xF7" => "\xD7", # CYRILLIC LETTER VE
204             "\xF8" => "\xD8", # CYRILLIC LETTER SOFT SIGN
205             "\xF9" => "\xD9", # CYRILLIC LETTER YERI
206             "\xFA" => "\xDA", # CYRILLIC LETTER ZE
207             "\xFB" => "\xDB", # CYRILLIC LETTER SHA
208             "\xFC" => "\xDC", # CYRILLIC LETTER REVERSED E
209             "\xFD" => "\xDD", # CYRILLIC LETTER SHCHA
210             "\xFE" => "\xDE", # CYRILLIC LETTER CHE
211             "\xFF" => "\xDF", # CYRILLIC LETTER HARD SIGN
212             );
213              
214             %uc = (%uc,
215             "\xA3" => "\xB3", # CYRILLIC LETTER IO
216             "\xC0" => "\xE0", # CYRILLIC LETTER IU
217             "\xC1" => "\xE1", # CYRILLIC LETTER A
218             "\xC2" => "\xE2", # CYRILLIC LETTER BE
219             "\xC3" => "\xE3", # CYRILLIC LETTER TSE
220             "\xC4" => "\xE4", # CYRILLIC LETTER DE
221             "\xC5" => "\xE5", # CYRILLIC LETTER IE
222             "\xC6" => "\xE6", # CYRILLIC LETTER EF
223             "\xC7" => "\xE7", # CYRILLIC LETTER GE
224             "\xC8" => "\xE8", # CYRILLIC LETTER KHA
225             "\xC9" => "\xE9", # CYRILLIC LETTER II
226             "\xCA" => "\xEA", # CYRILLIC LETTER SHORT II
227             "\xCB" => "\xEB", # CYRILLIC LETTER KA
228             "\xCC" => "\xEC", # CYRILLIC LETTER EL
229             "\xCD" => "\xED", # CYRILLIC LETTER EM
230             "\xCE" => "\xEE", # CYRILLIC LETTER EN
231             "\xCF" => "\xEF", # CYRILLIC LETTER O
232             "\xD0" => "\xF0", # CYRILLIC LETTER PE
233             "\xD1" => "\xF1", # CYRILLIC LETTER IA
234             "\xD2" => "\xF2", # CYRILLIC LETTER ER
235             "\xD3" => "\xF3", # CYRILLIC LETTER ES
236             "\xD4" => "\xF4", # CYRILLIC LETTER TE
237             "\xD5" => "\xF5", # CYRILLIC LETTER U
238             "\xD6" => "\xF6", # CYRILLIC LETTER ZHE
239             "\xD7" => "\xF7", # CYRILLIC LETTER VE
240             "\xD8" => "\xF8", # CYRILLIC LETTER SOFT SIGN
241             "\xD9" => "\xF9", # CYRILLIC LETTER YERI
242             "\xDA" => "\xFA", # CYRILLIC LETTER ZE
243             "\xDB" => "\xFB", # CYRILLIC LETTER SHA
244             "\xDC" => "\xFC", # CYRILLIC LETTER REVERSED E
245             "\xDD" => "\xFD", # CYRILLIC LETTER SHCHA
246             "\xDE" => "\xFE", # CYRILLIC LETTER CHE
247             "\xDF" => "\xFF", # CYRILLIC LETTER HARD SIGN
248             );
249              
250             %fc = (%fc,
251             "\xB3" => "\xA3", # CYRILLIC CAPITAL LETTER IO --> CYRILLIC SMALL LETTER IO
252             "\xE0" => "\xC0", # CYRILLIC CAPITAL LETTER YU --> CYRILLIC SMALL LETTER YU
253             "\xE1" => "\xC1", # CYRILLIC CAPITAL LETTER A --> CYRILLIC SMALL LETTER A
254             "\xE2" => "\xC2", # CYRILLIC CAPITAL LETTER BE --> CYRILLIC SMALL LETTER BE
255             "\xE3" => "\xC3", # CYRILLIC CAPITAL LETTER TSE --> CYRILLIC SMALL LETTER TSE
256             "\xE4" => "\xC4", # CYRILLIC CAPITAL LETTER DE --> CYRILLIC SMALL LETTER DE
257             "\xE5" => "\xC5", # CYRILLIC CAPITAL LETTER IE --> CYRILLIC SMALL LETTER IE
258             "\xE6" => "\xC6", # CYRILLIC CAPITAL LETTER EF --> CYRILLIC SMALL LETTER EF
259             "\xE7" => "\xC7", # CYRILLIC CAPITAL LETTER GHE --> CYRILLIC SMALL LETTER GHE
260             "\xE8" => "\xC8", # CYRILLIC CAPITAL LETTER HA --> CYRILLIC SMALL LETTER HA
261             "\xE9" => "\xC9", # CYRILLIC CAPITAL LETTER I --> CYRILLIC SMALL LETTER I
262             "\xEA" => "\xCA", # CYRILLIC CAPITAL LETTER SHORT I --> CYRILLIC SMALL LETTER SHORT I
263             "\xEB" => "\xCB", # CYRILLIC CAPITAL LETTER KA --> CYRILLIC SMALL LETTER KA
264             "\xEC" => "\xCC", # CYRILLIC CAPITAL LETTER EL --> CYRILLIC SMALL LETTER EL
265             "\xED" => "\xCD", # CYRILLIC CAPITAL LETTER EM --> CYRILLIC SMALL LETTER EM
266             "\xEE" => "\xCE", # CYRILLIC CAPITAL LETTER EN --> CYRILLIC SMALL LETTER EN
267             "\xEF" => "\xCF", # CYRILLIC CAPITAL LETTER O --> CYRILLIC SMALL LETTER O
268             "\xF0" => "\xD0", # CYRILLIC CAPITAL LETTER PE --> CYRILLIC SMALL LETTER PE
269             "\xF1" => "\xD1", # CYRILLIC CAPITAL LETTER YA --> CYRILLIC SMALL LETTER YA
270             "\xF2" => "\xD2", # CYRILLIC CAPITAL LETTER ER --> CYRILLIC SMALL LETTER ER
271             "\xF3" => "\xD3", # CYRILLIC CAPITAL LETTER ES --> CYRILLIC SMALL LETTER ES
272             "\xF4" => "\xD4", # CYRILLIC CAPITAL LETTER TE --> CYRILLIC SMALL LETTER TE
273             "\xF5" => "\xD5", # CYRILLIC CAPITAL LETTER U --> CYRILLIC SMALL LETTER U
274             "\xF6" => "\xD6", # CYRILLIC CAPITAL LETTER ZHE --> CYRILLIC SMALL LETTER ZHE
275             "\xF7" => "\xD7", # CYRILLIC CAPITAL LETTER VE --> CYRILLIC SMALL LETTER VE
276             "\xF8" => "\xD8", # CYRILLIC CAPITAL LETTER SOFT SIGN --> CYRILLIC SMALL LETTER SOFT SIGN
277             "\xF9" => "\xD9", # CYRILLIC CAPITAL LETTER YERU --> CYRILLIC SMALL LETTER YERU
278             "\xFA" => "\xDA", # CYRILLIC CAPITAL LETTER ZE --> CYRILLIC SMALL LETTER ZE
279             "\xFB" => "\xDB", # CYRILLIC CAPITAL LETTER SHA --> CYRILLIC SMALL LETTER SHA
280             "\xFC" => "\xDC", # CYRILLIC CAPITAL LETTER E --> CYRILLIC SMALL LETTER E
281             "\xFD" => "\xDD", # CYRILLIC CAPITAL LETTER SHCHA --> CYRILLIC SMALL LETTER SHCHA
282             "\xFE" => "\xDE", # CYRILLIC CAPITAL LETTER CHE --> CYRILLIC SMALL LETTER CHE
283             "\xFF" => "\xDF", # CYRILLIC CAPITAL LETTER HARD SIGN --> CYRILLIC SMALL LETTER HARD SIGN
284             );
285             }
286              
287             else {
288             croak "Don't know my package name '@{[__PACKAGE__]}'";
289             }
290              
291             #
292             # @ARGV wildcard globbing
293             #
294             sub import {
295              
296 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
297 0         0 my @argv = ();
298 0         0 for (@ARGV) {
299              
300             # has space
301 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
302 0 0       0 if (my @glob = Ekoi8r::glob(qq{"$_"})) {
303 0         0 push @argv, @glob;
304             }
305             else {
306 0         0 push @argv, $_;
307             }
308             }
309              
310             # has wildcard metachar
311             elsif (/\A (?:$q_char)*? [*?] /oxms) {
312 0 0       0 if (my @glob = Ekoi8r::glob($_)) {
313 0         0 push @argv, @glob;
314             }
315             else {
316 0         0 push @argv, $_;
317             }
318             }
319              
320             # no wildcard globbing
321             else {
322 0         0 push @argv, $_;
323             }
324             }
325 0         0 @ARGV = @argv;
326             }
327              
328 0         0 *Char::ord = \&KOI8R::ord;
329 0         0 *Char::ord_ = \&KOI8R::ord_;
330 0         0 *Char::reverse = \&KOI8R::reverse;
331 0         0 *Char::getc = \&KOI8R::getc;
332 0         0 *Char::length = \&KOI8R::length;
333 0         0 *Char::substr = \&KOI8R::substr;
334 0         0 *Char::index = \&KOI8R::index;
335 0         0 *Char::rindex = \&KOI8R::rindex;
336 0         0 *Char::eval = \&KOI8R::eval;
337 0         0 *Char::escape = \&KOI8R::escape;
338 0         0 *Char::escape_token = \&KOI8R::escape_token;
339 0         0 *Char::escape_script = \&KOI8R::escape_script;
340             }
341              
342             # P.230 Care with Prototypes
343             # in Chapter 6: Subroutines
344             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
345             #
346             # If you aren't careful, you can get yourself into trouble with prototypes.
347             # But if you are careful, you can do a lot of neat things with them. This is
348             # all very powerful, of course, and should only be used in moderation to make
349             # the world a better place.
350              
351             # P.332 Care with Prototypes
352             # in Chapter 7: Subroutines
353             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
354             #
355             # If you aren't careful, you can get yourself into trouble with prototypes.
356             # But if you are careful, you can do a lot of neat things with them. This is
357             # all very powerful, of course, and should only be used in moderation to make
358             # the world a better place.
359              
360             #
361             # Prototypes of subroutines
362             #
363       0     sub unimport {}
364             sub Ekoi8r::split(;$$$);
365             sub Ekoi8r::tr($$$$;$);
366             sub Ekoi8r::chop(@);
367             sub Ekoi8r::index($$;$);
368             sub Ekoi8r::rindex($$;$);
369             sub Ekoi8r::lcfirst(@);
370             sub Ekoi8r::lcfirst_();
371             sub Ekoi8r::lc(@);
372             sub Ekoi8r::lc_();
373             sub Ekoi8r::ucfirst(@);
374             sub Ekoi8r::ucfirst_();
375             sub Ekoi8r::uc(@);
376             sub Ekoi8r::uc_();
377             sub Ekoi8r::fc(@);
378             sub Ekoi8r::fc_();
379             sub Ekoi8r::ignorecase;
380             sub Ekoi8r::classic_character_class;
381             sub Ekoi8r::capture;
382             sub Ekoi8r::chr(;$);
383             sub Ekoi8r::chr_();
384             sub Ekoi8r::glob($);
385             sub Ekoi8r::glob_();
386              
387             sub KOI8R::ord(;$);
388             sub KOI8R::ord_();
389             sub KOI8R::reverse(@);
390             sub KOI8R::getc(;*@);
391             sub KOI8R::length(;$);
392             sub KOI8R::substr($$;$$);
393             sub KOI8R::index($$;$);
394             sub KOI8R::rindex($$;$);
395             sub KOI8R::escape(;$);
396              
397             #
398             # Regexp work
399             #
400 204         17347 use vars qw(
401             $re_a
402             $re_t
403             $re_n
404             $re_r
405 204     204   1497 );
  204         387  
406              
407             #
408             # Character class
409             #
410 204         2009718 use vars qw(
411             $dot
412             $dot_s
413             $eD
414             $eS
415             $eW
416             $eH
417             $eV
418             $eR
419             $eN
420             $not_alnum
421             $not_alpha
422             $not_ascii
423             $not_blank
424             $not_cntrl
425             $not_digit
426             $not_graph
427             $not_lower
428             $not_lower_i
429             $not_print
430             $not_punct
431             $not_space
432             $not_upper
433             $not_upper_i
434             $not_word
435             $not_xdigit
436             $eb
437             $eB
438 204     204   1928 );
  204         364  
439              
440             ${Ekoi8r::dot} = qr{(?>[^\x0A])};
441             ${Ekoi8r::dot_s} = qr{(?>[\x00-\xFF])};
442             ${Ekoi8r::eD} = qr{(?>[^0-9])};
443              
444             # Vertical tabs are now whitespace
445             # \s in a regex now matches a vertical tab in all circumstances.
446             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
447             # ${Ekoi8r::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
448             # ${Ekoi8r::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
449             ${Ekoi8r::eS} = qr{(?>[^\s])};
450              
451             ${Ekoi8r::eW} = qr{(?>[^0-9A-Z_a-z])};
452             ${Ekoi8r::eH} = qr{(?>[^\x09\x20])};
453             ${Ekoi8r::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
454             ${Ekoi8r::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
455             ${Ekoi8r::eN} = qr{(?>[^\x0A])};
456             ${Ekoi8r::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
457             ${Ekoi8r::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
458             ${Ekoi8r::not_ascii} = qr{(?>[^\x00-\x7F])};
459             ${Ekoi8r::not_blank} = qr{(?>[^\x09\x20])};
460             ${Ekoi8r::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
461             ${Ekoi8r::not_digit} = qr{(?>[^\x30-\x39])};
462             ${Ekoi8r::not_graph} = qr{(?>[^\x21-\x7F])};
463             ${Ekoi8r::not_lower} = qr{(?>[^\x61-\x7A])};
464             ${Ekoi8r::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
465             # ${Ekoi8r::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
466             ${Ekoi8r::not_print} = qr{(?>[^\x20-\x7F])};
467             ${Ekoi8r::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
468             ${Ekoi8r::not_space} = qr{(?>[^\s\x0B])};
469             ${Ekoi8r::not_upper} = qr{(?>[^\x41-\x5A])};
470             ${Ekoi8r::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
471             # ${Ekoi8r::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
472             ${Ekoi8r::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
473             ${Ekoi8r::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
474             ${Ekoi8r::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))};
475             ${Ekoi8r::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]))};
476              
477             # avoid: Name "Ekoi8r::foo" used only once: possible typo at here.
478             ${Ekoi8r::dot} = ${Ekoi8r::dot};
479             ${Ekoi8r::dot_s} = ${Ekoi8r::dot_s};
480             ${Ekoi8r::eD} = ${Ekoi8r::eD};
481             ${Ekoi8r::eS} = ${Ekoi8r::eS};
482             ${Ekoi8r::eW} = ${Ekoi8r::eW};
483             ${Ekoi8r::eH} = ${Ekoi8r::eH};
484             ${Ekoi8r::eV} = ${Ekoi8r::eV};
485             ${Ekoi8r::eR} = ${Ekoi8r::eR};
486             ${Ekoi8r::eN} = ${Ekoi8r::eN};
487             ${Ekoi8r::not_alnum} = ${Ekoi8r::not_alnum};
488             ${Ekoi8r::not_alpha} = ${Ekoi8r::not_alpha};
489             ${Ekoi8r::not_ascii} = ${Ekoi8r::not_ascii};
490             ${Ekoi8r::not_blank} = ${Ekoi8r::not_blank};
491             ${Ekoi8r::not_cntrl} = ${Ekoi8r::not_cntrl};
492             ${Ekoi8r::not_digit} = ${Ekoi8r::not_digit};
493             ${Ekoi8r::not_graph} = ${Ekoi8r::not_graph};
494             ${Ekoi8r::not_lower} = ${Ekoi8r::not_lower};
495             ${Ekoi8r::not_lower_i} = ${Ekoi8r::not_lower_i};
496             ${Ekoi8r::not_print} = ${Ekoi8r::not_print};
497             ${Ekoi8r::not_punct} = ${Ekoi8r::not_punct};
498             ${Ekoi8r::not_space} = ${Ekoi8r::not_space};
499             ${Ekoi8r::not_upper} = ${Ekoi8r::not_upper};
500             ${Ekoi8r::not_upper_i} = ${Ekoi8r::not_upper_i};
501             ${Ekoi8r::not_word} = ${Ekoi8r::not_word};
502             ${Ekoi8r::not_xdigit} = ${Ekoi8r::not_xdigit};
503             ${Ekoi8r::eb} = ${Ekoi8r::eb};
504             ${Ekoi8r::eB} = ${Ekoi8r::eB};
505              
506             #
507             # KOI8-R split
508             #
509             sub Ekoi8r::split(;$$$) {
510              
511             # P.794 29.2.161. split
512             # in Chapter 29: Functions
513             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
514              
515             # P.951 split
516             # in Chapter 27: Functions
517             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
518              
519 0     0 0 0 my $pattern = $_[0];
520 0         0 my $string = $_[1];
521 0         0 my $limit = $_[2];
522              
523             # if $pattern is also omitted or is the literal space, " "
524 0 0       0 if (not defined $pattern) {
525 0         0 $pattern = ' ';
526             }
527              
528             # if $string is omitted, the function splits the $_ string
529 0 0       0 if (not defined $string) {
530 0 0       0 if (defined $_) {
531 0         0 $string = $_;
532             }
533             else {
534 0         0 $string = '';
535             }
536             }
537              
538 0         0 my @split = ();
539              
540             # when string is empty
541 0 0       0 if ($string eq '') {
    0          
542              
543             # resulting list value in list context
544 0 0       0 if (wantarray) {
545 0         0 return @split;
546             }
547              
548             # count of substrings in scalar context
549             else {
550 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
551 0         0 @_ = @split;
552 0         0 return scalar @_;
553             }
554             }
555              
556             # split's first argument is more consistently interpreted
557             #
558             # After some changes earlier in v5.17, split's behavior has been simplified:
559             # if the PATTERN argument evaluates to a string containing one space, it is
560             # treated the way that a literal string containing one space once was.
561             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
562              
563             # if $pattern is also omitted or is the literal space, " ", the function splits
564             # on whitespace, /\s+/, after skipping any leading whitespace
565             # (and so on)
566              
567             elsif ($pattern eq ' ') {
568 0 0       0 if (not defined $limit) {
569 0         0 return CORE::split(' ', $string);
570             }
571             else {
572 0         0 return CORE::split(' ', $string, $limit);
573             }
574             }
575              
576             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
577 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
578              
579             # a pattern capable of matching either the null string or something longer than the
580             # null string will split the value of $string into separate characters wherever it
581             # matches the null string between characters
582             # (and so on)
583              
584 0 0       0 if ('' =~ / \A $pattern \z /xms) {
585 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
586 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
587              
588             # P.1024 Appendix W.10 Multibyte Processing
589             # of ISBN 1-56592-224-7 CJKV Information Processing
590             # (and so on)
591              
592             # the //m modifier is assumed when you split on the pattern /^/
593             # (and so on)
594              
595             # V
596 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
597              
598             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
599             # is included in the resulting list, interspersed with the fields that are ordinarily returned
600             # (and so on)
601              
602 0         0 local $@;
603 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
604 0         0 push @split, CORE::eval('$' . $digit);
605             }
606             }
607             }
608              
609             else {
610 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
611              
612             # V
613 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
614 0         0 local $@;
615 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
616 0         0 push @split, CORE::eval('$' . $digit);
617             }
618             }
619             }
620             }
621              
622             elsif ($limit > 0) {
623 0 0       0 if ('' =~ / \A $pattern \z /xms) {
624 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
625 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
626              
627             # V
628 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
629 0         0 local $@;
630 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
631 0         0 push @split, CORE::eval('$' . $digit);
632             }
633             }
634             }
635             }
636             else {
637 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
638 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
639              
640             # V
641 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
642 0         0 local $@;
643 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
644 0         0 push @split, CORE::eval('$' . $digit);
645             }
646             }
647             }
648             }
649             }
650              
651 0 0       0 if (CORE::length($string) > 0) {
652 0         0 push @split, $string;
653             }
654              
655             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
656 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
657 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
658 0         0 pop @split;
659             }
660             }
661              
662             # resulting list value in list context
663 0 0       0 if (wantarray) {
664 0         0 return @split;
665             }
666              
667             # count of substrings in scalar context
668             else {
669 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
670 0         0 @_ = @split;
671 0         0 return scalar @_;
672             }
673             }
674              
675             #
676             # get last subexpression offsets
677             #
678             sub _last_subexpression_offsets {
679 0     0   0 my $pattern = $_[0];
680              
681             # remove comment
682 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
683              
684 0         0 my $modifier = '';
685 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
686 0         0 $modifier = $1;
687 0         0 $modifier =~ s/-[A-Za-z]*//;
688             }
689              
690             # with /x modifier
691 0         0 my @char = ();
692 0 0       0 if ($modifier =~ /x/oxms) {
693 0         0 @char = $pattern =~ /\G((?>
694             [^\\\#\[\(] |
695             \\ $q_char |
696             \# (?>[^\n]*) $ |
697             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
698             \(\? |
699             $q_char
700             ))/oxmsg;
701             }
702              
703             # without /x modifier
704             else {
705 0         0 @char = $pattern =~ /\G((?>
706             [^\\\[\(] |
707             \\ $q_char |
708             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
709             \(\? |
710             $q_char
711             ))/oxmsg;
712             }
713              
714 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
715             }
716              
717             #
718             # KOI8-R transliteration (tr///)
719             #
720             sub Ekoi8r::tr($$$$;$) {
721              
722 0     0 0 0 my $bind_operator = $_[1];
723 0         0 my $searchlist = $_[2];
724 0         0 my $replacementlist = $_[3];
725 0   0     0 my $modifier = $_[4] || '';
726              
727 0 0       0 if ($modifier =~ /r/oxms) {
728 0 0       0 if ($bind_operator =~ / !~ /oxms) {
729 0         0 croak "Using !~ with tr///r doesn't make sense";
730             }
731             }
732              
733 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
734 0         0 my @searchlist = _charlist_tr($searchlist);
735 0         0 my @replacementlist = _charlist_tr($replacementlist);
736              
737 0         0 my %tr = ();
738 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
739 0 0       0 if (not exists $tr{$searchlist[$i]}) {
740 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
741 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
742             }
743             elsif ($modifier =~ /d/oxms) {
744 0         0 $tr{$searchlist[$i]} = '';
745             }
746             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
747 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
748             }
749             else {
750 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
751             }
752             }
753             }
754              
755 0         0 my $tr = 0;
756 0         0 my $replaced = '';
757 0 0       0 if ($modifier =~ /c/oxms) {
758 0         0 while (defined(my $char = shift @char)) {
759 0 0       0 if (not exists $tr{$char}) {
760 0 0       0 if (defined $replacementlist[0]) {
761 0         0 $replaced .= $replacementlist[0];
762             }
763 0         0 $tr++;
764 0 0       0 if ($modifier =~ /s/oxms) {
765 0   0     0 while (@char and (not exists $tr{$char[0]})) {
766 0         0 shift @char;
767 0         0 $tr++;
768             }
769             }
770             }
771             else {
772 0         0 $replaced .= $char;
773             }
774             }
775             }
776             else {
777 0         0 while (defined(my $char = shift @char)) {
778 0 0       0 if (exists $tr{$char}) {
779 0         0 $replaced .= $tr{$char};
780 0         0 $tr++;
781 0 0       0 if ($modifier =~ /s/oxms) {
782 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $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              
794 0 0       0 if ($modifier =~ /r/oxms) {
795 0         0 return $replaced;
796             }
797             else {
798 0         0 $_[0] = $replaced;
799 0 0       0 if ($bind_operator =~ / !~ /oxms) {
800 0         0 return not $tr;
801             }
802             else {
803 0         0 return $tr;
804             }
805             }
806             }
807              
808             #
809             # KOI8-R chop
810             #
811             sub Ekoi8r::chop(@) {
812              
813 0     0 0 0 my $chop;
814 0 0       0 if (@_ == 0) {
815 0         0 my @char = /\G (?>$q_char) /oxmsg;
816 0         0 $chop = pop @char;
817 0         0 $_ = join '', @char;
818             }
819             else {
820 0         0 for (@_) {
821 0         0 my @char = /\G (?>$q_char) /oxmsg;
822 0         0 $chop = pop @char;
823 0         0 $_ = join '', @char;
824             }
825             }
826 0         0 return $chop;
827             }
828              
829             #
830             # KOI8-R index by octet
831             #
832             sub Ekoi8r::index($$;$) {
833              
834 0     0 1 0 my($str,$substr,$position) = @_;
835 0   0     0 $position ||= 0;
836 0         0 my $pos = 0;
837              
838 0         0 while ($pos < CORE::length($str)) {
839 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
840 0 0       0 if ($pos >= $position) {
841 0         0 return $pos;
842             }
843             }
844 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
845 0         0 $pos += CORE::length($1);
846             }
847             else {
848 0         0 $pos += 1;
849             }
850             }
851 0         0 return -1;
852             }
853              
854             #
855             # KOI8-R reverse index
856             #
857             sub Ekoi8r::rindex($$;$) {
858              
859 0     0 0 0 my($str,$substr,$position) = @_;
860 0   0     0 $position ||= CORE::length($str) - 1;
861 0         0 my $pos = 0;
862 0         0 my $rindex = -1;
863              
864 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
865 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
866 0         0 $rindex = $pos;
867             }
868 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
869 0         0 $pos += CORE::length($1);
870             }
871             else {
872 0         0 $pos += 1;
873             }
874             }
875 0         0 return $rindex;
876             }
877              
878             #
879             # KOI8-R lower case first with parameter
880             #
881             sub Ekoi8r::lcfirst(@) {
882 0 0   0 0 0 if (@_) {
883 0         0 my $s = shift @_;
884 0 0 0     0 if (@_ and wantarray) {
885 0         0 return Ekoi8r::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
886             }
887             else {
888 0         0 return Ekoi8r::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
889             }
890             }
891             else {
892 0         0 return Ekoi8r::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
893             }
894             }
895              
896             #
897             # KOI8-R lower case first without parameter
898             #
899             sub Ekoi8r::lcfirst_() {
900 0     0 0 0 return Ekoi8r::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
901             }
902              
903             #
904             # KOI8-R lower case with parameter
905             #
906             sub Ekoi8r::lc(@) {
907 0 0   0 0 0 if (@_) {
908 0         0 my $s = shift @_;
909 0 0 0     0 if (@_ and wantarray) {
910 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
911             }
912             else {
913 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
914             }
915             }
916             else {
917 0         0 return Ekoi8r::lc_();
918             }
919             }
920              
921             #
922             # KOI8-R lower case without parameter
923             #
924             sub Ekoi8r::lc_() {
925 0     0 0 0 my $s = $_;
926 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
927             }
928              
929             #
930             # KOI8-R upper case first with parameter
931             #
932             sub Ekoi8r::ucfirst(@) {
933 0 0   0 0 0 if (@_) {
934 0         0 my $s = shift @_;
935 0 0 0     0 if (@_ and wantarray) {
936 0         0 return Ekoi8r::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
937             }
938             else {
939 0         0 return Ekoi8r::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
940             }
941             }
942             else {
943 0         0 return Ekoi8r::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
944             }
945             }
946              
947             #
948             # KOI8-R upper case first without parameter
949             #
950             sub Ekoi8r::ucfirst_() {
951 0     0 0 0 return Ekoi8r::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
952             }
953              
954             #
955             # KOI8-R upper case with parameter
956             #
957             sub Ekoi8r::uc(@) {
958 0 50   174 0 0 if (@_) {
959 174         279 my $s = shift @_;
960 174 50 33     212 if (@_ and wantarray) {
961 174 0       307 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
962             }
963             else {
964 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         556  
965             }
966             }
967             else {
968 174         662 return Ekoi8r::uc_();
969             }
970             }
971              
972             #
973             # KOI8-R upper case without parameter
974             #
975             sub Ekoi8r::uc_() {
976 0     0 0 0 my $s = $_;
977 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
978             }
979              
980             #
981             # KOI8-R fold case with parameter
982             #
983             sub Ekoi8r::fc(@) {
984 0 50   197 0 0 if (@_) {
985 197         273 my $s = shift @_;
986 197 50 33     227 if (@_ and wantarray) {
987 197 0       357 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
988             }
989             else {
990 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         474  
991             }
992             }
993             else {
994 197         1013 return Ekoi8r::fc_();
995             }
996             }
997              
998             #
999             # KOI8-R fold case without parameter
1000             #
1001             sub Ekoi8r::fc_() {
1002 0     0 0 0 my $s = $_;
1003 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1004             }
1005              
1006             #
1007             # KOI8-R regexp capture
1008             #
1009             {
1010             sub Ekoi8r::capture {
1011 0     0 1 0 return $_[0];
1012             }
1013             }
1014              
1015             #
1016             # KOI8-R regexp ignore case modifier
1017             #
1018             sub Ekoi8r::ignorecase {
1019              
1020 0     0 0 0 my @string = @_;
1021 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1022              
1023             # ignore case of $scalar or @array
1024 0         0 for my $string (@string) {
1025              
1026             # split regexp
1027 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1028              
1029             # unescape character
1030 0         0 for (my $i=0; $i <= $#char; $i++) {
1031 0 0       0 next if not defined $char[$i];
1032              
1033             # open character class [...]
1034 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1035 0         0 my $left = $i;
1036              
1037             # [] make die "unmatched [] in regexp ...\n"
1038              
1039 0 0       0 if ($char[$i+1] eq ']') {
1040 0         0 $i++;
1041             }
1042              
1043 0         0 while (1) {
1044 0 0       0 if (++$i > $#char) {
1045 0         0 croak "Unmatched [] in regexp";
1046             }
1047 0 0       0 if ($char[$i] eq ']') {
1048 0         0 my $right = $i;
1049 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1050              
1051             # escape character
1052 0         0 for my $char (@charlist) {
1053 0 0       0 if (0) {
1054             }
1055              
1056 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1057 0         0 $char = '\\' . $char;
1058             }
1059             }
1060              
1061             # [...]
1062 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1063              
1064 0         0 $i = $left;
1065 0         0 last;
1066             }
1067             }
1068             }
1069              
1070             # open character class [^...]
1071             elsif ($char[$i] eq '[^') {
1072 0         0 my $left = $i;
1073              
1074             # [^] make die "unmatched [] in regexp ...\n"
1075              
1076 0 0       0 if ($char[$i+1] eq ']') {
1077 0         0 $i++;
1078             }
1079              
1080 0         0 while (1) {
1081 0 0       0 if (++$i > $#char) {
1082 0         0 croak "Unmatched [] in regexp";
1083             }
1084 0 0       0 if ($char[$i] eq ']') {
1085 0         0 my $right = $i;
1086 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1087              
1088             # escape character
1089 0         0 for my $char (@charlist) {
1090 0 0       0 if (0) {
1091             }
1092              
1093 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1094 0         0 $char = '\\' . $char;
1095             }
1096             }
1097              
1098             # [^...]
1099 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1100              
1101 0         0 $i = $left;
1102 0         0 last;
1103             }
1104             }
1105             }
1106              
1107             # rewrite classic character class or escape character
1108             elsif (my $char = classic_character_class($char[$i])) {
1109 0         0 $char[$i] = $char;
1110             }
1111              
1112             # with /i modifier
1113             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1114 0         0 my $uc = Ekoi8r::uc($char[$i]);
1115 0         0 my $fc = Ekoi8r::fc($char[$i]);
1116 0 0       0 if ($uc ne $fc) {
1117 0 0       0 if (CORE::length($fc) == 1) {
1118 0         0 $char[$i] = '[' . $uc . $fc . ']';
1119             }
1120             else {
1121 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1122             }
1123             }
1124             }
1125             }
1126              
1127             # characterize
1128 0         0 for (my $i=0; $i <= $#char; $i++) {
1129 0 0       0 next if not defined $char[$i];
1130              
1131 0 0       0 if (0) {
1132             }
1133              
1134             # quote character before ? + * {
1135 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1136 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1137 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1138             }
1139             }
1140             }
1141              
1142 0         0 $string = join '', @char;
1143             }
1144              
1145             # make regexp string
1146 0         0 return @string;
1147             }
1148              
1149             #
1150             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1151             #
1152             sub Ekoi8r::classic_character_class {
1153 0     1867 0 0 my($char) = @_;
1154              
1155             return {
1156             '\D' => '${Ekoi8r::eD}',
1157             '\S' => '${Ekoi8r::eS}',
1158             '\W' => '${Ekoi8r::eW}',
1159             '\d' => '[0-9]',
1160              
1161             # Before Perl 5.6, \s only matched the five whitespace characters
1162             # tab, newline, form-feed, carriage return, and the space character
1163             # itself, which, taken together, is the character class [\t\n\f\r ].
1164              
1165             # Vertical tabs are now whitespace
1166             # \s in a regex now matches a vertical tab in all circumstances.
1167             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1168             # \t \n \v \f \r space
1169             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1170             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1171             '\s' => '\s',
1172              
1173             '\w' => '[0-9A-Z_a-z]',
1174             '\C' => '[\x00-\xFF]',
1175             '\X' => 'X',
1176              
1177             # \h \v \H \V
1178              
1179             # P.114 Character Class Shortcuts
1180             # in Chapter 7: In the World of Regular Expressions
1181             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1182              
1183             # P.357 13.2.3 Whitespace
1184             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1185             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1186             #
1187             # 0x00009 CHARACTER TABULATION h s
1188             # 0x0000a LINE FEED (LF) vs
1189             # 0x0000b LINE TABULATION v
1190             # 0x0000c FORM FEED (FF) vs
1191             # 0x0000d CARRIAGE RETURN (CR) vs
1192             # 0x00020 SPACE h s
1193              
1194             # P.196 Table 5-9. Alphanumeric regex metasymbols
1195             # in Chapter 5. Pattern Matching
1196             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1197              
1198             # (and so on)
1199              
1200             '\H' => '${Ekoi8r::eH}',
1201             '\V' => '${Ekoi8r::eV}',
1202             '\h' => '[\x09\x20]',
1203             '\v' => '[\x0A\x0B\x0C\x0D]',
1204             '\R' => '${Ekoi8r::eR}',
1205              
1206             # \N
1207             #
1208             # http://perldoc.perl.org/perlre.html
1209             # Character Classes and other Special Escapes
1210             # Any character but \n (experimental). Not affected by /s modifier
1211              
1212             '\N' => '${Ekoi8r::eN}',
1213              
1214             # \b \B
1215              
1216             # P.180 Boundaries: The \b and \B Assertions
1217             # in Chapter 5: Pattern Matching
1218             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1219              
1220             # P.219 Boundaries: The \b and \B Assertions
1221             # in Chapter 5: Pattern Matching
1222             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1223              
1224             # \b really means (?:(?<=\w)(?!\w)|(?
1225             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1226             '\b' => '${Ekoi8r::eb}',
1227              
1228             # \B really means (?:(?<=\w)(?=\w)|(?
1229             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1230             '\B' => '${Ekoi8r::eB}',
1231              
1232 1867   100     2621 }->{$char} || '';
1233             }
1234              
1235             #
1236             # prepare KOI8-R characters per length
1237             #
1238              
1239             # 1 octet characters
1240             my @chars1 = ();
1241             sub chars1 {
1242 1867 0   0 0 77330 if (@chars1) {
1243 0         0 return @chars1;
1244             }
1245 0 0       0 if (exists $range_tr{1}) {
1246 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1247 0         0 while (my @range = splice(@ranges,0,1)) {
1248 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1249 0         0 push @chars1, pack 'C', $oct0;
1250             }
1251             }
1252             }
1253 0         0 return @chars1;
1254             }
1255              
1256             # 2 octets characters
1257             my @chars2 = ();
1258             sub chars2 {
1259 0 0   0 0 0 if (@chars2) {
1260 0         0 return @chars2;
1261             }
1262 0 0       0 if (exists $range_tr{2}) {
1263 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1264 0         0 while (my @range = splice(@ranges,0,2)) {
1265 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1266 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1267 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1268             }
1269             }
1270             }
1271             }
1272 0         0 return @chars2;
1273             }
1274              
1275             # 3 octets characters
1276             my @chars3 = ();
1277             sub chars3 {
1278 0 0   0 0 0 if (@chars3) {
1279 0         0 return @chars3;
1280             }
1281 0 0       0 if (exists $range_tr{3}) {
1282 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1283 0         0 while (my @range = splice(@ranges,0,3)) {
1284 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1285 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1286 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1287 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1288             }
1289             }
1290             }
1291             }
1292             }
1293 0         0 return @chars3;
1294             }
1295              
1296             # 4 octets characters
1297             my @chars4 = ();
1298             sub chars4 {
1299 0 0   0 0 0 if (@chars4) {
1300 0         0 return @chars4;
1301             }
1302 0 0       0 if (exists $range_tr{4}) {
1303 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1304 0         0 while (my @range = splice(@ranges,0,4)) {
1305 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1306 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1307 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1308 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1309 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1310             }
1311             }
1312             }
1313             }
1314             }
1315             }
1316 0         0 return @chars4;
1317             }
1318              
1319             #
1320             # KOI8-R open character list for tr
1321             #
1322             sub _charlist_tr {
1323              
1324 0     0   0 local $_ = shift @_;
1325              
1326             # unescape character
1327 0         0 my @char = ();
1328 0         0 while (not /\G \z/oxmsgc) {
1329 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1330 0         0 push @char, '\-';
1331             }
1332             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1333 0         0 push @char, CORE::chr(oct $1);
1334             }
1335             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1336 0         0 push @char, CORE::chr(hex $1);
1337             }
1338             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1339 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1340             }
1341             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1342             push @char, {
1343             '\0' => "\0",
1344             '\n' => "\n",
1345             '\r' => "\r",
1346             '\t' => "\t",
1347             '\f' => "\f",
1348             '\b' => "\x08", # \b means backspace in character class
1349             '\a' => "\a",
1350             '\e' => "\e",
1351 0         0 }->{$1};
1352             }
1353             elsif (/\G \\ ($q_char) /oxmsgc) {
1354 0         0 push @char, $1;
1355             }
1356             elsif (/\G ($q_char) /oxmsgc) {
1357 0         0 push @char, $1;
1358             }
1359             }
1360              
1361             # join separated multiple-octet
1362 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1363              
1364             # unescape '-'
1365 0         0 my @i = ();
1366 0         0 for my $i (0 .. $#char) {
1367 0 0       0 if ($char[$i] eq '\-') {
    0          
1368 0         0 $char[$i] = '-';
1369             }
1370             elsif ($char[$i] eq '-') {
1371 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1372 0         0 push @i, $i;
1373             }
1374             }
1375             }
1376              
1377             # open character list (reverse for splice)
1378 0         0 for my $i (CORE::reverse @i) {
1379 0         0 my @range = ();
1380              
1381             # range error
1382 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1383 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1384             }
1385              
1386             # range of multiple-octet code
1387 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1388 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1389 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1390             }
1391             elsif (CORE::length($char[$i+1]) == 2) {
1392 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1393 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1394             }
1395             elsif (CORE::length($char[$i+1]) == 3) {
1396 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1397 0         0 push @range, chars2();
1398 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1399             }
1400             elsif (CORE::length($char[$i+1]) == 4) {
1401 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1402 0         0 push @range, chars2();
1403 0         0 push @range, chars3();
1404 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1405             }
1406             else {
1407 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1408             }
1409             }
1410             elsif (CORE::length($char[$i-1]) == 2) {
1411 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1412 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1413             }
1414             elsif (CORE::length($char[$i+1]) == 3) {
1415 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1416 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1417             }
1418             elsif (CORE::length($char[$i+1]) == 4) {
1419 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
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]) == 3) {
1428 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1429 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1430             }
1431             elsif (CORE::length($char[$i+1]) == 4) {
1432 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1433 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1434             }
1435             else {
1436 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1437             }
1438             }
1439             elsif (CORE::length($char[$i-1]) == 4) {
1440 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1441 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1442             }
1443             else {
1444 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1445             }
1446             }
1447             else {
1448 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1449             }
1450              
1451 0         0 splice @char, $i-1, 3, @range;
1452             }
1453              
1454 0         0 return @char;
1455             }
1456              
1457             #
1458             # KOI8-R open character class
1459             #
1460             sub _cc {
1461 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1462 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1463             }
1464             elsif (scalar(@_) == 1) {
1465 0         0 return sprintf('\x%02X',$_[0]);
1466             }
1467             elsif (scalar(@_) == 2) {
1468 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1469 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1470             }
1471             elsif ($_[0] == $_[1]) {
1472 0         0 return sprintf('\x%02X',$_[0]);
1473             }
1474             elsif (($_[0]+1) == $_[1]) {
1475 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1476             }
1477             else {
1478 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1479             }
1480             }
1481             else {
1482 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1483             }
1484             }
1485              
1486             #
1487             # KOI8-R octet range
1488             #
1489             sub _octets {
1490 0     182   0 my $length = shift @_;
1491              
1492 182 50       281 if ($length == 1) {
1493 182         397 my($a1) = unpack 'C', $_[0];
1494 182         491 my($z1) = unpack 'C', $_[1];
1495              
1496 182 50       306 if ($a1 > $z1) {
1497 182         332 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1498             }
1499              
1500 0 50       0 if ($a1 == $z1) {
    50          
1501 182         409 return sprintf('\x%02X',$a1);
1502             }
1503             elsif (($a1+1) == $z1) {
1504 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1505             }
1506             else {
1507 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1508             }
1509             }
1510             else {
1511 182         1162 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1512             }
1513             }
1514              
1515             #
1516             # KOI8-R range regexp
1517             #
1518             sub _range_regexp {
1519 0     182   0 my($length,$first,$last) = @_;
1520              
1521 182         357 my @range_regexp = ();
1522 182 50       233 if (not exists $range_tr{$length}) {
1523 182         467 return @range_regexp;
1524             }
1525              
1526 0         0 my @ranges = @{ $range_tr{$length} };
  182         258  
1527 182         387 while (my @range = splice(@ranges,0,$length)) {
1528 182         545 my $min = '';
1529 182         275 my $max = '';
1530 182         221 for (my $i=0; $i < $length; $i++) {
1531 182         456 $min .= pack 'C', $range[$i][0];
1532 182         617 $max .= pack 'C', $range[$i][-1];
1533             }
1534              
1535             # min___max
1536             # FIRST_____________LAST
1537             # (nothing)
1538              
1539 182 50 33     425 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1540             }
1541              
1542             # **********
1543             # min_________max
1544             # FIRST_____________LAST
1545             # **********
1546              
1547             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1548 182         1748 push @range_regexp, _octets($length,$first,$max,$min,$max);
1549             }
1550              
1551             # **********************
1552             # min________________max
1553             # FIRST_____________LAST
1554             # **********************
1555              
1556             elsif (($min eq $first) and ($max eq $last)) {
1557 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1558             }
1559              
1560             # *********
1561             # min___max
1562             # FIRST_____________LAST
1563             # *********
1564              
1565             elsif (($first le $min) and ($max le $last)) {
1566 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1567             }
1568              
1569             # **********************
1570             # min__________________________max
1571             # FIRST_____________LAST
1572             # **********************
1573              
1574             elsif (($min le $first) and ($last le $max)) {
1575 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1576             }
1577              
1578             # *********
1579             # min________max
1580             # FIRST_____________LAST
1581             # *********
1582              
1583             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1584 182         437 push @range_regexp, _octets($length,$min,$last,$min,$max);
1585             }
1586              
1587             # min___max
1588             # FIRST_____________LAST
1589             # (nothing)
1590              
1591             elsif ($last lt $min) {
1592             }
1593              
1594             else {
1595 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1596             }
1597             }
1598              
1599 0         0 return @range_regexp;
1600             }
1601              
1602             #
1603             # KOI8-R open character list for qr and not qr
1604             #
1605             sub _charlist {
1606              
1607 182     358   438 my $modifier = pop @_;
1608 358         542 my @char = @_;
1609              
1610 358 100       882 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1611              
1612             # unescape character
1613 358         771 for (my $i=0; $i <= $#char; $i++) {
1614              
1615             # escape - to ...
1616 358 100 100     1236 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1617 1125 100 100     8018 if ((0 < $i) and ($i < $#char)) {
1618 206         720 $char[$i] = '...';
1619             }
1620             }
1621              
1622             # octal escape sequence
1623             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1624 182         362 $char[$i] = octchr($1);
1625             }
1626              
1627             # hexadecimal escape sequence
1628             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1629 0         0 $char[$i] = hexchr($1);
1630             }
1631              
1632             # \b{...} --> b\{...}
1633             # \B{...} --> B\{...}
1634             # \N{CHARNAME} --> N\{CHARNAME}
1635             # \p{PROPERTY} --> p\{PROPERTY}
1636             # \P{PROPERTY} --> P\{PROPERTY}
1637             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1638 0         0 $char[$i] = $1 . '\\' . $2;
1639             }
1640              
1641             # \p, \P, \X --> p, P, X
1642             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1643 0         0 $char[$i] = $1;
1644             }
1645              
1646             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1647 0         0 $char[$i] = CORE::chr oct $1;
1648             }
1649             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1650 0         0 $char[$i] = CORE::chr hex $1;
1651             }
1652             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1653 22         95 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1654             }
1655             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1656             $char[$i] = {
1657             '\0' => "\0",
1658             '\n' => "\n",
1659             '\r' => "\r",
1660             '\t' => "\t",
1661             '\f' => "\f",
1662             '\b' => "\x08", # \b means backspace in character class
1663             '\a' => "\a",
1664             '\e' => "\e",
1665             '\d' => '[0-9]',
1666              
1667             # Vertical tabs are now whitespace
1668             # \s in a regex now matches a vertical tab in all circumstances.
1669             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1670             # \t \n \v \f \r space
1671             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1672             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1673             '\s' => '\s',
1674              
1675             '\w' => '[0-9A-Z_a-z]',
1676             '\D' => '${Ekoi8r::eD}',
1677             '\S' => '${Ekoi8r::eS}',
1678             '\W' => '${Ekoi8r::eW}',
1679              
1680             '\H' => '${Ekoi8r::eH}',
1681             '\V' => '${Ekoi8r::eV}',
1682             '\h' => '[\x09\x20]',
1683             '\v' => '[\x0A\x0B\x0C\x0D]',
1684             '\R' => '${Ekoi8r::eR}',
1685              
1686 0         0 }->{$1};
1687             }
1688              
1689             # POSIX-style character classes
1690             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1691             $char[$i] = {
1692              
1693             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1694             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1695             '[:^lower:]' => '${Ekoi8r::not_lower_i}',
1696             '[:^upper:]' => '${Ekoi8r::not_upper_i}',
1697              
1698 25         499 }->{$1};
1699             }
1700             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1701             $char[$i] = {
1702              
1703             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1704             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1705             '[:ascii:]' => '[\x00-\x7F]',
1706             '[:blank:]' => '[\x09\x20]',
1707             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1708             '[:digit:]' => '[\x30-\x39]',
1709             '[:graph:]' => '[\x21-\x7F]',
1710             '[:lower:]' => '[\x61-\x7A]',
1711             '[:print:]' => '[\x20-\x7F]',
1712             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1713              
1714             # P.174 POSIX-Style Character Classes
1715             # in Chapter 5: Pattern Matching
1716             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1717              
1718             # P.311 11.2.4 Character Classes and other Special Escapes
1719             # in Chapter 11: perlre: Perl regular expressions
1720             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1721              
1722             # P.210 POSIX-Style Character Classes
1723             # in Chapter 5: Pattern Matching
1724             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1725              
1726             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1727              
1728             '[:upper:]' => '[\x41-\x5A]',
1729             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1730             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1731             '[:^alnum:]' => '${Ekoi8r::not_alnum}',
1732             '[:^alpha:]' => '${Ekoi8r::not_alpha}',
1733             '[:^ascii:]' => '${Ekoi8r::not_ascii}',
1734             '[:^blank:]' => '${Ekoi8r::not_blank}',
1735             '[:^cntrl:]' => '${Ekoi8r::not_cntrl}',
1736             '[:^digit:]' => '${Ekoi8r::not_digit}',
1737             '[:^graph:]' => '${Ekoi8r::not_graph}',
1738             '[:^lower:]' => '${Ekoi8r::not_lower}',
1739             '[:^print:]' => '${Ekoi8r::not_print}',
1740             '[:^punct:]' => '${Ekoi8r::not_punct}',
1741             '[:^space:]' => '${Ekoi8r::not_space}',
1742             '[:^upper:]' => '${Ekoi8r::not_upper}',
1743             '[:^word:]' => '${Ekoi8r::not_word}',
1744             '[:^xdigit:]' => '${Ekoi8r::not_xdigit}',
1745              
1746 8         62 }->{$1};
1747             }
1748             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1749 70         1232 $char[$i] = $1;
1750             }
1751             }
1752              
1753             # open character list
1754 7         30 my @singleoctet = ();
1755 358         586 my @multipleoctet = ();
1756 358         542 for (my $i=0; $i <= $#char; ) {
1757              
1758             # escaped -
1759 358 100 100     874 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1760 943         4221 $i += 1;
1761 182         263 next;
1762             }
1763              
1764             # make range regexp
1765             elsif ($char[$i] eq '...') {
1766              
1767             # range error
1768 182 50       328 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1769 182         668 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1770             }
1771             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1772 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1773 182         432 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1774             }
1775             }
1776              
1777             # make range regexp per length
1778 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1779 182         514 my @regexp = ();
1780              
1781             # is first and last
1782 182 50 33     253 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1783 182         616 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1784             }
1785              
1786             # is first
1787             elsif ($length == CORE::length($char[$i-1])) {
1788 182         713 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1789             }
1790              
1791             # is inside in first and last
1792             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1793 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1794             }
1795              
1796             # is last
1797             elsif ($length == CORE::length($char[$i+1])) {
1798 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1799             }
1800              
1801             else {
1802 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1803             }
1804              
1805 0 50       0 if ($length == 1) {
1806 182         346 push @singleoctet, @regexp;
1807             }
1808             else {
1809 182         392 push @multipleoctet, @regexp;
1810             }
1811             }
1812              
1813 0         0 $i += 2;
1814             }
1815              
1816             # with /i modifier
1817             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1818 182 100       361 if ($modifier =~ /i/oxms) {
1819 493         755 my $uc = Ekoi8r::uc($char[$i]);
1820 24         48 my $fc = Ekoi8r::fc($char[$i]);
1821 24 100       43 if ($uc ne $fc) {
1822 24 50       44 if (CORE::length($fc) == 1) {
1823 12         27 push @singleoctet, $uc, $fc;
1824             }
1825             else {
1826 12         24 push @singleoctet, $uc;
1827 0         0 push @multipleoctet, $fc;
1828             }
1829             }
1830             else {
1831 0         0 push @singleoctet, $char[$i];
1832             }
1833             }
1834             else {
1835 12         22 push @singleoctet, $char[$i];
1836             }
1837 469         699 $i += 1;
1838             }
1839              
1840             # single character of single octet code
1841             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1842 493         799 push @singleoctet, "\t", "\x20";
1843 0         0 $i += 1;
1844             }
1845             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1846 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1847 0         0 $i += 1;
1848             }
1849             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1850 0         0 push @singleoctet, $char[$i];
1851 2         6 $i += 1;
1852             }
1853              
1854             # single character of multiple-octet code
1855             else {
1856 2         6 push @multipleoctet, $char[$i];
1857 84         164 $i += 1;
1858             }
1859             }
1860              
1861             # quote metachar
1862 84         145 for (@singleoctet) {
1863 358 50       668 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1864 689         3253 $_ = '-';
1865             }
1866             elsif (/\A \n \z/oxms) {
1867 0         0 $_ = '\n';
1868             }
1869             elsif (/\A \r \z/oxms) {
1870 8         17 $_ = '\r';
1871             }
1872             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1873 8         23 $_ = sprintf('\x%02X', CORE::ord $1);
1874             }
1875             elsif (/\A [\x00-\xFF] \z/oxms) {
1876 60         190 $_ = quotemeta $_;
1877             }
1878             }
1879              
1880             # return character list
1881 429         644 return \@singleoctet, \@multipleoctet;
1882             }
1883              
1884             #
1885             # KOI8-R octal escape sequence
1886             #
1887             sub octchr {
1888 358     5 0 1189 my($octdigit) = @_;
1889              
1890 5         14 my @binary = ();
1891 5         9 for my $octal (split(//,$octdigit)) {
1892             push @binary, {
1893             '0' => '000',
1894             '1' => '001',
1895             '2' => '010',
1896             '3' => '011',
1897             '4' => '100',
1898             '5' => '101',
1899             '6' => '110',
1900             '7' => '111',
1901 5         28 }->{$octal};
1902             }
1903 50         180 my $binary = join '', @binary;
1904              
1905             my $octchr = {
1906             # 1234567
1907             1 => pack('B*', "0000000$binary"),
1908             2 => pack('B*', "000000$binary"),
1909             3 => pack('B*', "00000$binary"),
1910             4 => pack('B*', "0000$binary"),
1911             5 => pack('B*', "000$binary"),
1912             6 => pack('B*', "00$binary"),
1913             7 => pack('B*', "0$binary"),
1914             0 => pack('B*', "$binary"),
1915              
1916 5         14 }->{CORE::length($binary) % 8};
1917              
1918 5         63 return $octchr;
1919             }
1920              
1921             #
1922             # KOI8-R hexadecimal escape sequence
1923             #
1924             sub hexchr {
1925 5     5 0 20 my($hexdigit) = @_;
1926              
1927             my $hexchr = {
1928             1 => pack('H*', "0$hexdigit"),
1929             0 => pack('H*', "$hexdigit"),
1930              
1931 5         13 }->{CORE::length($_[0]) % 2};
1932              
1933 5         44 return $hexchr;
1934             }
1935              
1936             #
1937             # KOI8-R open character list for qr
1938             #
1939             sub charlist_qr {
1940              
1941 5     314 0 18 my $modifier = pop @_;
1942 314         616 my @char = @_;
1943              
1944 314         757 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1945 314         916 my @singleoctet = @$singleoctet;
1946 314         669 my @multipleoctet = @$multipleoctet;
1947              
1948             # return character list
1949 314 100       457 if (scalar(@singleoctet) >= 1) {
1950              
1951             # with /i modifier
1952 314 100       665 if ($modifier =~ m/i/oxms) {
1953 236         547 my %singleoctet_ignorecase = ();
1954 22         34 for (@singleoctet) {
1955 22   100     46 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1956 46         200 for my $ord (hex($1) .. hex($2)) {
1957 46         129 my $char = CORE::chr($ord);
1958 66         101 my $uc = Ekoi8r::uc($char);
1959 66         91 my $fc = Ekoi8r::fc($char);
1960 66 100       101 if ($uc eq $fc) {
1961 66         107 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1962             }
1963             else {
1964 12 50       73 if (CORE::length($fc) == 1) {
1965 54         81 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1966 54         114 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1967             }
1968             else {
1969 54         177 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1970 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1971             }
1972             }
1973             }
1974             }
1975 0 50       0 if ($_ ne '') {
1976 46         96 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1977             }
1978             }
1979 0         0 my $i = 0;
1980 22         31 my @singleoctet_ignorecase = ();
1981 22         33 for my $ord (0 .. 255) {
1982 22 100       36 if (exists $singleoctet_ignorecase{$ord}) {
1983 5632         6390 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         94  
1984             }
1985             else {
1986 96         224 $i++;
1987             }
1988             }
1989 5536         5481 @singleoctet = ();
1990 22         35 for my $range (@singleoctet_ignorecase) {
1991 22 100       56 if (ref $range) {
1992 3648 100       5537 if (scalar(@{$range}) == 1) {
  56 50       54  
1993 56         82 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         39  
1994             }
1995 36         112 elsif (scalar(@{$range}) == 2) {
1996 20         26 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
1997             }
1998             else {
1999 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         22  
  20         24  
2000             }
2001             }
2002             }
2003             }
2004              
2005 20         84 my $not_anchor = '';
2006              
2007 236         376 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2008             }
2009 236 100       619 if (scalar(@multipleoctet) >= 2) {
2010 314         688 return '(?:' . join('|', @multipleoctet) . ')';
2011             }
2012             else {
2013 6         31 return $multipleoctet[0];
2014             }
2015             }
2016              
2017             #
2018             # KOI8-R open character list for not qr
2019             #
2020             sub charlist_not_qr {
2021              
2022 308     44 0 1231 my $modifier = pop @_;
2023 44         82 my @char = @_;
2024              
2025 44         107 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2026 44         111 my @singleoctet = @$singleoctet;
2027 44         118 my @multipleoctet = @$multipleoctet;
2028              
2029             # with /i modifier
2030 44 100       119 if ($modifier =~ m/i/oxms) {
2031 44         117 my %singleoctet_ignorecase = ();
2032 10         14 for (@singleoctet) {
2033 10   66     12 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2034 10         42 for my $ord (hex($1) .. hex($2)) {
2035 10         30 my $char = CORE::chr($ord);
2036 30         48 my $uc = Ekoi8r::uc($char);
2037 30         40 my $fc = Ekoi8r::fc($char);
2038 30 50       48 if ($uc eq $fc) {
2039 30         44 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2040             }
2041             else {
2042 0 50       0 if (CORE::length($fc) == 1) {
2043 30         43 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2044 30         67 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2045             }
2046             else {
2047 30         92 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2048 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2049             }
2050             }
2051             }
2052             }
2053 0 50       0 if ($_ ne '') {
2054 10         30 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2055             }
2056             }
2057 0         0 my $i = 0;
2058 10         14 my @singleoctet_ignorecase = ();
2059 10         11 for my $ord (0 .. 255) {
2060 10 100       15 if (exists $singleoctet_ignorecase{$ord}) {
2061 2560         2878 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         57  
2062             }
2063             else {
2064 60         101 $i++;
2065             }
2066             }
2067 2500         2497 @singleoctet = ();
2068 10         16 for my $range (@singleoctet_ignorecase) {
2069 10 100       23 if (ref $range) {
2070 960 50       1491 if (scalar(@{$range}) == 1) {
  20 50       19  
2071 20         30 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2072             }
2073 0         0 elsif (scalar(@{$range}) == 2) {
2074 20         24 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2075             }
2076             else {
2077 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         22  
  20         24  
2078             }
2079             }
2080             }
2081             }
2082              
2083             # return character list
2084 20 50       86 if (scalar(@multipleoctet) >= 1) {
2085 44 0       111 if (scalar(@singleoctet) >= 1) {
2086              
2087             # any character other than multiple-octet and single octet character class
2088 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2089             }
2090             else {
2091              
2092             # any character other than multiple-octet character class
2093 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2094             }
2095             }
2096             else {
2097 0 50       0 if (scalar(@singleoctet) >= 1) {
2098              
2099             # any character other than single octet character class
2100 44         96 return '(?:[^' . join('', @singleoctet) . '])';
2101             }
2102             else {
2103              
2104             # any character
2105 44         245 return "(?:$your_char)";
2106             }
2107             }
2108             }
2109              
2110             #
2111             # open file in read mode
2112             #
2113             sub _open_r {
2114 0     408   0 my(undef,$file) = @_;
2115 204     204   2311 use Fcntl qw(O_RDONLY);
  204         581  
  204         30134  
2116 408         1177 return CORE::sysopen($_[0], $file, &O_RDONLY);
2117             }
2118              
2119             #
2120             # open file in append mode
2121             #
2122             sub _open_a {
2123 408     204   16348 my(undef,$file) = @_;
2124 204     204   1477 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  204         615  
  204         643230  
2125 204         772 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2126             }
2127              
2128             #
2129             # safe system
2130             #
2131             sub _systemx {
2132              
2133             # P.707 29.2.33. exec
2134             # in Chapter 29: Functions
2135             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2136             #
2137             # Be aware that in older releases of Perl, exec (and system) did not flush
2138             # your output buffer, so you needed to enable command buffering by setting $|
2139             # on one or more filehandles to avoid lost output in the case of exec, or
2140             # misordererd output in the case of system. This situation was largely remedied
2141             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2142              
2143             # P.855 exec
2144             # in Chapter 27: Functions
2145             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2146             #
2147             # In very old release of Perl (before v5.6), exec (and system) did not flush
2148             # your output buffer, so you needed to enable command buffering by setting $|
2149             # on one or more filehandles to avoid lost output with exec or misordered
2150             # output with system.
2151              
2152 204     204   27659 $| = 1;
2153              
2154             # P.565 23.1.2. Cleaning Up Your Environment
2155             # in Chapter 23: Security
2156             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2157              
2158             # P.656 Cleaning Up Your Environment
2159             # in Chapter 20: Security
2160             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2161              
2162             # local $ENV{'PATH'} = '.';
2163 204         721 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2164              
2165             # P.707 29.2.33. exec
2166             # in Chapter 29: Functions
2167             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2168             #
2169             # As we mentioned earlier, exec treats a discrete list of arguments as an
2170             # indication that it should bypass shell processing. However, there is one
2171             # place where you might still get tripped up. The exec call (and system, too)
2172             # will not distinguish between a single scalar argument and an array containing
2173             # only one element.
2174             #
2175             # @args = ("echo surprise"); # just one element in list
2176             # exec @args # still subject to shell escapes
2177             # or die "exec: $!"; # because @args == 1
2178             #
2179             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2180             # first argument as the pathname, which forces the rest of the arguments to be
2181             # interpreted as a list, even if there is only one of them:
2182             #
2183             # exec { $args[0] } @args # safe even with one-argument list
2184             # or die "can't exec @args: $!";
2185              
2186             # P.855 exec
2187             # in Chapter 27: Functions
2188             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2189             #
2190             # As we mentioned earlier, exec treats a discrete list of arguments as a
2191             # directive to bypass shell processing. However, there is one place where
2192             # you might still get tripped up. The exec call (and system, too) cannot
2193             # distinguish between a single scalar argument and an array containing
2194             # only one element.
2195             #
2196             # @args = ("echo surprise"); # just one element in list
2197             # exec @args # still subject to shell escapes
2198             # || die "exec: $!"; # because @args == 1
2199             #
2200             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2201             # argument as the pathname, which forces the rest of the arguments to be
2202             # interpreted as a list, even if there is only one of them:
2203             #
2204             # exec { $args[0] } @args # safe even with one-argument list
2205             # || die "can't exec @args: $!";
2206              
2207 204         1974 return CORE::system { $_[0] } @_; # safe even with one-argument list
  204         414  
2208             }
2209              
2210             #
2211             # KOI8-R order to character (with parameter)
2212             #
2213             sub Ekoi8r::chr(;$) {
2214              
2215 204 0   0 0 18428530 my $c = @_ ? $_[0] : $_;
2216              
2217 0 0       0 if ($c == 0x00) {
2218 0         0 return "\x00";
2219             }
2220             else {
2221 0         0 my @chr = ();
2222 0         0 while ($c > 0) {
2223 0         0 unshift @chr, ($c % 0x100);
2224 0         0 $c = int($c / 0x100);
2225             }
2226 0         0 return pack 'C*', @chr;
2227             }
2228             }
2229              
2230             #
2231             # KOI8-R order to character (without parameter)
2232             #
2233             sub Ekoi8r::chr_() {
2234              
2235 0     0 0 0 my $c = $_;
2236              
2237 0 0       0 if ($c == 0x00) {
2238 0         0 return "\x00";
2239             }
2240             else {
2241 0         0 my @chr = ();
2242 0         0 while ($c > 0) {
2243 0         0 unshift @chr, ($c % 0x100);
2244 0         0 $c = int($c / 0x100);
2245             }
2246 0         0 return pack 'C*', @chr;
2247             }
2248             }
2249              
2250             #
2251             # KOI8-R path globbing (with parameter)
2252             #
2253             sub Ekoi8r::glob($) {
2254              
2255 0 0   0 0 0 if (wantarray) {
2256 0         0 my @glob = _DOS_like_glob(@_);
2257 0         0 for my $glob (@glob) {
2258 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2259             }
2260 0         0 return @glob;
2261             }
2262             else {
2263 0         0 my $glob = _DOS_like_glob(@_);
2264 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2265 0         0 return $glob;
2266             }
2267             }
2268              
2269             #
2270             # KOI8-R path globbing (without parameter)
2271             #
2272             sub Ekoi8r::glob_() {
2273              
2274 0 0   0 0 0 if (wantarray) {
2275 0         0 my @glob = _DOS_like_glob();
2276 0         0 for my $glob (@glob) {
2277 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2278             }
2279 0         0 return @glob;
2280             }
2281             else {
2282 0         0 my $glob = _DOS_like_glob();
2283 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2284 0         0 return $glob;
2285             }
2286             }
2287              
2288             #
2289             # KOI8-R path globbing via File::DosGlob 1.10
2290             #
2291             # Often I confuse "_dosglob" and "_doglob".
2292             # So, I renamed "_dosglob" to "_DOS_like_glob".
2293             #
2294             my %iter;
2295             my %entries;
2296             sub _DOS_like_glob {
2297              
2298             # context (keyed by second cxix argument provided by core)
2299 0     0   0 my($expr,$cxix) = @_;
2300              
2301             # glob without args defaults to $_
2302 0 0       0 $expr = $_ if not defined $expr;
2303              
2304             # represents the current user's home directory
2305             #
2306             # 7.3. Expanding Tildes in Filenames
2307             # in Chapter 7. File Access
2308             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2309             #
2310             # and File::HomeDir, File::HomeDir::Windows module
2311              
2312             # DOS-like system
2313 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2314 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2315             { my_home_MSWin32() }oxmse;
2316             }
2317              
2318             # UNIX-like system
2319 0 0 0     0 else {
  0         0  
2320             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2321             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2322             }
2323 0 0       0  
2324 0 0       0 # assume global context if not provided one
2325             $cxix = '_G_' if not defined $cxix;
2326             $iter{$cxix} = 0 if not exists $iter{$cxix};
2327 0 0       0  
2328 0         0 # if we're just beginning, do it all first
2329             if ($iter{$cxix} == 0) {
2330             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2331             }
2332 0 0       0  
2333 0         0 # chuck it all out, quick or slow
2334 0         0 if (wantarray) {
  0         0  
2335             delete $iter{$cxix};
2336             return @{delete $entries{$cxix}};
2337 0 0       0 }
  0         0  
2338 0         0 else {
  0         0  
2339             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2340             return shift @{$entries{$cxix}};
2341             }
2342 0         0 else {
2343 0         0 # return undef for EOL
2344 0         0 delete $iter{$cxix};
2345             delete $entries{$cxix};
2346             return undef;
2347             }
2348             }
2349             }
2350              
2351             #
2352             # KOI8-R path globbing subroutine
2353             #
2354 0     0   0 sub _do_glob {
2355 0         0  
2356 0         0 my($cond,@expr) = @_;
2357             my @glob = ();
2358             my $fix_drive_relative_paths = 0;
2359 0         0  
2360 0 0       0 OUTER:
2361 0 0       0 for my $expr (@expr) {
2362             next OUTER if not defined $expr;
2363 0         0 next OUTER if $expr eq '';
2364 0         0  
2365 0         0 my @matched = ();
2366 0         0 my @globdir = ();
2367 0         0 my $head = '.';
2368             my $pathsep = '/';
2369             my $tail;
2370 0 0       0  
2371 0         0 # if argument is within quotes strip em and do no globbing
2372 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2373 0 0       0 $expr = $1;
2374 0         0 if ($cond eq 'd') {
2375             if (-d $expr) {
2376             push @glob, $expr;
2377             }
2378 0 0       0 }
2379 0         0 else {
2380             if (-e $expr) {
2381             push @glob, $expr;
2382 0         0 }
2383             }
2384             next OUTER;
2385             }
2386              
2387 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2388 0 0       0 # to h:./*.pm to expand correctly
2389 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2390             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2391             $fix_drive_relative_paths = 1;
2392             }
2393 0 0       0 }
2394 0 0       0  
2395 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2396 0         0 if ($tail eq '') {
2397             push @glob, $expr;
2398 0 0       0 next OUTER;
2399 0 0       0 }
2400 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2401 0         0 if (@globdir = _do_glob('d', $head)) {
2402             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2403             next OUTER;
2404 0 0 0     0 }
2405 0         0 }
2406             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2407 0         0 $head .= $pathsep;
2408             }
2409             $expr = $tail;
2410             }
2411 0 0       0  
2412 0 0       0 # If file component has no wildcards, we can avoid opendir
2413 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2414             if ($head eq '.') {
2415 0 0 0     0 $head = '';
2416 0         0 }
2417             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2418 0         0 $head .= $pathsep;
2419 0 0       0 }
2420 0 0       0 $head .= $expr;
2421 0         0 if ($cond eq 'd') {
2422             if (-d $head) {
2423             push @glob, $head;
2424             }
2425 0 0       0 }
2426 0         0 else {
2427             if (-e $head) {
2428             push @glob, $head;
2429 0         0 }
2430             }
2431 0 0       0 next OUTER;
2432 0         0 }
2433 0         0 opendir(*DIR, $head) or next OUTER;
2434             my @leaf = readdir DIR;
2435 0 0       0 closedir DIR;
2436 0         0  
2437             if ($head eq '.') {
2438 0 0 0     0 $head = '';
2439 0         0 }
2440             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2441             $head .= $pathsep;
2442 0         0 }
2443 0         0  
2444 0         0 my $pattern = '';
2445             while ($expr =~ / \G ($q_char) /oxgc) {
2446             my $char = $1;
2447              
2448             # 6.9. Matching Shell Globs as Regular Expressions
2449             # in Chapter 6. Pattern Matching
2450             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2451 0 0       0 # (and so on)
    0          
    0          
2452 0         0  
2453             if ($char eq '*') {
2454             $pattern .= "(?:$your_char)*",
2455 0         0 }
2456             elsif ($char eq '?') {
2457             $pattern .= "(?:$your_char)?", # DOS style
2458             # $pattern .= "(?:$your_char)", # UNIX style
2459 0         0 }
2460             elsif ((my $fc = Ekoi8r::fc($char)) ne $char) {
2461             $pattern .= $fc;
2462 0         0 }
2463             else {
2464             $pattern .= quotemeta $char;
2465 0     0   0 }
  0         0  
2466             }
2467             my $matchsub = sub { Ekoi8r::fc($_[0]) =~ /\A $pattern \z/xms };
2468              
2469             # if ($@) {
2470             # print STDERR "$0: $@\n";
2471             # next OUTER;
2472             # }
2473 0         0  
2474 0 0 0     0 INNER:
2475 0         0 for my $leaf (@leaf) {
2476             if ($leaf eq '.' or $leaf eq '..') {
2477 0 0 0     0 next INNER;
2478 0         0 }
2479             if ($cond eq 'd' and not -d "$head$leaf") {
2480             next INNER;
2481 0 0       0 }
2482 0         0  
2483 0         0 if (&$matchsub($leaf)) {
2484             push @matched, "$head$leaf";
2485             next INNER;
2486             }
2487              
2488             # [DOS compatibility special case]
2489 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2490              
2491             if (Ekoi8r::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2492             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2493 0 0       0 Ekoi8r::index($pattern,'\\.') != -1 # pattern has a dot.
2494 0         0 ) {
2495 0         0 if (&$matchsub("$leaf.")) {
2496             push @matched, "$head$leaf";
2497             next INNER;
2498             }
2499 0 0       0 }
2500 0         0 }
2501             if (@matched) {
2502             push @glob, @matched;
2503 0 0       0 }
2504 0         0 }
2505 0         0 if ($fix_drive_relative_paths) {
2506             for my $glob (@glob) {
2507             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2508 0         0 }
2509             }
2510             return @glob;
2511             }
2512              
2513             #
2514             # KOI8-R parse line
2515             #
2516 0     0   0 sub _parse_line {
2517              
2518 0         0 my($line) = @_;
2519 0         0  
2520 0         0 $line .= ' ';
2521             my @piece = ();
2522             while ($line =~ /
2523             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2524             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2525 0 0       0 /oxmsg
2526             ) {
2527 0         0 push @piece, defined($1) ? $1 : $2;
2528             }
2529             return @piece;
2530             }
2531              
2532             #
2533             # KOI8-R parse path
2534             #
2535 0     0   0 sub _parse_path {
2536              
2537 0         0 my($path,$pathsep) = @_;
2538 0         0  
2539 0         0 $path .= '/';
2540             my @subpath = ();
2541             while ($path =~ /
2542             ((?: [^\/\\] )+?) [\/\\]
2543 0         0 /oxmsg
2544             ) {
2545             push @subpath, $1;
2546 0         0 }
2547 0         0  
2548 0         0 my $tail = pop @subpath;
2549             my $head = join $pathsep, @subpath;
2550             return $head, $tail;
2551             }
2552              
2553             #
2554             # via File::HomeDir::Windows 1.00
2555             #
2556             sub my_home_MSWin32 {
2557              
2558             # A lot of unix people and unix-derived tools rely on
2559 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2560 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2561             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2562             return $ENV{'HOME'};
2563             }
2564              
2565 0         0 # Do we have a user profile?
2566             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2567             return $ENV{'USERPROFILE'};
2568             }
2569              
2570 0         0 # Some Windows use something like $ENV{'HOME'}
2571             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2572             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2573 0         0 }
2574              
2575             return undef;
2576             }
2577              
2578             #
2579             # via File::HomeDir::Unix 1.00
2580 0     0 0 0 #
2581             sub my_home {
2582 0 0 0     0 my $home;
    0 0        
2583 0         0  
2584             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2585             $home = $ENV{'HOME'};
2586             }
2587              
2588             # This is from the original code, but I'm guessing
2589 0         0 # it means "login directory" and exists on some Unixes.
2590             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2591             $home = $ENV{'LOGDIR'};
2592             }
2593              
2594             ### More-desperate methods
2595              
2596 0         0 # Light desperation on any (Unixish) platform
2597             else {
2598             $home = CORE::eval q{ (getpwuid($<))[7] };
2599             }
2600              
2601 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2602 0         0 # For example, "nobody"-like users might use /nonexistant
2603             if (defined $home and ! -d($home)) {
2604 0         0 $home = undef;
2605             }
2606             return $home;
2607             }
2608              
2609             #
2610             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2611 0     0 0 0 #
2612             sub Ekoi8r::PREMATCH {
2613             return $`;
2614             }
2615              
2616             #
2617             # ${^MATCH}, $MATCH, $& the string that matched
2618 0     0 0 0 #
2619             sub Ekoi8r::MATCH {
2620             return $&;
2621             }
2622              
2623             #
2624             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2625 0     0 0 0 #
2626             sub Ekoi8r::POSTMATCH {
2627             return $';
2628             }
2629              
2630             #
2631             # KOI8-R character to order (with parameter)
2632             #
2633 0 0   0 1 0 sub KOI8R::ord(;$) {
2634              
2635 0 0       0 local $_ = shift if @_;
2636 0         0  
2637 0         0 if (/\A ($q_char) /oxms) {
2638 0         0 my @ord = unpack 'C*', $1;
2639 0         0 my $ord = 0;
2640             while (my $o = shift @ord) {
2641 0         0 $ord = $ord * 0x100 + $o;
2642             }
2643             return $ord;
2644 0         0 }
2645             else {
2646             return CORE::ord $_;
2647             }
2648             }
2649              
2650             #
2651             # KOI8-R character to order (without parameter)
2652             #
2653 0 0   0 0 0 sub KOI8R::ord_() {
2654 0         0  
2655 0         0 if (/\A ($q_char) /oxms) {
2656 0         0 my @ord = unpack 'C*', $1;
2657 0         0 my $ord = 0;
2658             while (my $o = shift @ord) {
2659 0         0 $ord = $ord * 0x100 + $o;
2660             }
2661             return $ord;
2662 0         0 }
2663             else {
2664             return CORE::ord $_;
2665             }
2666             }
2667              
2668             #
2669             # KOI8-R reverse
2670             #
2671 0 0   0 0 0 sub KOI8R::reverse(@) {
2672 0         0  
2673             if (wantarray) {
2674             return CORE::reverse @_;
2675             }
2676             else {
2677              
2678             # One of us once cornered Larry in an elevator and asked him what
2679             # problem he was solving with this, but he looked as far off into
2680             # the distance as he could in an elevator and said, "It seemed like
2681 0         0 # a good idea at the time."
2682              
2683             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2684             }
2685             }
2686              
2687             #
2688             # KOI8-R getc (with parameter, without parameter)
2689             #
2690 0     0 0 0 sub KOI8R::getc(;*@) {
2691 0 0       0  
2692 0 0 0     0 my($package) = caller;
2693             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2694 0         0 croak 'Too many arguments for KOI8R::getc' if @_ and not wantarray;
  0         0  
2695 0         0  
2696 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2697 0         0 my $getc = '';
2698 0 0       0 for my $length ($length[0] .. $length[-1]) {
2699 0 0       0 $getc .= CORE::getc($fh);
2700 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2701             if ($getc =~ /\A ${Ekoi8r::dot_s} \z/oxms) {
2702             return wantarray ? ($getc,@_) : $getc;
2703             }
2704 0 0       0 }
2705             }
2706             return wantarray ? ($getc,@_) : $getc;
2707             }
2708              
2709             #
2710             # KOI8-R length by character
2711             #
2712 0 0   0 1 0 sub KOI8R::length(;$) {
2713              
2714 0         0 local $_ = shift if @_;
2715 0         0  
2716             local @_ = /\G ($q_char) /oxmsg;
2717             return scalar @_;
2718             }
2719              
2720             #
2721             # KOI8-R substr by character
2722             #
2723             BEGIN {
2724              
2725             # P.232 The lvalue Attribute
2726             # in Chapter 6: Subroutines
2727             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2728              
2729             # P.336 The lvalue Attribute
2730             # in Chapter 7: Subroutines
2731             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2732              
2733             # P.144 8.4 Lvalue subroutines
2734             # in Chapter 8: perlsub: Perl subroutines
2735 204 50 0 204 1 138069 # 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  
2736              
2737             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2738             # vv----------------------*******
2739             sub KOI8R::substr($$;$$) %s {
2740              
2741             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2742              
2743             # If the substring is beyond either end of the string, substr() returns the undefined
2744             # value and produces a warning. When used as an lvalue, specifying a substring that
2745             # is entirely outside the string raises an exception.
2746             # http://perldoc.perl.org/functions/substr.html
2747              
2748             # A return with no argument returns the scalar value undef in scalar context,
2749             # an empty list () in list context, and (naturally) nothing at all in void
2750             # context.
2751              
2752             my $offset = $_[1];
2753             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2754             return;
2755             }
2756              
2757             # substr($string,$offset,$length,$replacement)
2758             if (@_ == 4) {
2759             my(undef,undef,$length,$replacement) = @_;
2760             my $substr = join '', splice(@char, $offset, $length, $replacement);
2761             $_[0] = join '', @char;
2762              
2763             # return $substr; this doesn't work, don't say "return"
2764             $substr;
2765             }
2766              
2767             # substr($string,$offset,$length)
2768             elsif (@_ == 3) {
2769             my(undef,undef,$length) = @_;
2770             my $octet_offset = 0;
2771             my $octet_length = 0;
2772             if ($offset == 0) {
2773             $octet_offset = 0;
2774             }
2775             elsif ($offset > 0) {
2776             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2777             }
2778             else {
2779             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2780             }
2781             if ($length == 0) {
2782             $octet_length = 0;
2783             }
2784             elsif ($length > 0) {
2785             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2786             }
2787             else {
2788             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2789             }
2790             CORE::substr($_[0], $octet_offset, $octet_length);
2791             }
2792              
2793             # substr($string,$offset)
2794             else {
2795             my $octet_offset = 0;
2796             if ($offset == 0) {
2797             $octet_offset = 0;
2798             }
2799             elsif ($offset > 0) {
2800             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2801             }
2802             else {
2803             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2804             }
2805             CORE::substr($_[0], $octet_offset);
2806             }
2807             }
2808             END
2809             }
2810              
2811             #
2812             # KOI8-R index by character
2813             #
2814 0     0 1 0 sub KOI8R::index($$;$) {
2815 0 0       0  
2816 0         0 my $index;
2817             if (@_ == 3) {
2818             $index = Ekoi8r::index($_[0], $_[1], CORE::length(KOI8R::substr($_[0], 0, $_[2])));
2819 0         0 }
2820             else {
2821             $index = Ekoi8r::index($_[0], $_[1]);
2822 0 0       0 }
2823 0         0  
2824             if ($index == -1) {
2825             return -1;
2826 0         0 }
2827             else {
2828             return KOI8R::length(CORE::substr $_[0], 0, $index);
2829             }
2830             }
2831              
2832             #
2833             # KOI8-R rindex by character
2834             #
2835 0     0 1 0 sub KOI8R::rindex($$;$) {
2836 0 0       0  
2837 0         0 my $rindex;
2838             if (@_ == 3) {
2839             $rindex = Ekoi8r::rindex($_[0], $_[1], CORE::length(KOI8R::substr($_[0], 0, $_[2])));
2840 0         0 }
2841             else {
2842             $rindex = Ekoi8r::rindex($_[0], $_[1]);
2843 0 0       0 }
2844 0         0  
2845             if ($rindex == -1) {
2846             return -1;
2847 0         0 }
2848             else {
2849             return KOI8R::length(CORE::substr $_[0], 0, $rindex);
2850             }
2851             }
2852              
2853 204     204   1584 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  204         538  
  204         27278  
2854             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2855             use vars qw($slash); $slash = 'm//';
2856              
2857             # ord() to ord() or KOI8R::ord()
2858             my $function_ord = 'ord';
2859              
2860             # ord to ord or KOI8R::ord_
2861             my $function_ord_ = 'ord';
2862              
2863             # reverse to reverse or KOI8R::reverse
2864             my $function_reverse = 'reverse';
2865              
2866             # getc to getc or KOI8R::getc
2867             my $function_getc = 'getc';
2868              
2869             # P.1023 Appendix W.9 Multibyte Anchoring
2870             # of ISBN 1-56592-224-7 CJKV Information Processing
2871              
2872 204     204   1647 my $anchor = '';
  204     0   370  
  204         9408388  
2873              
2874             use vars qw($nest);
2875              
2876             # regexp of nested parens in qqXX
2877              
2878             # P.340 Matching Nested Constructs with Embedded Code
2879             # in Chapter 7: Perl
2880             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2881              
2882             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2883             [^\\()] |
2884             \( (?{$nest++}) |
2885             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2886             \\ [^c] |
2887             \\c[\x40-\x5F] |
2888             [\x00-\xFF]
2889             }xms;
2890              
2891             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2892             [^\\{}] |
2893             \{ (?{$nest++}) |
2894             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2895             \\ [^c] |
2896             \\c[\x40-\x5F] |
2897             [\x00-\xFF]
2898             }xms;
2899              
2900             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2901             [^\\\[\]] |
2902             \[ (?{$nest++}) |
2903             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2904             \\ [^c] |
2905             \\c[\x40-\x5F] |
2906             [\x00-\xFF]
2907             }xms;
2908              
2909             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2910             [^\\<>] |
2911             \< (?{$nest++}) |
2912             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2913             \\ [^c] |
2914             \\c[\x40-\x5F] |
2915             [\x00-\xFF]
2916             }xms;
2917              
2918             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2919             (?: ::)? (?:
2920             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2921             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2922             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2923             ))
2924             }xms;
2925              
2926             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2927             (?: ::)? (?:
2928             (?>[0-9]+) |
2929             [^a-zA-Z_0-9\[\]] |
2930             ^[A-Z] |
2931             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2932             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2933             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2934             ))
2935             }xms;
2936              
2937             my $qq_substr = qr{(?> Char::substr | KOI8R::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2938             }xms;
2939              
2940             # regexp of nested parens in qXX
2941             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2942             [^()] |
2943             \( (?{$nest++}) |
2944             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2945             [\x00-\xFF]
2946             }xms;
2947              
2948             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2949             [^\{\}] |
2950             \{ (?{$nest++}) |
2951             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2952             [\x00-\xFF]
2953             }xms;
2954              
2955             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2956             [^\[\]] |
2957             \[ (?{$nest++}) |
2958             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2959             [\x00-\xFF]
2960             }xms;
2961              
2962             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2963             [^<>] |
2964             \< (?{$nest++}) |
2965             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2966             [\x00-\xFF]
2967             }xms;
2968              
2969             my $matched = '';
2970             my $s_matched = '';
2971              
2972             my $tr_variable = ''; # variable of tr///
2973             my $sub_variable = ''; # variable of s///
2974             my $bind_operator = ''; # =~ or !~
2975              
2976             my @heredoc = (); # here document
2977             my @heredoc_delimiter = ();
2978             my $here_script = ''; # here script
2979              
2980             #
2981             # escape KOI8-R script
2982 0 50   204 0 0 #
2983             sub KOI8R::escape(;$) {
2984             local($_) = $_[0] if @_;
2985              
2986             # P.359 The Study Function
2987             # in Chapter 7: Perl
2988 204         735 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2989              
2990             study $_; # Yes, I studied study yesterday.
2991              
2992             # while all script
2993              
2994             # 6.14. Matching from Where the Last Pattern Left Off
2995             # in Chapter 6. Pattern Matching
2996             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2997             # (and so on)
2998              
2999             # one member of Tag-team
3000             #
3001             # P.128 Start of match (or end of previous match): \G
3002             # P.130 Advanced Use of \G with Perl
3003             # in Chapter 3: Overview of Regular Expression Features and Flavors
3004             # P.255 Use leading anchors
3005             # P.256 Expose ^ and \G at the front expressions
3006             # in Chapter 6: Crafting an Efficient Expression
3007             # P.315 "Tag-team" matching with /gc
3008             # in Chapter 7: Perl
3009 204         384 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3010 204         355  
3011 204         806 my $e_script = '';
3012             while (not /\G \z/oxgc) { # member
3013             $e_script .= KOI8R::escape_token();
3014 74633         117884 }
3015              
3016             return $e_script;
3017             }
3018              
3019             #
3020             # escape KOI8-R token of script
3021             #
3022             sub KOI8R::escape_token {
3023              
3024 204     74633 0 2570 # \n output here document
3025              
3026             my $ignore_modules = join('|', qw(
3027             utf8
3028             bytes
3029             charnames
3030             I18N::Japanese
3031             I18N::Collate
3032             I18N::JExt
3033             File::DosGlob
3034             Wild
3035             Wildcard
3036             Japanese
3037             ));
3038              
3039             # another member of Tag-team
3040             #
3041             # P.315 "Tag-team" matching with /gc
3042             # in Chapter 7: Perl
3043 74633 100 100     94617 # 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          
3044 74633         2978164  
3045 12510 100       15625 if (/\G ( \n ) /oxgc) { # another member (and so on)
3046 12510         21627 my $heredoc = '';
3047             if (scalar(@heredoc_delimiter) >= 1) {
3048 174         215 $slash = 'm//';
3049 174         449  
3050             $heredoc = join '', @heredoc;
3051             @heredoc = ();
3052 174         389  
3053 174         296 # skip here document
3054             for my $heredoc_delimiter (@heredoc_delimiter) {
3055 174         1242 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3056             }
3057 174         319 @heredoc_delimiter = ();
3058              
3059 174         336 $here_script = '';
3060             }
3061             return "\n" . $heredoc;
3062             }
3063 12510         46010  
3064             # ignore space, comment
3065             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3066              
3067             # if (, elsif (, unless (, while (, until (, given (, and when (
3068              
3069             # given, when
3070              
3071             # P.225 The given Statement
3072             # in Chapter 15: Smart Matching and given-when
3073             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3074              
3075             # P.133 The given Statement
3076             # in Chapter 4: Statements and Declarations
3077             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3078 17914         54874  
3079 1401         2027 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3080             $slash = 'm//';
3081             return $1;
3082             }
3083              
3084             # scalar variable ($scalar = ...) =~ tr///;
3085             # scalar variable ($scalar = ...) =~ s///;
3086              
3087             # state
3088              
3089             # P.68 Persistent, Private Variables
3090             # in Chapter 4: Subroutines
3091             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3092              
3093             # P.160 Persistent Lexically Scoped Variables: state
3094             # in Chapter 4: Statements and Declarations
3095             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3096              
3097             # (and so on)
3098 1401         4406  
3099             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3100 86 50       204 my $e_string = e_string($1);
    50          
3101 86         2058  
3102 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3103 0         0 $tr_variable = $e_string . e_string($1);
3104 0         0 $bind_operator = $2;
3105             $slash = 'm//';
3106             return '';
3107 0         0 }
3108 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3109 0         0 $sub_variable = $e_string . e_string($1);
3110 0         0 $bind_operator = $2;
3111             $slash = 'm//';
3112             return '';
3113 0         0 }
3114 86         154 else {
3115             $slash = 'div';
3116             return $e_string;
3117             }
3118             }
3119              
3120 86         358 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
3121 4         9 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3122             $slash = 'div';
3123             return q{Ekoi8r::PREMATCH()};
3124             }
3125              
3126 4         11 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
3127 28         51 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3128             $slash = 'div';
3129             return q{Ekoi8r::MATCH()};
3130             }
3131              
3132 28         84 # $', ${'} --> $', ${'}
3133 1         4 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3134             $slash = 'div';
3135             return $1;
3136             }
3137              
3138 1         3 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
3139 3         7 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3140             $slash = 'div';
3141             return q{Ekoi8r::POSTMATCH()};
3142             }
3143              
3144             # scalar variable $scalar =~ tr///;
3145             # scalar variable $scalar =~ s///;
3146             # substr() =~ tr///;
3147 3         10 # substr() =~ s///;
3148             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3149 1671 100       3698 my $scalar = e_string($1);
    100          
3150 1671         7165  
3151 1         2 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3152 1         2 $tr_variable = $scalar;
3153 1         1 $bind_operator = $1;
3154             $slash = 'm//';
3155             return '';
3156 1         3 }
3157 61         122 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3158 61         115 $sub_variable = $scalar;
3159 61         81 $bind_operator = $1;
3160             $slash = 'm//';
3161             return '';
3162 61         184 }
3163 1609         2195 else {
3164             $slash = 'div';
3165             return $scalar;
3166             }
3167             }
3168              
3169 1609         4860 # end of statement
3170             elsif (/\G ( [,;] ) /oxgc) {
3171             $slash = 'm//';
3172 4986         7615  
3173             # clear tr/// variable
3174             $tr_variable = '';
3175 4986         5959  
3176             # clear s/// variable
3177 4986         5728 $sub_variable = '';
3178              
3179 4986         5497 $bind_operator = '';
3180              
3181             return $1;
3182             }
3183              
3184 4986         17227 # bareword
3185             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3186             return $1;
3187             }
3188              
3189 0         0 # $0 --> $0
3190 2         4 elsif (/\G ( \$ 0 ) /oxmsgc) {
3191             $slash = 'div';
3192             return $1;
3193 2         21 }
3194 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3195             $slash = 'div';
3196             return $1;
3197             }
3198              
3199 0         0 # $$ --> $$
3200 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3201             $slash = 'div';
3202             return $1;
3203             }
3204              
3205             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3206 1         3 # $1, $2, $3 --> $1, $2, $3 otherwise
3207 4         6 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3208             $slash = 'div';
3209             return e_capture($1);
3210 4         6 }
3211 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3212             $slash = 'div';
3213             return e_capture($1);
3214             }
3215              
3216 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3217 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3218             $slash = 'div';
3219             return e_capture($1.'->'.$2);
3220             }
3221              
3222 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3223 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3224             $slash = 'div';
3225             return e_capture($1.'->'.$2);
3226             }
3227              
3228 0         0 # $$foo
3229 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3230             $slash = 'div';
3231             return e_capture($1);
3232             }
3233              
3234 0         0 # ${ foo }
3235 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3236             $slash = 'div';
3237             return '${' . $1 . '}';
3238             }
3239              
3240 0         0 # ${ ... }
3241 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3242             $slash = 'div';
3243             return e_capture($1);
3244             }
3245              
3246             # variable or function
3247 0         0 # $ @ % & * $ #
3248 42         74 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) {
3249             $slash = 'div';
3250             return $1;
3251             }
3252             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3253 42         140 # $ @ # \ ' " / ? ( ) [ ] < >
3254 62         204 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3255             $slash = 'div';
3256             return $1;
3257             }
3258              
3259 62         229 # while ()
3260             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3261             return $1;
3262             }
3263              
3264             # while () --- glob
3265              
3266             # avoid "Error: Runtime exception" of perl version 5.005_03
3267 0         0  
3268             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3269             return 'while ($_ = Ekoi8r::glob("' . $1 . '"))';
3270             }
3271              
3272 0         0 # while (glob)
3273             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3274             return 'while ($_ = Ekoi8r::glob_)';
3275             }
3276              
3277 0         0 # while (glob(WILDCARD))
3278             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3279             return 'while ($_ = Ekoi8r::glob';
3280             }
3281 0         0  
  248         630  
3282             # doit if, doit unless, doit while, doit until, doit for, doit when
3283             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3284 248         990  
  19         38  
3285 19         64 # subroutines of package Ekoi8r
  0         0  
3286 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         17  
3287 13         33 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3288 0         0 elsif (/\G \b KOI8R::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         177  
3289 114         436 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         5  
3290 2         5 elsif (/\G \b KOI8R::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval KOI8R::escape'; }
  0         0  
3291 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         5  
3292 2         5 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::chop'; }
  0         0  
3293 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3294 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3295 0         0 elsif (/\G \b KOI8R::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8R::index'; }
  2         4  
3296 2         7 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::index'; }
  0         0  
3297 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3298 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3299 0         0 elsif (/\G \b KOI8R::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8R::rindex'; }
  1         12  
3300 1         6 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::rindex'; }
  0         0  
3301 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::lc'; }
  1         4  
3302 1         4 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::lcfirst'; }
  0         0  
3303 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::uc'; }
  6         11  
3304             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::ucfirst'; }
3305             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::fc'; }
3306 6         18  
  0         0  
3307 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3308 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3309 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3310 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3311 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3312 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3313             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3314 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  
3315 0         0  
  0         0  
3316 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3317 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3318 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3319 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3320 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3321             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3322             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3323 0         0  
  0         0  
3324 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3325 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3326 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3327             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3328 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         4  
3329 2         7  
  2         6  
3330 2         7 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         64  
3331 36         109 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         8  
3332 2         7 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::chr'; }
  8         16  
3333 8         23 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3334 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3335 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::glob'; }
  0         0  
3336 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::lc_'; }
  0         0  
3337 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::lcfirst_'; }
  0         0  
3338 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::uc_'; }
  0         0  
3339 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::ucfirst_'; }
  0         0  
3340             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::fc_'; }
3341 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3342 0         0  
  0         0  
3343 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3344 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3345 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::chr_'; }
  0         0  
3346 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3347 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3348 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::glob_'; }
  8         22  
3349             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3350             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3351 8         35 # split
3352             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3353 87         188 $slash = 'm//';
3354 87         131  
3355 87         381 my $e = '';
3356             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3357             $e .= $1;
3358             }
3359 85 100       318  
  87 100       5655  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3360             # end of split
3361             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8r::split' . $e; }
3362 2         9  
3363             # split scalar value
3364             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Ekoi8r::split' . $e . e_string($1); }
3365 1         6  
3366 0         0 # split literal space
3367 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Ekoi8r::split' . $e . qq {qq$1 $2}; }
3368 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3369 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3370 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3371 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3372 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3373 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Ekoi8r::split' . $e . qq {q$1 $2}; }
3374 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3375 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3376 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3377 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3378 10         49 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3379             elsif (/\G ' [ ] ' /oxgc) { return 'Ekoi8r::split' . $e . qq {' '}; }
3380             elsif (/\G " [ ] " /oxgc) { return 'Ekoi8r::split' . $e . qq {" "}; }
3381              
3382 0 0       0 # split qq//
  0         0  
3383             elsif (/\G \b (qq) \b /oxgc) {
3384 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3385 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3386 0         0 while (not /\G \z/oxgc) {
3387 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3388 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3389 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3390 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3391 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3392             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3393 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3394             }
3395             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3396             }
3397             }
3398              
3399 0 50       0 # split qr//
  12         410  
3400             elsif (/\G \b (qr) \b /oxgc) {
3401 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3402 12 50       57 else {
  12 50       3255  
    50          
    50          
    50          
    50          
    50          
    50          
3403 0         0 while (not /\G \z/oxgc) {
3404 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3405 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3406 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3407 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3408 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3409 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3410             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3411 12         80 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3412             }
3413             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3414             }
3415             }
3416              
3417 0 0       0 # split q//
  0         0  
3418             elsif (/\G \b (q) \b /oxgc) {
3419 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3420 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3421 0         0 while (not /\G \z/oxgc) {
3422 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3423 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3424 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3425 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3426 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3427             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3428 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3429             }
3430             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3431             }
3432             }
3433              
3434 0 50       0 # split m//
  18         456  
3435             elsif (/\G \b (m) \b /oxgc) {
3436 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3437 18 50       82 else {
  18 50       3767  
    50          
    50          
    50          
    50          
    50          
    50          
3438 0         0 while (not /\G \z/oxgc) {
3439 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3440 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3441 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3442 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3443 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3444 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3445             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3446 18         115 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3447             }
3448             die __FILE__, ": Search pattern not terminated\n";
3449             }
3450             }
3451              
3452 0         0 # split ''
3453 0         0 elsif (/\G (\') /oxgc) {
3454 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3455 0         0 while (not /\G \z/oxgc) {
3456 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3457 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3458             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3459 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3460             }
3461             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3462             }
3463              
3464 0         0 # split ""
3465 0         0 elsif (/\G (\") /oxgc) {
3466 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3467 0         0 while (not /\G \z/oxgc) {
3468 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3469 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3470             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3471 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3472             }
3473             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3474             }
3475              
3476 0         0 # split //
3477 44         241 elsif (/\G (\/) /oxgc) {
3478 44 50       148 my $regexp = '';
  381 50       1482  
    100          
    50          
3479 0         0 while (not /\G \z/oxgc) {
3480 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3481 44         190 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3482             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3483 337         680 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3484             }
3485             die __FILE__, ": Search pattern not terminated\n";
3486             }
3487             }
3488              
3489             # tr/// or y///
3490              
3491             # about [cdsrbB]* (/B modifier)
3492             #
3493             # P.559 appendix C
3494             # of ISBN 4-89052-384-7 Programming perl
3495             # (Japanese title is: Perl puroguramingu)
3496 0         0  
3497             elsif (/\G \b ( tr | y ) \b /oxgc) {
3498             my $ope = $1;
3499 3 50       9  
3500 3         39 # $1 $2 $3 $4 $5 $6
3501 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3502             my @tr = ($tr_variable,$2);
3503             return e_tr(@tr,'',$4,$6);
3504 0         0 }
3505 3         5 else {
3506 3 50       8 my $e = '';
  3 50       214  
    50          
    50          
    50          
    50          
3507             while (not /\G \z/oxgc) {
3508 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3509 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3510 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3511 0         0 while (not /\G \z/oxgc) {
3512 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3513 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3514 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3515 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3516             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3517 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3518             }
3519             die __FILE__, ": Transliteration replacement not terminated\n";
3520 0         0 }
3521 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3522 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3523 0         0 while (not /\G \z/oxgc) {
3524 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3525 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3526 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3527 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3528             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3529 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3530             }
3531             die __FILE__, ": Transliteration replacement not terminated\n";
3532 0         0 }
3533 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3534 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3535 0         0 while (not /\G \z/oxgc) {
3536 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3537 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3538 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3539 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3540             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3541 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3542             }
3543             die __FILE__, ": Transliteration replacement not terminated\n";
3544 0         0 }
3545 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3546 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3547 0         0 while (not /\G \z/oxgc) {
3548 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3549 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3550 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3551 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3552             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3553 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3554             }
3555             die __FILE__, ": Transliteration replacement not terminated\n";
3556             }
3557 0         0 # $1 $2 $3 $4 $5 $6
3558 3         11 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3559             my @tr = ($tr_variable,$2);
3560             return e_tr(@tr,'',$4,$6);
3561 3         7 }
3562             }
3563             die __FILE__, ": Transliteration pattern not terminated\n";
3564             }
3565             }
3566              
3567 0         0 # qq//
3568             elsif (/\G \b (qq) \b /oxgc) {
3569             my $ope = $1;
3570 2180 50       4847  
3571 2180         4179 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3572 0         0 if (/\G (\#) /oxgc) { # qq# #
3573 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3574 0         0 while (not /\G \z/oxgc) {
3575 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3576 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3577             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3578 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3579             }
3580             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3581             }
3582 0         0  
3583 2180         19059 else {
3584 2180 50       5202 my $e = '';
  2180 50       8183  
    100          
    50          
    50          
    0          
3585             while (not /\G \z/oxgc) {
3586             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3587              
3588 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3589 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3590 0         0 my $qq_string = '';
3591 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3592 0         0 while (not /\G \z/oxgc) {
3593 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3594             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3595 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3596 0         0 elsif (/\G (\)) /oxgc) {
3597             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3598 0         0 else { $qq_string .= $1; }
3599             }
3600 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3601             }
3602             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3603             }
3604              
3605 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3606 2150         2754 elsif (/\G (\{) /oxgc) { # qq { }
3607 2150         2902 my $qq_string = '';
3608 2150 100       4219 local $nest = 1;
  83993 50       254932  
    100          
    100          
    50          
3609 722         1414 while (not /\G \z/oxgc) {
3610 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         1602  
3611             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3612 1153 100       2171 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         5753  
3613 2150         4287 elsif (/\G (\}) /oxgc) {
3614             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3615 1153         2355 else { $qq_string .= $1; }
3616             }
3617 78815         157038 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_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3623 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3624 0         0 my $qq_string = '';
3625 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3626 0         0 while (not /\G \z/oxgc) {
3627 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3628             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3629 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3630 0         0 elsif (/\G (\]) /oxgc) {
3631             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3632 0         0 else { $qq_string .= $1; }
3633             }
3634 0         0 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_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3640 30         51 elsif (/\G (\<) /oxgc) { # qq < >
3641 30         45 my $qq_string = '';
3642 30 100       102 local $nest = 1;
  1166 50       3893  
    50          
    100          
    50          
3643 22         49 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 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         65  
3647 30         67 elsif (/\G (\>) /oxgc) {
3648             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3649 0         0 else { $qq_string .= $1; }
3650             }
3651 1114         2068 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 (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3657 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3658 0         0 my $delimiter = $1;
3659 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3660 0         0 while (not /\G \z/oxgc) {
3661 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3662 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3663             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3664 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3665             }
3666             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3667 0         0 }
3668             }
3669             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3670             }
3671             }
3672              
3673 0         0 # qr//
3674 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3675 0         0 my $ope = $1;
3676             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3677             return e_qr($ope,$1,$3,$2,$4);
3678 0         0 }
3679 0         0 else {
3680 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3681 0         0 while (not /\G \z/oxgc) {
3682 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3683 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3684 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3685 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3686 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3687 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3688             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3689 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3690             }
3691             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3692             }
3693             }
3694              
3695 0         0 # qw//
3696 16 50       48 elsif (/\G \b (qw) \b /oxgc) {
3697 16         65 my $ope = $1;
3698             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3699             return e_qw($ope,$1,$3,$2);
3700 0         0 }
3701 16         30 else {
3702 16 50       51 my $e = '';
  16 50       117  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3703             while (not /\G \z/oxgc) {
3704 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3705 16         53  
3706             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3707 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3708 0         0  
3709             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3710 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3711 0         0  
3712             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3713 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3714 0         0  
3715             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3716 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3717 0         0  
3718             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3719 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3720             }
3721             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3722             }
3723             }
3724              
3725 0         0 # qx//
3726 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3727 0         0 my $ope = $1;
3728             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3729             return e_qq($ope,$1,$3,$2);
3730 0         0 }
3731 0         0 else {
3732 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3733 0         0 while (not /\G \z/oxgc) {
3734 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3735 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3736 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3737 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3738 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3739             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3740 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3741             }
3742             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3743             }
3744             }
3745              
3746 0         0 # q//
3747             elsif (/\G \b (q) \b /oxgc) {
3748             my $ope = $1;
3749              
3750             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3751              
3752             # avoid "Error: Runtime exception" of perl version 5.005_03
3753 410 50       1147 # (and so on)
3754 410         1071  
3755 0         0 if (/\G (\#) /oxgc) { # q# #
3756 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3757 0         0 while (not /\G \z/oxgc) {
3758 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3759 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3760             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3761 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3762             }
3763             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3764             }
3765 0         0  
3766 410         683 else {
3767 410 50       1566 my $e = '';
  410 50       2470  
    100          
    50          
    100          
    50          
3768             while (not /\G \z/oxgc) {
3769             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3770              
3771 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3772 0         0 elsif (/\G (\() /oxgc) { # q ( )
3773 0         0 my $q_string = '';
3774 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3775 0         0 while (not /\G \z/oxgc) {
3776 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3777 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3778             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3779 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3780 0         0 elsif (/\G (\)) /oxgc) {
3781             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3782 0         0 else { $q_string .= $1; }
3783             }
3784 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3785             }
3786             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3787             }
3788              
3789 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3790 404         648 elsif (/\G (\{) /oxgc) { # q { }
3791 404         888 my $q_string = '';
3792 404 50       1032 local $nest = 1;
  6757 50       25642  
    50          
    100          
    100          
    50          
3793 0         0 while (not /\G \z/oxgc) {
3794 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3795 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         183  
3796             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3797 107 100       204 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         1012  
3798 404         1080 elsif (/\G (\}) /oxgc) {
3799             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3800 107         341 else { $q_string .= $1; }
3801             }
3802 6139         12965 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3803             }
3804             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3805             }
3806              
3807 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3808 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3809 0         0 my $q_string = '';
3810 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3811 0         0 while (not /\G \z/oxgc) {
3812 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3813 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3814             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3815 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3816 0         0 elsif (/\G (\]) /oxgc) {
3817             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3818 0         0 else { $q_string .= $1; }
3819             }
3820 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3821             }
3822             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3823             }
3824              
3825 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3826 5         11 elsif (/\G (\<) /oxgc) { # q < >
3827 5         10 my $q_string = '';
3828 5 50       18 local $nest = 1;
  88 50       364  
    50          
    50          
    100          
    50          
3829 0         0 while (not /\G \z/oxgc) {
3830 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3831 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3832             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3833 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         15  
3834 5         13 elsif (/\G (\>) /oxgc) {
3835             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3836 0         0 else { $q_string .= $1; }
3837             }
3838 83         159 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3839             }
3840             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3841             }
3842              
3843 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3844 1         2 elsif (/\G (\S) /oxgc) { # q * *
3845 1         2 my $delimiter = $1;
3846 1 50       3 my $q_string = '';
  14 50       61  
    100          
    50          
3847 0         0 while (not /\G \z/oxgc) {
3848 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3849 1         10 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3850             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3851 13         26 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3852             }
3853             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3854 0         0 }
3855             }
3856             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3857             }
3858             }
3859              
3860 0         0 # m//
3861 209 50       468 elsif (/\G \b (m) \b /oxgc) {
3862 209         1337 my $ope = $1;
3863             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3864             return e_qr($ope,$1,$3,$2,$4);
3865 0         0 }
3866 209         320 else {
3867 209 50       535 my $e = '';
  209 50       11395  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3868 0         0 while (not /\G \z/oxgc) {
3869 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3870 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3871 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3872 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3873 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3874 10         26 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3875 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3876             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3877 199         620 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3878             }
3879             die __FILE__, ": Search pattern not terminated\n";
3880             }
3881             }
3882              
3883             # s///
3884              
3885             # about [cegimosxpradlunbB]* (/cg modifier)
3886             #
3887             # P.67 Pattern-Matching Operators
3888             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3889 0         0  
3890             elsif (/\G \b (s) \b /oxgc) {
3891             my $ope = $1;
3892 97 100       245  
3893 97         1557 # $1 $2 $3 $4 $5 $6
3894             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3895             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3896 1         5 }
3897 96         185 else {
3898 96 50       285 my $e = '';
  96 50       11282  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3899             while (not /\G \z/oxgc) {
3900 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3901 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3902 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3903             while (not /\G \z/oxgc) {
3904 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3905 0         0 # $1 $2 $3 $4
3906 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3907 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3908 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3909 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3910 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3911 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3912 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3913             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3914 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3915             }
3916             die __FILE__, ": Substitution replacement not terminated\n";
3917 0         0 }
3918 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /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_bracket)*?) (\]) /oxgc) {
3936 0 0       0 my @s = ($1,$2,$3);
  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             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3946 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3947             }
3948             die __FILE__, ": Substitution replacement not terminated\n";
3949 0         0 }
3950 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3951 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3952             while (not /\G \z/oxgc) {
3953 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3954 0         0 # $1 $2 $3 $4
3955 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3956 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3957 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3958 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3960 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([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             }
3967 0         0 # $1 $2 $3 $4 $5 $6
3968             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3969             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3970             }
3971 21         66 # $1 $2 $3 $4 $5 $6
3972             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3973             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3974             }
3975 0         0 # $1 $2 $3 $4 $5 $6
3976             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3977             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3978             }
3979 0         0 # $1 $2 $3 $4 $5 $6
3980             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3981             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3982 75         330 }
3983             }
3984             die __FILE__, ": Substitution pattern not terminated\n";
3985             }
3986             }
3987 0         0  
3988 0         0 # require ignore module
3989 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
3990             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
3991             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
3992 0         0  
3993 37         288 # use strict; --> use strict; no strict qw(refs);
3994 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
3995             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
3996             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
3997              
3998 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
3999 2         26 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4000             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4001             return "use $1; no strict qw(refs);";
4002 0         0 }
4003             else {
4004             return "use $1;";
4005             }
4006 2 0 0     11 }
      0        
4007 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4008             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4009             return "use $1; no strict qw(refs);";
4010 0         0 }
4011             else {
4012             return "use $1;";
4013             }
4014             }
4015 0         0  
4016 2         19 # ignore use module
4017 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4018             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4019             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4020 0         0  
4021 0         0 # ignore no module
4022 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4023             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4024             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4025 0         0  
4026             # use else
4027             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4028 0         0  
4029             # use else
4030             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4031              
4032 2         8 # ''
4033 848         1718 elsif (/\G (?
4034 848 100       2111 my $q_string = '';
  8241 100       24957  
    100          
    50          
4035 4         9 while (not /\G \z/oxgc) {
4036 48         89 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4037 848         3061 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4038             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4039 7341         14550 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4040             }
4041             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4042             }
4043              
4044 0         0 # ""
4045 1780         3468 elsif (/\G (\") /oxgc) {
4046 1780 100       4452 my $qq_string = '';
  34872 100       100536  
    100          
    50          
4047 67         159 while (not /\G \z/oxgc) {
4048 12         24 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4049 1780         3865 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4050             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4051 33013         64041 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4052             }
4053             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4054             }
4055              
4056 0         0 # ``
4057 1         2 elsif (/\G (\`) /oxgc) {
4058 1 50       5 my $qx_string = '';
  19 50       66  
    100          
    50          
4059 0         0 while (not /\G \z/oxgc) {
4060 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4061 1         3 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4062             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4063 18         31 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4064             }
4065             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4066             }
4067              
4068 0         0 # // --- not divide operator (num / num), not defined-or
4069 453         1369 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4070 453 50       1383 my $regexp = '';
  4496 50       14293  
    100          
    50          
4071 0         0 while (not /\G \z/oxgc) {
4072 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4073 453         1588 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4074             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4075 4043         7878 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4076             }
4077             die __FILE__, ": Search pattern not terminated\n";
4078             }
4079              
4080 0         0 # ?? --- not conditional operator (condition ? then : else)
4081 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4082 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4083 0         0 while (not /\G \z/oxgc) {
4084 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4085 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4086             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4087 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4088             }
4089             die __FILE__, ": Search pattern not terminated\n";
4090             }
4091 0         0  
  0         0  
4092             # <<>> (a safer ARGV)
4093             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4094 0         0  
  0         0  
4095             # << (bit shift) --- not here document
4096             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4097              
4098 0         0 # <<~'HEREDOC'
4099 6         11 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4100 6         10 $slash = 'm//';
4101             my $here_quote = $1;
4102             my $delimiter = $2;
4103 6 50       10  
4104 6         12 # get here document
4105 6         36 if ($here_script eq '') {
4106             $here_script = CORE::substr $_, pos $_;
4107 6 50       31 $here_script =~ s/.*?\n//oxm;
4108 6         50 }
4109 6         12 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4110 6         10 my $heredoc = $1;
4111 6         48 my $indent = $2;
4112 6         20 $heredoc =~ s{^$indent}{}msg; # no /ox
4113             push @heredoc, $heredoc . qq{\n$delimiter\n};
4114             push @heredoc_delimiter, qq{\\s*$delimiter};
4115 6         11 }
4116             else {
4117 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4118             }
4119             return qq{<<'$delimiter'};
4120             }
4121              
4122             # <<~\HEREDOC
4123              
4124             # P.66 2.6.6. "Here" Documents
4125             # in Chapter 2: Bits and Pieces
4126             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4127              
4128             # P.73 "Here" Documents
4129             # in Chapter 2: Bits and Pieces
4130             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4131 6         24  
4132 3         7 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4133 3         5 $slash = 'm//';
4134             my $here_quote = $1;
4135             my $delimiter = $2;
4136 3 50       6  
4137 3         6 # get here document
4138 3         10 if ($here_script eq '') {
4139             $here_script = CORE::substr $_, pos $_;
4140 3 50       28 $here_script =~ s/.*?\n//oxm;
4141 3         41 }
4142 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4143 3         4 my $heredoc = $1;
4144 3         34 my $indent = $2;
4145 3         9 $heredoc =~ s{^$indent}{}msg; # no /ox
4146             push @heredoc, $heredoc . qq{\n$delimiter\n};
4147             push @heredoc_delimiter, qq{\\s*$delimiter};
4148 3         7 }
4149             else {
4150 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4151             }
4152             return qq{<<\\$delimiter};
4153             }
4154              
4155 3         11 # <<~"HEREDOC"
4156 6         12 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4157 6         10 $slash = 'm//';
4158             my $here_quote = $1;
4159             my $delimiter = $2;
4160 6 50       11  
4161 6         11 # get here document
4162 6         43 if ($here_script eq '') {
4163             $here_script = CORE::substr $_, pos $_;
4164 6 50       32 $here_script =~ s/.*?\n//oxm;
4165 6         59 }
4166 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4167 6         7 my $heredoc = $1;
4168 6         46 my $indent = $2;
4169 6         15 $heredoc =~ s{^$indent}{}msg; # no /ox
4170             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4171             push @heredoc_delimiter, qq{\\s*$delimiter};
4172 6         13 }
4173             else {
4174 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4175             }
4176             return qq{<<"$delimiter"};
4177             }
4178              
4179 6         25 # <<~HEREDOC
4180 3         7 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4181 3         7 $slash = 'm//';
4182             my $here_quote = $1;
4183             my $delimiter = $2;
4184 3 50       5  
4185 3         7 # get here document
4186 3         19 if ($here_script eq '') {
4187             $here_script = CORE::substr $_, pos $_;
4188 3 50       27 $here_script =~ s/.*?\n//oxm;
4189 3         40 }
4190 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4191 3         4 my $heredoc = $1;
4192 3         34 my $indent = $2;
4193 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
4194             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4195             push @heredoc_delimiter, qq{\\s*$delimiter};
4196 3         16 }
4197             else {
4198 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4199             }
4200             return qq{<<$delimiter};
4201             }
4202              
4203 3         15 # <<~`HEREDOC`
4204 6         12 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4205 6         10 $slash = 'm//';
4206             my $here_quote = $1;
4207             my $delimiter = $2;
4208 6 50       10  
4209 6         10 # get here document
4210 6         17 if ($here_script eq '') {
4211             $here_script = CORE::substr $_, pos $_;
4212 6 50       27 $here_script =~ s/.*?\n//oxm;
4213 6         54 }
4214 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4215 6         7 my $heredoc = $1;
4216 6         47 my $indent = $2;
4217 6         15 $heredoc =~ s{^$indent}{}msg; # no /ox
4218             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4219             push @heredoc_delimiter, qq{\\s*$delimiter};
4220 6         15 }
4221             else {
4222 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4223             }
4224             return qq{<<`$delimiter`};
4225             }
4226              
4227 6         22 # <<'HEREDOC'
4228 72         148 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4229 72         232 $slash = 'm//';
4230             my $here_quote = $1;
4231             my $delimiter = $2;
4232 72 50       148  
4233 72         146 # get here document
4234 72         391 if ($here_script eq '') {
4235             $here_script = CORE::substr $_, pos $_;
4236 72 50       389 $here_script =~ s/.*?\n//oxm;
4237 72         534 }
4238 72         227 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4239             push @heredoc, $1 . qq{\n$delimiter\n};
4240             push @heredoc_delimiter, $delimiter;
4241 72         113 }
4242             else {
4243 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4244             }
4245             return $here_quote;
4246             }
4247              
4248             # <<\HEREDOC
4249              
4250             # P.66 2.6.6. "Here" Documents
4251             # in Chapter 2: Bits and Pieces
4252             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4253              
4254             # P.73 "Here" Documents
4255             # in Chapter 2: Bits and Pieces
4256             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4257 72         341  
4258 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4259 0         0 $slash = 'm//';
4260             my $here_quote = $1;
4261             my $delimiter = $2;
4262 0 0       0  
4263 0         0 # get here document
4264 0         0 if ($here_script eq '') {
4265             $here_script = CORE::substr $_, pos $_;
4266 0 0       0 $here_script =~ s/.*?\n//oxm;
4267 0         0 }
4268 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4269             push @heredoc, $1 . qq{\n$delimiter\n};
4270             push @heredoc_delimiter, $delimiter;
4271 0         0 }
4272             else {
4273 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4274             }
4275             return $here_quote;
4276             }
4277              
4278 0         0 # <<"HEREDOC"
4279 36         105 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4280 36         83 $slash = 'm//';
4281             my $here_quote = $1;
4282             my $delimiter = $2;
4283 36 50       62  
4284 36         95 # get here document
4285 36         244 if ($here_script eq '') {
4286             $here_script = CORE::substr $_, pos $_;
4287 36 50       268 $here_script =~ s/.*?\n//oxm;
4288 36         571 }
4289 36         125 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4290             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4291             push @heredoc_delimiter, $delimiter;
4292 36         200 }
4293             else {
4294 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4295             }
4296             return $here_quote;
4297             }
4298              
4299 36         163 # <
4300 42         109 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4301 42         168 $slash = 'm//';
4302             my $here_quote = $1;
4303             my $delimiter = $2;
4304 42 50       75  
4305 42         109 # get here document
4306 42         280 if ($here_script eq '') {
4307             $here_script = CORE::substr $_, pos $_;
4308 42 50       317 $here_script =~ s/.*?\n//oxm;
4309 42         580 }
4310 42         150 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4311             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4312             push @heredoc_delimiter, $delimiter;
4313 42         108 }
4314             else {
4315 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4316             }
4317             return $here_quote;
4318             }
4319              
4320 42         198 # <<`HEREDOC`
4321 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4322 0         0 $slash = 'm//';
4323             my $here_quote = $1;
4324             my $delimiter = $2;
4325 0 0       0  
4326 0         0 # get here document
4327 0         0 if ($here_script eq '') {
4328             $here_script = CORE::substr $_, pos $_;
4329 0 0       0 $here_script =~ s/.*?\n//oxm;
4330 0         0 }
4331 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4332             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4333             push @heredoc_delimiter, $delimiter;
4334 0         0 }
4335             else {
4336 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4337             }
4338             return $here_quote;
4339             }
4340              
4341 0         0 # <<= <=> <= < operator
4342             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4343             return $1;
4344             }
4345              
4346 12         64 #
4347             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4348             return $1;
4349             }
4350              
4351             # --- glob
4352              
4353             # avoid "Error: Runtime exception" of perl version 5.005_03
4354 0         0  
4355             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4356             return 'Ekoi8r::glob("' . $1 . '")';
4357             }
4358 0         0  
4359             # __DATA__
4360             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4361 0         0  
4362             # __END__
4363             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4364              
4365             # \cD Control-D
4366              
4367             # P.68 2.6.8. Other Literal Tokens
4368             # in Chapter 2: Bits and Pieces
4369             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4370              
4371             # P.76 Other Literal Tokens
4372             # in Chapter 2: Bits and Pieces
4373 204         1358 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4374              
4375             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4376 0         0  
4377             # \cZ Control-Z
4378             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4379              
4380             # any operator before div
4381             elsif (/\G (
4382             -- | \+\+ |
4383 0         0 [\)\}\]]
  5081         10369  
4384              
4385             ) /oxgc) { $slash = 'div'; return $1; }
4386              
4387             # yada-yada or triple-dot operator
4388             elsif (/\G (
4389 5081         22223 \.\.\.
  7         13  
4390              
4391             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4392              
4393             # any operator before m//
4394              
4395             # //, //= (defined-or)
4396              
4397             # P.164 Logical Operators
4398             # in Chapter 10: More Control Structures
4399             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4400              
4401             # P.119 C-Style Logical (Short-Circuit) Operators
4402             # in Chapter 3: Unary and Binary Operators
4403             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4404              
4405             # (and so on)
4406              
4407             # ~~
4408              
4409             # P.221 The Smart Match Operator
4410             # in Chapter 15: Smart Matching and given-when
4411             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4412              
4413             # P.112 Smartmatch Operator
4414             # in Chapter 3: Unary and Binary Operators
4415             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4416              
4417             # (and so on)
4418              
4419             elsif (/\G ((?>
4420              
4421             !~~ | !~ | != | ! |
4422             %= | % |
4423             &&= | && | &= | &\.= | &\. | & |
4424             -= | -> | - |
4425             :(?>\s*)= |
4426             : |
4427             <<>> |
4428             <<= | <=> | <= | < |
4429             == | => | =~ | = |
4430             >>= | >> | >= | > |
4431             \*\*= | \*\* | \*= | \* |
4432             \+= | \+ |
4433             \.\. | \.= | \. |
4434             \/\/= | \/\/ |
4435             \/= | \/ |
4436             \? |
4437             \\ |
4438             \^= | \^\.= | \^\. | \^ |
4439             \b x= |
4440             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4441             ~~ | ~\. | ~ |
4442             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4443             \b(?: print )\b |
4444              
4445 7         28 [,;\(\{\[]
  8834         17870  
4446              
4447             )) /oxgc) { $slash = 'm//'; return $1; }
4448 8834         39503  
  15013         31084  
4449             # other any character
4450             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4451              
4452 15013         66989 # system error
4453             else {
4454             die __FILE__, ": Oops, this shouldn't happen!\n";
4455             }
4456             }
4457              
4458 0     1786 0 0 # escape KOI8-R string
4459 1786         4053 sub e_string {
4460             my($string) = @_;
4461 1786         2907 my $e_string = '';
4462              
4463             local $slash = 'm//';
4464              
4465             # P.1024 Appendix W.10 Multibyte Processing
4466             # of ISBN 1-56592-224-7 CJKV Information Processing
4467 1786         2728 # (and so on)
4468              
4469             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4470 1786 100 66     14678  
4471 1786 50       7746 # without { ... }
4472 1769         3819 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4473             if ($string !~ /<
4474             return $string;
4475             }
4476             }
4477 1769         4172  
4478 17 50       68 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          
4479             while ($string !~ /\G \z/oxgc) {
4480             if (0) {
4481             }
4482 190         11400  
4483 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Ekoi8r::PREMATCH()]}
4484 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4485             $e_string .= q{Ekoi8r::PREMATCH()};
4486             $slash = 'div';
4487             }
4488              
4489 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Ekoi8r::MATCH()]}
4490 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4491             $e_string .= q{Ekoi8r::MATCH()};
4492             $slash = 'div';
4493             }
4494              
4495 0         0 # $', ${'} --> $', ${'}
4496 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4497             $e_string .= $1;
4498             $slash = 'div';
4499             }
4500              
4501 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Ekoi8r::POSTMATCH()]}
4502 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4503             $e_string .= q{Ekoi8r::POSTMATCH()};
4504             $slash = 'div';
4505             }
4506              
4507 0         0 # bareword
4508 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4509             $e_string .= $1;
4510             $slash = 'div';
4511             }
4512              
4513 0         0 # $0 --> $0
4514 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4515             $e_string .= $1;
4516             $slash = 'div';
4517 0         0 }
4518 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4519             $e_string .= $1;
4520             $slash = 'div';
4521             }
4522              
4523 0         0 # $$ --> $$
4524 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4525             $e_string .= $1;
4526             $slash = 'div';
4527             }
4528              
4529             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4530 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4531 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4532             $e_string .= e_capture($1);
4533             $slash = 'div';
4534 0         0 }
4535 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4536             $e_string .= e_capture($1);
4537             $slash = 'div';
4538             }
4539              
4540 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4541 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4542             $e_string .= e_capture($1.'->'.$2);
4543             $slash = 'div';
4544             }
4545              
4546 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4547 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4548             $e_string .= e_capture($1.'->'.$2);
4549             $slash = 'div';
4550             }
4551              
4552 0         0 # $$foo
4553 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4554             $e_string .= e_capture($1);
4555             $slash = 'div';
4556             }
4557              
4558 0         0 # ${ foo }
4559 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4560             $e_string .= '${' . $1 . '}';
4561             $slash = 'div';
4562             }
4563              
4564 0         0 # ${ ... }
4565 3         9 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4566             $e_string .= e_capture($1);
4567             $slash = 'div';
4568             }
4569              
4570             # variable or function
4571 3         14 # $ @ % & * $ #
4572 7         18 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) {
4573             $e_string .= $1;
4574             $slash = 'div';
4575             }
4576             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4577 7         31 # $ @ # \ ' " / ? ( ) [ ] < >
4578 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4579             $e_string .= $1;
4580             $slash = 'div';
4581             }
4582 0         0  
  0         0  
4583 0         0 # subroutines of package Ekoi8r
  0         0  
4584 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4585 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4586 0         0 elsif ($string =~ /\G \b KOI8R::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4587 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4588 0         0 elsif ($string =~ /\G \b KOI8R::eval \b /oxgc) { $e_string .= 'eval KOI8R::escape'; $slash = 'm//'; }
  0         0  
4589 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4590 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Ekoi8r::chop'; $slash = 'm//'; }
  0         0  
4591 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4592 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4593 0         0 elsif ($string =~ /\G \b KOI8R::index \b /oxgc) { $e_string .= 'KOI8R::index'; $slash = 'm//'; }
  0         0  
4594 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Ekoi8r::index'; $slash = 'm//'; }
  0         0  
4595 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4596 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4597 0         0 elsif ($string =~ /\G \b KOI8R::rindex \b /oxgc) { $e_string .= 'KOI8R::rindex'; $slash = 'm//'; }
  0         0  
4598 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Ekoi8r::rindex'; $slash = 'm//'; }
  0         0  
4599 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::lc'; $slash = 'm//'; }
  0         0  
4600 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::lcfirst'; $slash = 'm//'; }
  0         0  
4601 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::uc'; $slash = 'm//'; }
  0         0  
4602             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::ucfirst'; $slash = 'm//'; }
4603             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::fc'; $slash = 'm//'; }
4604 0         0  
  0         0  
4605 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4606 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4607 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  
4608 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  
4609 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  
4610 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  
4611             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
4612 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  
4613 0         0  
  0         0  
4614 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4615 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  
4616 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  
4617 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  
4618 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  
4619             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4620             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4621 0         0  
  0         0  
4622 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
4623 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4624 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4625             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
4626 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4627 0         0  
  0         0  
4628 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4629 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4630 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::chr'; $slash = 'm//'; }
  0         0  
4631 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4632 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4633 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::glob'; $slash = 'm//'; }
  0         0  
4634 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Ekoi8r::lc_'; $slash = 'm//'; }
  0         0  
4635 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Ekoi8r::lcfirst_'; $slash = 'm//'; }
  0         0  
4636 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Ekoi8r::uc_'; $slash = 'm//'; }
  0         0  
4637 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Ekoi8r::ucfirst_'; $slash = 'm//'; }
  0         0  
4638             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Ekoi8r::fc_'; $slash = 'm//'; }
4639 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4640 0         0  
  0         0  
4641 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4642 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4643 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Ekoi8r::chr_'; $slash = 'm//'; }
  0         0  
4644 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4645 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4646 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Ekoi8r::glob_'; $slash = 'm//'; }
  0         0  
4647             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
4648             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
4649 0         0 # split
4650             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4651 0         0 $slash = 'm//';
4652 0         0  
4653 0         0 my $e = '';
4654             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4655             $e .= $1;
4656             }
4657 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          
4658             # end of split
4659             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8r::split' . $e; }
4660 0         0  
  0         0  
4661             # split scalar value
4662             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . e_string($1); next E_STRING_LOOP; }
4663 0         0  
  0         0  
4664 0         0 # split literal space
  0         0  
4665 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4666 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4667 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4668 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4669 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4670 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4671 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4672 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4673 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4674 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4675 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4676 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4677             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {' '}; next E_STRING_LOOP; }
4678             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {" "}; next E_STRING_LOOP; }
4679              
4680 0 0       0 # split qq//
  0         0  
  0         0  
4681             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4682 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
4683 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4684 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4685 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4686 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  
4687 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  
4688 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  
4689 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  
4690             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
4691 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 * *
4692             }
4693             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4694             }
4695             }
4696              
4697 0 0       0 # split qr//
  0         0  
  0         0  
4698             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4699 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
4700 0 0       0 else {
  0 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)*?) (\)) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ( )
  0         0  
4704 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  
4705 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  
4706 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  
4707 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  
4708             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
4709 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 * *
4710             }
4711             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4712             }
4713             }
4714              
4715 0 0       0 # split q//
  0         0  
  0         0  
4716             elsif ($string =~ /\G \b (q) \b /oxgc) {
4717 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
4718 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4719 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4720 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4721 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  
4722 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  
4723 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  
4724 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  
4725             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
4726 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 * *
4727             }
4728             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4729             }
4730             }
4731              
4732 0 0       0 # split m//
  0         0  
  0         0  
4733             elsif ($string =~ /\G \b (m) \b /oxgc) {
4734 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 # #
4735 0 0       0 else {
  0 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 (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ( ) --> qr ( )
  0         0  
4739 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  
4740 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  
4741 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  
4742 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  
4743             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
4744 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 * *
4745             }
4746             die __FILE__, ": Search pattern not terminated\n";
4747             }
4748             }
4749              
4750 0         0 # split ''
4751 0         0 elsif ($string =~ /\G (\') /oxgc) {
4752 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
4753 0         0 while ($string !~ /\G \z/oxgc) {
4754 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
4755 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4756             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
4757 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4758             }
4759             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4760             }
4761              
4762 0         0 # split ""
4763 0         0 elsif ($string =~ /\G (\") /oxgc) {
4764 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
4765 0         0 while ($string !~ /\G \z/oxgc) {
4766 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
4767 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4768             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
4769 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4770             }
4771             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4772             }
4773              
4774 0         0 # split //
4775 0         0 elsif ($string =~ /\G (\/) /oxgc) {
4776 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4777 0         0 while ($string !~ /\G \z/oxgc) {
4778 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
4779 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4780             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
4781 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4782             }
4783             die __FILE__, ": Search pattern not terminated\n";
4784             }
4785             }
4786              
4787 0         0 # qq//
4788 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4789 0         0 my $ope = $1;
4790             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4791             $e_string .= e_qq($ope,$1,$3,$2);
4792 0         0 }
4793 0         0 else {
4794 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4795 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4796 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4797 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4798 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4799 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4800             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4801 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4802             }
4803             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4804             }
4805             }
4806              
4807 0         0 # qx//
4808 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4809 0         0 my $ope = $1;
4810             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4811             $e_string .= e_qq($ope,$1,$3,$2);
4812 0         0 }
4813 0         0 else {
4814 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4815 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4816 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4817 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4818 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4819 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4820 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4821             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4822 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4823             }
4824             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4825             }
4826             }
4827              
4828 0         0 # q//
4829 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4830 0         0 my $ope = $1;
4831             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4832             $e_string .= e_q($ope,$1,$3,$2);
4833 0         0 }
4834 0         0 else {
4835 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4836 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4837 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4838 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4839 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4840 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4841             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4842 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 * *
4843             }
4844             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4845             }
4846             }
4847 0         0  
4848             # ''
4849             elsif ($string =~ /\G (?
4850 0         0  
4851             # ""
4852             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4853 0         0  
4854             # ``
4855             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4856 0         0  
4857             # <<>> (a safer ARGV)
4858             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4859 0         0  
4860             # <<= <=> <= < operator
4861             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4862 0         0  
4863             #
4864             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4865              
4866 0         0 # --- glob
4867             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4868             $e_string .= 'Ekoi8r::glob("' . $1 . '")';
4869             }
4870              
4871 0         0 # << (bit shift) --- not here document
4872 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
4873             $slash = 'm//';
4874             $e_string .= $1;
4875             }
4876              
4877 0         0 # <<~'HEREDOC'
4878 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4879 0         0 $slash = 'm//';
4880             my $here_quote = $1;
4881             my $delimiter = $2;
4882 0 0       0  
4883 0         0 # get here document
4884 0         0 if ($here_script eq '') {
4885             $here_script = CORE::substr $_, pos $_;
4886 0 0       0 $here_script =~ s/.*?\n//oxm;
4887 0         0 }
4888 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4889 0         0 my $heredoc = $1;
4890 0         0 my $indent = $2;
4891 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4892             push @heredoc, $heredoc . qq{\n$delimiter\n};
4893             push @heredoc_delimiter, qq{\\s*$delimiter};
4894 0         0 }
4895             else {
4896 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4897             }
4898             $e_string .= qq{<<'$delimiter'};
4899             }
4900              
4901 0         0 # <<~\HEREDOC
4902 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4903 0         0 $slash = 'm//';
4904             my $here_quote = $1;
4905             my $delimiter = $2;
4906 0 0       0  
4907 0         0 # get here document
4908 0         0 if ($here_script eq '') {
4909             $here_script = CORE::substr $_, pos $_;
4910 0 0       0 $here_script =~ s/.*?\n//oxm;
4911 0         0 }
4912 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4913 0         0 my $heredoc = $1;
4914 0         0 my $indent = $2;
4915 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4916             push @heredoc, $heredoc . qq{\n$delimiter\n};
4917             push @heredoc_delimiter, qq{\\s*$delimiter};
4918 0         0 }
4919             else {
4920 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4921             }
4922             $e_string .= qq{<<\\$delimiter};
4923             }
4924              
4925 0         0 # <<~"HEREDOC"
4926 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4927 0         0 $slash = 'm//';
4928             my $here_quote = $1;
4929             my $delimiter = $2;
4930 0 0       0  
4931 0         0 # get here document
4932 0         0 if ($here_script eq '') {
4933             $here_script = CORE::substr $_, pos $_;
4934 0 0       0 $here_script =~ s/.*?\n//oxm;
4935 0         0 }
4936 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4937 0         0 my $heredoc = $1;
4938 0         0 my $indent = $2;
4939 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4940             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4941             push @heredoc_delimiter, qq{\\s*$delimiter};
4942 0         0 }
4943             else {
4944 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4945             }
4946             $e_string .= qq{<<"$delimiter"};
4947             }
4948              
4949 0         0 # <<~HEREDOC
4950 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4951 0         0 $slash = 'm//';
4952             my $here_quote = $1;
4953             my $delimiter = $2;
4954 0 0       0  
4955 0         0 # get here document
4956 0         0 if ($here_script eq '') {
4957             $here_script = CORE::substr $_, pos $_;
4958 0 0       0 $here_script =~ s/.*?\n//oxm;
4959 0         0 }
4960 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4961 0         0 my $heredoc = $1;
4962 0         0 my $indent = $2;
4963 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4964             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4965             push @heredoc_delimiter, qq{\\s*$delimiter};
4966 0         0 }
4967             else {
4968 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4969             }
4970             $e_string .= qq{<<$delimiter};
4971             }
4972              
4973 0         0 # <<~`HEREDOC`
4974 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4975 0         0 $slash = 'm//';
4976             my $here_quote = $1;
4977             my $delimiter = $2;
4978 0 0       0  
4979 0         0 # get here document
4980 0         0 if ($here_script eq '') {
4981             $here_script = CORE::substr $_, pos $_;
4982 0 0       0 $here_script =~ s/.*?\n//oxm;
4983 0         0 }
4984 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4985 0         0 my $heredoc = $1;
4986 0         0 my $indent = $2;
4987 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4988             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4989             push @heredoc_delimiter, qq{\\s*$delimiter};
4990 0         0 }
4991             else {
4992 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4993             }
4994             $e_string .= qq{<<`$delimiter`};
4995             }
4996              
4997 0         0 # <<'HEREDOC'
4998 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4999 0         0 $slash = 'm//';
5000             my $here_quote = $1;
5001             my $delimiter = $2;
5002 0 0       0  
5003 0         0 # get here document
5004 0         0 if ($here_script eq '') {
5005             $here_script = CORE::substr $_, pos $_;
5006 0 0       0 $here_script =~ s/.*?\n//oxm;
5007 0         0 }
5008 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5009             push @heredoc, $1 . qq{\n$delimiter\n};
5010             push @heredoc_delimiter, $delimiter;
5011 0         0 }
5012             else {
5013 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5014             }
5015             $e_string .= $here_quote;
5016             }
5017              
5018 0         0 # <<\HEREDOC
5019 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5020 0         0 $slash = 'm//';
5021             my $here_quote = $1;
5022             my $delimiter = $2;
5023 0 0       0  
5024 0         0 # get here document
5025 0         0 if ($here_script eq '') {
5026             $here_script = CORE::substr $_, pos $_;
5027 0 0       0 $here_script =~ s/.*?\n//oxm;
5028 0         0 }
5029 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5030             push @heredoc, $1 . qq{\n$delimiter\n};
5031             push @heredoc_delimiter, $delimiter;
5032 0         0 }
5033             else {
5034 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5035             }
5036             $e_string .= $here_quote;
5037             }
5038              
5039 0         0 # <<"HEREDOC"
5040 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5041 0         0 $slash = 'm//';
5042             my $here_quote = $1;
5043             my $delimiter = $2;
5044 0 0       0  
5045 0         0 # get here document
5046 0         0 if ($here_script eq '') {
5047             $here_script = CORE::substr $_, pos $_;
5048 0 0       0 $here_script =~ s/.*?\n//oxm;
5049 0         0 }
5050 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5051             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5052             push @heredoc_delimiter, $delimiter;
5053 0         0 }
5054             else {
5055 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5056             }
5057             $e_string .= $here_quote;
5058             }
5059              
5060 0         0 # <
5061 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5062 0         0 $slash = 'm//';
5063             my $here_quote = $1;
5064             my $delimiter = $2;
5065 0 0       0  
5066 0         0 # get here document
5067 0         0 if ($here_script eq '') {
5068             $here_script = CORE::substr $_, pos $_;
5069 0 0       0 $here_script =~ s/.*?\n//oxm;
5070 0         0 }
5071 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5072             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5073             push @heredoc_delimiter, $delimiter;
5074 0         0 }
5075             else {
5076 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5077             }
5078             $e_string .= $here_quote;
5079             }
5080              
5081 0         0 # <<`HEREDOC`
5082 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5083 0         0 $slash = 'm//';
5084             my $here_quote = $1;
5085             my $delimiter = $2;
5086 0 0       0  
5087 0         0 # get here document
5088 0         0 if ($here_script eq '') {
5089             $here_script = CORE::substr $_, pos $_;
5090 0 0       0 $here_script =~ s/.*?\n//oxm;
5091 0         0 }
5092 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5093             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5094             push @heredoc_delimiter, $delimiter;
5095 0         0 }
5096             else {
5097 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5098             }
5099             $e_string .= $here_quote;
5100             }
5101              
5102             # any operator before div
5103             elsif ($string =~ /\G (
5104             -- | \+\+ |
5105 0         0 [\)\}\]]
  18         33  
5106              
5107             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
5108              
5109             # yada-yada or triple-dot operator
5110             elsif ($string =~ /\G (
5111 18         54 \.\.\.
  0         0  
5112              
5113             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
5114              
5115             # any operator before m//
5116             elsif ($string =~ /\G ((?>
5117              
5118             !~~ | !~ | != | ! |
5119             %= | % |
5120             &&= | && | &= | &\.= | &\. | & |
5121             -= | -> | - |
5122             :(?>\s*)= |
5123             : |
5124             <<>> |
5125             <<= | <=> | <= | < |
5126             == | => | =~ | = |
5127             >>= | >> | >= | > |
5128             \*\*= | \*\* | \*= | \* |
5129             \+= | \+ |
5130             \.\. | \.= | \. |
5131             \/\/= | \/\/ |
5132             \/= | \/ |
5133             \? |
5134             \\ |
5135             \^= | \^\.= | \^\. | \^ |
5136             \b x= |
5137             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
5138             ~~ | ~\. | ~ |
5139             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
5140             \b(?: print )\b |
5141              
5142 0         0 [,;\(\{\[]
  31         57  
5143              
5144             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
5145 31         122  
5146             # other any character
5147             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
5148              
5149 131         389 # system error
5150             else {
5151             die __FILE__, ": Oops, this shouldn't happen!\n";
5152             }
5153 0         0 }
5154              
5155             return $e_string;
5156             }
5157              
5158             #
5159             # character class
5160 17     1919 0 71 #
5161             sub character_class {
5162 1919 100       3488 my($char,$modifier) = @_;
5163 1919 100       3098  
5164 52         150 if ($char eq '.') {
5165             if ($modifier =~ /s/) {
5166             return '${Ekoi8r::dot_s}';
5167 17         38 }
5168             else {
5169             return '${Ekoi8r::dot}';
5170             }
5171 35         101 }
5172             else {
5173             return Ekoi8r::classic_character_class($char);
5174             }
5175             }
5176              
5177             #
5178             # escape capture ($1, $2, $3, ...)
5179             #
5180 1867     212 0 3270 sub e_capture {
5181              
5182             return join '', '${', $_[0], '}';
5183             }
5184              
5185             #
5186             # escape transliteration (tr/// or y///)
5187 212     3 0 697 #
5188 3         10 sub e_tr {
5189 3   50     5 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
5190             my $e_tr = '';
5191 3         5 $modifier ||= '';
5192              
5193             $slash = 'div';
5194 3         4  
5195             # quote character class 1
5196             $charclass = q_tr($charclass);
5197 3         11  
5198             # quote character class 2
5199             $charclass2 = q_tr($charclass2);
5200 3 50       4  
5201 3 0       7 # /b /B modifier
5202 0         0 if ($modifier =~ tr/bB//d) {
5203             if ($variable eq '') {
5204             $e_tr = qq{tr$charclass$e$charclass2$modifier};
5205 0         0 }
5206             else {
5207             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
5208             }
5209 0 100       0 }
5210 3         6 else {
5211             if ($variable eq '') {
5212             $e_tr = qq{Ekoi8r::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
5213 2         6 }
5214             else {
5215             $e_tr = qq{Ekoi8r::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
5216             }
5217             }
5218 1         4  
5219 3         4 # clear tr/// variable
5220             $tr_variable = '';
5221 3         4 $bind_operator = '';
5222              
5223             return $e_tr;
5224             }
5225              
5226             #
5227             # quote for escape transliteration (tr/// or y///)
5228 3     6 0 16 #
5229             sub q_tr {
5230             my($charclass) = @_;
5231 6 50       10  
    0          
    0          
    0          
    0          
    0          
5232 6         12 # quote character class
5233             if ($charclass !~ /'/oxms) {
5234             return e_q('', "'", "'", $charclass); # --> q' '
5235 6         9 }
5236             elsif ($charclass !~ /\//oxms) {
5237             return e_q('q', '/', '/', $charclass); # --> q/ /
5238 0         0 }
5239             elsif ($charclass !~ /\#/oxms) {
5240             return e_q('q', '#', '#', $charclass); # --> q# #
5241 0         0 }
5242             elsif ($charclass !~ /[\<\>]/oxms) {
5243             return e_q('q', '<', '>', $charclass); # --> q< >
5244 0         0 }
5245             elsif ($charclass !~ /[\(\)]/oxms) {
5246             return e_q('q', '(', ')', $charclass); # --> q( )
5247 0         0 }
5248             elsif ($charclass !~ /[\{\}]/oxms) {
5249             return e_q('q', '{', '}', $charclass); # --> q{ }
5250 0         0 }
5251 0 0       0 else {
5252 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5253             if ($charclass !~ /\Q$char\E/xms) {
5254             return e_q('q', $char, $char, $charclass);
5255             }
5256             }
5257 0         0 }
5258              
5259             return e_q('q', '{', '}', $charclass);
5260             }
5261              
5262             #
5263             # escape q string (q//, '')
5264 0     1264 0 0 #
5265             sub e_q {
5266 1264         2820 my($ope,$delimiter,$end_delimiter,$string) = @_;
5267              
5268 1264         1803 $slash = 'div';
5269              
5270             return join '', $ope, $delimiter, $string, $end_delimiter;
5271             }
5272              
5273             #
5274             # escape qq string (qq//, "", qx//, ``)
5275 1264     4042 0 6772 #
5276             sub e_qq {
5277 4042         9046 my($ope,$delimiter,$end_delimiter,$string) = @_;
5278              
5279 4042         5437 $slash = 'div';
5280 4042         4922  
5281             my $left_e = 0;
5282             my $right_e = 0;
5283 4042         4486  
5284             # split regexp
5285             my @char = $string =~ /\G((?>
5286             [^\\\$] |
5287             \\x\{ (?>[0-9A-Fa-f]+) \} |
5288             \\o\{ (?>[0-7]+) \} |
5289             \\N\{ (?>[^0-9\}][^\}]*) \} |
5290             \\ $q_char |
5291             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5292             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5293             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5294             \$ (?>\s* [0-9]+) |
5295             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5296             \$ \$ (?![\w\{]) |
5297             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5298             $q_char
5299 4042         137333 ))/oxmsg;
5300              
5301             for (my $i=0; $i <= $#char; $i++) {
5302 4042 50 33     12681  
    50 33        
    100          
    100          
    50          
5303 113560         365141 # "\L\u" --> "\u\L"
5304             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5305             @char[$i,$i+1] = @char[$i+1,$i];
5306             }
5307              
5308 0         0 # "\U\l" --> "\l\U"
5309             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5310             @char[$i,$i+1] = @char[$i+1,$i];
5311             }
5312              
5313 0         0 # octal escape sequence
5314             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5315             $char[$i] = Ekoi8r::octchr($1);
5316             }
5317              
5318 1         3 # hexadecimal escape sequence
5319             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5320             $char[$i] = Ekoi8r::hexchr($1);
5321             }
5322              
5323 1         4 # \N{CHARNAME} --> N{CHARNAME}
5324             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5325             $char[$i] = $1;
5326 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          
5327              
5328             if (0) {
5329             }
5330              
5331             # \F
5332             #
5333             # P.69 Table 2-6. Translation escapes
5334             # in Chapter 2: Bits and Pieces
5335             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5336             # (and so on)
5337 113560         971737  
5338 0 50       0 # \u \l \U \L \F \Q \E
5339 484         1002 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5340             if ($right_e < $left_e) {
5341             $char[$i] = '\\' . $char[$i];
5342             }
5343             }
5344             elsif ($char[$i] eq '\u') {
5345              
5346             # "STRING @{[ LIST EXPR ]} MORE STRING"
5347              
5348             # P.257 Other Tricks You Can Do with Hard References
5349             # in Chapter 8: References
5350             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5351              
5352             # P.353 Other Tricks You Can Do with Hard References
5353             # in Chapter 8: References
5354             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5355              
5356 0         0 # (and so on)
5357 0         0  
5358             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
5359             $left_e++;
5360 0         0 }
5361 0         0 elsif ($char[$i] eq '\l') {
5362             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
5363             $left_e++;
5364 0         0 }
5365 0         0 elsif ($char[$i] eq '\U') {
5366             $char[$i] = '@{[Ekoi8r::uc qq<';
5367             $left_e++;
5368 0         0 }
5369 0         0 elsif ($char[$i] eq '\L') {
5370             $char[$i] = '@{[Ekoi8r::lc qq<';
5371             $left_e++;
5372 0         0 }
5373 24         35 elsif ($char[$i] eq '\F') {
5374             $char[$i] = '@{[Ekoi8r::fc qq<';
5375             $left_e++;
5376 24         47 }
5377 0         0 elsif ($char[$i] eq '\Q') {
5378             $char[$i] = '@{[CORE::quotemeta qq<';
5379             $left_e++;
5380 0 50       0 }
5381 24         43 elsif ($char[$i] eq '\E') {
5382 24         36 if ($right_e < $left_e) {
5383             $char[$i] = '>]}';
5384             $right_e++;
5385 24         96 }
5386             else {
5387             $char[$i] = '';
5388             }
5389 0         0 }
5390 0 0       0 elsif ($char[$i] eq '\Q') {
5391 0         0 while (1) {
5392             if (++$i > $#char) {
5393 0 0       0 last;
5394 0         0 }
5395             if ($char[$i] eq '\E') {
5396             last;
5397             }
5398             }
5399             }
5400             elsif ($char[$i] eq '\E') {
5401             }
5402              
5403             # $0 --> $0
5404             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5405             }
5406             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5407             }
5408              
5409             # $$ --> $$
5410             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5411             }
5412              
5413             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5414 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5415             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5416             $char[$i] = e_capture($1);
5417 205         391 }
5418             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5419             $char[$i] = e_capture($1);
5420             }
5421              
5422 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5423             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5424             $char[$i] = e_capture($1.'->'.$2);
5425             }
5426              
5427 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5428             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5429             $char[$i] = e_capture($1.'->'.$2);
5430             }
5431              
5432 0         0 # $$foo
5433             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5434             $char[$i] = e_capture($1);
5435             }
5436              
5437 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
5438             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5439             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
5440             }
5441              
5442 44         111 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
5443             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5444             $char[$i] = '@{[Ekoi8r::MATCH()]}';
5445             }
5446              
5447 45         158 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
5448             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5449             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
5450             }
5451              
5452             # ${ foo } --> ${ foo }
5453             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5454             }
5455              
5456 33         111 # ${ ... }
5457             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5458             $char[$i] = e_capture($1);
5459             }
5460             }
5461 0 50       0  
5462 4042         7290 # return string
5463             if ($left_e > $right_e) {
5464 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5465             }
5466             return join '', $ope, $delimiter, @char, $end_delimiter;
5467             }
5468              
5469             #
5470             # escape qw string (qw//)
5471 4042     16 0 35267 #
5472             sub e_qw {
5473 16         74 my($ope,$delimiter,$end_delimiter,$string) = @_;
5474              
5475             $slash = 'div';
5476 16         33  
  16         200  
5477 483 50       773 # choice again delimiter
    0          
    0          
    0          
    0          
5478 16         103 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5479             if (not $octet{$end_delimiter}) {
5480             return join '', $ope, $delimiter, $string, $end_delimiter;
5481 16         135 }
5482             elsif (not $octet{')'}) {
5483             return join '', $ope, '(', $string, ')';
5484 0         0 }
5485             elsif (not $octet{'}'}) {
5486             return join '', $ope, '{', $string, '}';
5487 0         0 }
5488             elsif (not $octet{']'}) {
5489             return join '', $ope, '[', $string, ']';
5490 0         0 }
5491             elsif (not $octet{'>'}) {
5492             return join '', $ope, '<', $string, '>';
5493 0         0 }
5494 0 0       0 else {
5495 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5496             if (not $octet{$char}) {
5497             return join '', $ope, $char, $string, $char;
5498             }
5499             }
5500             }
5501 0         0  
5502 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5503 0         0 my @string = CORE::split(/\s+/, $string);
5504 0         0 for my $string (@string) {
5505 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5506 0         0 for my $octet (@octet) {
5507             if ($octet =~ /\A (['\\]) \z/oxms) {
5508             $octet = '\\' . $1;
5509 0         0 }
5510             }
5511 0         0 $string = join '', @octet;
  0         0  
5512             }
5513             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5514             }
5515              
5516             #
5517             # escape here document (<<"HEREDOC", <
5518 0     93 0 0 #
5519             sub e_heredoc {
5520 93         403 my($string) = @_;
5521              
5522 93         177 $slash = 'm//';
5523              
5524 93         446 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5525 93         146  
5526             my $left_e = 0;
5527             my $right_e = 0;
5528 93         123  
5529             # split regexp
5530             my @char = $string =~ /\G((?>
5531             [^\\\$] |
5532             \\x\{ (?>[0-9A-Fa-f]+) \} |
5533             \\o\{ (?>[0-7]+) \} |
5534             \\N\{ (?>[^0-9\}][^\}]*) \} |
5535             \\ $q_char |
5536             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5537             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5538             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5539             \$ (?>\s* [0-9]+) |
5540             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5541             \$ \$ (?![\w\{]) |
5542             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5543             $q_char
5544 93         8635 ))/oxmsg;
5545              
5546             for (my $i=0; $i <= $#char; $i++) {
5547 93 50 33     662  
    50 33        
    100          
    100          
    50          
5548 3151         11569 # "\L\u" --> "\u\L"
5549             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5550             @char[$i,$i+1] = @char[$i+1,$i];
5551             }
5552              
5553 0         0 # "\U\l" --> "\l\U"
5554             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5555             @char[$i,$i+1] = @char[$i+1,$i];
5556             }
5557              
5558 0         0 # octal escape sequence
5559             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5560             $char[$i] = Ekoi8r::octchr($1);
5561             }
5562              
5563 1         4 # hexadecimal escape sequence
5564             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5565             $char[$i] = Ekoi8r::hexchr($1);
5566             }
5567              
5568 1         3 # \N{CHARNAME} --> N{CHARNAME}
5569             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5570             $char[$i] = $1;
5571 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          
5572              
5573             if (0) {
5574             }
5575 3151         28400  
5576 0 0       0 # \u \l \U \L \F \Q \E
5577 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5578             if ($right_e < $left_e) {
5579             $char[$i] = '\\' . $char[$i];
5580             }
5581 0         0 }
5582 0         0 elsif ($char[$i] eq '\u') {
5583             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
5584             $left_e++;
5585 0         0 }
5586 0         0 elsif ($char[$i] eq '\l') {
5587             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
5588             $left_e++;
5589 0         0 }
5590 0         0 elsif ($char[$i] eq '\U') {
5591             $char[$i] = '@{[Ekoi8r::uc qq<';
5592             $left_e++;
5593 0         0 }
5594 0         0 elsif ($char[$i] eq '\L') {
5595             $char[$i] = '@{[Ekoi8r::lc qq<';
5596             $left_e++;
5597 0         0 }
5598 0         0 elsif ($char[$i] eq '\F') {
5599             $char[$i] = '@{[Ekoi8r::fc qq<';
5600             $left_e++;
5601 0         0 }
5602 0         0 elsif ($char[$i] eq '\Q') {
5603             $char[$i] = '@{[CORE::quotemeta qq<';
5604             $left_e++;
5605 0 0       0 }
5606 0         0 elsif ($char[$i] eq '\E') {
5607 0         0 if ($right_e < $left_e) {
5608             $char[$i] = '>]}';
5609             $right_e++;
5610 0         0 }
5611             else {
5612             $char[$i] = '';
5613             }
5614 0         0 }
5615 0 0       0 elsif ($char[$i] eq '\Q') {
5616 0         0 while (1) {
5617             if (++$i > $#char) {
5618 0 0       0 last;
5619 0         0 }
5620             if ($char[$i] eq '\E') {
5621             last;
5622             }
5623             }
5624             }
5625             elsif ($char[$i] eq '\E') {
5626             }
5627              
5628             # $0 --> $0
5629             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5630             }
5631             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5632             }
5633              
5634             # $$ --> $$
5635             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5636             }
5637              
5638             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5639 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5640             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5641             $char[$i] = e_capture($1);
5642 0         0 }
5643             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5644             $char[$i] = e_capture($1);
5645             }
5646              
5647 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5648             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5649             $char[$i] = e_capture($1.'->'.$2);
5650             }
5651              
5652 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5653             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5654             $char[$i] = e_capture($1.'->'.$2);
5655             }
5656              
5657 0         0 # $$foo
5658             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5659             $char[$i] = e_capture($1);
5660             }
5661              
5662 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
5663             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5664             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
5665             }
5666              
5667 8         43 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
5668             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5669             $char[$i] = '@{[Ekoi8r::MATCH()]}';
5670             }
5671              
5672 8         51 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
5673             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5674             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
5675             }
5676              
5677             # ${ foo } --> ${ foo }
5678             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5679             }
5680              
5681 6         36 # ${ ... }
5682             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5683             $char[$i] = e_capture($1);
5684             }
5685             }
5686 0 50       0  
5687 93         227 # return string
5688             if ($left_e > $right_e) {
5689 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5690             }
5691             return join '', @char;
5692             }
5693              
5694             #
5695             # escape regexp (m//, qr//)
5696 93     652 0 1008 #
5697 652   100     2712 sub e_qr {
5698             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5699 652         4791 $modifier ||= '';
5700 652 50       1192  
5701 652         1712 $modifier =~ tr/p//d;
5702 0         0 if ($modifier =~ /([adlu])/oxms) {
5703 0 0       0 my $line = 0;
5704 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5705 0         0 if ($filename ne __FILE__) {
5706             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5707             last;
5708 0         0 }
5709             }
5710             die qq{Unsupported modifier "$1" used at line $line.\n};
5711 0         0 }
5712              
5713             $slash = 'div';
5714 652 100       970  
    100          
5715 652         2055 # literal null string pattern
5716 8         7 if ($string eq '') {
5717 8         10 $modifier =~ tr/bB//d;
5718             $modifier =~ tr/i//d;
5719             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5720             }
5721              
5722             # /b /B modifier
5723             elsif ($modifier =~ tr/bB//d) {
5724 8 50       42  
5725 2         6 # choice again delimiter
5726 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5727 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5728 0         0 my %octet = map {$_ => 1} @char;
5729 0         0 if (not $octet{')'}) {
5730             $delimiter = '(';
5731             $end_delimiter = ')';
5732 0         0 }
5733 0         0 elsif (not $octet{'}'}) {
5734             $delimiter = '{';
5735             $end_delimiter = '}';
5736 0         0 }
5737 0         0 elsif (not $octet{']'}) {
5738             $delimiter = '[';
5739             $end_delimiter = ']';
5740 0         0 }
5741 0         0 elsif (not $octet{'>'}) {
5742             $delimiter = '<';
5743             $end_delimiter = '>';
5744 0         0 }
5745 0 0       0 else {
5746 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5747 0         0 if (not $octet{$char}) {
5748 0         0 $delimiter = $char;
5749             $end_delimiter = $char;
5750             last;
5751             }
5752             }
5753             }
5754 0 50 33     0 }
5755 2         11  
5756             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5757             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5758 0         0 }
5759             else {
5760             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5761             }
5762 2 100       12 }
5763 642         1422  
5764             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5765             my $metachar = qr/[\@\\|[\]{^]/oxms;
5766 642         2314  
5767             # split regexp
5768             my @char = $string =~ /\G((?>
5769             [^\\\$\@\[\(] |
5770             \\x (?>[0-9A-Fa-f]{1,2}) |
5771             \\ (?>[0-7]{2,3}) |
5772             \\c [\x40-\x5F] |
5773             \\x\{ (?>[0-9A-Fa-f]+) \} |
5774             \\o\{ (?>[0-7]+) \} |
5775             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5776             \\ $q_char |
5777             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5778             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5779             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5780             [\$\@] $qq_variable |
5781             \$ (?>\s* [0-9]+) |
5782             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5783             \$ \$ (?![\w\{]) |
5784             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5785             \[\^ |
5786             \[\: (?>[a-z]+) :\] |
5787             \[\:\^ (?>[a-z]+) :\] |
5788             \(\? |
5789             $q_char
5790             ))/oxmsg;
5791 642 50       80099  
5792 642         3125 # choice again delimiter
  0         0  
5793 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5794 0         0 my %octet = map {$_ => 1} @char;
5795 0         0 if (not $octet{')'}) {
5796             $delimiter = '(';
5797             $end_delimiter = ')';
5798 0         0 }
5799 0         0 elsif (not $octet{'}'}) {
5800             $delimiter = '{';
5801             $end_delimiter = '}';
5802 0         0 }
5803 0         0 elsif (not $octet{']'}) {
5804             $delimiter = '[';
5805             $end_delimiter = ']';
5806 0         0 }
5807 0         0 elsif (not $octet{'>'}) {
5808             $delimiter = '<';
5809             $end_delimiter = '>';
5810 0         0 }
5811 0 0       0 else {
5812 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5813 0         0 if (not $octet{$char}) {
5814 0         0 $delimiter = $char;
5815             $end_delimiter = $char;
5816             last;
5817             }
5818             }
5819             }
5820 0         0 }
5821 642         949  
5822 642         837 my $left_e = 0;
5823             my $right_e = 0;
5824             for (my $i=0; $i <= $#char; $i++) {
5825 642 50 66     1577  
    50 66        
    100          
    100          
    100          
    100          
5826 1872         9760 # "\L\u" --> "\u\L"
5827             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5828             @char[$i,$i+1] = @char[$i+1,$i];
5829             }
5830              
5831 0         0 # "\U\l" --> "\l\U"
5832             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5833             @char[$i,$i+1] = @char[$i+1,$i];
5834             }
5835              
5836 0         0 # octal escape sequence
5837             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5838             $char[$i] = Ekoi8r::octchr($1);
5839             }
5840              
5841 1         3 # hexadecimal escape sequence
5842             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5843             $char[$i] = Ekoi8r::hexchr($1);
5844             }
5845              
5846             # \b{...} --> b\{...}
5847             # \B{...} --> B\{...}
5848             # \N{CHARNAME} --> N\{CHARNAME}
5849             # \p{PROPERTY} --> p\{PROPERTY}
5850 1         3 # \P{PROPERTY} --> P\{PROPERTY}
5851             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5852             $char[$i] = $1 . '\\' . $2;
5853             }
5854              
5855 6         18 # \p, \P, \X --> p, P, X
5856             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5857             $char[$i] = $1;
5858 4 100 100     12 }
    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          
5859              
5860             if (0) {
5861             }
5862 1872         6455  
5863 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5864 6         77 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5865             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)) {
5866             $char[$i] .= join '', splice @char, $i+1, 3;
5867 0         0 }
5868             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)) {
5869             $char[$i] .= join '', splice @char, $i+1, 2;
5870 0         0 }
5871             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)) {
5872             $char[$i] .= join '', splice @char, $i+1, 1;
5873             }
5874             }
5875              
5876 0         0 # open character class [...]
5877             elsif ($char[$i] eq '[') {
5878             my $left = $i;
5879              
5880             # [] make die "Unmatched [] in regexp ...\n"
5881 328 100       419 # (and so on)
5882 328         849  
5883             if ($char[$i+1] eq ']') {
5884             $i++;
5885 3         5 }
5886 328 50       411  
5887 1379         2066 while (1) {
5888             if (++$i > $#char) {
5889 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5890 1379         2038 }
5891             if ($char[$i] eq ']') {
5892             my $right = $i;
5893 328 100       404  
5894 328         1587 # [...]
  30         62  
5895             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5896             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5897 90         131 }
5898             else {
5899             splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
5900 298         1084 }
5901 328         570  
5902             $i = $left;
5903             last;
5904             }
5905             }
5906             }
5907              
5908 328         773 # open character class [^...]
5909             elsif ($char[$i] eq '[^') {
5910             my $left = $i;
5911              
5912             # [^] make die "Unmatched [] in regexp ...\n"
5913 74 100       100 # (and so on)
5914 74         150  
5915             if ($char[$i+1] eq ']') {
5916             $i++;
5917 4         7 }
5918 74 50       87  
5919 272         368 while (1) {
5920             if (++$i > $#char) {
5921 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5922 272         402 }
5923             if ($char[$i] eq ']') {
5924             my $right = $i;
5925 74 100       85  
5926 74         371 # [^...]
  30         61  
5927             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5928             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5929 90         134 }
5930             else {
5931             splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5932 44         161 }
5933 74         131  
5934             $i = $left;
5935             last;
5936             }
5937             }
5938             }
5939              
5940 74         189 # rewrite character class or escape character
5941             elsif (my $char = character_class($char[$i],$modifier)) {
5942             $char[$i] = $char;
5943             }
5944              
5945 139 50       340 # /i modifier
5946 20         31 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
5947             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
5948             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
5949 20         38 }
5950             else {
5951             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
5952             }
5953             }
5954              
5955 0 50       0 # \u \l \U \L \F \Q \E
5956 1         4 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5957             if ($right_e < $left_e) {
5958             $char[$i] = '\\' . $char[$i];
5959             }
5960 0         0 }
5961 0         0 elsif ($char[$i] eq '\u') {
5962             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
5963             $left_e++;
5964 0         0 }
5965 0         0 elsif ($char[$i] eq '\l') {
5966             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
5967             $left_e++;
5968 0         0 }
5969 1         3 elsif ($char[$i] eq '\U') {
5970             $char[$i] = '@{[Ekoi8r::uc qq<';
5971             $left_e++;
5972 1         3 }
5973 1         2 elsif ($char[$i] eq '\L') {
5974             $char[$i] = '@{[Ekoi8r::lc qq<';
5975             $left_e++;
5976 1         3 }
5977 18         36 elsif ($char[$i] eq '\F') {
5978             $char[$i] = '@{[Ekoi8r::fc qq<';
5979             $left_e++;
5980 18         44 }
5981 1         2 elsif ($char[$i] eq '\Q') {
5982             $char[$i] = '@{[CORE::quotemeta qq<';
5983             $left_e++;
5984 1 50       3 }
5985 21         50 elsif ($char[$i] eq '\E') {
5986 21         37 if ($right_e < $left_e) {
5987             $char[$i] = '>]}';
5988             $right_e++;
5989 21         49 }
5990             else {
5991             $char[$i] = '';
5992             }
5993 0         0 }
5994 0 0       0 elsif ($char[$i] eq '\Q') {
5995 0         0 while (1) {
5996             if (++$i > $#char) {
5997 0 0       0 last;
5998 0         0 }
5999             if ($char[$i] eq '\E') {
6000             last;
6001             }
6002             }
6003             }
6004             elsif ($char[$i] eq '\E') {
6005             }
6006              
6007 0 0       0 # $0 --> $0
6008 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6009             if ($ignorecase) {
6010             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6011             }
6012 0 0       0 }
6013 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6014             if ($ignorecase) {
6015             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6016             }
6017             }
6018              
6019             # $$ --> $$
6020             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6021             }
6022              
6023             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6024 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6025 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6026 0         0 $char[$i] = e_capture($1);
6027             if ($ignorecase) {
6028             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6029             }
6030 0         0 }
6031 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6032 0         0 $char[$i] = e_capture($1);
6033             if ($ignorecase) {
6034             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6035             }
6036             }
6037              
6038 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6039 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) {
6040 0         0 $char[$i] = e_capture($1.'->'.$2);
6041             if ($ignorecase) {
6042             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6043             }
6044             }
6045              
6046 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6047 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) {
6048 0         0 $char[$i] = e_capture($1.'->'.$2);
6049             if ($ignorecase) {
6050             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6051             }
6052             }
6053              
6054 0         0 # $$foo
6055 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6056 0         0 $char[$i] = e_capture($1);
6057             if ($ignorecase) {
6058             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6059             }
6060             }
6061              
6062 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
6063 8         20 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6064             if ($ignorecase) {
6065             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::PREMATCH())]}';
6066 0         0 }
6067             else {
6068             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
6069             }
6070             }
6071              
6072 8 50       23 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
6073 8         22 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6074             if ($ignorecase) {
6075             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::MATCH())]}';
6076 0         0 }
6077             else {
6078             $char[$i] = '@{[Ekoi8r::MATCH()]}';
6079             }
6080             }
6081              
6082 8 50       34 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
6083 6         15 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6084             if ($ignorecase) {
6085             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::POSTMATCH())]}';
6086 0         0 }
6087             else {
6088             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
6089             }
6090             }
6091              
6092 6 0       20 # ${ foo }
6093 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) {
6094             if ($ignorecase) {
6095             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6096             }
6097             }
6098              
6099 0         0 # ${ ... }
6100 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6101 0         0 $char[$i] = e_capture($1);
6102             if ($ignorecase) {
6103             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6104             }
6105             }
6106              
6107 0         0 # $scalar or @array
6108 21 100       59 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6109 21         125 $char[$i] = e_string($char[$i]);
6110             if ($ignorecase) {
6111             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6112             }
6113             }
6114              
6115 11 100 33     41 # quote character before ? + * {
    50          
6116             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6117             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6118 138         1102 }
6119 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6120 0         0 my $char = $char[$i-1];
6121             if ($char[$i] eq '{') {
6122             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
6123 0         0 }
6124             else {
6125             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
6126             }
6127 0         0 }
6128             else {
6129             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6130             }
6131             }
6132             }
6133 127         518  
6134 642 50       1180 # make regexp string
6135 642 0 0     1347 $modifier =~ tr/i//d;
6136 0         0 if ($left_e > $right_e) {
6137             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6138             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
6139 0         0 }
6140             else {
6141             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6142 0 50 33     0 }
6143 642         3264 }
6144             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6145             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
6146 0         0 }
6147             else {
6148             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6149             }
6150             }
6151              
6152             #
6153             # double quote stuff
6154 642     180 0 5255 #
6155             sub qq_stuff {
6156             my($delimiter,$end_delimiter,$stuff) = @_;
6157 180 100       265  
6158 180         351 # scalar variable or array variable
6159             if ($stuff =~ /\A [\$\@] /oxms) {
6160             return $stuff;
6161             }
6162 100         313  
  80         175  
6163 80         224 # quote by delimiter
6164 80 50       174 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
6165 80 50       128 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6166 80 50       113 next if $char eq $delimiter;
6167 80         122 next if $char eq $end_delimiter;
6168             if (not $octet{$char}) {
6169             return join '', 'qq', $char, $stuff, $char;
6170 80         290 }
6171             }
6172             return join '', 'qq', '<', $stuff, '>';
6173             }
6174              
6175             #
6176             # escape regexp (m'', qr'', and m''b, qr''b)
6177 0     10 0 0 #
6178 10   50     45 sub e_qr_q {
6179             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6180 10         46 $modifier ||= '';
6181 10 50       14  
6182 10         17 $modifier =~ tr/p//d;
6183 0         0 if ($modifier =~ /([adlu])/oxms) {
6184 0 0       0 my $line = 0;
6185 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6186 0         0 if ($filename ne __FILE__) {
6187             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6188             last;
6189 0         0 }
6190             }
6191             die qq{Unsupported modifier "$1" used at line $line.\n};
6192 0         0 }
6193              
6194             $slash = 'div';
6195 10 100       17  
    50          
6196 10         22 # literal null string pattern
6197 8         9 if ($string eq '') {
6198 8         11 $modifier =~ tr/bB//d;
6199             $modifier =~ tr/i//d;
6200             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6201             }
6202              
6203 8         38 # with /b /B modifier
6204             elsif ($modifier =~ tr/bB//d) {
6205             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6206             }
6207              
6208 0         0 # without /b /B modifier
6209             else {
6210             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6211             }
6212             }
6213              
6214             #
6215             # escape regexp (m'', qr'')
6216 2     2 0 9 #
6217             sub e_qr_qt {
6218 2 50       7 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6219              
6220             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6221 2         7  
6222             # split regexp
6223             my @char = $string =~ /\G((?>
6224             [^\\\[\$\@\/] |
6225             [\x00-\xFF] |
6226             \[\^ |
6227             \[\: (?>[a-z]+) \:\] |
6228             \[\:\^ (?>[a-z]+) \:\] |
6229             [\$\@\/] |
6230             \\ (?:$q_char) |
6231             (?:$q_char)
6232             ))/oxmsg;
6233 2         64  
6234 2 50 33     10 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
6235             for (my $i=0; $i <= $#char; $i++) {
6236             if (0) {
6237             }
6238 2         31  
6239 0         0 # open character class [...]
6240 0 0       0 elsif ($char[$i] eq '[') {
6241 0         0 my $left = $i;
6242             if ($char[$i+1] eq ']') {
6243 0         0 $i++;
6244 0 0       0 }
6245 0         0 while (1) {
6246             if (++$i > $#char) {
6247 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6248 0         0 }
6249             if ($char[$i] eq ']') {
6250             my $right = $i;
6251 0         0  
6252             # [...]
6253 0         0 splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
6254 0         0  
6255             $i = $left;
6256             last;
6257             }
6258             }
6259             }
6260              
6261 0         0 # open character class [^...]
6262 0 0       0 elsif ($char[$i] eq '[^') {
6263 0         0 my $left = $i;
6264             if ($char[$i+1] eq ']') {
6265 0         0 $i++;
6266 0 0       0 }
6267 0         0 while (1) {
6268             if (++$i > $#char) {
6269 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6270 0         0 }
6271             if ($char[$i] eq ']') {
6272             my $right = $i;
6273 0         0  
6274             # [^...]
6275 0         0 splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6276 0         0  
6277             $i = $left;
6278             last;
6279             }
6280             }
6281             }
6282              
6283 0         0 # escape $ @ / and \
6284             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6285             $char[$i] = '\\' . $char[$i];
6286             }
6287              
6288 0         0 # rewrite character class or escape character
6289             elsif (my $char = character_class($char[$i],$modifier)) {
6290             $char[$i] = $char;
6291             }
6292              
6293 0 0       0 # /i modifier
6294 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
6295             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
6296             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
6297 0         0 }
6298             else {
6299             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
6300             }
6301             }
6302              
6303 0 0       0 # quote character before ? + * {
6304             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6305             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6306 0         0 }
6307             else {
6308             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6309             }
6310             }
6311 0         0 }
6312 2         5  
6313             $delimiter = '/';
6314 2         5 $end_delimiter = '/';
6315 2         3  
6316             $modifier =~ tr/i//d;
6317             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6318             }
6319              
6320             #
6321             # escape regexp (m''b, qr''b)
6322 2     0 0 17 #
6323             sub e_qr_qb {
6324             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6325 0         0  
6326             # split regexp
6327             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6328 0         0  
6329 0 0       0 # unescape character
    0          
6330             for (my $i=0; $i <= $#char; $i++) {
6331             if (0) {
6332             }
6333 0         0  
6334             # remain \\
6335             elsif ($char[$i] eq '\\\\') {
6336             }
6337              
6338 0         0 # escape $ @ / and \
6339             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6340             $char[$i] = '\\' . $char[$i];
6341             }
6342 0         0 }
6343 0         0  
6344 0         0 $delimiter = '/';
6345             $end_delimiter = '/';
6346             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6347             }
6348              
6349             #
6350             # escape regexp (s/here//)
6351 0     76 0 0 #
6352 76   100     232 sub e_s1 {
6353             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6354 76         300 $modifier ||= '';
6355 76 50       132  
6356 76         209 $modifier =~ tr/p//d;
6357 0         0 if ($modifier =~ /([adlu])/oxms) {
6358 0 0       0 my $line = 0;
6359 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6360 0         0 if ($filename ne __FILE__) {
6361             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6362             last;
6363 0         0 }
6364             }
6365             die qq{Unsupported modifier "$1" used at line $line.\n};
6366 0         0 }
6367              
6368             $slash = 'div';
6369 76 100       151  
    50          
6370 76         288 # literal null string pattern
6371 8         10 if ($string eq '') {
6372 8         10 $modifier =~ tr/bB//d;
6373             $modifier =~ tr/i//d;
6374             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6375             }
6376              
6377             # /b /B modifier
6378             elsif ($modifier =~ tr/bB//d) {
6379 8 0       48  
6380 0         0 # choice again delimiter
6381 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
6382 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
6383 0         0 my %octet = map {$_ => 1} @char;
6384 0         0 if (not $octet{')'}) {
6385             $delimiter = '(';
6386             $end_delimiter = ')';
6387 0         0 }
6388 0         0 elsif (not $octet{'}'}) {
6389             $delimiter = '{';
6390             $end_delimiter = '}';
6391 0         0 }
6392 0         0 elsif (not $octet{']'}) {
6393             $delimiter = '[';
6394             $end_delimiter = ']';
6395 0         0 }
6396 0         0 elsif (not $octet{'>'}) {
6397             $delimiter = '<';
6398             $end_delimiter = '>';
6399 0         0 }
6400 0 0       0 else {
6401 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6402 0         0 if (not $octet{$char}) {
6403 0         0 $delimiter = $char;
6404             $end_delimiter = $char;
6405             last;
6406             }
6407             }
6408             }
6409 0         0 }
6410 0         0  
6411             my $prematch = '';
6412             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6413 0 100       0 }
6414 68         208  
6415             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6416             my $metachar = qr/[\@\\|[\]{^]/oxms;
6417 68         655  
6418             # split regexp
6419             my @char = $string =~ /\G((?>
6420             [^\\\$\@\[\(] |
6421             \\ (?>[1-9][0-9]*) |
6422             \\g (?>\s*) (?>[1-9][0-9]*) |
6423             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6424             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6425             \\x (?>[0-9A-Fa-f]{1,2}) |
6426             \\ (?>[0-7]{2,3}) |
6427             \\c [\x40-\x5F] |
6428             \\x\{ (?>[0-9A-Fa-f]+) \} |
6429             \\o\{ (?>[0-7]+) \} |
6430             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6431             \\ $q_char |
6432             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6433             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6434             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6435             [\$\@] $qq_variable |
6436             \$ (?>\s* [0-9]+) |
6437             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6438             \$ \$ (?![\w\{]) |
6439             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6440             \[\^ |
6441             \[\: (?>[a-z]+) :\] |
6442             \[\:\^ (?>[a-z]+) :\] |
6443             \(\? |
6444             $q_char
6445             ))/oxmsg;
6446 68 50       16021  
6447 68         483 # choice again delimiter
  0         0  
6448 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
6449 0         0 my %octet = map {$_ => 1} @char;
6450 0         0 if (not $octet{')'}) {
6451             $delimiter = '(';
6452             $end_delimiter = ')';
6453 0         0 }
6454 0         0 elsif (not $octet{'}'}) {
6455             $delimiter = '{';
6456             $end_delimiter = '}';
6457 0         0 }
6458 0         0 elsif (not $octet{']'}) {
6459             $delimiter = '[';
6460             $end_delimiter = ']';
6461 0         0 }
6462 0         0 elsif (not $octet{'>'}) {
6463             $delimiter = '<';
6464             $end_delimiter = '>';
6465 0         0 }
6466 0 0       0 else {
6467 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6468 0         0 if (not $octet{$char}) {
6469 0         0 $delimiter = $char;
6470             $end_delimiter = $char;
6471             last;
6472             }
6473             }
6474             }
6475             }
6476 0         0  
  68         134  
6477             # count '('
6478 253         427 my $parens = grep { $_ eq '(' } @char;
6479 68         97  
6480 68         90 my $left_e = 0;
6481             my $right_e = 0;
6482             for (my $i=0; $i <= $#char; $i++) {
6483 68 50 33     190  
    50 33        
    100          
    100          
    50          
    50          
6484 195         1092 # "\L\u" --> "\u\L"
6485             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6486             @char[$i,$i+1] = @char[$i+1,$i];
6487             }
6488              
6489 0         0 # "\U\l" --> "\l\U"
6490             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6491             @char[$i,$i+1] = @char[$i+1,$i];
6492             }
6493              
6494 0         0 # octal escape sequence
6495             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6496             $char[$i] = Ekoi8r::octchr($1);
6497             }
6498              
6499 1         3 # hexadecimal escape sequence
6500             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6501             $char[$i] = Ekoi8r::hexchr($1);
6502             }
6503              
6504             # \b{...} --> b\{...}
6505             # \B{...} --> B\{...}
6506             # \N{CHARNAME} --> N\{CHARNAME}
6507             # \p{PROPERTY} --> p\{PROPERTY}
6508 1         4 # \P{PROPERTY} --> P\{PROPERTY}
6509             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6510             $char[$i] = $1 . '\\' . $2;
6511             }
6512              
6513 0         0 # \p, \P, \X --> p, P, X
6514             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6515             $char[$i] = $1;
6516 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          
6517              
6518             if (0) {
6519             }
6520 195         792  
6521 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6522 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6523             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)) {
6524             $char[$i] .= join '', splice @char, $i+1, 3;
6525 0         0 }
6526             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)) {
6527             $char[$i] .= join '', splice @char, $i+1, 2;
6528 0         0 }
6529             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)) {
6530             $char[$i] .= join '', splice @char, $i+1, 1;
6531             }
6532             }
6533              
6534 0         0 # open character class [...]
6535 13 50       19 elsif ($char[$i] eq '[') {
6536 13         44 my $left = $i;
6537             if ($char[$i+1] eq ']') {
6538 0         0 $i++;
6539 13 50       16 }
6540 58         85 while (1) {
6541             if (++$i > $#char) {
6542 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6543 58         131 }
6544             if ($char[$i] eq ']') {
6545             my $right = $i;
6546 13 50       19  
6547 13         77 # [...]
  0         0  
6548             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6549             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6550 0         0 }
6551             else {
6552             splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
6553 13         57 }
6554 13         26  
6555             $i = $left;
6556             last;
6557             }
6558             }
6559             }
6560              
6561 13         35 # open character class [^...]
6562 0 0       0 elsif ($char[$i] eq '[^') {
6563 0         0 my $left = $i;
6564             if ($char[$i+1] eq ']') {
6565 0         0 $i++;
6566 0 0       0 }
6567 0         0 while (1) {
6568             if (++$i > $#char) {
6569 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6570 0         0 }
6571             if ($char[$i] eq ']') {
6572             my $right = $i;
6573 0 0       0  
6574 0         0 # [^...]
  0         0  
6575             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6576             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6577 0         0 }
6578             else {
6579             splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6580 0         0 }
6581 0         0  
6582             $i = $left;
6583             last;
6584             }
6585             }
6586             }
6587              
6588 0         0 # rewrite character class or escape character
6589             elsif (my $char = character_class($char[$i],$modifier)) {
6590             $char[$i] = $char;
6591             }
6592              
6593 7 50       17 # /i modifier
6594 3         5 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
6595             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
6596             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
6597 3         5 }
6598             else {
6599             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
6600             }
6601             }
6602              
6603 0 0       0 # \u \l \U \L \F \Q \E
6604 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6605             if ($right_e < $left_e) {
6606             $char[$i] = '\\' . $char[$i];
6607             }
6608 0         0 }
6609 0         0 elsif ($char[$i] eq '\u') {
6610             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
6611             $left_e++;
6612 0         0 }
6613 0         0 elsif ($char[$i] eq '\l') {
6614             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
6615             $left_e++;
6616 0         0 }
6617 0         0 elsif ($char[$i] eq '\U') {
6618             $char[$i] = '@{[Ekoi8r::uc qq<';
6619             $left_e++;
6620 0         0 }
6621 0         0 elsif ($char[$i] eq '\L') {
6622             $char[$i] = '@{[Ekoi8r::lc qq<';
6623             $left_e++;
6624 0         0 }
6625 0         0 elsif ($char[$i] eq '\F') {
6626             $char[$i] = '@{[Ekoi8r::fc qq<';
6627             $left_e++;
6628 0         0 }
6629 0         0 elsif ($char[$i] eq '\Q') {
6630             $char[$i] = '@{[CORE::quotemeta qq<';
6631             $left_e++;
6632 0 0       0 }
6633 0         0 elsif ($char[$i] eq '\E') {
6634 0         0 if ($right_e < $left_e) {
6635             $char[$i] = '>]}';
6636             $right_e++;
6637 0         0 }
6638             else {
6639             $char[$i] = '';
6640             }
6641 0         0 }
6642 0 0       0 elsif ($char[$i] eq '\Q') {
6643 0         0 while (1) {
6644             if (++$i > $#char) {
6645 0 0       0 last;
6646 0         0 }
6647             if ($char[$i] eq '\E') {
6648             last;
6649             }
6650             }
6651             }
6652             elsif ($char[$i] eq '\E') {
6653             }
6654              
6655             # \0 --> \0
6656             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6657             }
6658              
6659             # \g{N}, \g{-N}
6660              
6661             # P.108 Using Simple Patterns
6662             # in Chapter 7: In the World of Regular Expressions
6663             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6664              
6665             # P.221 Capturing
6666             # in Chapter 5: Pattern Matching
6667             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6668              
6669             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6670             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6671             }
6672              
6673             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6674             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6675             }
6676              
6677             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6678             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6679             }
6680              
6681             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6682             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6683             }
6684              
6685 0 0       0 # $0 --> $0
6686 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6687             if ($ignorecase) {
6688             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6689             }
6690 0 0       0 }
6691 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6692             if ($ignorecase) {
6693             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6694             }
6695             }
6696              
6697             # $$ --> $$
6698             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6699             }
6700              
6701             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6702 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6703 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6704 0         0 $char[$i] = e_capture($1);
6705             if ($ignorecase) {
6706             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6707             }
6708 0         0 }
6709 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6710 0         0 $char[$i] = e_capture($1);
6711             if ($ignorecase) {
6712             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6713             }
6714             }
6715              
6716 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6717 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) {
6718 0         0 $char[$i] = e_capture($1.'->'.$2);
6719             if ($ignorecase) {
6720             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6721             }
6722             }
6723              
6724 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6725 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) {
6726 0         0 $char[$i] = e_capture($1.'->'.$2);
6727             if ($ignorecase) {
6728             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6729             }
6730             }
6731              
6732 0         0 # $$foo
6733 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6734 0         0 $char[$i] = e_capture($1);
6735             if ($ignorecase) {
6736             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6737             }
6738             }
6739              
6740 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
6741 4         14 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6742             if ($ignorecase) {
6743             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::PREMATCH())]}';
6744 0         0 }
6745             else {
6746             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
6747             }
6748             }
6749              
6750 4 50       15 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
6751 4         13 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6752             if ($ignorecase) {
6753             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::MATCH())]}';
6754 0         0 }
6755             else {
6756             $char[$i] = '@{[Ekoi8r::MATCH()]}';
6757             }
6758             }
6759              
6760 4 50       16 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
6761 3         10 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6762             if ($ignorecase) {
6763             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::POSTMATCH())]}';
6764 0         0 }
6765             else {
6766             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
6767             }
6768             }
6769              
6770 3 0       12 # ${ foo }
6771 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) {
6772             if ($ignorecase) {
6773             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6774             }
6775             }
6776              
6777 0         0 # ${ ... }
6778 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6779 0         0 $char[$i] = e_capture($1);
6780             if ($ignorecase) {
6781             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6782             }
6783             }
6784              
6785 0         0 # $scalar or @array
6786 4 50       127 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6787 4         22 $char[$i] = e_string($char[$i]);
6788             if ($ignorecase) {
6789             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6790             }
6791             }
6792              
6793 0 50       0 # quote character before ? + * {
6794             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6795             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6796 13         263 }
6797             else {
6798             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6799             }
6800             }
6801             }
6802 13         65  
6803 68         149 # make regexp string
6804 68 50       113 my $prematch = '';
6805 68         167 $modifier =~ tr/i//d;
6806             if ($left_e > $right_e) {
6807 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6808             }
6809             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6810             }
6811              
6812             #
6813             # escape regexp (s'here'' or s'here''b)
6814 68     21 0 721 #
6815 21   100     48 sub e_s1_q {
6816             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6817 21         69 $modifier ||= '';
6818 21 50       27  
6819 21         174 $modifier =~ tr/p//d;
6820 0         0 if ($modifier =~ /([adlu])/oxms) {
6821 0 0       0 my $line = 0;
6822 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6823 0         0 if ($filename ne __FILE__) {
6824             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6825             last;
6826 0         0 }
6827             }
6828             die qq{Unsupported modifier "$1" used at line $line.\n};
6829 0         0 }
6830              
6831             $slash = 'div';
6832 21 100       38  
    50          
6833 21         61 # literal null string pattern
6834 8         8 if ($string eq '') {
6835 8         9 $modifier =~ tr/bB//d;
6836             $modifier =~ tr/i//d;
6837             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6838             }
6839              
6840 8         46 # with /b /B modifier
6841             elsif ($modifier =~ tr/bB//d) {
6842             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6843             }
6844              
6845 0         0 # without /b /B modifier
6846             else {
6847             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6848             }
6849             }
6850              
6851             #
6852             # escape regexp (s'here'')
6853 13     13 0 33 #
6854             sub e_s1_qt {
6855 13 50       29 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6856              
6857             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6858 13         25  
6859             # split regexp
6860             my @char = $string =~ /\G((?>
6861             [^\\\[\$\@\/] |
6862             [\x00-\xFF] |
6863             \[\^ |
6864             \[\: (?>[a-z]+) \:\] |
6865             \[\:\^ (?>[a-z]+) \:\] |
6866             [\$\@\/] |
6867             \\ (?:$q_char) |
6868             (?:$q_char)
6869             ))/oxmsg;
6870 13         196  
6871 13 50 33     37 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6872             for (my $i=0; $i <= $#char; $i++) {
6873             if (0) {
6874             }
6875 25         108  
6876 0         0 # open character class [...]
6877 0 0       0 elsif ($char[$i] eq '[') {
6878 0         0 my $left = $i;
6879             if ($char[$i+1] eq ']') {
6880 0         0 $i++;
6881 0 0       0 }
6882 0         0 while (1) {
6883             if (++$i > $#char) {
6884 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6885 0         0 }
6886             if ($char[$i] eq ']') {
6887             my $right = $i;
6888 0         0  
6889             # [...]
6890 0         0 splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
6891 0         0  
6892             $i = $left;
6893             last;
6894             }
6895             }
6896             }
6897              
6898 0         0 # open character class [^...]
6899 0 0       0 elsif ($char[$i] eq '[^') {
6900 0         0 my $left = $i;
6901             if ($char[$i+1] eq ']') {
6902 0         0 $i++;
6903 0 0       0 }
6904 0         0 while (1) {
6905             if (++$i > $#char) {
6906 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6907 0         0 }
6908             if ($char[$i] eq ']') {
6909             my $right = $i;
6910 0         0  
6911             # [^...]
6912 0         0 splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6913 0         0  
6914             $i = $left;
6915             last;
6916             }
6917             }
6918             }
6919              
6920 0         0 # escape $ @ / and \
6921             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6922             $char[$i] = '\\' . $char[$i];
6923             }
6924              
6925 0         0 # rewrite character class or escape character
6926             elsif (my $char = character_class($char[$i],$modifier)) {
6927             $char[$i] = $char;
6928             }
6929              
6930 6 0       12 # /i modifier
6931 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
6932             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
6933             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
6934 0         0 }
6935             else {
6936             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
6937             }
6938             }
6939              
6940 0 0       0 # quote character before ? + * {
6941             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6942             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6943 0         0 }
6944             else {
6945             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6946             }
6947             }
6948 0         0 }
6949 13         26  
6950 13         20 $modifier =~ tr/i//d;
6951 13         16 $delimiter = '/';
6952 13         16 $end_delimiter = '/';
6953             my $prematch = '';
6954             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6955             }
6956              
6957             #
6958             # escape regexp (s'here''b)
6959 13     0 0 103 #
6960             sub e_s1_qb {
6961             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6962 0         0  
6963             # split regexp
6964             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6965 0         0  
6966 0 0       0 # unescape character
    0          
6967             for (my $i=0; $i <= $#char; $i++) {
6968             if (0) {
6969             }
6970 0         0  
6971             # remain \\
6972             elsif ($char[$i] eq '\\\\') {
6973             }
6974              
6975 0         0 # escape $ @ / and \
6976             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6977             $char[$i] = '\\' . $char[$i];
6978             }
6979 0         0 }
6980 0         0  
6981 0         0 $delimiter = '/';
6982 0         0 $end_delimiter = '/';
6983             my $prematch = '';
6984             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6985             }
6986              
6987             #
6988             # escape regexp (s''here')
6989 0     16 0 0 #
6990             sub e_s2_q {
6991 16         32 my($ope,$delimiter,$end_delimiter,$string) = @_;
6992              
6993 16         22 $slash = 'div';
6994 16         99  
6995 16 100       43 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
6996             for (my $i=0; $i <= $#char; $i++) {
6997             if (0) {
6998             }
6999 9         28  
7000             # not escape \\
7001             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
7002             }
7003              
7004 0         0 # escape $ @ / and \
7005             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7006             $char[$i] = '\\' . $char[$i];
7007             }
7008 5         14 }
7009              
7010             return join '', $ope, $delimiter, @char, $end_delimiter;
7011             }
7012              
7013             #
7014             # escape regexp (s/here/and here/modifier)
7015 16     97 0 47 #
7016 97   100     724 sub e_sub {
7017             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
7018 97         380 $modifier ||= '';
7019 97 50       174  
7020 97         252 $modifier =~ tr/p//d;
7021 0         0 if ($modifier =~ /([adlu])/oxms) {
7022 0 0       0 my $line = 0;
7023 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7024 0         0 if ($filename ne __FILE__) {
7025             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7026             last;
7027 0         0 }
7028             }
7029             die qq{Unsupported modifier "$1" used at line $line.\n};
7030 0 100       0 }
7031 97         241  
7032 36         44 if ($variable eq '') {
7033             $variable = '$_';
7034             $bind_operator = ' =~ ';
7035 36         43 }
7036              
7037             $slash = 'div';
7038              
7039             # P.128 Start of match (or end of previous match): \G
7040             # P.130 Advanced Use of \G with Perl
7041             # in Chapter 3: Overview of Regular Expression Features and Flavors
7042             # P.312 Iterative Matching: Scalar Context, with /g
7043             # in Chapter 7: Perl
7044             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
7045              
7046             # P.181 Where You Left Off: The \G Assertion
7047             # in Chapter 5: Pattern Matching
7048             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7049              
7050             # P.220 Where You Left Off: The \G Assertion
7051             # in Chapter 5: Pattern Matching
7052 97         145 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7053 97         176  
7054             my $e_modifier = $modifier =~ tr/e//d;
7055 97         146 my $r_modifier = $modifier =~ tr/r//d;
7056 97 50       139  
7057 97         242 my $my = '';
7058 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
7059 0         0 $my = $variable;
7060             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
7061             $variable =~ s/ = .+ \z//oxms;
7062 0         0 }
7063 97         222  
7064             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
7065             $variable_basename =~ s/ \s+ \z//oxms;
7066 97         163  
7067 97 100       149 # quote replacement string
7068 97         229 my $e_replacement = '';
7069 17         33 if ($e_modifier >= 1) {
7070             $e_replacement = e_qq('', '', '', $replacement);
7071             $e_modifier--;
7072 17 100       24 }
7073 80         184 else {
7074             if ($delimiter2 eq "'") {
7075             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
7076 16         32 }
7077             else {
7078             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
7079             }
7080 64         150 }
7081              
7082             my $sub = '';
7083 97 100       182  
7084 97 100       222 # with /r
7085             if ($r_modifier) {
7086             if (0) {
7087             }
7088 8         18  
7089 0 50       0 # s///gr without multibyte anchoring
7090             elsif ($modifier =~ /g/oxms) {
7091             $sub = sprintf(
7092             # 1 2 3 4 5
7093             q,
7094              
7095             $variable, # 1
7096             ($delimiter1 eq "'") ? # 2
7097             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7098             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7099             $s_matched, # 3
7100             $e_replacement, # 4
7101             '$Ekoi8r::re_r=CORE::eval $Ekoi8r::re_r; ' x $e_modifier, # 5
7102             );
7103             }
7104              
7105             # s///r
7106 4         13 else {
7107              
7108 4 50       5 my $prematch = q{$`};
7109              
7110             $sub = sprintf(
7111             # 1 2 3 4 5 6 7
7112             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Ekoi8r::re_r=%s; %s"%s$Ekoi8r::re_r$'" } : %s>,
7113              
7114             $variable, # 1
7115             ($delimiter1 eq "'") ? # 2
7116             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7117             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7118             $s_matched, # 3
7119             $e_replacement, # 4
7120             '$Ekoi8r::re_r=CORE::eval $Ekoi8r::re_r; ' x $e_modifier, # 5
7121             $prematch, # 6
7122             $variable, # 7
7123             );
7124             }
7125 4 50       11  
7126 8         23 # $var !~ s///r doesn't make sense
7127             if ($bind_operator =~ / !~ /oxms) {
7128             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
7129             }
7130             }
7131              
7132 0 100       0 # without /r
7133             else {
7134             if (0) {
7135             }
7136 89         195  
7137 0 100       0 # s///g without multibyte anchoring
    100          
7138             elsif ($modifier =~ /g/oxms) {
7139             $sub = sprintf(
7140             # 1 2 3 4 5 6 7 8
7141             q,
7142              
7143             $variable, # 1
7144             ($delimiter1 eq "'") ? # 2
7145             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7146             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7147             $s_matched, # 3
7148             $e_replacement, # 4
7149             '$Ekoi8r::re_r=CORE::eval $Ekoi8r::re_r; ' x $e_modifier, # 5
7150             $variable, # 6
7151             $variable, # 7
7152             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
7153             );
7154             }
7155              
7156             # s///
7157 22         76 else {
7158              
7159 67 100       107 my $prematch = q{$`};
    100          
7160              
7161             $sub = sprintf(
7162              
7163             ($bind_operator =~ / =~ /oxms) ?
7164              
7165             # 1 2 3 4 5 6 7 8
7166             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Ekoi8r::re_r=%s; %s%s="%s$Ekoi8r::re_r$'"; 1 } : undef> :
7167              
7168             # 1 2 3 4 5 6 7 8
7169             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Ekoi8r::re_r=%s; %s%s="%s$Ekoi8r::re_r$'"; undef }>,
7170              
7171             $variable, # 1
7172             $bind_operator, # 2
7173             ($delimiter1 eq "'") ? # 3
7174             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7175             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7176             $s_matched, # 4
7177             $e_replacement, # 5
7178             '$Ekoi8r::re_r=CORE::eval $Ekoi8r::re_r; ' x $e_modifier, # 6
7179             $variable, # 7
7180             $prematch, # 8
7181             );
7182             }
7183             }
7184 67 50       349  
7185 97         268 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
7186             if ($my ne '') {
7187             $sub = "($my, $sub)[1]";
7188             }
7189 0         0  
7190 97         152 # clear s/// variable
7191             $sub_variable = '';
7192 97         125 $bind_operator = '';
7193              
7194             return $sub;
7195             }
7196              
7197             #
7198             # escape regexp of split qr//
7199 97     74 0 740 #
7200 74   100     347 sub e_split {
7201             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7202 74         444 $modifier ||= '';
7203 74 50       122  
7204 74         199 $modifier =~ tr/p//d;
7205 0         0 if ($modifier =~ /([adlu])/oxms) {
7206 0 0       0 my $line = 0;
7207 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7208 0         0 if ($filename ne __FILE__) {
7209             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7210             last;
7211 0         0 }
7212             }
7213             die qq{Unsupported modifier "$1" used at line $line.\n};
7214 0         0 }
7215              
7216             $slash = 'div';
7217 74 50       144  
7218 74         177 # /b /B modifier
7219             if ($modifier =~ tr/bB//d) {
7220             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7221 0 50       0 }
7222 74         191  
7223             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7224             my $metachar = qr/[\@\\|[\]{^]/oxms;
7225 74         294  
7226             # split regexp
7227             my @char = $string =~ /\G((?>
7228             [^\\\$\@\[\(] |
7229             \\x (?>[0-9A-Fa-f]{1,2}) |
7230             \\ (?>[0-7]{2,3}) |
7231             \\c [\x40-\x5F] |
7232             \\x\{ (?>[0-9A-Fa-f]+) \} |
7233             \\o\{ (?>[0-7]+) \} |
7234             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7235             \\ $q_char |
7236             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7237             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7238             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7239             [\$\@] $qq_variable |
7240             \$ (?>\s* [0-9]+) |
7241             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7242             \$ \$ (?![\w\{]) |
7243             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7244             \[\^ |
7245             \[\: (?>[a-z]+) :\] |
7246             \[\:\^ (?>[a-z]+) :\] |
7247             \(\? |
7248             $q_char
7249 74         8852 ))/oxmsg;
7250 74         250  
7251 74         114 my $left_e = 0;
7252             my $right_e = 0;
7253             for (my $i=0; $i <= $#char; $i++) {
7254 74 50 33     351  
    50 33        
    100          
    100          
    50          
    50          
7255 249         1348 # "\L\u" --> "\u\L"
7256             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7257             @char[$i,$i+1] = @char[$i+1,$i];
7258             }
7259              
7260 0         0 # "\U\l" --> "\l\U"
7261             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7262             @char[$i,$i+1] = @char[$i+1,$i];
7263             }
7264              
7265 0         0 # octal escape sequence
7266             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7267             $char[$i] = Ekoi8r::octchr($1);
7268             }
7269              
7270 1         3 # hexadecimal escape sequence
7271             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7272             $char[$i] = Ekoi8r::hexchr($1);
7273             }
7274              
7275             # \b{...} --> b\{...}
7276             # \B{...} --> B\{...}
7277             # \N{CHARNAME} --> N\{CHARNAME}
7278             # \p{PROPERTY} --> p\{PROPERTY}
7279 1         4 # \P{PROPERTY} --> P\{PROPERTY}
7280             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7281             $char[$i] = $1 . '\\' . $2;
7282             }
7283              
7284 0         0 # \p, \P, \X --> p, P, X
7285             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7286             $char[$i] = $1;
7287 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          
7288              
7289             if (0) {
7290             }
7291 249         818  
7292 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
7293 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7294             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)) {
7295             $char[$i] .= join '', splice @char, $i+1, 3;
7296 0         0 }
7297             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)) {
7298             $char[$i] .= join '', splice @char, $i+1, 2;
7299 0         0 }
7300             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)) {
7301             $char[$i] .= join '', splice @char, $i+1, 1;
7302             }
7303             }
7304              
7305 0         0 # open character class [...]
7306 3 50       6 elsif ($char[$i] eq '[') {
7307 3         9 my $left = $i;
7308             if ($char[$i+1] eq ']') {
7309 0         0 $i++;
7310 3 50       4 }
7311 7         13 while (1) {
7312             if (++$i > $#char) {
7313 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7314 7         12 }
7315             if ($char[$i] eq ']') {
7316             my $right = $i;
7317 3 50       4  
7318 3         13 # [...]
  0         0  
7319             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7320             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7321 0         0 }
7322             else {
7323             splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
7324 3         13 }
7325 3         5  
7326             $i = $left;
7327             last;
7328             }
7329             }
7330             }
7331              
7332 3         9 # open character class [^...]
7333 0 0       0 elsif ($char[$i] eq '[^') {
7334 0         0 my $left = $i;
7335             if ($char[$i+1] eq ']') {
7336 0         0 $i++;
7337 0 0       0 }
7338 0         0 while (1) {
7339             if (++$i > $#char) {
7340 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7341 0         0 }
7342             if ($char[$i] eq ']') {
7343             my $right = $i;
7344 0 0       0  
7345 0         0 # [^...]
  0         0  
7346             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7347             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7348 0         0 }
7349             else {
7350             splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7351 0         0 }
7352 0         0  
7353             $i = $left;
7354             last;
7355             }
7356             }
7357             }
7358              
7359 0         0 # rewrite character class or escape character
7360             elsif (my $char = character_class($char[$i],$modifier)) {
7361             $char[$i] = $char;
7362             }
7363              
7364             # P.794 29.2.161. split
7365             # in Chapter 29: Functions
7366             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7367              
7368             # P.951 split
7369             # in Chapter 27: Functions
7370             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7371              
7372             # said "The //m modifier is assumed when you split on the pattern /^/",
7373             # but perl5.008 is not so. Therefore, this software adds //m.
7374             # (and so on)
7375              
7376 1         3 # split(m/^/) --> split(m/^/m)
7377             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7378             $modifier .= 'm';
7379             }
7380              
7381 7 0       22 # /i modifier
7382 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
7383             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
7384             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
7385 0         0 }
7386             else {
7387             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
7388             }
7389             }
7390              
7391 0 0       0 # \u \l \U \L \F \Q \E
7392 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7393             if ($right_e < $left_e) {
7394             $char[$i] = '\\' . $char[$i];
7395             }
7396 0         0 }
7397 0         0 elsif ($char[$i] eq '\u') {
7398             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
7399             $left_e++;
7400 0         0 }
7401 0         0 elsif ($char[$i] eq '\l') {
7402             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
7403             $left_e++;
7404 0         0 }
7405 0         0 elsif ($char[$i] eq '\U') {
7406             $char[$i] = '@{[Ekoi8r::uc qq<';
7407             $left_e++;
7408 0         0 }
7409 0         0 elsif ($char[$i] eq '\L') {
7410             $char[$i] = '@{[Ekoi8r::lc qq<';
7411             $left_e++;
7412 0         0 }
7413 0         0 elsif ($char[$i] eq '\F') {
7414             $char[$i] = '@{[Ekoi8r::fc qq<';
7415             $left_e++;
7416 0         0 }
7417 0         0 elsif ($char[$i] eq '\Q') {
7418             $char[$i] = '@{[CORE::quotemeta qq<';
7419             $left_e++;
7420 0 0       0 }
7421 0         0 elsif ($char[$i] eq '\E') {
7422 0         0 if ($right_e < $left_e) {
7423             $char[$i] = '>]}';
7424             $right_e++;
7425 0         0 }
7426             else {
7427             $char[$i] = '';
7428             }
7429 0         0 }
7430 0 0       0 elsif ($char[$i] eq '\Q') {
7431 0         0 while (1) {
7432             if (++$i > $#char) {
7433 0 0       0 last;
7434 0         0 }
7435             if ($char[$i] eq '\E') {
7436             last;
7437             }
7438             }
7439             }
7440             elsif ($char[$i] eq '\E') {
7441             }
7442              
7443 0 0       0 # $0 --> $0
7444 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7445             if ($ignorecase) {
7446             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7447             }
7448 0 0       0 }
7449 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7450             if ($ignorecase) {
7451             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7452             }
7453             }
7454              
7455             # $$ --> $$
7456             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7457             }
7458              
7459             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7460 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7461 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7462 0         0 $char[$i] = e_capture($1);
7463             if ($ignorecase) {
7464             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7465             }
7466 0         0 }
7467 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7468 0         0 $char[$i] = e_capture($1);
7469             if ($ignorecase) {
7470             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7471             }
7472             }
7473              
7474 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7475 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) {
7476 0         0 $char[$i] = e_capture($1.'->'.$2);
7477             if ($ignorecase) {
7478             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7479             }
7480             }
7481              
7482 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7483 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) {
7484 0         0 $char[$i] = e_capture($1.'->'.$2);
7485             if ($ignorecase) {
7486             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7487             }
7488             }
7489              
7490 0         0 # $$foo
7491 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7492 0         0 $char[$i] = e_capture($1);
7493             if ($ignorecase) {
7494             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7495             }
7496             }
7497              
7498 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
7499 12         30 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7500             if ($ignorecase) {
7501             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::PREMATCH())]}';
7502 0         0 }
7503             else {
7504             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
7505             }
7506             }
7507              
7508 12 50       48 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
7509 12         32 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7510             if ($ignorecase) {
7511             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::MATCH())]}';
7512 0         0 }
7513             else {
7514             $char[$i] = '@{[Ekoi8r::MATCH()]}';
7515             }
7516             }
7517              
7518 12 50       52 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
7519 9         27 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7520             if ($ignorecase) {
7521             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::POSTMATCH())]}';
7522 0         0 }
7523             else {
7524             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
7525             }
7526             }
7527              
7528 9 0       39 # ${ foo }
7529 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) {
7530             if ($ignorecase) {
7531             $char[$i] = '@{[Ekoi8r::ignorecase(' . $1 . ')]}';
7532             }
7533             }
7534              
7535 0         0 # ${ ... }
7536 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7537 0         0 $char[$i] = e_capture($1);
7538             if ($ignorecase) {
7539             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7540             }
7541             }
7542              
7543 0         0 # $scalar or @array
7544 3 50       10 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7545 3         13 $char[$i] = e_string($char[$i]);
7546             if ($ignorecase) {
7547             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7548             }
7549             }
7550              
7551 0 50       0 # quote character before ? + * {
7552             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7553             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7554 1         7 }
7555             else {
7556             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7557             }
7558             }
7559             }
7560 0         0  
7561 74 50       231 # make regexp string
7562 74         149 $modifier =~ tr/i//d;
7563             if ($left_e > $right_e) {
7564 0         0 return join '', 'Ekoi8r::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7565             }
7566             return join '', 'Ekoi8r::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7567             }
7568              
7569             #
7570             # escape regexp of split qr''
7571 74     0 0 713 #
7572 0   0       sub e_split_q {
7573             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7574 0           $modifier ||= '';
7575 0 0          
7576 0           $modifier =~ tr/p//d;
7577 0           if ($modifier =~ /([adlu])/oxms) {
7578 0 0         my $line = 0;
7579 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7580 0           if ($filename ne __FILE__) {
7581             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7582             last;
7583 0           }
7584             }
7585             die qq{Unsupported modifier "$1" used at line $line.\n};
7586 0           }
7587              
7588             $slash = 'div';
7589 0 0          
7590 0           # /b /B modifier
7591             if ($modifier =~ tr/bB//d) {
7592             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7593 0 0         }
7594              
7595             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7596 0            
7597             # split regexp
7598             my @char = $string =~ /\G((?>
7599             [^\\\[] |
7600             [\x00-\xFF] |
7601             \[\^ |
7602             \[\: (?>[a-z]+) \:\] |
7603             \[\:\^ (?>[a-z]+) \:\] |
7604             \\ (?:$q_char) |
7605             (?:$q_char)
7606             ))/oxmsg;
7607 0            
7608 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7609             for (my $i=0; $i <= $#char; $i++) {
7610             if (0) {
7611             }
7612 0            
7613 0           # open character class [...]
7614 0 0         elsif ($char[$i] eq '[') {
7615 0           my $left = $i;
7616             if ($char[$i+1] eq ']') {
7617 0           $i++;
7618 0 0         }
7619 0           while (1) {
7620             if (++$i > $#char) {
7621 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7622 0           }
7623             if ($char[$i] eq ']') {
7624             my $right = $i;
7625 0            
7626             # [...]
7627 0           splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
7628 0            
7629             $i = $left;
7630             last;
7631             }
7632             }
7633             }
7634              
7635 0           # open character class [^...]
7636 0 0         elsif ($char[$i] eq '[^') {
7637 0           my $left = $i;
7638             if ($char[$i+1] eq ']') {
7639 0           $i++;
7640 0 0         }
7641 0           while (1) {
7642             if (++$i > $#char) {
7643 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7644 0           }
7645             if ($char[$i] eq ']') {
7646             my $right = $i;
7647 0            
7648             # [^...]
7649 0           splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7650 0            
7651             $i = $left;
7652             last;
7653             }
7654             }
7655             }
7656              
7657 0           # rewrite character class or escape character
7658             elsif (my $char = character_class($char[$i],$modifier)) {
7659             $char[$i] = $char;
7660             }
7661              
7662 0           # split(m/^/) --> split(m/^/m)
7663             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7664             $modifier .= 'm';
7665             }
7666              
7667 0 0         # /i modifier
7668 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
7669             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
7670             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
7671 0           }
7672             else {
7673             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
7674             }
7675             }
7676              
7677 0 0         # quote character before ? + * {
7678             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7679             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7680 0           }
7681             else {
7682             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7683             }
7684             }
7685 0           }
7686 0            
7687             $modifier =~ tr/i//d;
7688             return join '', 'Ekoi8r::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7689             }
7690              
7691             #
7692             # instead of Carp::carp
7693 0     0 0   #
7694 0           sub carp {
7695             my($package,$filename,$line) = caller(1);
7696             print STDERR "@_ at $filename line $line.\n";
7697             }
7698              
7699             #
7700             # instead of Carp::croak
7701 0     0 0   #
7702 0           sub croak {
7703 0           my($package,$filename,$line) = caller(1);
7704             print STDERR "@_ at $filename line $line.\n";
7705             die "\n";
7706             }
7707              
7708             #
7709             # instead of Carp::cluck
7710 0     0 0   #
7711 0           sub cluck {
7712 0           my $i = 0;
7713 0           my @cluck = ();
7714 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7715             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7716 0           $i++;
7717 0           }
7718 0           print STDERR CORE::reverse @cluck;
7719             print STDERR "\n";
7720             print STDERR @_;
7721             }
7722              
7723             #
7724             # instead of Carp::confess
7725 0     0 0   #
7726 0           sub confess {
7727 0           my $i = 0;
7728 0           my @confess = ();
7729 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7730             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7731 0           $i++;
7732 0           }
7733 0           print STDERR CORE::reverse @confess;
7734 0           print STDERR "\n";
7735             print STDERR @_;
7736             die "\n";
7737             }
7738              
7739             1;
7740              
7741             __END__