File Coverage

blib/lib/Ekoi8u.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 Ekoi8u;
2 204     204   1456 use strict;
  204         327  
  204         5807  
3             ######################################################################
4             #
5             # Ekoi8u - Run-time routines for KOI8U.pm
6             #
7             # http://search.cpan.org/dist/Char-KOI8U/
8             #
9             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
10             ######################################################################
11              
12 204     204   5111 use 5.00503; # Galapagos Consensus 1998 for primetools
  204         8551  
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   2500 use vars qw($VERSION);
  204         367  
  204         35448  
28             $VERSION = '1.13';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 204 50   204   2911 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 204         605 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 204         49899 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   14165 CORE::eval q{
  204     204   2739  
  204     66   810  
  204         24256  
  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       81066 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 (Ekoi8u::index($name,'::') >= 0) {
78 0         0 return $name;
79             }
80             elsif (Ekoi8u::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   1486 no strict qw(refs);
  204         485  
  204         16310  
113 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
114             }
115             else {
116 204     204   5386 no strict qw(refs);
  204     0   502  
  204         39958  
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   1473 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  204         475  
  204         14050  
149 204     204   1383 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  204         390  
  204         411053  
150              
151             #
152             # KOI8-U character range per length
153             #
154             my %range_tr = ();
155              
156             #
157             # KOI8-U 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 Ekoi8u \z/oxms) {
173             %range_tr = (
174             1 => [ [0x00..0xFF],
175             ],
176             );
177              
178             %lc = (%lc,
179             "\xB3" => "\xA3", # CYRILLIC LETTER IO
180             "\xB4" => "\xA4", # CYRILLIC LETTER UKRAINIAN IE
181             "\xB6" => "\xA6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
182             "\xB7" => "\xA7", # CYRILLIC LETTER YI (UKRAINIAN)
183             "\xBD" => "\xAD", # CYRILLIC LETTER GHE WITH UPTURN
184             "\xE0" => "\xC0", # CYRILLIC LETTER YU
185             "\xE1" => "\xC1", # CYRILLIC LETTER A
186             "\xE2" => "\xC2", # CYRILLIC LETTER BE
187             "\xE3" => "\xC3", # CYRILLIC LETTER TSE
188             "\xE4" => "\xC4", # CYRILLIC LETTER DE
189             "\xE5" => "\xC5", # CYRILLIC LETTER IE
190             "\xE6" => "\xC6", # CYRILLIC LETTER EF
191             "\xE7" => "\xC7", # CYRILLIC LETTER GHE
192             "\xE8" => "\xC8", # CYRILLIC LETTER KHA
193             "\xE9" => "\xC9", # CYRILLIC LETTER I
194             "\xEA" => "\xCA", # CYRILLIC LETTER SHORT I
195             "\xEB" => "\xCB", # CYRILLIC LETTER KA
196             "\xEC" => "\xCC", # CYRILLIC LETTER EL
197             "\xED" => "\xCD", # CYRILLIC LETTER EM
198             "\xEE" => "\xCE", # CYRILLIC LETTER EN
199             "\xEF" => "\xCF", # CYRILLIC LETTER O
200             "\xF0" => "\xD0", # CYRILLIC LETTER PE
201             "\xF1" => "\xD1", # CYRILLIC LETTER YA
202             "\xF2" => "\xD2", # CYRILLIC LETTER ER
203             "\xF3" => "\xD3", # CYRILLIC LETTER ES
204             "\xF4" => "\xD4", # CYRILLIC LETTER TE
205             "\xF5" => "\xD5", # CYRILLIC LETTER U
206             "\xF6" => "\xD6", # CYRILLIC LETTER ZHE
207             "\xF7" => "\xD7", # CYRILLIC LETTER VE
208             "\xF8" => "\xD8", # CYRILLIC LETTER SOFT SIGN
209             "\xF9" => "\xD9", # CYRILLIC LETTER YERU
210             "\xFA" => "\xDA", # CYRILLIC LETTER ZE
211             "\xFB" => "\xDB", # CYRILLIC LETTER SHA
212             "\xFC" => "\xDC", # CYRILLIC LETTER E
213             "\xFD" => "\xDD", # CYRILLIC LETTER SHCHA
214             "\xFE" => "\xDE", # CYRILLIC LETTER CHE
215             "\xFF" => "\xDF", # CYRILLIC LETTER HARD SIGN
216             );
217              
218             %uc = (%uc,
219             "\xA3" => "\xB3", # CYRILLIC LETTER IO
220             "\xA4" => "\xB4", # CYRILLIC LETTER UKRAINIAN IE
221             "\xA6" => "\xB6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
222             "\xA7" => "\xB7", # CYRILLIC LETTER YI (UKRAINIAN)
223             "\xAD" => "\xBD", # CYRILLIC LETTER GHE WITH UPTURN
224             "\xC0" => "\xE0", # CYRILLIC LETTER YU
225             "\xC1" => "\xE1", # CYRILLIC LETTER A
226             "\xC2" => "\xE2", # CYRILLIC LETTER BE
227             "\xC3" => "\xE3", # CYRILLIC LETTER TSE
228             "\xC4" => "\xE4", # CYRILLIC LETTER DE
229             "\xC5" => "\xE5", # CYRILLIC LETTER IE
230             "\xC6" => "\xE6", # CYRILLIC LETTER EF
231             "\xC7" => "\xE7", # CYRILLIC LETTER GHE
232             "\xC8" => "\xE8", # CYRILLIC LETTER KHA
233             "\xC9" => "\xE9", # CYRILLIC LETTER I
234             "\xCA" => "\xEA", # CYRILLIC LETTER SHORT I
235             "\xCB" => "\xEB", # CYRILLIC LETTER KA
236             "\xCC" => "\xEC", # CYRILLIC LETTER EL
237             "\xCD" => "\xED", # CYRILLIC LETTER EM
238             "\xCE" => "\xEE", # CYRILLIC LETTER EN
239             "\xCF" => "\xEF", # CYRILLIC LETTER O
240             "\xD0" => "\xF0", # CYRILLIC LETTER PE
241             "\xD1" => "\xF1", # CYRILLIC LETTER YA
242             "\xD2" => "\xF2", # CYRILLIC LETTER ER
243             "\xD3" => "\xF3", # CYRILLIC LETTER ES
244             "\xD4" => "\xF4", # CYRILLIC LETTER TE
245             "\xD5" => "\xF5", # CYRILLIC LETTER U
246             "\xD6" => "\xF6", # CYRILLIC LETTER ZHE
247             "\xD7" => "\xF7", # CYRILLIC LETTER VE
248             "\xD8" => "\xF8", # CYRILLIC LETTER SOFT SIGN
249             "\xD9" => "\xF9", # CYRILLIC LETTER YERU
250             "\xDA" => "\xFA", # CYRILLIC LETTER ZE
251             "\xDB" => "\xFB", # CYRILLIC LETTER SHA
252             "\xDC" => "\xFC", # CYRILLIC LETTER E
253             "\xDD" => "\xFD", # CYRILLIC LETTER SHCHA
254             "\xDE" => "\xFE", # CYRILLIC LETTER CHE
255             "\xDF" => "\xFF", # CYRILLIC LETTER HARD SIGN
256             );
257              
258             %fc = (%fc,
259             "\xB3" => "\xA3", # CYRILLIC CAPITAL LETTER IO --> CYRILLIC SMALL LETTER IO
260             "\xB4" => "\xA4", # CYRILLIC CAPITAL LETTER UKRAINIAN IE --> CYRILLIC SMALL LETTER UKRAINIAN IE
261             "\xB6" => "\xA6", # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I --> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
262             "\xB7" => "\xA7", # CYRILLIC CAPITAL LETTER YI --> CYRILLIC SMALL LETTER YI
263             "\xBD" => "\xAD", # CYRILLIC CAPITAL LETTER GHE WITH UPTURN --> CYRILLIC SMALL LETTER GHE WITH UPTURN
264             "\xE0" => "\xC0", # CYRILLIC CAPITAL LETTER YU --> CYRILLIC SMALL LETTER YU
265             "\xE1" => "\xC1", # CYRILLIC CAPITAL LETTER A --> CYRILLIC SMALL LETTER A
266             "\xE2" => "\xC2", # CYRILLIC CAPITAL LETTER BE --> CYRILLIC SMALL LETTER BE
267             "\xE3" => "\xC3", # CYRILLIC CAPITAL LETTER TSE --> CYRILLIC SMALL LETTER TSE
268             "\xE4" => "\xC4", # CYRILLIC CAPITAL LETTER DE --> CYRILLIC SMALL LETTER DE
269             "\xE5" => "\xC5", # CYRILLIC CAPITAL LETTER IE --> CYRILLIC SMALL LETTER IE
270             "\xE6" => "\xC6", # CYRILLIC CAPITAL LETTER EF --> CYRILLIC SMALL LETTER EF
271             "\xE7" => "\xC7", # CYRILLIC CAPITAL LETTER GHE --> CYRILLIC SMALL LETTER GHE
272             "\xE8" => "\xC8", # CYRILLIC CAPITAL LETTER HA --> CYRILLIC SMALL LETTER HA
273             "\xE9" => "\xC9", # CYRILLIC CAPITAL LETTER I --> CYRILLIC SMALL LETTER I
274             "\xEA" => "\xCA", # CYRILLIC CAPITAL LETTER SHORT I --> CYRILLIC SMALL LETTER SHORT I
275             "\xEB" => "\xCB", # CYRILLIC CAPITAL LETTER KA --> CYRILLIC SMALL LETTER KA
276             "\xEC" => "\xCC", # CYRILLIC CAPITAL LETTER EL --> CYRILLIC SMALL LETTER EL
277             "\xED" => "\xCD", # CYRILLIC CAPITAL LETTER EM --> CYRILLIC SMALL LETTER EM
278             "\xEE" => "\xCE", # CYRILLIC CAPITAL LETTER EN --> CYRILLIC SMALL LETTER EN
279             "\xEF" => "\xCF", # CYRILLIC CAPITAL LETTER O --> CYRILLIC SMALL LETTER O
280             "\xF0" => "\xD0", # CYRILLIC CAPITAL LETTER PE --> CYRILLIC SMALL LETTER PE
281             "\xF1" => "\xD1", # CYRILLIC CAPITAL LETTER YA --> CYRILLIC SMALL LETTER YA
282             "\xF2" => "\xD2", # CYRILLIC CAPITAL LETTER ER --> CYRILLIC SMALL LETTER ER
283             "\xF3" => "\xD3", # CYRILLIC CAPITAL LETTER ES --> CYRILLIC SMALL LETTER ES
284             "\xF4" => "\xD4", # CYRILLIC CAPITAL LETTER TE --> CYRILLIC SMALL LETTER TE
285             "\xF5" => "\xD5", # CYRILLIC CAPITAL LETTER U --> CYRILLIC SMALL LETTER U
286             "\xF6" => "\xD6", # CYRILLIC CAPITAL LETTER ZHE --> CYRILLIC SMALL LETTER ZHE
287             "\xF7" => "\xD7", # CYRILLIC CAPITAL LETTER VE --> CYRILLIC SMALL LETTER VE
288             "\xF8" => "\xD8", # CYRILLIC CAPITAL LETTER SOFT SIGN --> CYRILLIC SMALL LETTER SOFT SIGN
289             "\xF9" => "\xD9", # CYRILLIC CAPITAL LETTER YERU --> CYRILLIC SMALL LETTER YERU
290             "\xFA" => "\xDA", # CYRILLIC CAPITAL LETTER ZE --> CYRILLIC SMALL LETTER ZE
291             "\xFB" => "\xDB", # CYRILLIC CAPITAL LETTER SHA --> CYRILLIC SMALL LETTER SHA
292             "\xFC" => "\xDC", # CYRILLIC CAPITAL LETTER E --> CYRILLIC SMALL LETTER E
293             "\xFD" => "\xDD", # CYRILLIC CAPITAL LETTER SHCHA --> CYRILLIC SMALL LETTER SHCHA
294             "\xFE" => "\xDE", # CYRILLIC CAPITAL LETTER CHE --> CYRILLIC SMALL LETTER CHE
295             "\xFF" => "\xDF", # CYRILLIC CAPITAL LETTER HARD SIGN --> CYRILLIC SMALL LETTER HARD SIGN
296             );
297             }
298              
299             else {
300             croak "Don't know my package name '@{[__PACKAGE__]}'";
301             }
302              
303             #
304             # @ARGV wildcard globbing
305             #
306             sub import {
307              
308 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
309 0         0 my @argv = ();
310 0         0 for (@ARGV) {
311              
312             # has space
313 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
314 0 0       0 if (my @glob = Ekoi8u::glob(qq{"$_"})) {
315 0         0 push @argv, @glob;
316             }
317             else {
318 0         0 push @argv, $_;
319             }
320             }
321              
322             # has wildcard metachar
323             elsif (/\A (?:$q_char)*? [*?] /oxms) {
324 0 0       0 if (my @glob = Ekoi8u::glob($_)) {
325 0         0 push @argv, @glob;
326             }
327             else {
328 0         0 push @argv, $_;
329             }
330             }
331              
332             # no wildcard globbing
333             else {
334 0         0 push @argv, $_;
335             }
336             }
337 0         0 @ARGV = @argv;
338             }
339              
340 0         0 *Char::ord = \&KOI8U::ord;
341 0         0 *Char::ord_ = \&KOI8U::ord_;
342 0         0 *Char::reverse = \&KOI8U::reverse;
343 0         0 *Char::getc = \&KOI8U::getc;
344 0         0 *Char::length = \&KOI8U::length;
345 0         0 *Char::substr = \&KOI8U::substr;
346 0         0 *Char::index = \&KOI8U::index;
347 0         0 *Char::rindex = \&KOI8U::rindex;
348 0         0 *Char::eval = \&KOI8U::eval;
349 0         0 *Char::escape = \&KOI8U::escape;
350 0         0 *Char::escape_token = \&KOI8U::escape_token;
351 0         0 *Char::escape_script = \&KOI8U::escape_script;
352             }
353              
354             # P.230 Care with Prototypes
355             # in Chapter 6: Subroutines
356             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
357             #
358             # If you aren't careful, you can get yourself into trouble with prototypes.
359             # But if you are careful, you can do a lot of neat things with them. This is
360             # all very powerful, of course, and should only be used in moderation to make
361             # the world a better place.
362              
363             # P.332 Care with Prototypes
364             # in Chapter 7: Subroutines
365             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
366             #
367             # If you aren't careful, you can get yourself into trouble with prototypes.
368             # But if you are careful, you can do a lot of neat things with them. This is
369             # all very powerful, of course, and should only be used in moderation to make
370             # the world a better place.
371              
372             #
373             # Prototypes of subroutines
374             #
375       0     sub unimport {}
376             sub Ekoi8u::split(;$$$);
377             sub Ekoi8u::tr($$$$;$);
378             sub Ekoi8u::chop(@);
379             sub Ekoi8u::index($$;$);
380             sub Ekoi8u::rindex($$;$);
381             sub Ekoi8u::lcfirst(@);
382             sub Ekoi8u::lcfirst_();
383             sub Ekoi8u::lc(@);
384             sub Ekoi8u::lc_();
385             sub Ekoi8u::ucfirst(@);
386             sub Ekoi8u::ucfirst_();
387             sub Ekoi8u::uc(@);
388             sub Ekoi8u::uc_();
389             sub Ekoi8u::fc(@);
390             sub Ekoi8u::fc_();
391             sub Ekoi8u::ignorecase;
392             sub Ekoi8u::classic_character_class;
393             sub Ekoi8u::capture;
394             sub Ekoi8u::chr(;$);
395             sub Ekoi8u::chr_();
396             sub Ekoi8u::glob($);
397             sub Ekoi8u::glob_();
398              
399             sub KOI8U::ord(;$);
400             sub KOI8U::ord_();
401             sub KOI8U::reverse(@);
402             sub KOI8U::getc(;*@);
403             sub KOI8U::length(;$);
404             sub KOI8U::substr($$;$$);
405             sub KOI8U::index($$;$);
406             sub KOI8U::rindex($$;$);
407             sub KOI8U::escape(;$);
408              
409             #
410             # Regexp work
411             #
412 204         35909 use vars qw(
413             $re_a
414             $re_t
415             $re_n
416             $re_r
417 204     204   1742 );
  204         515  
418              
419             #
420             # Character class
421             #
422 204         2232518 use vars qw(
423             $dot
424             $dot_s
425             $eD
426             $eS
427             $eW
428             $eH
429             $eV
430             $eR
431             $eN
432             $not_alnum
433             $not_alpha
434             $not_ascii
435             $not_blank
436             $not_cntrl
437             $not_digit
438             $not_graph
439             $not_lower
440             $not_lower_i
441             $not_print
442             $not_punct
443             $not_space
444             $not_upper
445             $not_upper_i
446             $not_word
447             $not_xdigit
448             $eb
449             $eB
450 204     204   1455 );
  204         493  
451              
452             ${Ekoi8u::dot} = qr{(?>[^\x0A])};
453             ${Ekoi8u::dot_s} = qr{(?>[\x00-\xFF])};
454             ${Ekoi8u::eD} = qr{(?>[^0-9])};
455              
456             # Vertical tabs are now whitespace
457             # \s in a regex now matches a vertical tab in all circumstances.
458             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
459             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
460             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
461             ${Ekoi8u::eS} = qr{(?>[^\s])};
462              
463             ${Ekoi8u::eW} = qr{(?>[^0-9A-Z_a-z])};
464             ${Ekoi8u::eH} = qr{(?>[^\x09\x20])};
465             ${Ekoi8u::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
466             ${Ekoi8u::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
467             ${Ekoi8u::eN} = qr{(?>[^\x0A])};
468             ${Ekoi8u::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
469             ${Ekoi8u::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
470             ${Ekoi8u::not_ascii} = qr{(?>[^\x00-\x7F])};
471             ${Ekoi8u::not_blank} = qr{(?>[^\x09\x20])};
472             ${Ekoi8u::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
473             ${Ekoi8u::not_digit} = qr{(?>[^\x30-\x39])};
474             ${Ekoi8u::not_graph} = qr{(?>[^\x21-\x7F])};
475             ${Ekoi8u::not_lower} = qr{(?>[^\x61-\x7A])};
476             ${Ekoi8u::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
477             # ${Ekoi8u::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
478             ${Ekoi8u::not_print} = qr{(?>[^\x20-\x7F])};
479             ${Ekoi8u::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
480             ${Ekoi8u::not_space} = qr{(?>[^\s\x0B])};
481             ${Ekoi8u::not_upper} = qr{(?>[^\x41-\x5A])};
482             ${Ekoi8u::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
483             # ${Ekoi8u::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
484             ${Ekoi8u::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
485             ${Ekoi8u::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
486             ${Ekoi8u::eb} = qr{(?:\A(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[0-9A-Z_a-z])|(?<=[0-9A-Z_a-z])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]|\z))};
487             ${Ekoi8u::eB} = qr{(?:(?<=[0-9A-Z_a-z])(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]))};
488              
489             # avoid: Name "Ekoi8u::foo" used only once: possible typo at here.
490             ${Ekoi8u::dot} = ${Ekoi8u::dot};
491             ${Ekoi8u::dot_s} = ${Ekoi8u::dot_s};
492             ${Ekoi8u::eD} = ${Ekoi8u::eD};
493             ${Ekoi8u::eS} = ${Ekoi8u::eS};
494             ${Ekoi8u::eW} = ${Ekoi8u::eW};
495             ${Ekoi8u::eH} = ${Ekoi8u::eH};
496             ${Ekoi8u::eV} = ${Ekoi8u::eV};
497             ${Ekoi8u::eR} = ${Ekoi8u::eR};
498             ${Ekoi8u::eN} = ${Ekoi8u::eN};
499             ${Ekoi8u::not_alnum} = ${Ekoi8u::not_alnum};
500             ${Ekoi8u::not_alpha} = ${Ekoi8u::not_alpha};
501             ${Ekoi8u::not_ascii} = ${Ekoi8u::not_ascii};
502             ${Ekoi8u::not_blank} = ${Ekoi8u::not_blank};
503             ${Ekoi8u::not_cntrl} = ${Ekoi8u::not_cntrl};
504             ${Ekoi8u::not_digit} = ${Ekoi8u::not_digit};
505             ${Ekoi8u::not_graph} = ${Ekoi8u::not_graph};
506             ${Ekoi8u::not_lower} = ${Ekoi8u::not_lower};
507             ${Ekoi8u::not_lower_i} = ${Ekoi8u::not_lower_i};
508             ${Ekoi8u::not_print} = ${Ekoi8u::not_print};
509             ${Ekoi8u::not_punct} = ${Ekoi8u::not_punct};
510             ${Ekoi8u::not_space} = ${Ekoi8u::not_space};
511             ${Ekoi8u::not_upper} = ${Ekoi8u::not_upper};
512             ${Ekoi8u::not_upper_i} = ${Ekoi8u::not_upper_i};
513             ${Ekoi8u::not_word} = ${Ekoi8u::not_word};
514             ${Ekoi8u::not_xdigit} = ${Ekoi8u::not_xdigit};
515             ${Ekoi8u::eb} = ${Ekoi8u::eb};
516             ${Ekoi8u::eB} = ${Ekoi8u::eB};
517              
518             #
519             # KOI8-U split
520             #
521             sub Ekoi8u::split(;$$$) {
522              
523             # P.794 29.2.161. split
524             # in Chapter 29: Functions
525             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
526              
527             # P.951 split
528             # in Chapter 27: Functions
529             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
530              
531 0     0 0 0 my $pattern = $_[0];
532 0         0 my $string = $_[1];
533 0         0 my $limit = $_[2];
534              
535             # if $pattern is also omitted or is the literal space, " "
536 0 0       0 if (not defined $pattern) {
537 0         0 $pattern = ' ';
538             }
539              
540             # if $string is omitted, the function splits the $_ string
541 0 0       0 if (not defined $string) {
542 0 0       0 if (defined $_) {
543 0         0 $string = $_;
544             }
545             else {
546 0         0 $string = '';
547             }
548             }
549              
550 0         0 my @split = ();
551              
552             # when string is empty
553 0 0       0 if ($string eq '') {
    0          
554              
555             # resulting list value in list context
556 0 0       0 if (wantarray) {
557 0         0 return @split;
558             }
559              
560             # count of substrings in scalar context
561             else {
562 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
563 0         0 @_ = @split;
564 0         0 return scalar @_;
565             }
566             }
567              
568             # split's first argument is more consistently interpreted
569             #
570             # After some changes earlier in v5.17, split's behavior has been simplified:
571             # if the PATTERN argument evaluates to a string containing one space, it is
572             # treated the way that a literal string containing one space once was.
573             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
574              
575             # if $pattern is also omitted or is the literal space, " ", the function splits
576             # on whitespace, /\s+/, after skipping any leading whitespace
577             # (and so on)
578              
579             elsif ($pattern eq ' ') {
580 0 0       0 if (not defined $limit) {
581 0         0 return CORE::split(' ', $string);
582             }
583             else {
584 0         0 return CORE::split(' ', $string, $limit);
585             }
586             }
587              
588             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
589 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
590              
591             # a pattern capable of matching either the null string or something longer than the
592             # null string will split the value of $string into separate characters wherever it
593             # matches the null string between characters
594             # (and so on)
595              
596 0 0       0 if ('' =~ / \A $pattern \z /xms) {
597 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
598 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
599              
600             # P.1024 Appendix W.10 Multibyte Processing
601             # of ISBN 1-56592-224-7 CJKV Information Processing
602             # (and so on)
603              
604             # the //m modifier is assumed when you split on the pattern /^/
605             # (and so on)
606              
607             # V
608 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
609              
610             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
611             # is included in the resulting list, interspersed with the fields that are ordinarily returned
612             # (and so on)
613              
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             else {
622 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
623              
624             # V
625 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
626 0         0 local $@;
627 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
628 0         0 push @split, CORE::eval('$' . $digit);
629             }
630             }
631             }
632             }
633              
634             elsif ($limit > 0) {
635 0 0       0 if ('' =~ / \A $pattern \z /xms) {
636 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
637 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
638              
639             # V
640 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
641 0         0 local $@;
642 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
643 0         0 push @split, CORE::eval('$' . $digit);
644             }
645             }
646             }
647             }
648             else {
649 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
650 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
651              
652             # V
653 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
654 0         0 local $@;
655 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
656 0         0 push @split, CORE::eval('$' . $digit);
657             }
658             }
659             }
660             }
661             }
662              
663 0 0       0 if (CORE::length($string) > 0) {
664 0         0 push @split, $string;
665             }
666              
667             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
668 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
669 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
670 0         0 pop @split;
671             }
672             }
673              
674             # resulting list value in list context
675 0 0       0 if (wantarray) {
676 0         0 return @split;
677             }
678              
679             # count of substrings in scalar context
680             else {
681 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
682 0         0 @_ = @split;
683 0         0 return scalar @_;
684             }
685             }
686              
687             #
688             # get last subexpression offsets
689             #
690             sub _last_subexpression_offsets {
691 0     0   0 my $pattern = $_[0];
692              
693             # remove comment
694 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
695              
696 0         0 my $modifier = '';
697 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
698 0         0 $modifier = $1;
699 0         0 $modifier =~ s/-[A-Za-z]*//;
700             }
701              
702             # with /x modifier
703 0         0 my @char = ();
704 0 0       0 if ($modifier =~ /x/oxms) {
705 0         0 @char = $pattern =~ /\G((?>
706             [^\\\#\[\(] |
707             \\ $q_char |
708             \# (?>[^\n]*) $ |
709             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
710             \(\? |
711             $q_char
712             ))/oxmsg;
713             }
714              
715             # without /x modifier
716             else {
717 0         0 @char = $pattern =~ /\G((?>
718             [^\\\[\(] |
719             \\ $q_char |
720             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
721             \(\? |
722             $q_char
723             ))/oxmsg;
724             }
725              
726 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
727             }
728              
729             #
730             # KOI8-U transliteration (tr///)
731             #
732             sub Ekoi8u::tr($$$$;$) {
733              
734 0     0 0 0 my $bind_operator = $_[1];
735 0         0 my $searchlist = $_[2];
736 0         0 my $replacementlist = $_[3];
737 0   0     0 my $modifier = $_[4] || '';
738              
739 0 0       0 if ($modifier =~ /r/oxms) {
740 0 0       0 if ($bind_operator =~ / !~ /oxms) {
741 0         0 croak "Using !~ with tr///r doesn't make sense";
742             }
743             }
744              
745 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
746 0         0 my @searchlist = _charlist_tr($searchlist);
747 0         0 my @replacementlist = _charlist_tr($replacementlist);
748              
749 0         0 my %tr = ();
750 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
751 0 0       0 if (not exists $tr{$searchlist[$i]}) {
752 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
753 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
754             }
755             elsif ($modifier =~ /d/oxms) {
756 0         0 $tr{$searchlist[$i]} = '';
757             }
758             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
759 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
760             }
761             else {
762 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
763             }
764             }
765             }
766              
767 0         0 my $tr = 0;
768 0         0 my $replaced = '';
769 0 0       0 if ($modifier =~ /c/oxms) {
770 0         0 while (defined(my $char = shift @char)) {
771 0 0       0 if (not exists $tr{$char}) {
772 0 0       0 if (defined $replacementlist[0]) {
773 0         0 $replaced .= $replacementlist[0];
774             }
775 0         0 $tr++;
776 0 0       0 if ($modifier =~ /s/oxms) {
777 0   0     0 while (@char and (not exists $tr{$char[0]})) {
778 0         0 shift @char;
779 0         0 $tr++;
780             }
781             }
782             }
783             else {
784 0         0 $replaced .= $char;
785             }
786             }
787             }
788             else {
789 0         0 while (defined(my $char = shift @char)) {
790 0 0       0 if (exists $tr{$char}) {
791 0         0 $replaced .= $tr{$char};
792 0         0 $tr++;
793 0 0       0 if ($modifier =~ /s/oxms) {
794 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
795 0         0 shift @char;
796 0         0 $tr++;
797             }
798             }
799             }
800             else {
801 0         0 $replaced .= $char;
802             }
803             }
804             }
805              
806 0 0       0 if ($modifier =~ /r/oxms) {
807 0         0 return $replaced;
808             }
809             else {
810 0         0 $_[0] = $replaced;
811 0 0       0 if ($bind_operator =~ / !~ /oxms) {
812 0         0 return not $tr;
813             }
814             else {
815 0         0 return $tr;
816             }
817             }
818             }
819              
820             #
821             # KOI8-U chop
822             #
823             sub Ekoi8u::chop(@) {
824              
825 0     0 0 0 my $chop;
826 0 0       0 if (@_ == 0) {
827 0         0 my @char = /\G (?>$q_char) /oxmsg;
828 0         0 $chop = pop @char;
829 0         0 $_ = join '', @char;
830             }
831             else {
832 0         0 for (@_) {
833 0         0 my @char = /\G (?>$q_char) /oxmsg;
834 0         0 $chop = pop @char;
835 0         0 $_ = join '', @char;
836             }
837             }
838 0         0 return $chop;
839             }
840              
841             #
842             # KOI8-U index by octet
843             #
844             sub Ekoi8u::index($$;$) {
845              
846 0     0 1 0 my($str,$substr,$position) = @_;
847 0   0     0 $position ||= 0;
848 0         0 my $pos = 0;
849              
850 0         0 while ($pos < CORE::length($str)) {
851 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
852 0 0       0 if ($pos >= $position) {
853 0         0 return $pos;
854             }
855             }
856 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
857 0         0 $pos += CORE::length($1);
858             }
859             else {
860 0         0 $pos += 1;
861             }
862             }
863 0         0 return -1;
864             }
865              
866             #
867             # KOI8-U reverse index
868             #
869             sub Ekoi8u::rindex($$;$) {
870              
871 0     0 0 0 my($str,$substr,$position) = @_;
872 0   0     0 $position ||= CORE::length($str) - 1;
873 0         0 my $pos = 0;
874 0         0 my $rindex = -1;
875              
876 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
877 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
878 0         0 $rindex = $pos;
879             }
880 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
881 0         0 $pos += CORE::length($1);
882             }
883             else {
884 0         0 $pos += 1;
885             }
886             }
887 0         0 return $rindex;
888             }
889              
890             #
891             # KOI8-U lower case first with parameter
892             #
893             sub Ekoi8u::lcfirst(@) {
894 0 0   0 0 0 if (@_) {
895 0         0 my $s = shift @_;
896 0 0 0     0 if (@_ and wantarray) {
897 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
898             }
899             else {
900 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
901             }
902             }
903             else {
904 0         0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
905             }
906             }
907              
908             #
909             # KOI8-U lower case first without parameter
910             #
911             sub Ekoi8u::lcfirst_() {
912 0     0 0 0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
913             }
914              
915             #
916             # KOI8-U lower case with parameter
917             #
918             sub Ekoi8u::lc(@) {
919 0 0   0 0 0 if (@_) {
920 0         0 my $s = shift @_;
921 0 0 0     0 if (@_ and wantarray) {
922 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
923             }
924             else {
925 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
926             }
927             }
928             else {
929 0         0 return Ekoi8u::lc_();
930             }
931             }
932              
933             #
934             # KOI8-U lower case without parameter
935             #
936             sub Ekoi8u::lc_() {
937 0     0 0 0 my $s = $_;
938 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
939             }
940              
941             #
942             # KOI8-U upper case first with parameter
943             #
944             sub Ekoi8u::ucfirst(@) {
945 0 0   0 0 0 if (@_) {
946 0         0 my $s = shift @_;
947 0 0 0     0 if (@_ and wantarray) {
948 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
949             }
950             else {
951 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
952             }
953             }
954             else {
955 0         0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
956             }
957             }
958              
959             #
960             # KOI8-U upper case first without parameter
961             #
962             sub Ekoi8u::ucfirst_() {
963 0     0 0 0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
964             }
965              
966             #
967             # KOI8-U upper case with parameter
968             #
969             sub Ekoi8u::uc(@) {
970 0 50   174 0 0 if (@_) {
971 174         278 my $s = shift @_;
972 174 50 33     308 if (@_ and wantarray) {
973 174 0       317 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
974             }
975             else {
976 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         628  
977             }
978             }
979             else {
980 174         646 return Ekoi8u::uc_();
981             }
982             }
983              
984             #
985             # KOI8-U upper case without parameter
986             #
987             sub Ekoi8u::uc_() {
988 0     0 0 0 my $s = $_;
989 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
990             }
991              
992             #
993             # KOI8-U fold case with parameter
994             #
995             sub Ekoi8u::fc(@) {
996 0 50   197 0 0 if (@_) {
997 197         281 my $s = shift @_;
998 197 50 33     226 if (@_ and wantarray) {
999 197 0       393 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1000             }
1001             else {
1002 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         525  
1003             }
1004             }
1005             else {
1006 197         1191 return Ekoi8u::fc_();
1007             }
1008             }
1009              
1010             #
1011             # KOI8-U fold case without parameter
1012             #
1013             sub Ekoi8u::fc_() {
1014 0     0 0 0 my $s = $_;
1015 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1016             }
1017              
1018             #
1019             # KOI8-U regexp capture
1020             #
1021             {
1022             sub Ekoi8u::capture {
1023 0     0 1 0 return $_[0];
1024             }
1025             }
1026              
1027             #
1028             # KOI8-U regexp ignore case modifier
1029             #
1030             sub Ekoi8u::ignorecase {
1031              
1032 0     0 0 0 my @string = @_;
1033 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1034              
1035             # ignore case of $scalar or @array
1036 0         0 for my $string (@string) {
1037              
1038             # split regexp
1039 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1040              
1041             # unescape character
1042 0         0 for (my $i=0; $i <= $#char; $i++) {
1043 0 0       0 next if not defined $char[$i];
1044              
1045             # open character class [...]
1046 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1047 0         0 my $left = $i;
1048              
1049             # [] make die "unmatched [] in regexp ...\n"
1050              
1051 0 0       0 if ($char[$i+1] eq ']') {
1052 0         0 $i++;
1053             }
1054              
1055 0         0 while (1) {
1056 0 0       0 if (++$i > $#char) {
1057 0         0 croak "Unmatched [] in regexp";
1058             }
1059 0 0       0 if ($char[$i] eq ']') {
1060 0         0 my $right = $i;
1061 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1062              
1063             # escape character
1064 0         0 for my $char (@charlist) {
1065 0 0       0 if (0) {
1066             }
1067              
1068 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1069 0         0 $char = '\\' . $char;
1070             }
1071             }
1072              
1073             # [...]
1074 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1075              
1076 0         0 $i = $left;
1077 0         0 last;
1078             }
1079             }
1080             }
1081              
1082             # open character class [^...]
1083             elsif ($char[$i] eq '[^') {
1084 0         0 my $left = $i;
1085              
1086             # [^] make die "unmatched [] in regexp ...\n"
1087              
1088 0 0       0 if ($char[$i+1] eq ']') {
1089 0         0 $i++;
1090             }
1091              
1092 0         0 while (1) {
1093 0 0       0 if (++$i > $#char) {
1094 0         0 croak "Unmatched [] in regexp";
1095             }
1096 0 0       0 if ($char[$i] eq ']') {
1097 0         0 my $right = $i;
1098 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1099              
1100             # escape character
1101 0         0 for my $char (@charlist) {
1102 0 0       0 if (0) {
1103             }
1104              
1105 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1106 0         0 $char = '\\' . $char;
1107             }
1108             }
1109              
1110             # [^...]
1111 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1112              
1113 0         0 $i = $left;
1114 0         0 last;
1115             }
1116             }
1117             }
1118              
1119             # rewrite classic character class or escape character
1120             elsif (my $char = classic_character_class($char[$i])) {
1121 0         0 $char[$i] = $char;
1122             }
1123              
1124             # with /i modifier
1125             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1126 0         0 my $uc = Ekoi8u::uc($char[$i]);
1127 0         0 my $fc = Ekoi8u::fc($char[$i]);
1128 0 0       0 if ($uc ne $fc) {
1129 0 0       0 if (CORE::length($fc) == 1) {
1130 0         0 $char[$i] = '[' . $uc . $fc . ']';
1131             }
1132             else {
1133 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1134             }
1135             }
1136             }
1137             }
1138              
1139             # characterize
1140 0         0 for (my $i=0; $i <= $#char; $i++) {
1141 0 0       0 next if not defined $char[$i];
1142              
1143 0 0       0 if (0) {
1144             }
1145              
1146             # quote character before ? + * {
1147 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1148 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1149 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1150             }
1151             }
1152             }
1153              
1154 0         0 $string = join '', @char;
1155             }
1156              
1157             # make regexp string
1158 0         0 return @string;
1159             }
1160              
1161             #
1162             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1163             #
1164             sub Ekoi8u::classic_character_class {
1165 0     1867 0 0 my($char) = @_;
1166              
1167             return {
1168             '\D' => '${Ekoi8u::eD}',
1169             '\S' => '${Ekoi8u::eS}',
1170             '\W' => '${Ekoi8u::eW}',
1171             '\d' => '[0-9]',
1172              
1173             # Before Perl 5.6, \s only matched the five whitespace characters
1174             # tab, newline, form-feed, carriage return, and the space character
1175             # itself, which, taken together, is the character class [\t\n\f\r ].
1176              
1177             # Vertical tabs are now whitespace
1178             # \s in a regex now matches a vertical tab in all circumstances.
1179             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1180             # \t \n \v \f \r space
1181             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1182             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1183             '\s' => '\s',
1184              
1185             '\w' => '[0-9A-Z_a-z]',
1186             '\C' => '[\x00-\xFF]',
1187             '\X' => 'X',
1188              
1189             # \h \v \H \V
1190              
1191             # P.114 Character Class Shortcuts
1192             # in Chapter 7: In the World of Regular Expressions
1193             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1194              
1195             # P.357 13.2.3 Whitespace
1196             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1197             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1198             #
1199             # 0x00009 CHARACTER TABULATION h s
1200             # 0x0000a LINE FEED (LF) vs
1201             # 0x0000b LINE TABULATION v
1202             # 0x0000c FORM FEED (FF) vs
1203             # 0x0000d CARRIAGE RETURN (CR) vs
1204             # 0x00020 SPACE h s
1205              
1206             # P.196 Table 5-9. Alphanumeric regex metasymbols
1207             # in Chapter 5. Pattern Matching
1208             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1209              
1210             # (and so on)
1211              
1212             '\H' => '${Ekoi8u::eH}',
1213             '\V' => '${Ekoi8u::eV}',
1214             '\h' => '[\x09\x20]',
1215             '\v' => '[\x0A\x0B\x0C\x0D]',
1216             '\R' => '${Ekoi8u::eR}',
1217              
1218             # \N
1219             #
1220             # http://perldoc.perl.org/perlre.html
1221             # Character Classes and other Special Escapes
1222             # Any character but \n (experimental). Not affected by /s modifier
1223              
1224             '\N' => '${Ekoi8u::eN}',
1225              
1226             # \b \B
1227              
1228             # P.180 Boundaries: The \b and \B Assertions
1229             # in Chapter 5: Pattern Matching
1230             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1231              
1232             # P.219 Boundaries: The \b and \B Assertions
1233             # in Chapter 5: Pattern Matching
1234             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1235              
1236             # \b really means (?:(?<=\w)(?!\w)|(?
1237             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1238             '\b' => '${Ekoi8u::eb}',
1239              
1240             # \B really means (?:(?<=\w)(?=\w)|(?
1241             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1242             '\B' => '${Ekoi8u::eB}',
1243              
1244 1867   100     2591 }->{$char} || '';
1245             }
1246              
1247             #
1248             # prepare KOI8-U characters per length
1249             #
1250              
1251             # 1 octet characters
1252             my @chars1 = ();
1253             sub chars1 {
1254 1867 0   0 0 70900 if (@chars1) {
1255 0         0 return @chars1;
1256             }
1257 0 0       0 if (exists $range_tr{1}) {
1258 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1259 0         0 while (my @range = splice(@ranges,0,1)) {
1260 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1261 0         0 push @chars1, pack 'C', $oct0;
1262             }
1263             }
1264             }
1265 0         0 return @chars1;
1266             }
1267              
1268             # 2 octets characters
1269             my @chars2 = ();
1270             sub chars2 {
1271 0 0   0 0 0 if (@chars2) {
1272 0         0 return @chars2;
1273             }
1274 0 0       0 if (exists $range_tr{2}) {
1275 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1276 0         0 while (my @range = splice(@ranges,0,2)) {
1277 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1278 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1279 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1280             }
1281             }
1282             }
1283             }
1284 0         0 return @chars2;
1285             }
1286              
1287             # 3 octets characters
1288             my @chars3 = ();
1289             sub chars3 {
1290 0 0   0 0 0 if (@chars3) {
1291 0         0 return @chars3;
1292             }
1293 0 0       0 if (exists $range_tr{3}) {
1294 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1295 0         0 while (my @range = splice(@ranges,0,3)) {
1296 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1297 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1298 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1299 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1300             }
1301             }
1302             }
1303             }
1304             }
1305 0         0 return @chars3;
1306             }
1307              
1308             # 4 octets characters
1309             my @chars4 = ();
1310             sub chars4 {
1311 0 0   0 0 0 if (@chars4) {
1312 0         0 return @chars4;
1313             }
1314 0 0       0 if (exists $range_tr{4}) {
1315 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1316 0         0 while (my @range = splice(@ranges,0,4)) {
1317 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1318 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1319 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1320 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1321 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1322             }
1323             }
1324             }
1325             }
1326             }
1327             }
1328 0         0 return @chars4;
1329             }
1330              
1331             #
1332             # KOI8-U open character list for tr
1333             #
1334             sub _charlist_tr {
1335              
1336 0     0   0 local $_ = shift @_;
1337              
1338             # unescape character
1339 0         0 my @char = ();
1340 0         0 while (not /\G \z/oxmsgc) {
1341 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1342 0         0 push @char, '\-';
1343             }
1344             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1345 0         0 push @char, CORE::chr(oct $1);
1346             }
1347             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1348 0         0 push @char, CORE::chr(hex $1);
1349             }
1350             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1351 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1352             }
1353             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1354             push @char, {
1355             '\0' => "\0",
1356             '\n' => "\n",
1357             '\r' => "\r",
1358             '\t' => "\t",
1359             '\f' => "\f",
1360             '\b' => "\x08", # \b means backspace in character class
1361             '\a' => "\a",
1362             '\e' => "\e",
1363 0         0 }->{$1};
1364             }
1365             elsif (/\G \\ ($q_char) /oxmsgc) {
1366 0         0 push @char, $1;
1367             }
1368             elsif (/\G ($q_char) /oxmsgc) {
1369 0         0 push @char, $1;
1370             }
1371             }
1372              
1373             # join separated multiple-octet
1374 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1375              
1376             # unescape '-'
1377 0         0 my @i = ();
1378 0         0 for my $i (0 .. $#char) {
1379 0 0       0 if ($char[$i] eq '\-') {
    0          
1380 0         0 $char[$i] = '-';
1381             }
1382             elsif ($char[$i] eq '-') {
1383 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1384 0         0 push @i, $i;
1385             }
1386             }
1387             }
1388              
1389             # open character list (reverse for splice)
1390 0         0 for my $i (CORE::reverse @i) {
1391 0         0 my @range = ();
1392              
1393             # range error
1394 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1395 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1396             }
1397              
1398             # range of multiple-octet code
1399 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1400 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1401 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1402             }
1403             elsif (CORE::length($char[$i+1]) == 2) {
1404 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1405 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1406             }
1407             elsif (CORE::length($char[$i+1]) == 3) {
1408 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1409 0         0 push @range, chars2();
1410 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1411             }
1412             elsif (CORE::length($char[$i+1]) == 4) {
1413 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1414 0         0 push @range, chars2();
1415 0         0 push @range, chars3();
1416 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1417             }
1418             else {
1419 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1420             }
1421             }
1422             elsif (CORE::length($char[$i-1]) == 2) {
1423 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1424 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1425             }
1426             elsif (CORE::length($char[$i+1]) == 3) {
1427 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1428 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1429             }
1430             elsif (CORE::length($char[$i+1]) == 4) {
1431 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1432 0         0 push @range, chars3();
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]) == 3) {
1440 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1441 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1442             }
1443             elsif (CORE::length($char[$i+1]) == 4) {
1444 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1445 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
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             elsif (CORE::length($char[$i-1]) == 4) {
1452 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1453 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1454             }
1455             else {
1456 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1457             }
1458             }
1459             else {
1460 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1461             }
1462              
1463 0         0 splice @char, $i-1, 3, @range;
1464             }
1465              
1466 0         0 return @char;
1467             }
1468              
1469             #
1470             # KOI8-U open character class
1471             #
1472             sub _cc {
1473 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1474 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1475             }
1476             elsif (scalar(@_) == 1) {
1477 0         0 return sprintf('\x%02X',$_[0]);
1478             }
1479             elsif (scalar(@_) == 2) {
1480 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1481 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1482             }
1483             elsif ($_[0] == $_[1]) {
1484 0         0 return sprintf('\x%02X',$_[0]);
1485             }
1486             elsif (($_[0]+1) == $_[1]) {
1487 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1488             }
1489             else {
1490 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1491             }
1492             }
1493             else {
1494 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1495             }
1496             }
1497              
1498             #
1499             # KOI8-U octet range
1500             #
1501             sub _octets {
1502 0     182   0 my $length = shift @_;
1503              
1504 182 50       319 if ($length == 1) {
1505 182         357 my($a1) = unpack 'C', $_[0];
1506 182         502 my($z1) = unpack 'C', $_[1];
1507              
1508 182 50       328 if ($a1 > $z1) {
1509 182         348 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1510             }
1511              
1512 0 50       0 if ($a1 == $z1) {
    50          
1513 182         494 return sprintf('\x%02X',$a1);
1514             }
1515             elsif (($a1+1) == $z1) {
1516 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1517             }
1518             else {
1519 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1520             }
1521             }
1522             else {
1523 182         1183 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1524             }
1525             }
1526              
1527             #
1528             # KOI8-U range regexp
1529             #
1530             sub _range_regexp {
1531 0     182   0 my($length,$first,$last) = @_;
1532              
1533 182         379 my @range_regexp = ();
1534 182 50       249 if (not exists $range_tr{$length}) {
1535 182         423 return @range_regexp;
1536             }
1537              
1538 0         0 my @ranges = @{ $range_tr{$length} };
  182         274  
1539 182         394 while (my @range = splice(@ranges,0,$length)) {
1540 182         583 my $min = '';
1541 182         282 my $max = '';
1542 182         225 for (my $i=0; $i < $length; $i++) {
1543 182         496 $min .= pack 'C', $range[$i][0];
1544 182         656 $max .= pack 'C', $range[$i][-1];
1545             }
1546              
1547             # min___max
1548             # FIRST_____________LAST
1549             # (nothing)
1550              
1551 182 50 33     458 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1552             }
1553              
1554             # **********
1555             # min_________max
1556             # FIRST_____________LAST
1557             # **********
1558              
1559             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1560 182         2162 push @range_regexp, _octets($length,$first,$max,$min,$max);
1561             }
1562              
1563             # **********************
1564             # min________________max
1565             # FIRST_____________LAST
1566             # **********************
1567              
1568             elsif (($min eq $first) and ($max eq $last)) {
1569 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1570             }
1571              
1572             # *********
1573             # min___max
1574             # FIRST_____________LAST
1575             # *********
1576              
1577             elsif (($first le $min) and ($max le $last)) {
1578 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1579             }
1580              
1581             # **********************
1582             # min__________________________max
1583             # FIRST_____________LAST
1584             # **********************
1585              
1586             elsif (($min le $first) and ($last le $max)) {
1587 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1588             }
1589              
1590             # *********
1591             # min________max
1592             # FIRST_____________LAST
1593             # *********
1594              
1595             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1596 182         503 push @range_regexp, _octets($length,$min,$last,$min,$max);
1597             }
1598              
1599             # min___max
1600             # FIRST_____________LAST
1601             # (nothing)
1602              
1603             elsif ($last lt $min) {
1604             }
1605              
1606             else {
1607 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1608             }
1609             }
1610              
1611 0         0 return @range_regexp;
1612             }
1613              
1614             #
1615             # KOI8-U open character list for qr and not qr
1616             #
1617             sub _charlist {
1618              
1619 182     358   386 my $modifier = pop @_;
1620 358         566 my @char = @_;
1621              
1622 358 100       742 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1623              
1624             # unescape character
1625 358         836 for (my $i=0; $i <= $#char; $i++) {
1626              
1627             # escape - to ...
1628 358 100 100     1277 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1629 1125 100 100     8464 if ((0 < $i) and ($i < $#char)) {
1630 206         796 $char[$i] = '...';
1631             }
1632             }
1633              
1634             # octal escape sequence
1635             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1636 182         411 $char[$i] = octchr($1);
1637             }
1638              
1639             # hexadecimal escape sequence
1640             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1641 0         0 $char[$i] = hexchr($1);
1642             }
1643              
1644             # \b{...} --> b\{...}
1645             # \B{...} --> B\{...}
1646             # \N{CHARNAME} --> N\{CHARNAME}
1647             # \p{PROPERTY} --> p\{PROPERTY}
1648             # \P{PROPERTY} --> P\{PROPERTY}
1649             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1650 0         0 $char[$i] = $1 . '\\' . $2;
1651             }
1652              
1653             # \p, \P, \X --> p, P, X
1654             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1655 0         0 $char[$i] = $1;
1656             }
1657              
1658             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1659 0         0 $char[$i] = CORE::chr oct $1;
1660             }
1661             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1662 0         0 $char[$i] = CORE::chr hex $1;
1663             }
1664             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1665 22         113 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1666             }
1667             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1668             $char[$i] = {
1669             '\0' => "\0",
1670             '\n' => "\n",
1671             '\r' => "\r",
1672             '\t' => "\t",
1673             '\f' => "\f",
1674             '\b' => "\x08", # \b means backspace in character class
1675             '\a' => "\a",
1676             '\e' => "\e",
1677             '\d' => '[0-9]',
1678              
1679             # Vertical tabs are now whitespace
1680             # \s in a regex now matches a vertical tab in all circumstances.
1681             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1682             # \t \n \v \f \r space
1683             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1684             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1685             '\s' => '\s',
1686              
1687             '\w' => '[0-9A-Z_a-z]',
1688             '\D' => '${Ekoi8u::eD}',
1689             '\S' => '${Ekoi8u::eS}',
1690             '\W' => '${Ekoi8u::eW}',
1691              
1692             '\H' => '${Ekoi8u::eH}',
1693             '\V' => '${Ekoi8u::eV}',
1694             '\h' => '[\x09\x20]',
1695             '\v' => '[\x0A\x0B\x0C\x0D]',
1696             '\R' => '${Ekoi8u::eR}',
1697              
1698 0         0 }->{$1};
1699             }
1700              
1701             # POSIX-style character classes
1702             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1703             $char[$i] = {
1704              
1705             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1706             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1707             '[:^lower:]' => '${Ekoi8u::not_lower_i}',
1708             '[:^upper:]' => '${Ekoi8u::not_upper_i}',
1709              
1710 25         385 }->{$1};
1711             }
1712             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1713             $char[$i] = {
1714              
1715             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1716             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1717             '[:ascii:]' => '[\x00-\x7F]',
1718             '[:blank:]' => '[\x09\x20]',
1719             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1720             '[:digit:]' => '[\x30-\x39]',
1721             '[:graph:]' => '[\x21-\x7F]',
1722             '[:lower:]' => '[\x61-\x7A]',
1723             '[:print:]' => '[\x20-\x7F]',
1724             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1725              
1726             # P.174 POSIX-Style Character Classes
1727             # in Chapter 5: Pattern Matching
1728             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1729              
1730             # P.311 11.2.4 Character Classes and other Special Escapes
1731             # in Chapter 11: perlre: Perl regular expressions
1732             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1733              
1734             # P.210 POSIX-Style Character Classes
1735             # in Chapter 5: Pattern Matching
1736             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1737              
1738             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1739              
1740             '[:upper:]' => '[\x41-\x5A]',
1741             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1742             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1743             '[:^alnum:]' => '${Ekoi8u::not_alnum}',
1744             '[:^alpha:]' => '${Ekoi8u::not_alpha}',
1745             '[:^ascii:]' => '${Ekoi8u::not_ascii}',
1746             '[:^blank:]' => '${Ekoi8u::not_blank}',
1747             '[:^cntrl:]' => '${Ekoi8u::not_cntrl}',
1748             '[:^digit:]' => '${Ekoi8u::not_digit}',
1749             '[:^graph:]' => '${Ekoi8u::not_graph}',
1750             '[:^lower:]' => '${Ekoi8u::not_lower}',
1751             '[:^print:]' => '${Ekoi8u::not_print}',
1752             '[:^punct:]' => '${Ekoi8u::not_punct}',
1753             '[:^space:]' => '${Ekoi8u::not_space}',
1754             '[:^upper:]' => '${Ekoi8u::not_upper}',
1755             '[:^word:]' => '${Ekoi8u::not_word}',
1756             '[:^xdigit:]' => '${Ekoi8u::not_xdigit}',
1757              
1758 8         114 }->{$1};
1759             }
1760             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1761 70         1396 $char[$i] = $1;
1762             }
1763             }
1764              
1765             # open character list
1766 7         34 my @singleoctet = ();
1767 358         721 my @multipleoctet = ();
1768 358         642 for (my $i=0; $i <= $#char; ) {
1769              
1770             # escaped -
1771 358 100 100     1070 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1772 943         10044 $i += 1;
1773 182         228 next;
1774             }
1775              
1776             # make range regexp
1777             elsif ($char[$i] eq '...') {
1778              
1779             # range error
1780 182 50       326 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1781 182         748 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1782             }
1783             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1784 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1785 182         514 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1786             }
1787             }
1788              
1789             # make range regexp per length
1790 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1791 182         495 my @regexp = ();
1792              
1793             # is first and last
1794 182 50 33     242 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1795 182         646 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1796             }
1797              
1798             # is first
1799             elsif ($length == CORE::length($char[$i-1])) {
1800 182         548 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1801             }
1802              
1803             # is inside in first and last
1804             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1805 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1806             }
1807              
1808             # is last
1809             elsif ($length == CORE::length($char[$i+1])) {
1810 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1811             }
1812              
1813             else {
1814 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1815             }
1816              
1817 0 50       0 if ($length == 1) {
1818 182         354 push @singleoctet, @regexp;
1819             }
1820             else {
1821 182         403 push @multipleoctet, @regexp;
1822             }
1823             }
1824              
1825 0         0 $i += 2;
1826             }
1827              
1828             # with /i modifier
1829             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1830 182 100       389 if ($modifier =~ /i/oxms) {
1831 493         742 my $uc = Ekoi8u::uc($char[$i]);
1832 24         62 my $fc = Ekoi8u::fc($char[$i]);
1833 24 100       71 if ($uc ne $fc) {
1834 24 50       56 if (CORE::length($fc) == 1) {
1835 12         29 push @singleoctet, $uc, $fc;
1836             }
1837             else {
1838 12         27 push @singleoctet, $uc;
1839 0         0 push @multipleoctet, $fc;
1840             }
1841             }
1842             else {
1843 0         0 push @singleoctet, $char[$i];
1844             }
1845             }
1846             else {
1847 12         27 push @singleoctet, $char[$i];
1848             }
1849 469         796 $i += 1;
1850             }
1851              
1852             # single character of single octet code
1853             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1854 493         886 push @singleoctet, "\t", "\x20";
1855 0         0 $i += 1;
1856             }
1857             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1858 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1859 0         0 $i += 1;
1860             }
1861             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1862 0         0 push @singleoctet, $char[$i];
1863 2         7 $i += 1;
1864             }
1865              
1866             # single character of multiple-octet code
1867             else {
1868 2         15 push @multipleoctet, $char[$i];
1869 84         165 $i += 1;
1870             }
1871             }
1872              
1873             # quote metachar
1874 84         202 for (@singleoctet) {
1875 358 50       875 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1876 689         3168 $_ = '-';
1877             }
1878             elsif (/\A \n \z/oxms) {
1879 0         0 $_ = '\n';
1880             }
1881             elsif (/\A \r \z/oxms) {
1882 8         22 $_ = '\r';
1883             }
1884             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1885 8         17 $_ = sprintf('\x%02X', CORE::ord $1);
1886             }
1887             elsif (/\A [\x00-\xFF] \z/oxms) {
1888 60         223 $_ = quotemeta $_;
1889             }
1890             }
1891              
1892             # return character list
1893 429         711 return \@singleoctet, \@multipleoctet;
1894             }
1895              
1896             #
1897             # KOI8-U octal escape sequence
1898             #
1899             sub octchr {
1900 358     5 0 1281 my($octdigit) = @_;
1901              
1902 5         13 my @binary = ();
1903 5         6 for my $octal (split(//,$octdigit)) {
1904             push @binary, {
1905             '0' => '000',
1906             '1' => '001',
1907             '2' => '010',
1908             '3' => '011',
1909             '4' => '100',
1910             '5' => '101',
1911             '6' => '110',
1912             '7' => '111',
1913 5         26 }->{$octal};
1914             }
1915 50         177 my $binary = join '', @binary;
1916              
1917             my $octchr = {
1918             # 1234567
1919             1 => pack('B*', "0000000$binary"),
1920             2 => pack('B*', "000000$binary"),
1921             3 => pack('B*', "00000$binary"),
1922             4 => pack('B*', "0000$binary"),
1923             5 => pack('B*', "000$binary"),
1924             6 => pack('B*', "00$binary"),
1925             7 => pack('B*', "0$binary"),
1926             0 => pack('B*', "$binary"),
1927              
1928 5         14 }->{CORE::length($binary) % 8};
1929              
1930 5         59 return $octchr;
1931             }
1932              
1933             #
1934             # KOI8-U hexadecimal escape sequence
1935             #
1936             sub hexchr {
1937 5     5 0 20 my($hexdigit) = @_;
1938              
1939             my $hexchr = {
1940             1 => pack('H*', "0$hexdigit"),
1941             0 => pack('H*', "$hexdigit"),
1942              
1943 5         12 }->{CORE::length($_[0]) % 2};
1944              
1945 5         42 return $hexchr;
1946             }
1947              
1948             #
1949             # KOI8-U open character list for qr
1950             #
1951             sub charlist_qr {
1952              
1953 5     314 0 18 my $modifier = pop @_;
1954 314         580 my @char = @_;
1955              
1956 314         822 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1957 314         1045 my @singleoctet = @$singleoctet;
1958 314         687 my @multipleoctet = @$multipleoctet;
1959              
1960             # return character list
1961 314 100       491 if (scalar(@singleoctet) >= 1) {
1962              
1963             # with /i modifier
1964 314 100       707 if ($modifier =~ m/i/oxms) {
1965 236         505 my %singleoctet_ignorecase = ();
1966 22         42 for (@singleoctet) {
1967 22   100     46 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1968 46         241 for my $ord (hex($1) .. hex($2)) {
1969 46         164 my $char = CORE::chr($ord);
1970 66         105 my $uc = Ekoi8u::uc($char);
1971 66         121 my $fc = Ekoi8u::fc($char);
1972 66 100       116 if ($uc eq $fc) {
1973 66         121 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1974             }
1975             else {
1976 12 50       396 if (CORE::length($fc) == 1) {
1977 54         87 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1978 54         122 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1979             }
1980             else {
1981 54         182 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1982 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1983             }
1984             }
1985             }
1986             }
1987 0 50       0 if ($_ ne '') {
1988 46         111 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1989             }
1990             }
1991 0         0 my $i = 0;
1992 22         33 my @singleoctet_ignorecase = ();
1993 22         35 for my $ord (0 .. 255) {
1994 22 100       44 if (exists $singleoctet_ignorecase{$ord}) {
1995 5632         6546 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         89  
1996             }
1997             else {
1998 96         227 $i++;
1999             }
2000             }
2001 5536         5438 @singleoctet = ();
2002 22         41 for my $range (@singleoctet_ignorecase) {
2003 22 100       72 if (ref $range) {
2004 3648 100       6227 if (scalar(@{$range}) == 1) {
  56 50       57  
2005 56         98 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         44  
2006             }
2007 36         126 elsif (scalar(@{$range}) == 2) {
2008 20         31 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2009             }
2010             else {
2011 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         25  
  20         24  
2012             }
2013             }
2014             }
2015             }
2016              
2017 20         76 my $not_anchor = '';
2018              
2019 236         360 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2020             }
2021 236 100       612 if (scalar(@multipleoctet) >= 2) {
2022 314         685 return '(?:' . join('|', @multipleoctet) . ')';
2023             }
2024             else {
2025 6         29 return $multipleoctet[0];
2026             }
2027             }
2028              
2029             #
2030             # KOI8-U open character list for not qr
2031             #
2032             sub charlist_not_qr {
2033              
2034 308     44 0 1306 my $modifier = pop @_;
2035 44         86 my @char = @_;
2036              
2037 44         102 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2038 44         126 my @singleoctet = @$singleoctet;
2039 44         95 my @multipleoctet = @$multipleoctet;
2040              
2041             # with /i modifier
2042 44 100       67 if ($modifier =~ m/i/oxms) {
2043 44         122 my %singleoctet_ignorecase = ();
2044 10         12 for (@singleoctet) {
2045 10   66     14 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2046 10         45 for my $ord (hex($1) .. hex($2)) {
2047 10         38 my $char = CORE::chr($ord);
2048 30         46 my $uc = Ekoi8u::uc($char);
2049 30         44 my $fc = Ekoi8u::fc($char);
2050 30 50       48 if ($uc eq $fc) {
2051 30         53 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2052             }
2053             else {
2054 0 50       0 if (CORE::length($fc) == 1) {
2055 30         46 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2056 30         72 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2057             }
2058             else {
2059 30         90 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2060 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2061             }
2062             }
2063             }
2064             }
2065 0 50       0 if ($_ ne '') {
2066 10         27 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2067             }
2068             }
2069 0         0 my $i = 0;
2070 10         13 my @singleoctet_ignorecase = ();
2071 10         13 for my $ord (0 .. 255) {
2072 10 100       14 if (exists $singleoctet_ignorecase{$ord}) {
2073 2560         3300 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         56  
2074             }
2075             else {
2076 60         98 $i++;
2077             }
2078             }
2079 2500         2666 @singleoctet = ();
2080 10         15 for my $range (@singleoctet_ignorecase) {
2081 10 100       31 if (ref $range) {
2082 960 50       1672 if (scalar(@{$range}) == 1) {
  20 50       21  
2083 20         31 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2084             }
2085 0         0 elsif (scalar(@{$range}) == 2) {
2086 20         32 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2087             }
2088             else {
2089 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         23  
  20         23  
2090             }
2091             }
2092             }
2093             }
2094              
2095             # return character list
2096 20 50       85 if (scalar(@multipleoctet) >= 1) {
2097 44 0       107 if (scalar(@singleoctet) >= 1) {
2098              
2099             # any character other than multiple-octet and single octet character class
2100 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2101             }
2102             else {
2103              
2104             # any character other than multiple-octet character class
2105 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2106             }
2107             }
2108             else {
2109 0 50       0 if (scalar(@singleoctet) >= 1) {
2110              
2111             # any character other than single octet character class
2112 44         89 return '(?:[^' . join('', @singleoctet) . '])';
2113             }
2114             else {
2115              
2116             # any character
2117 44         263 return "(?:$your_char)";
2118             }
2119             }
2120             }
2121              
2122             #
2123             # open file in read mode
2124             #
2125             sub _open_r {
2126 0     408   0 my(undef,$file) = @_;
2127 204     204   2896 use Fcntl qw(O_RDONLY);
  204         473  
  204         30384  
2128 408         1253 return CORE::sysopen($_[0], $file, &O_RDONLY);
2129             }
2130              
2131             #
2132             # open file in append mode
2133             #
2134             sub _open_a {
2135 408     204   17968 my(undef,$file) = @_;
2136 204     204   1446 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  204         550  
  204         736305  
2137 204         698 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2138             }
2139              
2140             #
2141             # safe system
2142             #
2143             sub _systemx {
2144              
2145             # P.707 29.2.33. exec
2146             # in Chapter 29: Functions
2147             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2148             #
2149             # Be aware that in older releases of Perl, exec (and system) did not flush
2150             # your output buffer, so you needed to enable command buffering by setting $|
2151             # on one or more filehandles to avoid lost output in the case of exec, or
2152             # misordererd output in the case of system. This situation was largely remedied
2153             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2154              
2155             # P.855 exec
2156             # in Chapter 27: Functions
2157             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2158             #
2159             # In very old release of Perl (before v5.6), exec (and system) did not flush
2160             # your output buffer, so you needed to enable command buffering by setting $|
2161             # on one or more filehandles to avoid lost output with exec or misordered
2162             # output with system.
2163              
2164 204     204   33623 $| = 1;
2165              
2166             # P.565 23.1.2. Cleaning Up Your Environment
2167             # in Chapter 23: Security
2168             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2169              
2170             # P.656 Cleaning Up Your Environment
2171             # in Chapter 20: Security
2172             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2173              
2174             # local $ENV{'PATH'} = '.';
2175 204         832 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2176              
2177             # P.707 29.2.33. exec
2178             # in Chapter 29: Functions
2179             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2180             #
2181             # As we mentioned earlier, exec treats a discrete list of arguments as an
2182             # indication that it should bypass shell processing. However, there is one
2183             # place where you might still get tripped up. The exec call (and system, too)
2184             # will not distinguish between a single scalar argument and an array containing
2185             # only one element.
2186             #
2187             # @args = ("echo surprise"); # just one element in list
2188             # exec @args # still subject to shell escapes
2189             # or die "exec: $!"; # because @args == 1
2190             #
2191             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2192             # first argument as the pathname, which forces the rest of the arguments to be
2193             # interpreted as a list, even if there is only one of them:
2194             #
2195             # exec { $args[0] } @args # safe even with one-argument list
2196             # or die "can't exec @args: $!";
2197              
2198             # P.855 exec
2199             # in Chapter 27: Functions
2200             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2201             #
2202             # As we mentioned earlier, exec treats a discrete list of arguments as a
2203             # directive to bypass shell processing. However, there is one place where
2204             # you might still get tripped up. The exec call (and system, too) cannot
2205             # distinguish between a single scalar argument and an array containing
2206             # only one element.
2207             #
2208             # @args = ("echo surprise"); # just one element in list
2209             # exec @args # still subject to shell escapes
2210             # || die "exec: $!"; # because @args == 1
2211             #
2212             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2213             # argument as the pathname, which forces the rest of the arguments to be
2214             # interpreted as a list, even if there is only one of them:
2215             #
2216             # exec { $args[0] } @args # safe even with one-argument list
2217             # || die "can't exec @args: $!";
2218              
2219 204         1809 return CORE::system { $_[0] } @_; # safe even with one-argument list
  204         414  
2220             }
2221              
2222             #
2223             # KOI8-U order to character (with parameter)
2224             #
2225             sub Ekoi8u::chr(;$) {
2226              
2227 204 0   0 0 20437808 my $c = @_ ? $_[0] : $_;
2228              
2229 0 0       0 if ($c == 0x00) {
2230 0         0 return "\x00";
2231             }
2232             else {
2233 0         0 my @chr = ();
2234 0         0 while ($c > 0) {
2235 0         0 unshift @chr, ($c % 0x100);
2236 0         0 $c = int($c / 0x100);
2237             }
2238 0         0 return pack 'C*', @chr;
2239             }
2240             }
2241              
2242             #
2243             # KOI8-U order to character (without parameter)
2244             #
2245             sub Ekoi8u::chr_() {
2246              
2247 0     0 0 0 my $c = $_;
2248              
2249 0 0       0 if ($c == 0x00) {
2250 0         0 return "\x00";
2251             }
2252             else {
2253 0         0 my @chr = ();
2254 0         0 while ($c > 0) {
2255 0         0 unshift @chr, ($c % 0x100);
2256 0         0 $c = int($c / 0x100);
2257             }
2258 0         0 return pack 'C*', @chr;
2259             }
2260             }
2261              
2262             #
2263             # KOI8-U path globbing (with parameter)
2264             #
2265             sub Ekoi8u::glob($) {
2266              
2267 0 0   0 0 0 if (wantarray) {
2268 0         0 my @glob = _DOS_like_glob(@_);
2269 0         0 for my $glob (@glob) {
2270 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2271             }
2272 0         0 return @glob;
2273             }
2274             else {
2275 0         0 my $glob = _DOS_like_glob(@_);
2276 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2277 0         0 return $glob;
2278             }
2279             }
2280              
2281             #
2282             # KOI8-U path globbing (without parameter)
2283             #
2284             sub Ekoi8u::glob_() {
2285              
2286 0 0   0 0 0 if (wantarray) {
2287 0         0 my @glob = _DOS_like_glob();
2288 0         0 for my $glob (@glob) {
2289 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2290             }
2291 0         0 return @glob;
2292             }
2293             else {
2294 0         0 my $glob = _DOS_like_glob();
2295 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2296 0         0 return $glob;
2297             }
2298             }
2299              
2300             #
2301             # KOI8-U path globbing via File::DosGlob 1.10
2302             #
2303             # Often I confuse "_dosglob" and "_doglob".
2304             # So, I renamed "_dosglob" to "_DOS_like_glob".
2305             #
2306             my %iter;
2307             my %entries;
2308             sub _DOS_like_glob {
2309              
2310             # context (keyed by second cxix argument provided by core)
2311 0     0   0 my($expr,$cxix) = @_;
2312              
2313             # glob without args defaults to $_
2314 0 0       0 $expr = $_ if not defined $expr;
2315              
2316             # represents the current user's home directory
2317             #
2318             # 7.3. Expanding Tildes in Filenames
2319             # in Chapter 7. File Access
2320             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2321             #
2322             # and File::HomeDir, File::HomeDir::Windows module
2323              
2324             # DOS-like system
2325 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2326 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2327             { my_home_MSWin32() }oxmse;
2328             }
2329              
2330             # UNIX-like system
2331 0 0 0     0 else {
  0         0  
2332             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2333             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2334             }
2335 0 0       0  
2336 0 0       0 # assume global context if not provided one
2337             $cxix = '_G_' if not defined $cxix;
2338             $iter{$cxix} = 0 if not exists $iter{$cxix};
2339 0 0       0  
2340 0         0 # if we're just beginning, do it all first
2341             if ($iter{$cxix} == 0) {
2342             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2343             }
2344 0 0       0  
2345 0         0 # chuck it all out, quick or slow
2346 0         0 if (wantarray) {
  0         0  
2347             delete $iter{$cxix};
2348             return @{delete $entries{$cxix}};
2349 0 0       0 }
  0         0  
2350 0         0 else {
  0         0  
2351             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2352             return shift @{$entries{$cxix}};
2353             }
2354 0         0 else {
2355 0         0 # return undef for EOL
2356 0         0 delete $iter{$cxix};
2357             delete $entries{$cxix};
2358             return undef;
2359             }
2360             }
2361             }
2362              
2363             #
2364             # KOI8-U path globbing subroutine
2365             #
2366 0     0   0 sub _do_glob {
2367 0         0  
2368 0         0 my($cond,@expr) = @_;
2369             my @glob = ();
2370             my $fix_drive_relative_paths = 0;
2371 0         0  
2372 0 0       0 OUTER:
2373 0 0       0 for my $expr (@expr) {
2374             next OUTER if not defined $expr;
2375 0         0 next OUTER if $expr eq '';
2376 0         0  
2377 0         0 my @matched = ();
2378 0         0 my @globdir = ();
2379 0         0 my $head = '.';
2380             my $pathsep = '/';
2381             my $tail;
2382 0 0       0  
2383 0         0 # if argument is within quotes strip em and do no globbing
2384 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2385 0 0       0 $expr = $1;
2386 0         0 if ($cond eq 'd') {
2387             if (-d $expr) {
2388             push @glob, $expr;
2389             }
2390 0 0       0 }
2391 0         0 else {
2392             if (-e $expr) {
2393             push @glob, $expr;
2394 0         0 }
2395             }
2396             next OUTER;
2397             }
2398              
2399 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2400 0 0       0 # to h:./*.pm to expand correctly
2401 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2402             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2403             $fix_drive_relative_paths = 1;
2404             }
2405 0 0       0 }
2406 0 0       0  
2407 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2408 0         0 if ($tail eq '') {
2409             push @glob, $expr;
2410 0 0       0 next OUTER;
2411 0 0       0 }
2412 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2413 0         0 if (@globdir = _do_glob('d', $head)) {
2414             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2415             next OUTER;
2416 0 0 0     0 }
2417 0         0 }
2418             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2419 0         0 $head .= $pathsep;
2420             }
2421             $expr = $tail;
2422             }
2423 0 0       0  
2424 0 0       0 # If file component has no wildcards, we can avoid opendir
2425 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2426             if ($head eq '.') {
2427 0 0 0     0 $head = '';
2428 0         0 }
2429             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2430 0         0 $head .= $pathsep;
2431 0 0       0 }
2432 0 0       0 $head .= $expr;
2433 0         0 if ($cond eq 'd') {
2434             if (-d $head) {
2435             push @glob, $head;
2436             }
2437 0 0       0 }
2438 0         0 else {
2439             if (-e $head) {
2440             push @glob, $head;
2441 0         0 }
2442             }
2443 0 0       0 next OUTER;
2444 0         0 }
2445 0         0 opendir(*DIR, $head) or next OUTER;
2446             my @leaf = readdir DIR;
2447 0 0       0 closedir DIR;
2448 0         0  
2449             if ($head eq '.') {
2450 0 0 0     0 $head = '';
2451 0         0 }
2452             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2453             $head .= $pathsep;
2454 0         0 }
2455 0         0  
2456 0         0 my $pattern = '';
2457             while ($expr =~ / \G ($q_char) /oxgc) {
2458             my $char = $1;
2459              
2460             # 6.9. Matching Shell Globs as Regular Expressions
2461             # in Chapter 6. Pattern Matching
2462             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2463 0 0       0 # (and so on)
    0          
    0          
2464 0         0  
2465             if ($char eq '*') {
2466             $pattern .= "(?:$your_char)*",
2467 0         0 }
2468             elsif ($char eq '?') {
2469             $pattern .= "(?:$your_char)?", # DOS style
2470             # $pattern .= "(?:$your_char)", # UNIX style
2471 0         0 }
2472             elsif ((my $fc = Ekoi8u::fc($char)) ne $char) {
2473             $pattern .= $fc;
2474 0         0 }
2475             else {
2476             $pattern .= quotemeta $char;
2477 0     0   0 }
  0         0  
2478             }
2479             my $matchsub = sub { Ekoi8u::fc($_[0]) =~ /\A $pattern \z/xms };
2480              
2481             # if ($@) {
2482             # print STDERR "$0: $@\n";
2483             # next OUTER;
2484             # }
2485 0         0  
2486 0 0 0     0 INNER:
2487 0         0 for my $leaf (@leaf) {
2488             if ($leaf eq '.' or $leaf eq '..') {
2489 0 0 0     0 next INNER;
2490 0         0 }
2491             if ($cond eq 'd' and not -d "$head$leaf") {
2492             next INNER;
2493 0 0       0 }
2494 0         0  
2495 0         0 if (&$matchsub($leaf)) {
2496             push @matched, "$head$leaf";
2497             next INNER;
2498             }
2499              
2500             # [DOS compatibility special case]
2501 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2502              
2503             if (Ekoi8u::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2504             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2505 0 0       0 Ekoi8u::index($pattern,'\\.') != -1 # pattern has a dot.
2506 0         0 ) {
2507 0         0 if (&$matchsub("$leaf.")) {
2508             push @matched, "$head$leaf";
2509             next INNER;
2510             }
2511 0 0       0 }
2512 0         0 }
2513             if (@matched) {
2514             push @glob, @matched;
2515 0 0       0 }
2516 0         0 }
2517 0         0 if ($fix_drive_relative_paths) {
2518             for my $glob (@glob) {
2519             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2520 0         0 }
2521             }
2522             return @glob;
2523             }
2524              
2525             #
2526             # KOI8-U parse line
2527             #
2528 0     0   0 sub _parse_line {
2529              
2530 0         0 my($line) = @_;
2531 0         0  
2532 0         0 $line .= ' ';
2533             my @piece = ();
2534             while ($line =~ /
2535             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2536             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2537 0 0       0 /oxmsg
2538             ) {
2539 0         0 push @piece, defined($1) ? $1 : $2;
2540             }
2541             return @piece;
2542             }
2543              
2544             #
2545             # KOI8-U parse path
2546             #
2547 0     0   0 sub _parse_path {
2548              
2549 0         0 my($path,$pathsep) = @_;
2550 0         0  
2551 0         0 $path .= '/';
2552             my @subpath = ();
2553             while ($path =~ /
2554             ((?: [^\/\\] )+?) [\/\\]
2555 0         0 /oxmsg
2556             ) {
2557             push @subpath, $1;
2558 0         0 }
2559 0         0  
2560 0         0 my $tail = pop @subpath;
2561             my $head = join $pathsep, @subpath;
2562             return $head, $tail;
2563             }
2564              
2565             #
2566             # via File::HomeDir::Windows 1.00
2567             #
2568             sub my_home_MSWin32 {
2569              
2570             # A lot of unix people and unix-derived tools rely on
2571 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2572 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2573             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2574             return $ENV{'HOME'};
2575             }
2576              
2577 0         0 # Do we have a user profile?
2578             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2579             return $ENV{'USERPROFILE'};
2580             }
2581              
2582 0         0 # Some Windows use something like $ENV{'HOME'}
2583             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2584             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2585 0         0 }
2586              
2587             return undef;
2588             }
2589              
2590             #
2591             # via File::HomeDir::Unix 1.00
2592 0     0 0 0 #
2593             sub my_home {
2594 0 0 0     0 my $home;
    0 0        
2595 0         0  
2596             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2597             $home = $ENV{'HOME'};
2598             }
2599              
2600             # This is from the original code, but I'm guessing
2601 0         0 # it means "login directory" and exists on some Unixes.
2602             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2603             $home = $ENV{'LOGDIR'};
2604             }
2605              
2606             ### More-desperate methods
2607              
2608 0         0 # Light desperation on any (Unixish) platform
2609             else {
2610             $home = CORE::eval q{ (getpwuid($<))[7] };
2611             }
2612              
2613 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2614 0         0 # For example, "nobody"-like users might use /nonexistant
2615             if (defined $home and ! -d($home)) {
2616 0         0 $home = undef;
2617             }
2618             return $home;
2619             }
2620              
2621             #
2622             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2623 0     0 0 0 #
2624             sub Ekoi8u::PREMATCH {
2625             return $`;
2626             }
2627              
2628             #
2629             # ${^MATCH}, $MATCH, $& the string that matched
2630 0     0 0 0 #
2631             sub Ekoi8u::MATCH {
2632             return $&;
2633             }
2634              
2635             #
2636             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2637 0     0 0 0 #
2638             sub Ekoi8u::POSTMATCH {
2639             return $';
2640             }
2641              
2642             #
2643             # KOI8-U character to order (with parameter)
2644             #
2645 0 0   0 1 0 sub KOI8U::ord(;$) {
2646              
2647 0 0       0 local $_ = shift if @_;
2648 0         0  
2649 0         0 if (/\A ($q_char) /oxms) {
2650 0         0 my @ord = unpack 'C*', $1;
2651 0         0 my $ord = 0;
2652             while (my $o = shift @ord) {
2653 0         0 $ord = $ord * 0x100 + $o;
2654             }
2655             return $ord;
2656 0         0 }
2657             else {
2658             return CORE::ord $_;
2659             }
2660             }
2661              
2662             #
2663             # KOI8-U character to order (without parameter)
2664             #
2665 0 0   0 0 0 sub KOI8U::ord_() {
2666 0         0  
2667 0         0 if (/\A ($q_char) /oxms) {
2668 0         0 my @ord = unpack 'C*', $1;
2669 0         0 my $ord = 0;
2670             while (my $o = shift @ord) {
2671 0         0 $ord = $ord * 0x100 + $o;
2672             }
2673             return $ord;
2674 0         0 }
2675             else {
2676             return CORE::ord $_;
2677             }
2678             }
2679              
2680             #
2681             # KOI8-U reverse
2682             #
2683 0 0   0 0 0 sub KOI8U::reverse(@) {
2684 0         0  
2685             if (wantarray) {
2686             return CORE::reverse @_;
2687             }
2688             else {
2689              
2690             # One of us once cornered Larry in an elevator and asked him what
2691             # problem he was solving with this, but he looked as far off into
2692             # the distance as he could in an elevator and said, "It seemed like
2693 0         0 # a good idea at the time."
2694              
2695             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2696             }
2697             }
2698              
2699             #
2700             # KOI8-U getc (with parameter, without parameter)
2701             #
2702 0     0 0 0 sub KOI8U::getc(;*@) {
2703 0 0       0  
2704 0 0 0     0 my($package) = caller;
2705             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2706 0         0 croak 'Too many arguments for KOI8U::getc' if @_ and not wantarray;
  0         0  
2707 0         0  
2708 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2709 0         0 my $getc = '';
2710 0 0       0 for my $length ($length[0] .. $length[-1]) {
2711 0 0       0 $getc .= CORE::getc($fh);
2712 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2713             if ($getc =~ /\A ${Ekoi8u::dot_s} \z/oxms) {
2714             return wantarray ? ($getc,@_) : $getc;
2715             }
2716 0 0       0 }
2717             }
2718             return wantarray ? ($getc,@_) : $getc;
2719             }
2720              
2721             #
2722             # KOI8-U length by character
2723             #
2724 0 0   0 1 0 sub KOI8U::length(;$) {
2725              
2726 0         0 local $_ = shift if @_;
2727 0         0  
2728             local @_ = /\G ($q_char) /oxmsg;
2729             return scalar @_;
2730             }
2731              
2732             #
2733             # KOI8-U substr by character
2734             #
2735             BEGIN {
2736              
2737             # P.232 The lvalue Attribute
2738             # in Chapter 6: Subroutines
2739             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2740              
2741             # P.336 The lvalue Attribute
2742             # in Chapter 7: Subroutines
2743             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2744              
2745             # P.144 8.4 Lvalue subroutines
2746             # in Chapter 8: perlsub: Perl subroutines
2747 204 50 0 204 1 132425 # 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  
2748              
2749             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2750             # vv----------------------*******
2751             sub KOI8U::substr($$;$$) %s {
2752              
2753             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2754              
2755             # If the substring is beyond either end of the string, substr() returns the undefined
2756             # value and produces a warning. When used as an lvalue, specifying a substring that
2757             # is entirely outside the string raises an exception.
2758             # http://perldoc.perl.org/functions/substr.html
2759              
2760             # A return with no argument returns the scalar value undef in scalar context,
2761             # an empty list () in list context, and (naturally) nothing at all in void
2762             # context.
2763              
2764             my $offset = $_[1];
2765             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2766             return;
2767             }
2768              
2769             # substr($string,$offset,$length,$replacement)
2770             if (@_ == 4) {
2771             my(undef,undef,$length,$replacement) = @_;
2772             my $substr = join '', splice(@char, $offset, $length, $replacement);
2773             $_[0] = join '', @char;
2774              
2775             # return $substr; this doesn't work, don't say "return"
2776             $substr;
2777             }
2778              
2779             # substr($string,$offset,$length)
2780             elsif (@_ == 3) {
2781             my(undef,undef,$length) = @_;
2782             my $octet_offset = 0;
2783             my $octet_length = 0;
2784             if ($offset == 0) {
2785             $octet_offset = 0;
2786             }
2787             elsif ($offset > 0) {
2788             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2789             }
2790             else {
2791             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2792             }
2793             if ($length == 0) {
2794             $octet_length = 0;
2795             }
2796             elsif ($length > 0) {
2797             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2798             }
2799             else {
2800             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2801             }
2802             CORE::substr($_[0], $octet_offset, $octet_length);
2803             }
2804              
2805             # substr($string,$offset)
2806             else {
2807             my $octet_offset = 0;
2808             if ($offset == 0) {
2809             $octet_offset = 0;
2810             }
2811             elsif ($offset > 0) {
2812             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2813             }
2814             else {
2815             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2816             }
2817             CORE::substr($_[0], $octet_offset);
2818             }
2819             }
2820             END
2821             }
2822              
2823             #
2824             # KOI8-U index by character
2825             #
2826 0     0 1 0 sub KOI8U::index($$;$) {
2827 0 0       0  
2828 0         0 my $index;
2829             if (@_ == 3) {
2830             $index = Ekoi8u::index($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2831 0         0 }
2832             else {
2833             $index = Ekoi8u::index($_[0], $_[1]);
2834 0 0       0 }
2835 0         0  
2836             if ($index == -1) {
2837             return -1;
2838 0         0 }
2839             else {
2840             return KOI8U::length(CORE::substr $_[0], 0, $index);
2841             }
2842             }
2843              
2844             #
2845             # KOI8-U rindex by character
2846             #
2847 0     0 1 0 sub KOI8U::rindex($$;$) {
2848 0 0       0  
2849 0         0 my $rindex;
2850             if (@_ == 3) {
2851             $rindex = Ekoi8u::rindex($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2852 0         0 }
2853             else {
2854             $rindex = Ekoi8u::rindex($_[0], $_[1]);
2855 0 0       0 }
2856 0         0  
2857             if ($rindex == -1) {
2858             return -1;
2859 0         0 }
2860             else {
2861             return KOI8U::length(CORE::substr $_[0], 0, $rindex);
2862             }
2863             }
2864              
2865 204     204   1827 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  204         441  
  204         25635  
2866             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2867             use vars qw($slash); $slash = 'm//';
2868              
2869             # ord() to ord() or KOI8U::ord()
2870             my $function_ord = 'ord';
2871              
2872             # ord to ord or KOI8U::ord_
2873             my $function_ord_ = 'ord';
2874              
2875             # reverse to reverse or KOI8U::reverse
2876             my $function_reverse = 'reverse';
2877              
2878             # getc to getc or KOI8U::getc
2879             my $function_getc = 'getc';
2880              
2881             # P.1023 Appendix W.9 Multibyte Anchoring
2882             # of ISBN 1-56592-224-7 CJKV Information Processing
2883              
2884 204     204   1654 my $anchor = '';
  204     0   429  
  204         10421388  
2885              
2886             use vars qw($nest);
2887              
2888             # regexp of nested parens in qqXX
2889              
2890             # P.340 Matching Nested Constructs with Embedded Code
2891             # in Chapter 7: Perl
2892             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2893              
2894             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2895             [^\\()] |
2896             \( (?{$nest++}) |
2897             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2898             \\ [^c] |
2899             \\c[\x40-\x5F] |
2900             [\x00-\xFF]
2901             }xms;
2902              
2903             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2904             [^\\{}] |
2905             \{ (?{$nest++}) |
2906             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2907             \\ [^c] |
2908             \\c[\x40-\x5F] |
2909             [\x00-\xFF]
2910             }xms;
2911              
2912             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2913             [^\\\[\]] |
2914             \[ (?{$nest++}) |
2915             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2916             \\ [^c] |
2917             \\c[\x40-\x5F] |
2918             [\x00-\xFF]
2919             }xms;
2920              
2921             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2922             [^\\<>] |
2923             \< (?{$nest++}) |
2924             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2925             \\ [^c] |
2926             \\c[\x40-\x5F] |
2927             [\x00-\xFF]
2928             }xms;
2929              
2930             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2931             (?: ::)? (?:
2932             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2933             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2934             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2935             ))
2936             }xms;
2937              
2938             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2939             (?: ::)? (?:
2940             (?>[0-9]+) |
2941             [^a-zA-Z_0-9\[\]] |
2942             ^[A-Z] |
2943             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2944             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2945             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2946             ))
2947             }xms;
2948              
2949             my $qq_substr = qr{(?> Char::substr | KOI8U::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2950             }xms;
2951              
2952             # regexp of nested parens in qXX
2953             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2954             [^()] |
2955             \( (?{$nest++}) |
2956             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2957             [\x00-\xFF]
2958             }xms;
2959              
2960             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2961             [^\{\}] |
2962             \{ (?{$nest++}) |
2963             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2964             [\x00-\xFF]
2965             }xms;
2966              
2967             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2968             [^\[\]] |
2969             \[ (?{$nest++}) |
2970             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2971             [\x00-\xFF]
2972             }xms;
2973              
2974             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2975             [^<>] |
2976             \< (?{$nest++}) |
2977             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2978             [\x00-\xFF]
2979             }xms;
2980              
2981             my $matched = '';
2982             my $s_matched = '';
2983              
2984             my $tr_variable = ''; # variable of tr///
2985             my $sub_variable = ''; # variable of s///
2986             my $bind_operator = ''; # =~ or !~
2987              
2988             my @heredoc = (); # here document
2989             my @heredoc_delimiter = ();
2990             my $here_script = ''; # here script
2991              
2992             #
2993             # escape KOI8-U script
2994 0 50   204 0 0 #
2995             sub KOI8U::escape(;$) {
2996             local($_) = $_[0] if @_;
2997              
2998             # P.359 The Study Function
2999             # in Chapter 7: Perl
3000 204         1173 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3001              
3002             study $_; # Yes, I studied study yesterday.
3003              
3004             # while all script
3005              
3006             # 6.14. Matching from Where the Last Pattern Left Off
3007             # in Chapter 6. Pattern Matching
3008             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3009             # (and so on)
3010              
3011             # one member of Tag-team
3012             #
3013             # P.128 Start of match (or end of previous match): \G
3014             # P.130 Advanced Use of \G with Perl
3015             # in Chapter 3: Overview of Regular Expression Features and Flavors
3016             # P.255 Use leading anchors
3017             # P.256 Expose ^ and \G at the front expressions
3018             # in Chapter 6: Crafting an Efficient Expression
3019             # P.315 "Tag-team" matching with /gc
3020             # in Chapter 7: Perl
3021 204         386 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3022 204         328  
3023 204         846 my $e_script = '';
3024             while (not /\G \z/oxgc) { # member
3025             $e_script .= KOI8U::escape_token();
3026 74753         116768 }
3027              
3028             return $e_script;
3029             }
3030              
3031             #
3032             # escape KOI8-U token of script
3033             #
3034             sub KOI8U::escape_token {
3035              
3036 204     74753 0 3106 # \n output here document
3037              
3038             my $ignore_modules = join('|', qw(
3039             utf8
3040             bytes
3041             charnames
3042             I18N::Japanese
3043             I18N::Collate
3044             I18N::JExt
3045             File::DosGlob
3046             Wild
3047             Wildcard
3048             Japanese
3049             ));
3050              
3051             # another member of Tag-team
3052             #
3053             # P.315 "Tag-team" matching with /gc
3054             # in Chapter 7: Perl
3055 74753 100 100     95217 # 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          
3056 74753         3133450  
3057 12522 100       16755 if (/\G ( \n ) /oxgc) { # another member (and so on)
3058 12522         23326 my $heredoc = '';
3059             if (scalar(@heredoc_delimiter) >= 1) {
3060 174         224 $slash = 'm//';
3061 174         341  
3062             $heredoc = join '', @heredoc;
3063             @heredoc = ();
3064 174         276  
3065 174         310 # skip here document
3066             for my $heredoc_delimiter (@heredoc_delimiter) {
3067 174         1078 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3068             }
3069 174         307 @heredoc_delimiter = ();
3070              
3071 174         243 $here_script = '';
3072             }
3073             return "\n" . $heredoc;
3074             }
3075 12522         36903  
3076             # ignore space, comment
3077             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3078              
3079             # if (, elsif (, unless (, while (, until (, given (, and when (
3080              
3081             # given, when
3082              
3083             # P.225 The given Statement
3084             # in Chapter 15: Smart Matching and given-when
3085             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3086              
3087             # P.133 The given Statement
3088             # in Chapter 4: Statements and Declarations
3089             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3090 17974         57751  
3091 1401         2382 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3092             $slash = 'm//';
3093             return $1;
3094             }
3095              
3096             # scalar variable ($scalar = ...) =~ tr///;
3097             # scalar variable ($scalar = ...) =~ s///;
3098              
3099             # state
3100              
3101             # P.68 Persistent, Private Variables
3102             # in Chapter 4: Subroutines
3103             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3104              
3105             # P.160 Persistent Lexically Scoped Variables: state
3106             # in Chapter 4: Statements and Declarations
3107             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3108              
3109             # (and so on)
3110 1401         4322  
3111             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3112 86 50       199 my $e_string = e_string($1);
    50          
3113 86         2008  
3114 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3115 0         0 $tr_variable = $e_string . e_string($1);
3116 0         0 $bind_operator = $2;
3117             $slash = 'm//';
3118             return '';
3119 0         0 }
3120 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3121 0         0 $sub_variable = $e_string . e_string($1);
3122 0         0 $bind_operator = $2;
3123             $slash = 'm//';
3124             return '';
3125 0         0 }
3126 86         163 else {
3127             $slash = 'div';
3128             return $e_string;
3129             }
3130             }
3131              
3132 86         336 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
3133 4         9 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3134             $slash = 'div';
3135             return q{Ekoi8u::PREMATCH()};
3136             }
3137              
3138 4         12 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
3139 28         51 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3140             $slash = 'div';
3141             return q{Ekoi8u::MATCH()};
3142             }
3143              
3144 28         79 # $', ${'} --> $', ${'}
3145 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3146             $slash = 'div';
3147             return $1;
3148             }
3149              
3150 1         3 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
3151 3         6 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3152             $slash = 'div';
3153             return q{Ekoi8u::POSTMATCH()};
3154             }
3155              
3156             # scalar variable $scalar =~ tr///;
3157             # scalar variable $scalar =~ s///;
3158             # substr() =~ tr///;
3159 3         19 # substr() =~ s///;
3160             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3161 1671 100       3681 my $scalar = e_string($1);
    100          
3162 1671         7832  
3163 1         2 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3164 1         3 $tr_variable = $scalar;
3165 1         60 $bind_operator = $1;
3166             $slash = 'm//';
3167             return '';
3168 1         7 }
3169 61         128 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3170 61         115 $sub_variable = $scalar;
3171 61         91 $bind_operator = $1;
3172             $slash = 'm//';
3173             return '';
3174 61         226 }
3175 1609         3222 else {
3176             $slash = 'div';
3177             return $scalar;
3178             }
3179             }
3180              
3181 1609         4735 # end of statement
3182             elsif (/\G ( [,;] ) /oxgc) {
3183             $slash = 'm//';
3184 4998         7501  
3185             # clear tr/// variable
3186             $tr_variable = '';
3187 4998         7801  
3188             # clear s/// variable
3189 4998         6152 $sub_variable = '';
3190              
3191 4998         5942 $bind_operator = '';
3192              
3193             return $1;
3194             }
3195              
3196 4998         18334 # bareword
3197             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3198             return $1;
3199             }
3200              
3201 0         0 # $0 --> $0
3202 2         4 elsif (/\G ( \$ 0 ) /oxmsgc) {
3203             $slash = 'div';
3204             return $1;
3205 2         6 }
3206 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3207             $slash = 'div';
3208             return $1;
3209             }
3210              
3211 0         0 # $$ --> $$
3212 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3213             $slash = 'div';
3214             return $1;
3215             }
3216              
3217             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3218 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
3219 4         6 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3220             $slash = 'div';
3221             return e_capture($1);
3222 4         8 }
3223 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3224             $slash = 'div';
3225             return e_capture($1);
3226             }
3227              
3228 0         0 # $$foo[ ... ] --> $ $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.'->'.$2);
3232             }
3233              
3234 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3235 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3236             $slash = 'div';
3237             return e_capture($1.'->'.$2);
3238             }
3239              
3240 0         0 # $$foo
3241 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3242             $slash = 'div';
3243             return e_capture($1);
3244             }
3245              
3246 0         0 # ${ foo }
3247 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3248             $slash = 'div';
3249             return '${' . $1 . '}';
3250             }
3251              
3252 0         0 # ${ ... }
3253 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3254             $slash = 'div';
3255             return e_capture($1);
3256             }
3257              
3258             # variable or function
3259 0         0 # $ @ % & * $ #
3260 42         73 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) {
3261             $slash = 'div';
3262             return $1;
3263             }
3264             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3265 42         129 # $ @ # \ ' " / ? ( ) [ ] < >
3266 62         119 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3267             $slash = 'div';
3268             return $1;
3269             }
3270              
3271 62         496 # while ()
3272             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3273             return $1;
3274             }
3275              
3276             # while () --- glob
3277              
3278             # avoid "Error: Runtime exception" of perl version 5.005_03
3279 0         0  
3280             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3281             return 'while ($_ = Ekoi8u::glob("' . $1 . '"))';
3282             }
3283              
3284 0         0 # while (glob)
3285             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3286             return 'while ($_ = Ekoi8u::glob_)';
3287             }
3288              
3289 0         0 # while (glob(WILDCARD))
3290             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3291             return 'while ($_ = Ekoi8u::glob';
3292             }
3293 0         0  
  248         548  
3294             # doit if, doit unless, doit while, doit until, doit for, doit when
3295             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3296 248         1126  
  19         45  
3297 19         69 # subroutines of package Ekoi8u
  0         0  
3298 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         30  
3299 13         49 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3300 0         0 elsif (/\G \b KOI8U::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         163  
3301 114         325 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         4  
3302 2         5 elsif (/\G \b KOI8U::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval KOI8U::escape'; }
  0         0  
3303 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         5  
3304 2         5 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chop'; }
  0         0  
3305 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3306 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3307 0         0 elsif (/\G \b KOI8U::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::index'; }
  2         4  
3308 2         6 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::index'; }
  0         0  
3309 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3310 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3311 0         0 elsif (/\G \b KOI8U::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::rindex'; }
  1         3  
3312 1         3 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::rindex'; }
  0         0  
3313 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc'; }
  1         3  
3314 1         3 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst'; }
  0         0  
3315 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc'; }
  6         10  
3316             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst'; }
3317             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc'; }
3318 6         15  
  0         0  
3319 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3320 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3321 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3322 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3323 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3324 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3325             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3326 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  
3327 0         0  
  0         0  
3328 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3329 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3330 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3331 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3332 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3333             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3334             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3335 0         0  
  0         0  
3336 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3337 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3338 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3339             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3340 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         4  
3341 2         7  
  2         15  
3342 2         7 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         76  
3343 36         122 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         4  
3344 2         6 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr'; }
  8         14  
3345 8         22 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3346 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3347 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob'; }
  0         0  
3348 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc_'; }
  0         0  
3349 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst_'; }
  0         0  
3350 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc_'; }
  0         0  
3351 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst_'; }
  0         0  
3352             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc_'; }
3353 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3354 0         0  
  0         0  
3355 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3356 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3357 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr_'; }
  0         0  
3358 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3359 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3360 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob_'; }
  8         22  
3361             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3362             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3363 8         37 # split
3364             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3365 87         184 $slash = 'm//';
3366 87         126  
3367 87         299 my $e = '';
3368             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3369             $e .= $1;
3370             }
3371 85 100       330  
  87 100       6163  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3372             # end of split
3373             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8u::split' . $e; }
3374 2         8  
3375             # split scalar value
3376             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Ekoi8u::split' . $e . e_string($1); }
3377 1         8  
3378 0         0 # split literal space
3379 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {qq$1 $2}; }
3380 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3381 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3382 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3383 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3384 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3385 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {q$1 $2}; }
3386 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3387 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3388 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3389 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3390 10         49 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3391             elsif (/\G ' [ ] ' /oxgc) { return 'Ekoi8u::split' . $e . qq {' '}; }
3392             elsif (/\G " [ ] " /oxgc) { return 'Ekoi8u::split' . $e . qq {" "}; }
3393              
3394 0 0       0 # split qq//
  0         0  
3395             elsif (/\G \b (qq) \b /oxgc) {
3396 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3397 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3398 0         0 while (not /\G \z/oxgc) {
3399 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3400 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3401 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3402 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3403 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3404             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3405 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3406             }
3407             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3408             }
3409             }
3410              
3411 0 50       0 # split qr//
  12         407  
3412             elsif (/\G \b (qr) \b /oxgc) {
3413 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3414 12 50       63 else {
  12 50       3076  
    50          
    50          
    50          
    50          
    50          
    50          
3415 0         0 while (not /\G \z/oxgc) {
3416 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3417 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3418 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3419 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3420 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3421 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3422             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3423 12         86 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3424             }
3425             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3426             }
3427             }
3428              
3429 0 0       0 # split q//
  0         0  
3430             elsif (/\G \b (q) \b /oxgc) {
3431 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3432 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3433 0         0 while (not /\G \z/oxgc) {
3434 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3435 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3436 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3437 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3438 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3439             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3440 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3441             }
3442             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3443             }
3444             }
3445              
3446 0 50       0 # split m//
  18         453  
3447             elsif (/\G \b (m) \b /oxgc) {
3448 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3449 18 50       77 else {
  18 50       3760  
    50          
    50          
    50          
    50          
    50          
    50          
3450 0         0 while (not /\G \z/oxgc) {
3451 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3452 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3453 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3454 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3455 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3456 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3457             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3458 18         120 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3459             }
3460             die __FILE__, ": Search pattern not terminated\n";
3461             }
3462             }
3463              
3464 0         0 # split ''
3465 0         0 elsif (/\G (\') /oxgc) {
3466 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3467 0         0 while (not /\G \z/oxgc) {
3468 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3469 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3470             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3471 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3472             }
3473             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3474             }
3475              
3476 0         0 # split ""
3477 0         0 elsif (/\G (\") /oxgc) {
3478 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3479 0         0 while (not /\G \z/oxgc) {
3480 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3481 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3482             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3483 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3484             }
3485             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3486             }
3487              
3488 0         0 # split //
3489 44         117 elsif (/\G (\/) /oxgc) {
3490 44 50       140 my $regexp = '';
  381 50       1501  
    100          
    50          
3491 0         0 while (not /\G \z/oxgc) {
3492 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3493 44         213 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3494             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3495 337         660 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3496             }
3497             die __FILE__, ": Search pattern not terminated\n";
3498             }
3499             }
3500              
3501             # tr/// or y///
3502              
3503             # about [cdsrbB]* (/B modifier)
3504             #
3505             # P.559 appendix C
3506             # of ISBN 4-89052-384-7 Programming perl
3507             # (Japanese title is: Perl puroguramingu)
3508 0         0  
3509             elsif (/\G \b ( tr | y ) \b /oxgc) {
3510             my $ope = $1;
3511 3 50       8  
3512 3         40 # $1 $2 $3 $4 $5 $6
3513 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3514             my @tr = ($tr_variable,$2);
3515             return e_tr(@tr,'',$4,$6);
3516 0         0 }
3517 3         4 else {
3518 3 50       10 my $e = '';
  3 50       250  
    50          
    50          
    50          
    50          
3519             while (not /\G \z/oxgc) {
3520 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3521 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /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_brace)*?) (\}) /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_bracket)*?) (\]) /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 0         0 }
3557 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3558 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3559 0         0 while (not /\G \z/oxgc) {
3560 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3561 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3562 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3563 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3564             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3565 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3566             }
3567             die __FILE__, ": Transliteration replacement not terminated\n";
3568             }
3569 0         0 # $1 $2 $3 $4 $5 $6
3570 3         23 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3571             my @tr = ($tr_variable,$2);
3572             return e_tr(@tr,'',$4,$6);
3573 3         11 }
3574             }
3575             die __FILE__, ": Transliteration pattern not terminated\n";
3576             }
3577             }
3578              
3579 0         0 # qq//
3580             elsif (/\G \b (qq) \b /oxgc) {
3581             my $ope = $1;
3582 2180 50       5137  
3583 2180         4712 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3584 0         0 if (/\G (\#) /oxgc) { # qq# #
3585 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3586 0         0 while (not /\G \z/oxgc) {
3587 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3588 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3589             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3590 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3591             }
3592             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3593             }
3594 0         0  
3595 2180         2876 else {
3596 2180 50       4971 my $e = '';
  2180 50       27240  
    100          
    50          
    50          
    0          
3597             while (not /\G \z/oxgc) {
3598             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3599              
3600 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3601 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3602 0         0 my $qq_string = '';
3603 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3604 0         0 while (not /\G \z/oxgc) {
3605 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3606             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3607 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3608 0         0 elsif (/\G (\)) /oxgc) {
3609             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3610 0         0 else { $qq_string .= $1; }
3611             }
3612 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3613             }
3614             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3615             }
3616              
3617 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3618 2150         3080 elsif (/\G (\{) /oxgc) { # qq { }
3619 2150         3442 my $qq_string = '';
3620 2150 100       4621 local $nest = 1;
  83993 50       300580  
    100          
    100          
    50          
3621 722         1349 while (not /\G \z/oxgc) {
3622 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         1567  
3623             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3624 1153 100       1893 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         5116  
3625 2150         4544 elsif (/\G (\}) /oxgc) {
3626             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3627 1153         2307 else { $qq_string .= $1; }
3628             }
3629 78815         171854 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3630             }
3631             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3632             }
3633              
3634 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3635 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3636 0         0 my $qq_string = '';
3637 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3638 0         0 while (not /\G \z/oxgc) {
3639 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3640             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3641 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3642 0         0 elsif (/\G (\]) /oxgc) {
3643             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3644 0         0 else { $qq_string .= $1; }
3645             }
3646 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3647             }
3648             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3649             }
3650              
3651 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3652 30         51 elsif (/\G (\<) /oxgc) { # qq < >
3653 30         51 my $qq_string = '';
3654 30 100       98 local $nest = 1;
  1166 50       4113  
    50          
    100          
    50          
3655 22         54 while (not /\G \z/oxgc) {
3656 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3657             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3658 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         152  
3659 30         79 elsif (/\G (\>) /oxgc) {
3660             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3661 0         0 else { $qq_string .= $1; }
3662             }
3663 1114         2402 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3664             }
3665             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3666             }
3667              
3668 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3669 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3670 0         0 my $delimiter = $1;
3671 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3672 0         0 while (not /\G \z/oxgc) {
3673 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3674 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3675             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3676 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3677             }
3678             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3679 0         0 }
3680             }
3681             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3682             }
3683             }
3684              
3685 0         0 # qr//
3686 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3687 0         0 my $ope = $1;
3688             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3689             return e_qr($ope,$1,$3,$2,$4);
3690 0         0 }
3691 0         0 else {
3692 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3693 0         0 while (not /\G \z/oxgc) {
3694 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3695 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3696 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3697 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3698 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3699 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3700             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3701 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3702             }
3703             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3704             }
3705             }
3706              
3707 0         0 # qw//
3708 16 50       45 elsif (/\G \b (qw) \b /oxgc) {
3709 16         50 my $ope = $1;
3710             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3711             return e_qw($ope,$1,$3,$2);
3712 0         0 }
3713 16         28 else {
3714 16 50       59 my $e = '';
  16 50       119  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3715             while (not /\G \z/oxgc) {
3716 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3717 16         51  
3718             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3719 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3720 0         0  
3721             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3722 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3723 0         0  
3724             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3725 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3726 0         0  
3727             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3728 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3729 0         0  
3730             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3731 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3732             }
3733             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3734             }
3735             }
3736              
3737 0         0 # qx//
3738 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3739 0         0 my $ope = $1;
3740             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3741             return e_qq($ope,$1,$3,$2);
3742 0         0 }
3743 0         0 else {
3744 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3745 0         0 while (not /\G \z/oxgc) {
3746 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3747 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3748 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3749 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3750 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3751             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3752 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3753             }
3754             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3755             }
3756             }
3757              
3758 0         0 # q//
3759             elsif (/\G \b (q) \b /oxgc) {
3760             my $ope = $1;
3761              
3762             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3763              
3764             # avoid "Error: Runtime exception" of perl version 5.005_03
3765 410 50       1097 # (and so on)
3766 410         977  
3767 0         0 if (/\G (\#) /oxgc) { # q# #
3768 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3769 0         0 while (not /\G \z/oxgc) {
3770 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3771 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3772             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3773 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3774             }
3775             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3776             }
3777 0         0  
3778 410         670 else {
3779 410 50       1353 my $e = '';
  410 50       2129  
    100          
    50          
    100          
    50          
3780             while (not /\G \z/oxgc) {
3781             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3782              
3783 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3784 0         0 elsif (/\G (\() /oxgc) { # q ( )
3785 0         0 my $q_string = '';
3786 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3787 0         0 while (not /\G \z/oxgc) {
3788 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3789 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3790             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3791 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3792 0         0 elsif (/\G (\)) /oxgc) {
3793             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3794 0         0 else { $q_string .= $1; }
3795             }
3796 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3797             }
3798             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3799             }
3800              
3801 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3802 404         831 elsif (/\G (\{) /oxgc) { # q { }
3803 404         691 my $q_string = '';
3804 404 50       1313 local $nest = 1;
  6757 50       24470  
    50          
    100          
    100          
    50          
3805 0         0 while (not /\G \z/oxgc) {
3806 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3807 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         154  
3808             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3809 107 100       194 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         969  
3810 404         1228 elsif (/\G (\}) /oxgc) {
3811             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3812 107         219 else { $q_string .= $1; }
3813             }
3814 6139         11080 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3815             }
3816             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3817             }
3818              
3819 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3820 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3821 0         0 my $q_string = '';
3822 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3823 0         0 while (not /\G \z/oxgc) {
3824 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3825 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3826             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3827 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3828 0         0 elsif (/\G (\]) /oxgc) {
3829             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3830 0         0 else { $q_string .= $1; }
3831             }
3832 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3833             }
3834             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3835             }
3836              
3837 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3838 5         10 elsif (/\G (\<) /oxgc) { # q < >
3839 5         8 my $q_string = '';
3840 5 50       20 local $nest = 1;
  88 50       377  
    50          
    50          
    100          
    50          
3841 0         0 while (not /\G \z/oxgc) {
3842 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3843 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3844             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3845 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         34  
3846 5         26 elsif (/\G (\>) /oxgc) {
3847             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3848 0         0 else { $q_string .= $1; }
3849             }
3850 83         163 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3851             }
3852             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3853             }
3854              
3855 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3856 1         4 elsif (/\G (\S) /oxgc) { # q * *
3857 1         2 my $delimiter = $1;
3858 1 50       5 my $q_string = '';
  14 50       66  
    100          
    50          
3859 0         0 while (not /\G \z/oxgc) {
3860 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3861 1         4 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3862             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3863 13         27 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3864             }
3865             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3866 0         0 }
3867             }
3868             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3869             }
3870             }
3871              
3872 0         0 # m//
3873 209 50       536 elsif (/\G \b (m) \b /oxgc) {
3874 209         1462 my $ope = $1;
3875             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3876             return e_qr($ope,$1,$3,$2,$4);
3877 0         0 }
3878 209         316 else {
3879 209 50       518 my $e = '';
  209 50       10311  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3880 0         0 while (not /\G \z/oxgc) {
3881 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3882 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3883 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3884 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3885 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3886 10         28 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3887 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3888             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3889 199         647 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3890             }
3891             die __FILE__, ": Search pattern not terminated\n";
3892             }
3893             }
3894              
3895             # s///
3896              
3897             # about [cegimosxpradlunbB]* (/cg modifier)
3898             #
3899             # P.67 Pattern-Matching Operators
3900             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3901 0         0  
3902             elsif (/\G \b (s) \b /oxgc) {
3903             my $ope = $1;
3904 97 100       262  
3905 97         1757 # $1 $2 $3 $4 $5 $6
3906             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3907             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3908 1         6 }
3909 96         179 else {
3910 96 50       909 my $e = '';
  96 50       13016  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3911             while (not /\G \z/oxgc) {
3912 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3913 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3914 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3915             while (not /\G \z/oxgc) {
3916 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3917 0         0 # $1 $2 $3 $4
3918 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3919 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3920 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3921 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3922 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3923 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3924 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3925             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3926 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3927             }
3928             die __FILE__, ": Substitution replacement not terminated\n";
3929 0         0 }
3930 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3931 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3932             while (not /\G \z/oxgc) {
3933 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3934 0         0 # $1 $2 $3 $4
3935 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3936 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3937 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3938 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3939 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3940 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3941 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3942             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3943 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3944             }
3945             die __FILE__, ": Substitution replacement not terminated\n";
3946 0         0 }
3947 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3948 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3949             while (not /\G \z/oxgc) {
3950 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3951 0         0 # $1 $2 $3 $4
3952 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3953 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3954 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3955 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3956 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3957             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3958 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959             }
3960             die __FILE__, ": Substitution replacement not terminated\n";
3961 0         0 }
3962 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3963 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3964             while (not /\G \z/oxgc) {
3965 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3966 0         0 # $1 $2 $3 $4
3967 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3968 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3969 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3970 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3971 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3972 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3973 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3974             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3975 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3976             }
3977             die __FILE__, ": Substitution replacement not terminated\n";
3978             }
3979 0         0 # $1 $2 $3 $4 $5 $6
3980             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3981             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3982             }
3983 21         62 # $1 $2 $3 $4 $5 $6
3984             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3985             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3986             }
3987 0         0 # $1 $2 $3 $4 $5 $6
3988             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3989             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3990             }
3991 0         0 # $1 $2 $3 $4 $5 $6
3992             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3993             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3994 75         439 }
3995             }
3996             die __FILE__, ": Substitution pattern not terminated\n";
3997             }
3998             }
3999 0         0  
4000 0         0 # require ignore module
4001 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
4002             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
4003             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4004 0         0  
4005 37         349 # use strict; --> use strict; no strict qw(refs);
4006 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4007             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4008             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4009              
4010 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
4011 2         25 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4012             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4013             return "use $1; no strict qw(refs);";
4014 0         0 }
4015             else {
4016             return "use $1;";
4017             }
4018 2 0 0     12 }
      0        
4019 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4020             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4021             return "use $1; no strict qw(refs);";
4022 0         0 }
4023             else {
4024             return "use $1;";
4025             }
4026             }
4027 0         0  
4028 2         27 # ignore use module
4029 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4030             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4031             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4032 0         0  
4033 0         0 # ignore no module
4034 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4035             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4036             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4037 0         0  
4038             # use else
4039             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4040 0         0  
4041             # use else
4042             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4043              
4044 2         9 # ''
4045 848         1810 elsif (/\G (?
4046 848 100       2170 my $q_string = '';
  8241 100       27904  
    100          
    50          
4047 4         11 while (not /\G \z/oxgc) {
4048 48         84 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4049 848         1933 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4050             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4051 7341         15012 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4052             }
4053             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4054             }
4055              
4056 0         0 # ""
4057 1804         3812 elsif (/\G (\") /oxgc) {
4058 1804 100       4504 my $qq_string = '';
  34992 100       127226  
    100          
    50          
4059 67         155 while (not /\G \z/oxgc) {
4060 12         25 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4061 1804         4175 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4062             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4063 33109         82472 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4064             }
4065             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4066             }
4067              
4068 0         0 # ``
4069 1         3 elsif (/\G (\`) /oxgc) {
4070 1 50       4 my $qx_string = '';
  19 50       68  
    100          
    50          
4071 0         0 while (not /\G \z/oxgc) {
4072 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4073 1         2 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4074             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4075 18         30 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4076             }
4077             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4078             }
4079              
4080 0         0 # // --- not divide operator (num / num), not defined-or
4081 453         1448 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4082 453 50       1272 my $regexp = '';
  4496 50       16275  
    100          
    50          
4083 0         0 while (not /\G \z/oxgc) {
4084 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4085 453         9550 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4086             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4087 4043         8294 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4088             }
4089             die __FILE__, ": Search pattern not terminated\n";
4090             }
4091              
4092 0         0 # ?? --- not conditional operator (condition ? then : else)
4093 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4094 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4095 0         0 while (not /\G \z/oxgc) {
4096 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4097 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4098             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4099 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4100             }
4101             die __FILE__, ": Search pattern not terminated\n";
4102             }
4103 0         0  
  0         0  
4104             # <<>> (a safer ARGV)
4105             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4106 0         0  
  0         0  
4107             # << (bit shift) --- not here document
4108             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4109              
4110 0         0 # <<~'HEREDOC'
4111 6         12 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4112 6         9 $slash = 'm//';
4113             my $here_quote = $1;
4114             my $delimiter = $2;
4115 6 50       9  
4116 6         14 # get here document
4117 6         28 if ($here_script eq '') {
4118             $here_script = CORE::substr $_, pos $_;
4119 6 50       29 $here_script =~ s/.*?\n//oxm;
4120 6         59 }
4121 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4122 6         11 my $heredoc = $1;
4123 6         43 my $indent = $2;
4124 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4125             push @heredoc, $heredoc . qq{\n$delimiter\n};
4126             push @heredoc_delimiter, qq{\\s*$delimiter};
4127 6         12 }
4128             else {
4129 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4130             }
4131             return qq{<<'$delimiter'};
4132             }
4133              
4134             # <<~\HEREDOC
4135              
4136             # P.66 2.6.6. "Here" Documents
4137             # in Chapter 2: Bits and Pieces
4138             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4139              
4140             # P.73 "Here" Documents
4141             # in Chapter 2: Bits and Pieces
4142             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4143 6         22  
4144 3         7 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4145 3         6 $slash = 'm//';
4146             my $here_quote = $1;
4147             my $delimiter = $2;
4148 3 50       5  
4149 3         8 # get here document
4150 3         19 if ($here_script eq '') {
4151             $here_script = CORE::substr $_, pos $_;
4152 3 50       17 $here_script =~ s/.*?\n//oxm;
4153 3         73 }
4154 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4155 3         6 my $heredoc = $1;
4156 3         37 my $indent = $2;
4157 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
4158             push @heredoc, $heredoc . qq{\n$delimiter\n};
4159             push @heredoc_delimiter, qq{\\s*$delimiter};
4160 3         7 }
4161             else {
4162 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4163             }
4164             return qq{<<\\$delimiter};
4165             }
4166              
4167 3         12 # <<~"HEREDOC"
4168 6         16 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4169 6         13 $slash = 'm//';
4170             my $here_quote = $1;
4171             my $delimiter = $2;
4172 6 50       14  
4173 6         15 # get here document
4174 6         2128 if ($here_script eq '') {
4175             $here_script = CORE::substr $_, pos $_;
4176 6 50       40 $here_script =~ s/.*?\n//oxm;
4177 6         75 }
4178 6         16 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4179 6         9 my $heredoc = $1;
4180 6         54 my $indent = $2;
4181 6         19 $heredoc =~ s{^$indent}{}msg; # no /ox
4182             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4183             push @heredoc_delimiter, qq{\\s*$delimiter};
4184 6         17 }
4185             else {
4186 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4187             }
4188             return qq{<<"$delimiter"};
4189             }
4190              
4191 6         27 # <<~HEREDOC
4192 3         7 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4193 3         9 $slash = 'm//';
4194             my $here_quote = $1;
4195             my $delimiter = $2;
4196 3 50       7  
4197 3         10 # get here document
4198 3         13 if ($here_script eq '') {
4199             $here_script = CORE::substr $_, pos $_;
4200 3 50       26 $here_script =~ s/.*?\n//oxm;
4201 3         43 }
4202 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4203 3         13 my $heredoc = $1;
4204 3         42 my $indent = $2;
4205 3         12 $heredoc =~ s{^$indent}{}msg; # no /ox
4206             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4207             push @heredoc_delimiter, qq{\\s*$delimiter};
4208 3         10 }
4209             else {
4210 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4211             }
4212             return qq{<<$delimiter};
4213             }
4214              
4215 3         14 # <<~`HEREDOC`
4216 6         18 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4217 6         13 $slash = 'm//';
4218             my $here_quote = $1;
4219             my $delimiter = $2;
4220 6 50       10  
4221 6         17 # get here document
4222 6         24 if ($here_script eq '') {
4223             $here_script = CORE::substr $_, pos $_;
4224 6 50       34 $here_script =~ s/.*?\n//oxm;
4225 6         70 }
4226 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4227 6         9 my $heredoc = $1;
4228 6         50 my $indent = $2;
4229 6         20 $heredoc =~ s{^$indent}{}msg; # no /ox
4230             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4231             push @heredoc_delimiter, qq{\\s*$delimiter};
4232 6         14 }
4233             else {
4234 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4235             }
4236             return qq{<<`$delimiter`};
4237             }
4238              
4239 6         25 # <<'HEREDOC'
4240 72         137 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4241 72         152 $slash = 'm//';
4242             my $here_quote = $1;
4243             my $delimiter = $2;
4244 72 50       111  
4245 72         140 # get here document
4246 72         375 if ($here_script eq '') {
4247             $here_script = CORE::substr $_, pos $_;
4248 72 50       664 $here_script =~ s/.*?\n//oxm;
4249 72         550 }
4250 72         245 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4251             push @heredoc, $1 . qq{\n$delimiter\n};
4252             push @heredoc_delimiter, $delimiter;
4253 72         239 }
4254             else {
4255 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4256             }
4257             return $here_quote;
4258             }
4259              
4260             # <<\HEREDOC
4261              
4262             # P.66 2.6.6. "Here" Documents
4263             # in Chapter 2: Bits and Pieces
4264             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4265              
4266             # P.73 "Here" Documents
4267             # in Chapter 2: Bits and Pieces
4268             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4269 72         282  
4270 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4271 0         0 $slash = 'm//';
4272             my $here_quote = $1;
4273             my $delimiter = $2;
4274 0 0       0  
4275 0         0 # get here document
4276 0         0 if ($here_script eq '') {
4277             $here_script = CORE::substr $_, pos $_;
4278 0 0       0 $here_script =~ s/.*?\n//oxm;
4279 0         0 }
4280 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4281             push @heredoc, $1 . qq{\n$delimiter\n};
4282             push @heredoc_delimiter, $delimiter;
4283 0         0 }
4284             else {
4285 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4286             }
4287             return $here_quote;
4288             }
4289              
4290 0         0 # <<"HEREDOC"
4291 36         77 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4292 36         85 $slash = 'm//';
4293             my $here_quote = $1;
4294             my $delimiter = $2;
4295 36 50       68  
4296 36         92 # get here document
4297 36         248 if ($here_script eq '') {
4298             $here_script = CORE::substr $_, pos $_;
4299 36 50       201 $here_script =~ s/.*?\n//oxm;
4300 36         513 }
4301 36         118 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4302             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4303             push @heredoc_delimiter, $delimiter;
4304 36         84 }
4305             else {
4306 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4307             }
4308             return $here_quote;
4309             }
4310              
4311 36         145 # <
4312 42         102 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4313 42         88 $slash = 'm//';
4314             my $here_quote = $1;
4315             my $delimiter = $2;
4316 42 50       80  
4317 42         96 # get here document
4318 42         304 if ($here_script eq '') {
4319             $here_script = CORE::substr $_, pos $_;
4320 42 50       307 $here_script =~ s/.*?\n//oxm;
4321 42         581 }
4322 42         245 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4323             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4324             push @heredoc_delimiter, $delimiter;
4325 42         91 }
4326             else {
4327 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4328             }
4329             return $here_quote;
4330             }
4331              
4332 42         172 # <<`HEREDOC`
4333 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4334 0         0 $slash = 'm//';
4335             my $here_quote = $1;
4336             my $delimiter = $2;
4337 0 0       0  
4338 0         0 # get here document
4339 0         0 if ($here_script eq '') {
4340             $here_script = CORE::substr $_, pos $_;
4341 0 0       0 $here_script =~ s/.*?\n//oxm;
4342 0         0 }
4343 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4344             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4345             push @heredoc_delimiter, $delimiter;
4346 0         0 }
4347             else {
4348 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4349             }
4350             return $here_quote;
4351             }
4352              
4353 0         0 # <<= <=> <= < operator
4354             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4355             return $1;
4356             }
4357              
4358 12         62 #
4359             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4360             return $1;
4361             }
4362              
4363             # --- glob
4364              
4365             # avoid "Error: Runtime exception" of perl version 5.005_03
4366 0         0  
4367             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4368             return 'Ekoi8u::glob("' . $1 . '")';
4369             }
4370 0         0  
4371             # __DATA__
4372             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4373 0         0  
4374             # __END__
4375             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4376              
4377             # \cD Control-D
4378              
4379             # P.68 2.6.8. Other Literal Tokens
4380             # in Chapter 2: Bits and Pieces
4381             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4382              
4383             # P.76 Other Literal Tokens
4384             # in Chapter 2: Bits and Pieces
4385 204         1911 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4386              
4387             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4388 0         0  
4389             # \cZ Control-Z
4390             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4391              
4392             # any operator before div
4393             elsif (/\G (
4394             -- | \+\+ |
4395 0         0 [\)\}\]]
  5081         11491  
4396              
4397             ) /oxgc) { $slash = 'div'; return $1; }
4398              
4399             # yada-yada or triple-dot operator
4400             elsif (/\G (
4401 5081         23425 \.\.\.
  7         14  
4402              
4403             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4404              
4405             # any operator before m//
4406              
4407             # //, //= (defined-or)
4408              
4409             # P.164 Logical Operators
4410             # in Chapter 10: More Control Structures
4411             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4412              
4413             # P.119 C-Style Logical (Short-Circuit) Operators
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             # ~~
4420              
4421             # P.221 The Smart Match Operator
4422             # in Chapter 15: Smart Matching and given-when
4423             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4424              
4425             # P.112 Smartmatch Operator
4426             # in Chapter 3: Unary and Binary Operators
4427             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4428              
4429             # (and so on)
4430              
4431             elsif (/\G ((?>
4432              
4433             !~~ | !~ | != | ! |
4434             %= | % |
4435             &&= | && | &= | &\.= | &\. | & |
4436             -= | -> | - |
4437             :(?>\s*)= |
4438             : |
4439             <<>> |
4440             <<= | <=> | <= | < |
4441             == | => | =~ | = |
4442             >>= | >> | >= | > |
4443             \*\*= | \*\* | \*= | \* |
4444             \+= | \+ |
4445             \.\. | \.= | \. |
4446             \/\/= | \/\/ |
4447             \/= | \/ |
4448             \? |
4449             \\ |
4450             \^= | \^\.= | \^\. | \^ |
4451             \b x= |
4452             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4453             ~~ | ~\. | ~ |
4454             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4455             \b(?: print )\b |
4456              
4457 7         24 [,;\(\{\[]
  8846         17255  
4458              
4459             )) /oxgc) { $slash = 'm//'; return $1; }
4460 8846         39260  
  15013         28489  
4461             # other any character
4462             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4463              
4464 15013         73093 # system error
4465             else {
4466             die __FILE__, ": Oops, this shouldn't happen!\n";
4467             }
4468             }
4469              
4470 0     1786 0 0 # escape KOI8-U string
4471 1786         5172 sub e_string {
4472             my($string) = @_;
4473 1786         4285 my $e_string = '';
4474              
4475             local $slash = 'm//';
4476              
4477             # P.1024 Appendix W.10 Multibyte Processing
4478             # of ISBN 1-56592-224-7 CJKV Information Processing
4479 1786         2666 # (and so on)
4480              
4481             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4482 1786 100 66     15278  
4483 1786 50       8167 # without { ... }
4484 1769         3781 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4485             if ($string !~ /<
4486             return $string;
4487             }
4488             }
4489 1769         4429  
4490 17 50       65 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          
4491             while ($string !~ /\G \z/oxgc) {
4492             if (0) {
4493             }
4494 190         11888  
4495 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Ekoi8u::PREMATCH()]}
4496 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4497             $e_string .= q{Ekoi8u::PREMATCH()};
4498             $slash = 'div';
4499             }
4500              
4501 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Ekoi8u::MATCH()]}
4502 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4503             $e_string .= q{Ekoi8u::MATCH()};
4504             $slash = 'div';
4505             }
4506              
4507 0         0 # $', ${'} --> $', ${'}
4508 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4509             $e_string .= $1;
4510             $slash = 'div';
4511             }
4512              
4513 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Ekoi8u::POSTMATCH()]}
4514 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4515             $e_string .= q{Ekoi8u::POSTMATCH()};
4516             $slash = 'div';
4517             }
4518              
4519 0         0 # bareword
4520 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4521             $e_string .= $1;
4522             $slash = 'div';
4523             }
4524              
4525 0         0 # $0 --> $0
4526 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4527             $e_string .= $1;
4528             $slash = 'div';
4529 0         0 }
4530 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4531             $e_string .= $1;
4532             $slash = 'div';
4533             }
4534              
4535 0         0 # $$ --> $$
4536 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4537             $e_string .= $1;
4538             $slash = 'div';
4539             }
4540              
4541             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4542 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4543 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4544             $e_string .= e_capture($1);
4545             $slash = 'div';
4546 0         0 }
4547 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4548             $e_string .= e_capture($1);
4549             $slash = 'div';
4550             }
4551              
4552 0         0 # $$foo[ ... ] --> $ $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.'->'.$2);
4555             $slash = 'div';
4556             }
4557              
4558 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4559 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4560             $e_string .= e_capture($1.'->'.$2);
4561             $slash = 'div';
4562             }
4563              
4564 0         0 # $$foo
4565 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4566             $e_string .= e_capture($1);
4567             $slash = 'div';
4568             }
4569              
4570 0         0 # ${ foo }
4571 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4572             $e_string .= '${' . $1 . '}';
4573             $slash = 'div';
4574             }
4575              
4576 0         0 # ${ ... }
4577 3         10 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4578             $e_string .= e_capture($1);
4579             $slash = 'div';
4580             }
4581              
4582             # variable or function
4583 3         17 # $ @ % & * $ #
4584 7         20 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) {
4585             $e_string .= $1;
4586             $slash = 'div';
4587             }
4588             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4589 7         22 # $ @ # \ ' " / ? ( ) [ ] < >
4590 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4591             $e_string .= $1;
4592             $slash = 'div';
4593             }
4594 0         0  
  0         0  
4595 0         0 # subroutines of package Ekoi8u
  0         0  
4596 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4597 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4598 0         0 elsif ($string =~ /\G \b KOI8U::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4599 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4600 0         0 elsif ($string =~ /\G \b KOI8U::eval \b /oxgc) { $e_string .= 'eval KOI8U::escape'; $slash = 'm//'; }
  0         0  
4601 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4602 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Ekoi8u::chop'; $slash = 'm//'; }
  0         0  
4603 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4604 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4605 0         0 elsif ($string =~ /\G \b KOI8U::index \b /oxgc) { $e_string .= 'KOI8U::index'; $slash = 'm//'; }
  0         0  
4606 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Ekoi8u::index'; $slash = 'm//'; }
  0         0  
4607 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4608 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4609 0         0 elsif ($string =~ /\G \b KOI8U::rindex \b /oxgc) { $e_string .= 'KOI8U::rindex'; $slash = 'm//'; }
  0         0  
4610 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Ekoi8u::rindex'; $slash = 'm//'; }
  0         0  
4611 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::lc'; $slash = 'm//'; }
  0         0  
4612 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::lcfirst'; $slash = 'm//'; }
  0         0  
4613 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::uc'; $slash = 'm//'; }
  0         0  
4614             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::ucfirst'; $slash = 'm//'; }
4615             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::fc'; $slash = 'm//'; }
4616 0         0  
  0         0  
4617 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4618 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4619 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  
4620 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  
4621 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  
4622 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  
4623             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
4624 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  
4625 0         0  
  0         0  
4626 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4627 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  
4628 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  
4629 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  
4630 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  
4631             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4632             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4633 0         0  
  0         0  
4634 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
4635 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4636 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4637             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
4638 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4639 0         0  
  0         0  
4640 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4641 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4642 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::chr'; $slash = 'm//'; }
  0         0  
4643 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4644 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4645 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::glob'; $slash = 'm//'; }
  0         0  
4646 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Ekoi8u::lc_'; $slash = 'm//'; }
  0         0  
4647 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Ekoi8u::lcfirst_'; $slash = 'm//'; }
  0         0  
4648 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Ekoi8u::uc_'; $slash = 'm//'; }
  0         0  
4649 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Ekoi8u::ucfirst_'; $slash = 'm//'; }
  0         0  
4650             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Ekoi8u::fc_'; $slash = 'm//'; }
4651 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4652 0         0  
  0         0  
4653 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4654 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4655 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Ekoi8u::chr_'; $slash = 'm//'; }
  0         0  
4656 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4657 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4658 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Ekoi8u::glob_'; $slash = 'm//'; }
  0         0  
4659             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
4660             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
4661 0         0 # split
4662             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4663 0         0 $slash = 'm//';
4664 0         0  
4665 0         0 my $e = '';
4666             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4667             $e .= $1;
4668             }
4669 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          
4670             # end of split
4671             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8u::split' . $e; }
4672 0         0  
  0         0  
4673             # split scalar value
4674             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . e_string($1); next E_STRING_LOOP; }
4675 0         0  
  0         0  
4676 0         0 # split literal space
  0         0  
4677 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4678 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4679 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4680 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4681 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4682 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4683 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4684 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4685 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4686 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4687 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4688 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4689             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {' '}; next E_STRING_LOOP; }
4690             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {" "}; next E_STRING_LOOP; }
4691              
4692 0 0       0 # split qq//
  0         0  
  0         0  
4693             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4694 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
4695 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4696 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4697 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4698 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  
4699 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  
4700 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  
4701 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  
4702             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
4703 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 * *
4704             }
4705             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4706             }
4707             }
4708              
4709 0 0       0 # split qr//
  0         0  
  0         0  
4710             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4711 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
4712 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4713 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4714 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4715 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  
4716 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  
4717 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  
4718 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  
4719 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  
4720             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
4721 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 * *
4722             }
4723             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4724             }
4725             }
4726              
4727 0 0       0 # split q//
  0         0  
  0         0  
4728             elsif ($string =~ /\G \b (q) \b /oxgc) {
4729 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
4730 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4731 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4732 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4733 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  
4734 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  
4735 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  
4736 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  
4737             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
4738 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 * *
4739             }
4740             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4741             }
4742             }
4743              
4744 0 0       0 # split m//
  0         0  
  0         0  
4745             elsif ($string =~ /\G \b (m) \b /oxgc) {
4746 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 # #
4747 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4748 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4749 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4750 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  
4751 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  
4752 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  
4753 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  
4754 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  
4755             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
4756 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 * *
4757             }
4758             die __FILE__, ": Search pattern not terminated\n";
4759             }
4760             }
4761              
4762 0         0 # split ''
4763 0         0 elsif ($string =~ /\G (\') /oxgc) {
4764 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
4765 0         0 while ($string !~ /\G \z/oxgc) {
4766 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
4767 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4768             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
4769 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_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 $qq_string = '';
  0 0       0  
    0          
    0          
4777 0         0 while ($string !~ /\G \z/oxgc) {
4778 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
4779 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4780             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
4781 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4782             }
4783             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4784             }
4785              
4786 0         0 # split //
4787 0         0 elsif ($string =~ /\G (\/) /oxgc) {
4788 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4789 0         0 while ($string !~ /\G \z/oxgc) {
4790 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
4791 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4792             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
4793 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4794             }
4795             die __FILE__, ": Search pattern not terminated\n";
4796             }
4797             }
4798              
4799 0         0 # qq//
4800 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4801 0         0 my $ope = $1;
4802             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4803             $e_string .= e_qq($ope,$1,$3,$2);
4804 0         0 }
4805 0         0 else {
4806 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4807 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4808 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4809 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4810 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4811 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4812             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4813 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4814             }
4815             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4816             }
4817             }
4818              
4819 0         0 # qx//
4820 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4821 0         0 my $ope = $1;
4822             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4823             $e_string .= e_qq($ope,$1,$3,$2);
4824 0         0 }
4825 0         0 else {
4826 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4827 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4828 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4829 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4830 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4831 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4832 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4833             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4834 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4835             }
4836             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4837             }
4838             }
4839              
4840 0         0 # q//
4841 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4842 0         0 my $ope = $1;
4843             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4844             $e_string .= e_q($ope,$1,$3,$2);
4845 0         0 }
4846 0         0 else {
4847 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4848 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4849 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4850 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4851 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4852 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4853             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4854 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 * *
4855             }
4856             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4857             }
4858             }
4859 0         0  
4860             # ''
4861             elsif ($string =~ /\G (?
4862 0         0  
4863             # ""
4864             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4865 0         0  
4866             # ``
4867             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4868 0         0  
4869             # <<>> (a safer ARGV)
4870             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4871 0         0  
4872             # <<= <=> <= < operator
4873             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4874 0         0  
4875             #
4876             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4877              
4878 0         0 # --- glob
4879             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4880             $e_string .= 'Ekoi8u::glob("' . $1 . '")';
4881             }
4882              
4883 0         0 # << (bit shift) --- not here document
4884 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
4885             $slash = 'm//';
4886             $e_string .= $1;
4887             }
4888              
4889 0         0 # <<~'HEREDOC'
4890 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4891 0         0 $slash = 'm//';
4892             my $here_quote = $1;
4893             my $delimiter = $2;
4894 0 0       0  
4895 0         0 # get here document
4896 0         0 if ($here_script eq '') {
4897             $here_script = CORE::substr $_, pos $_;
4898 0 0       0 $here_script =~ s/.*?\n//oxm;
4899 0         0 }
4900 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4901 0         0 my $heredoc = $1;
4902 0         0 my $indent = $2;
4903 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4904             push @heredoc, $heredoc . qq{\n$delimiter\n};
4905             push @heredoc_delimiter, qq{\\s*$delimiter};
4906 0         0 }
4907             else {
4908 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4909             }
4910             $e_string .= qq{<<'$delimiter'};
4911             }
4912              
4913 0         0 # <<~\HEREDOC
4914 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4915 0         0 $slash = 'm//';
4916             my $here_quote = $1;
4917             my $delimiter = $2;
4918 0 0       0  
4919 0         0 # get here document
4920 0         0 if ($here_script eq '') {
4921             $here_script = CORE::substr $_, pos $_;
4922 0 0       0 $here_script =~ s/.*?\n//oxm;
4923 0         0 }
4924 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4925 0         0 my $heredoc = $1;
4926 0         0 my $indent = $2;
4927 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4928             push @heredoc, $heredoc . qq{\n$delimiter\n};
4929             push @heredoc_delimiter, qq{\\s*$delimiter};
4930 0         0 }
4931             else {
4932 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4933             }
4934             $e_string .= qq{<<\\$delimiter};
4935             }
4936              
4937 0         0 # <<~"HEREDOC"
4938 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4939 0         0 $slash = 'm//';
4940             my $here_quote = $1;
4941             my $delimiter = $2;
4942 0 0       0  
4943 0         0 # get here document
4944 0         0 if ($here_script eq '') {
4945             $here_script = CORE::substr $_, pos $_;
4946 0 0       0 $here_script =~ s/.*?\n//oxm;
4947 0         0 }
4948 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4949 0         0 my $heredoc = $1;
4950 0         0 my $indent = $2;
4951 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4952             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4953             push @heredoc_delimiter, qq{\\s*$delimiter};
4954 0         0 }
4955             else {
4956 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4957             }
4958             $e_string .= qq{<<"$delimiter"};
4959             }
4960              
4961 0         0 # <<~HEREDOC
4962 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4963 0         0 $slash = 'm//';
4964             my $here_quote = $1;
4965             my $delimiter = $2;
4966 0 0       0  
4967 0         0 # get here document
4968 0         0 if ($here_script eq '') {
4969             $here_script = CORE::substr $_, pos $_;
4970 0 0       0 $here_script =~ s/.*?\n//oxm;
4971 0         0 }
4972 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4973 0         0 my $heredoc = $1;
4974 0         0 my $indent = $2;
4975 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4976             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4977             push @heredoc_delimiter, qq{\\s*$delimiter};
4978 0         0 }
4979             else {
4980 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4981             }
4982             $e_string .= qq{<<$delimiter};
4983             }
4984              
4985 0         0 # <<~`HEREDOC`
4986 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4987 0         0 $slash = 'm//';
4988             my $here_quote = $1;
4989             my $delimiter = $2;
4990 0 0       0  
4991 0         0 # get here document
4992 0         0 if ($here_script eq '') {
4993             $here_script = CORE::substr $_, pos $_;
4994 0 0       0 $here_script =~ s/.*?\n//oxm;
4995 0         0 }
4996 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4997 0         0 my $heredoc = $1;
4998 0         0 my $indent = $2;
4999 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
5000             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5001             push @heredoc_delimiter, qq{\\s*$delimiter};
5002 0         0 }
5003             else {
5004 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5005             }
5006             $e_string .= qq{<<`$delimiter`};
5007             }
5008              
5009 0         0 # <<'HEREDOC'
5010 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
5011 0         0 $slash = 'm//';
5012             my $here_quote = $1;
5013             my $delimiter = $2;
5014 0 0       0  
5015 0         0 # get here document
5016 0         0 if ($here_script eq '') {
5017             $here_script = CORE::substr $_, pos $_;
5018 0 0       0 $here_script =~ s/.*?\n//oxm;
5019 0         0 }
5020 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5021             push @heredoc, $1 . qq{\n$delimiter\n};
5022             push @heredoc_delimiter, $delimiter;
5023 0         0 }
5024             else {
5025 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5026             }
5027             $e_string .= $here_quote;
5028             }
5029              
5030 0         0 # <<\HEREDOC
5031 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5032 0         0 $slash = 'm//';
5033             my $here_quote = $1;
5034             my $delimiter = $2;
5035 0 0       0  
5036 0         0 # get here document
5037 0         0 if ($here_script eq '') {
5038             $here_script = CORE::substr $_, pos $_;
5039 0 0       0 $here_script =~ s/.*?\n//oxm;
5040 0         0 }
5041 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5042             push @heredoc, $1 . qq{\n$delimiter\n};
5043             push @heredoc_delimiter, $delimiter;
5044 0         0 }
5045             else {
5046 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5047             }
5048             $e_string .= $here_quote;
5049             }
5050              
5051 0         0 # <<"HEREDOC"
5052 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5053 0         0 $slash = 'm//';
5054             my $here_quote = $1;
5055             my $delimiter = $2;
5056 0 0       0  
5057 0         0 # get here document
5058 0         0 if ($here_script eq '') {
5059             $here_script = CORE::substr $_, pos $_;
5060 0 0       0 $here_script =~ s/.*?\n//oxm;
5061 0         0 }
5062 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5063             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5064             push @heredoc_delimiter, $delimiter;
5065 0         0 }
5066             else {
5067 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5068             }
5069             $e_string .= $here_quote;
5070             }
5071              
5072 0         0 # <
5073 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5074 0         0 $slash = 'm//';
5075             my $here_quote = $1;
5076             my $delimiter = $2;
5077 0 0       0  
5078 0         0 # get here document
5079 0         0 if ($here_script eq '') {
5080             $here_script = CORE::substr $_, pos $_;
5081 0 0       0 $here_script =~ s/.*?\n//oxm;
5082 0         0 }
5083 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5084             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5085             push @heredoc_delimiter, $delimiter;
5086 0         0 }
5087             else {
5088 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5089             }
5090             $e_string .= $here_quote;
5091             }
5092              
5093 0         0 # <<`HEREDOC`
5094 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5095 0         0 $slash = 'm//';
5096             my $here_quote = $1;
5097             my $delimiter = $2;
5098 0 0       0  
5099 0         0 # get here document
5100 0         0 if ($here_script eq '') {
5101             $here_script = CORE::substr $_, pos $_;
5102 0 0       0 $here_script =~ s/.*?\n//oxm;
5103 0         0 }
5104 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5105             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5106             push @heredoc_delimiter, $delimiter;
5107 0         0 }
5108             else {
5109 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5110             }
5111             $e_string .= $here_quote;
5112             }
5113              
5114             # any operator before div
5115             elsif ($string =~ /\G (
5116             -- | \+\+ |
5117 0         0 [\)\}\]]
  18         28  
5118              
5119             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
5120              
5121             # yada-yada or triple-dot operator
5122             elsif ($string =~ /\G (
5123 18         52 \.\.\.
  0         0  
5124              
5125             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
5126              
5127             # any operator before m//
5128             elsif ($string =~ /\G ((?>
5129              
5130             !~~ | !~ | != | ! |
5131             %= | % |
5132             &&= | && | &= | &\.= | &\. | & |
5133             -= | -> | - |
5134             :(?>\s*)= |
5135             : |
5136             <<>> |
5137             <<= | <=> | <= | < |
5138             == | => | =~ | = |
5139             >>= | >> | >= | > |
5140             \*\*= | \*\* | \*= | \* |
5141             \+= | \+ |
5142             \.\. | \.= | \. |
5143             \/\/= | \/\/ |
5144             \/= | \/ |
5145             \? |
5146             \\ |
5147             \^= | \^\.= | \^\. | \^ |
5148             \b x= |
5149             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
5150             ~~ | ~\. | ~ |
5151             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
5152             \b(?: print )\b |
5153              
5154 0         0 [,;\(\{\[]
  31         56  
5155              
5156             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
5157 31         105  
5158             # other any character
5159             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
5160              
5161 131         406 # system error
5162             else {
5163             die __FILE__, ": Oops, this shouldn't happen!\n";
5164             }
5165 0         0 }
5166              
5167             return $e_string;
5168             }
5169              
5170             #
5171             # character class
5172 17     1919 0 116 #
5173             sub character_class {
5174 1919 100       4085 my($char,$modifier) = @_;
5175 1919 100       3192  
5176 52         98 if ($char eq '.') {
5177             if ($modifier =~ /s/) {
5178             return '${Ekoi8u::dot_s}';
5179 17         37 }
5180             else {
5181             return '${Ekoi8u::dot}';
5182             }
5183 35         82 }
5184             else {
5185             return Ekoi8u::classic_character_class($char);
5186             }
5187             }
5188              
5189             #
5190             # escape capture ($1, $2, $3, ...)
5191             #
5192 1867     212 0 3278 sub e_capture {
5193              
5194             return join '', '${', $_[0], '}';
5195             }
5196              
5197             #
5198             # escape transliteration (tr/// or y///)
5199 212     3 0 845 #
5200 3         15 sub e_tr {
5201 3   50     6 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
5202             my $e_tr = '';
5203 3         7 $modifier ||= '';
5204              
5205             $slash = 'div';
5206 3         4  
5207             # quote character class 1
5208             $charclass = q_tr($charclass);
5209 3         7  
5210             # quote character class 2
5211             $charclass2 = q_tr($charclass2);
5212 3 50       5  
5213 3 0       8 # /b /B modifier
5214 0         0 if ($modifier =~ tr/bB//d) {
5215             if ($variable eq '') {
5216             $e_tr = qq{tr$charclass$e$charclass2$modifier};
5217 0         0 }
5218             else {
5219             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
5220             }
5221 0 100       0 }
5222 3         8 else {
5223             if ($variable eq '') {
5224             $e_tr = qq{Ekoi8u::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
5225 2         6 }
5226             else {
5227             $e_tr = qq{Ekoi8u::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
5228             }
5229             }
5230 1         4  
5231 3         6 # clear tr/// variable
5232             $tr_variable = '';
5233 3         52 $bind_operator = '';
5234              
5235             return $e_tr;
5236             }
5237              
5238             #
5239             # quote for escape transliteration (tr/// or y///)
5240 3     6 0 20 #
5241             sub q_tr {
5242             my($charclass) = @_;
5243 6 50       8  
    0          
    0          
    0          
    0          
    0          
5244 6         14 # quote character class
5245             if ($charclass !~ /'/oxms) {
5246             return e_q('', "'", "'", $charclass); # --> q' '
5247 6         9 }
5248             elsif ($charclass !~ /\//oxms) {
5249             return e_q('q', '/', '/', $charclass); # --> q/ /
5250 0         0 }
5251             elsif ($charclass !~ /\#/oxms) {
5252             return e_q('q', '#', '#', $charclass); # --> q# #
5253 0         0 }
5254             elsif ($charclass !~ /[\<\>]/oxms) {
5255             return e_q('q', '<', '>', $charclass); # --> q< >
5256 0         0 }
5257             elsif ($charclass !~ /[\(\)]/oxms) {
5258             return e_q('q', '(', ')', $charclass); # --> q( )
5259 0         0 }
5260             elsif ($charclass !~ /[\{\}]/oxms) {
5261             return e_q('q', '{', '}', $charclass); # --> q{ }
5262 0         0 }
5263 0 0       0 else {
5264 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5265             if ($charclass !~ /\Q$char\E/xms) {
5266             return e_q('q', $char, $char, $charclass);
5267             }
5268             }
5269 0         0 }
5270              
5271             return e_q('q', '{', '}', $charclass);
5272             }
5273              
5274             #
5275             # escape q string (q//, '')
5276 0     1264 0 0 #
5277             sub e_q {
5278 1264         2859 my($ope,$delimiter,$end_delimiter,$string) = @_;
5279              
5280 1264         1746 $slash = 'div';
5281              
5282             return join '', $ope, $delimiter, $string, $end_delimiter;
5283             }
5284              
5285             #
5286             # escape qq string (qq//, "", qx//, ``)
5287 1264     4066 0 10720 #
5288             sub e_qq {
5289 4066         9722 my($ope,$delimiter,$end_delimiter,$string) = @_;
5290              
5291 4066         6740 $slash = 'div';
5292 4066         4775  
5293             my $left_e = 0;
5294             my $right_e = 0;
5295 4066         5567  
5296             # split regexp
5297             my @char = $string =~ /\G((?>
5298             [^\\\$] |
5299             \\x\{ (?>[0-9A-Fa-f]+) \} |
5300             \\o\{ (?>[0-7]+) \} |
5301             \\N\{ (?>[^0-9\}][^\}]*) \} |
5302             \\ $q_char |
5303             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5304             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5305             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5306             \$ (?>\s* [0-9]+) |
5307             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5308             \$ \$ (?![\w\{]) |
5309             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5310             $q_char
5311 4066         157144 ))/oxmsg;
5312              
5313             for (my $i=0; $i <= $#char; $i++) {
5314 4066 50 33     13406  
    50 33        
    100          
    100          
    50          
5315 113632         424099 # "\L\u" --> "\u\L"
5316             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5317             @char[$i,$i+1] = @char[$i+1,$i];
5318             }
5319              
5320 0         0 # "\U\l" --> "\l\U"
5321             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5322             @char[$i,$i+1] = @char[$i+1,$i];
5323             }
5324              
5325 0         0 # octal escape sequence
5326             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5327             $char[$i] = Ekoi8u::octchr($1);
5328             }
5329              
5330 1         4 # hexadecimal escape sequence
5331             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5332             $char[$i] = Ekoi8u::hexchr($1);
5333             }
5334              
5335 1         4 # \N{CHARNAME} --> N{CHARNAME}
5336             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5337             $char[$i] = $1;
5338 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          
5339              
5340             if (0) {
5341             }
5342              
5343             # \F
5344             #
5345             # P.69 Table 2-6. Translation escapes
5346             # in Chapter 2: Bits and Pieces
5347             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5348             # (and so on)
5349 113632         1016253  
5350 0 50       0 # \u \l \U \L \F \Q \E
5351 484         1127 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5352             if ($right_e < $left_e) {
5353             $char[$i] = '\\' . $char[$i];
5354             }
5355             }
5356             elsif ($char[$i] eq '\u') {
5357              
5358             # "STRING @{[ LIST EXPR ]} MORE STRING"
5359              
5360             # P.257 Other Tricks You Can Do with Hard References
5361             # in Chapter 8: References
5362             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5363              
5364             # P.353 Other Tricks You Can Do with Hard References
5365             # in Chapter 8: References
5366             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5367              
5368 0         0 # (and so on)
5369 0         0  
5370             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5371             $left_e++;
5372 0         0 }
5373 0         0 elsif ($char[$i] eq '\l') {
5374             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5375             $left_e++;
5376 0         0 }
5377 0         0 elsif ($char[$i] eq '\U') {
5378             $char[$i] = '@{[Ekoi8u::uc qq<';
5379             $left_e++;
5380 0         0 }
5381 0         0 elsif ($char[$i] eq '\L') {
5382             $char[$i] = '@{[Ekoi8u::lc qq<';
5383             $left_e++;
5384 0         0 }
5385 24         30 elsif ($char[$i] eq '\F') {
5386             $char[$i] = '@{[Ekoi8u::fc qq<';
5387             $left_e++;
5388 24         47 }
5389 0         0 elsif ($char[$i] eq '\Q') {
5390             $char[$i] = '@{[CORE::quotemeta qq<';
5391             $left_e++;
5392 0 50       0 }
5393 24         39 elsif ($char[$i] eq '\E') {
5394 24         28 if ($right_e < $left_e) {
5395             $char[$i] = '>]}';
5396             $right_e++;
5397 24         68 }
5398             else {
5399             $char[$i] = '';
5400             }
5401 0         0 }
5402 0 0       0 elsif ($char[$i] eq '\Q') {
5403 0         0 while (1) {
5404             if (++$i > $#char) {
5405 0 0       0 last;
5406 0         0 }
5407             if ($char[$i] eq '\E') {
5408             last;
5409             }
5410             }
5411             }
5412             elsif ($char[$i] eq '\E') {
5413             }
5414              
5415             # $0 --> $0
5416             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5417             }
5418             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5419             }
5420              
5421             # $$ --> $$
5422             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5423             }
5424              
5425             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5426 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5427             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5428             $char[$i] = e_capture($1);
5429 205         377 }
5430             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5431             $char[$i] = e_capture($1);
5432             }
5433              
5434 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5435             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5436             $char[$i] = e_capture($1.'->'.$2);
5437             }
5438              
5439 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5440             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5441             $char[$i] = e_capture($1.'->'.$2);
5442             }
5443              
5444 0         0 # $$foo
5445             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5446             $char[$i] = e_capture($1);
5447             }
5448              
5449 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5450             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5451             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5452             }
5453              
5454 44         140 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5455             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5456             $char[$i] = '@{[Ekoi8u::MATCH()]}';
5457             }
5458              
5459 45         115 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5460             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5461             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5462             }
5463              
5464             # ${ foo } --> ${ foo }
5465             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5466             }
5467              
5468 33         92 # ${ ... }
5469             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5470             $char[$i] = e_capture($1);
5471             }
5472             }
5473 0 50       0  
5474 4066         9364 # return string
5475             if ($left_e > $right_e) {
5476 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5477             }
5478             return join '', $ope, $delimiter, @char, $end_delimiter;
5479             }
5480              
5481             #
5482             # escape qw string (qw//)
5483 4066     16 0 35850 #
5484             sub e_qw {
5485 16         79 my($ope,$delimiter,$end_delimiter,$string) = @_;
5486              
5487             $slash = 'div';
5488 16         32  
  16         198  
5489 483 50       714 # choice again delimiter
    0          
    0          
    0          
    0          
5490 16         99 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5491             if (not $octet{$end_delimiter}) {
5492             return join '', $ope, $delimiter, $string, $end_delimiter;
5493 16         124 }
5494             elsif (not $octet{')'}) {
5495             return join '', $ope, '(', $string, ')';
5496 0         0 }
5497             elsif (not $octet{'}'}) {
5498             return join '', $ope, '{', $string, '}';
5499 0         0 }
5500             elsif (not $octet{']'}) {
5501             return join '', $ope, '[', $string, ']';
5502 0         0 }
5503             elsif (not $octet{'>'}) {
5504             return join '', $ope, '<', $string, '>';
5505 0         0 }
5506 0 0       0 else {
5507 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5508             if (not $octet{$char}) {
5509             return join '', $ope, $char, $string, $char;
5510             }
5511             }
5512             }
5513 0         0  
5514 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5515 0         0 my @string = CORE::split(/\s+/, $string);
5516 0         0 for my $string (@string) {
5517 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5518 0         0 for my $octet (@octet) {
5519             if ($octet =~ /\A (['\\]) \z/oxms) {
5520             $octet = '\\' . $1;
5521 0         0 }
5522             }
5523 0         0 $string = join '', @octet;
  0         0  
5524             }
5525             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5526             }
5527              
5528             #
5529             # escape here document (<<"HEREDOC", <
5530 0     93 0 0 #
5531             sub e_heredoc {
5532 93         252 my($string) = @_;
5533              
5534 93         146 $slash = 'm//';
5535              
5536 93         483 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5537 93         142  
5538             my $left_e = 0;
5539             my $right_e = 0;
5540 93         118  
5541             # split regexp
5542             my @char = $string =~ /\G((?>
5543             [^\\\$] |
5544             \\x\{ (?>[0-9A-Fa-f]+) \} |
5545             \\o\{ (?>[0-7]+) \} |
5546             \\N\{ (?>[^0-9\}][^\}]*) \} |
5547             \\ $q_char |
5548             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5549             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5550             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5551             \$ (?>\s* [0-9]+) |
5552             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5553             \$ \$ (?![\w\{]) |
5554             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5555             $q_char
5556 93         8417 ))/oxmsg;
5557              
5558             for (my $i=0; $i <= $#char; $i++) {
5559 93 50 33     506  
    50 33        
    100          
    100          
    50          
5560 3151         11204 # "\L\u" --> "\u\L"
5561             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5562             @char[$i,$i+1] = @char[$i+1,$i];
5563             }
5564              
5565 0         0 # "\U\l" --> "\l\U"
5566             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5567             @char[$i,$i+1] = @char[$i+1,$i];
5568             }
5569              
5570 0         0 # octal escape sequence
5571             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5572             $char[$i] = Ekoi8u::octchr($1);
5573             }
5574              
5575 1         3 # hexadecimal escape sequence
5576             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5577             $char[$i] = Ekoi8u::hexchr($1);
5578             }
5579              
5580 1         4 # \N{CHARNAME} --> N{CHARNAME}
5581             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5582             $char[$i] = $1;
5583 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          
5584              
5585             if (0) {
5586             }
5587 3151         28534  
5588 0 0       0 # \u \l \U \L \F \Q \E
5589 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5590             if ($right_e < $left_e) {
5591             $char[$i] = '\\' . $char[$i];
5592             }
5593 0         0 }
5594 0         0 elsif ($char[$i] eq '\u') {
5595             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5596             $left_e++;
5597 0         0 }
5598 0         0 elsif ($char[$i] eq '\l') {
5599             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5600             $left_e++;
5601 0         0 }
5602 0         0 elsif ($char[$i] eq '\U') {
5603             $char[$i] = '@{[Ekoi8u::uc qq<';
5604             $left_e++;
5605 0         0 }
5606 0         0 elsif ($char[$i] eq '\L') {
5607             $char[$i] = '@{[Ekoi8u::lc qq<';
5608             $left_e++;
5609 0         0 }
5610 0         0 elsif ($char[$i] eq '\F') {
5611             $char[$i] = '@{[Ekoi8u::fc qq<';
5612             $left_e++;
5613 0         0 }
5614 0         0 elsif ($char[$i] eq '\Q') {
5615             $char[$i] = '@{[CORE::quotemeta qq<';
5616             $left_e++;
5617 0 0       0 }
5618 0         0 elsif ($char[$i] eq '\E') {
5619 0         0 if ($right_e < $left_e) {
5620             $char[$i] = '>]}';
5621             $right_e++;
5622 0         0 }
5623             else {
5624             $char[$i] = '';
5625             }
5626 0         0 }
5627 0 0       0 elsif ($char[$i] eq '\Q') {
5628 0         0 while (1) {
5629             if (++$i > $#char) {
5630 0 0       0 last;
5631 0         0 }
5632             if ($char[$i] eq '\E') {
5633             last;
5634             }
5635             }
5636             }
5637             elsif ($char[$i] eq '\E') {
5638             }
5639              
5640             # $0 --> $0
5641             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5642             }
5643             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5644             }
5645              
5646             # $$ --> $$
5647             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5648             }
5649              
5650             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5651 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5652             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5653             $char[$i] = e_capture($1);
5654 0         0 }
5655             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5656             $char[$i] = e_capture($1);
5657             }
5658              
5659 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5660             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5661             $char[$i] = e_capture($1.'->'.$2);
5662             }
5663              
5664 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5665             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5666             $char[$i] = e_capture($1.'->'.$2);
5667             }
5668              
5669 0         0 # $$foo
5670             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5671             $char[$i] = e_capture($1);
5672             }
5673              
5674 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5675             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5676             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5677             }
5678              
5679 8         43 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5680             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5681             $char[$i] = '@{[Ekoi8u::MATCH()]}';
5682             }
5683              
5684 8         43 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5685             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5686             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5687             }
5688              
5689             # ${ foo } --> ${ foo }
5690             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5691             }
5692              
5693 6         34 # ${ ... }
5694             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5695             $char[$i] = e_capture($1);
5696             }
5697             }
5698 0 50       0  
5699 93         220 # return string
5700             if ($left_e > $right_e) {
5701 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5702             }
5703             return join '', @char;
5704             }
5705              
5706             #
5707             # escape regexp (m//, qr//)
5708 93     652 0 740 #
5709 652   100     2730 sub e_qr {
5710             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5711 652         3556 $modifier ||= '';
5712 652 50       1182  
5713 652         1509 $modifier =~ tr/p//d;
5714 0         0 if ($modifier =~ /([adlu])/oxms) {
5715 0 0       0 my $line = 0;
5716 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5717 0         0 if ($filename ne __FILE__) {
5718             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5719             last;
5720 0         0 }
5721             }
5722             die qq{Unsupported modifier "$1" used at line $line.\n};
5723 0         0 }
5724              
5725             $slash = 'div';
5726 652 100       1088  
    100          
5727 652         24944 # literal null string pattern
5728 8         10 if ($string eq '') {
5729 8         10 $modifier =~ tr/bB//d;
5730             $modifier =~ tr/i//d;
5731             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5732             }
5733              
5734             # /b /B modifier
5735             elsif ($modifier =~ tr/bB//d) {
5736 8 50       37  
5737 2         6 # choice again delimiter
5738 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5739 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5740 0         0 my %octet = map {$_ => 1} @char;
5741 0         0 if (not $octet{')'}) {
5742             $delimiter = '(';
5743             $end_delimiter = ')';
5744 0         0 }
5745 0         0 elsif (not $octet{'}'}) {
5746             $delimiter = '{';
5747             $end_delimiter = '}';
5748 0         0 }
5749 0         0 elsif (not $octet{']'}) {
5750             $delimiter = '[';
5751             $end_delimiter = ']';
5752 0         0 }
5753 0         0 elsif (not $octet{'>'}) {
5754             $delimiter = '<';
5755             $end_delimiter = '>';
5756 0         0 }
5757 0 0       0 else {
5758 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5759 0         0 if (not $octet{$char}) {
5760 0         0 $delimiter = $char;
5761             $end_delimiter = $char;
5762             last;
5763             }
5764             }
5765             }
5766 0 50 33     0 }
5767 2         10  
5768             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5769             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5770 0         0 }
5771             else {
5772             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5773             }
5774 2 100       10 }
5775 642         1950  
5776             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5777             my $metachar = qr/[\@\\|[\]{^]/oxms;
5778 642         2544  
5779             # split regexp
5780             my @char = $string =~ /\G((?>
5781             [^\\\$\@\[\(] |
5782             \\x (?>[0-9A-Fa-f]{1,2}) |
5783             \\ (?>[0-7]{2,3}) |
5784             \\c [\x40-\x5F] |
5785             \\x\{ (?>[0-9A-Fa-f]+) \} |
5786             \\o\{ (?>[0-7]+) \} |
5787             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5788             \\ $q_char |
5789             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5790             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5791             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5792             [\$\@] $qq_variable |
5793             \$ (?>\s* [0-9]+) |
5794             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5795             \$ \$ (?![\w\{]) |
5796             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5797             \[\^ |
5798             \[\: (?>[a-z]+) :\] |
5799             \[\:\^ (?>[a-z]+) :\] |
5800             \(\? |
5801             $q_char
5802             ))/oxmsg;
5803 642 50       91626  
5804 642         2745 # choice again delimiter
  0         0  
5805 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5806 0         0 my %octet = map {$_ => 1} @char;
5807 0         0 if (not $octet{')'}) {
5808             $delimiter = '(';
5809             $end_delimiter = ')';
5810 0         0 }
5811 0         0 elsif (not $octet{'}'}) {
5812             $delimiter = '{';
5813             $end_delimiter = '}';
5814 0         0 }
5815 0         0 elsif (not $octet{']'}) {
5816             $delimiter = '[';
5817             $end_delimiter = ']';
5818 0         0 }
5819 0         0 elsif (not $octet{'>'}) {
5820             $delimiter = '<';
5821             $end_delimiter = '>';
5822 0         0 }
5823 0 0       0 else {
5824 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5825 0         0 if (not $octet{$char}) {
5826 0         0 $delimiter = $char;
5827             $end_delimiter = $char;
5828             last;
5829             }
5830             }
5831             }
5832 0         0 }
5833 642         1027  
5834 642         995 my $left_e = 0;
5835             my $right_e = 0;
5836             for (my $i=0; $i <= $#char; $i++) {
5837 642 50 66     1951  
    50 66        
    100          
    100          
    100          
    100          
5838 1872         10243 # "\L\u" --> "\u\L"
5839             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5840             @char[$i,$i+1] = @char[$i+1,$i];
5841             }
5842              
5843 0         0 # "\U\l" --> "\l\U"
5844             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5845             @char[$i,$i+1] = @char[$i+1,$i];
5846             }
5847              
5848 0         0 # octal escape sequence
5849             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5850             $char[$i] = Ekoi8u::octchr($1);
5851             }
5852              
5853 1         3 # hexadecimal escape sequence
5854             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5855             $char[$i] = Ekoi8u::hexchr($1);
5856             }
5857              
5858             # \b{...} --> b\{...}
5859             # \B{...} --> B\{...}
5860             # \N{CHARNAME} --> N\{CHARNAME}
5861             # \p{PROPERTY} --> p\{PROPERTY}
5862 1         4 # \P{PROPERTY} --> P\{PROPERTY}
5863             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5864             $char[$i] = $1 . '\\' . $2;
5865             }
5866              
5867 6         18 # \p, \P, \X --> p, P, X
5868             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5869             $char[$i] = $1;
5870 4 100 100     10 }
    100 100        
    100 100        
    100          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
5871              
5872             if (0) {
5873             }
5874 1872         5447  
5875 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5876 6         83 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5877             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)) {
5878             $char[$i] .= join '', splice @char, $i+1, 3;
5879 0         0 }
5880             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)) {
5881             $char[$i] .= join '', splice @char, $i+1, 2;
5882 0         0 }
5883             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)) {
5884             $char[$i] .= join '', splice @char, $i+1, 1;
5885             }
5886             }
5887              
5888 0         0 # open character class [...]
5889             elsif ($char[$i] eq '[') {
5890             my $left = $i;
5891              
5892             # [] make die "Unmatched [] in regexp ...\n"
5893 328 100       496 # (and so on)
5894 328         898  
5895             if ($char[$i+1] eq ']') {
5896             $i++;
5897 3         6 }
5898 328 50       407  
5899 1379         2080 while (1) {
5900             if (++$i > $#char) {
5901 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5902 1379         2031 }
5903             if ($char[$i] eq ']') {
5904             my $right = $i;
5905 328 100       403  
5906 328         1727 # [...]
  30         90  
5907             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5908             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5909 90         162 }
5910             else {
5911             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
5912 298         1095 }
5913 328         636  
5914             $i = $left;
5915             last;
5916             }
5917             }
5918             }
5919              
5920 328         1980 # open character class [^...]
5921             elsif ($char[$i] eq '[^') {
5922             my $left = $i;
5923              
5924             # [^] make die "Unmatched [] in regexp ...\n"
5925 74 100       103 # (and so on)
5926 74         168  
5927             if ($char[$i+1] eq ']') {
5928             $i++;
5929 4         7 }
5930 74 50       89  
5931 272         367 while (1) {
5932             if (++$i > $#char) {
5933 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5934 272         409 }
5935             if ($char[$i] eq ']') {
5936             my $right = $i;
5937 74 100       89  
5938 74         371 # [^...]
  30         74  
5939             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5940             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5941 90         188 }
5942             else {
5943             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5944 44         172 }
5945 74         135  
5946             $i = $left;
5947             last;
5948             }
5949             }
5950             }
5951              
5952 74         1471 # rewrite character class or escape character
5953             elsif (my $char = character_class($char[$i],$modifier)) {
5954             $char[$i] = $char;
5955             }
5956              
5957 139 50       361 # /i modifier
5958 20         33 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
5959             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
5960             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
5961 20         32 }
5962             else {
5963             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
5964             }
5965             }
5966              
5967 0 50       0 # \u \l \U \L \F \Q \E
5968 1         4 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5969             if ($right_e < $left_e) {
5970             $char[$i] = '\\' . $char[$i];
5971             }
5972 0         0 }
5973 0         0 elsif ($char[$i] eq '\u') {
5974             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5975             $left_e++;
5976 0         0 }
5977 0         0 elsif ($char[$i] eq '\l') {
5978             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5979             $left_e++;
5980 0         0 }
5981 1         3 elsif ($char[$i] eq '\U') {
5982             $char[$i] = '@{[Ekoi8u::uc qq<';
5983             $left_e++;
5984 1         3 }
5985 1         4 elsif ($char[$i] eq '\L') {
5986             $char[$i] = '@{[Ekoi8u::lc qq<';
5987             $left_e++;
5988 1         3 }
5989 18         32 elsif ($char[$i] eq '\F') {
5990             $char[$i] = '@{[Ekoi8u::fc qq<';
5991             $left_e++;
5992 18         37 }
5993 1         3 elsif ($char[$i] eq '\Q') {
5994             $char[$i] = '@{[CORE::quotemeta qq<';
5995             $left_e++;
5996 1 50       3 }
5997 21         45 elsif ($char[$i] eq '\E') {
5998 21         239 if ($right_e < $left_e) {
5999             $char[$i] = '>]}';
6000             $right_e++;
6001 21         51 }
6002             else {
6003             $char[$i] = '';
6004             }
6005 0         0 }
6006 0 0       0 elsif ($char[$i] eq '\Q') {
6007 0         0 while (1) {
6008             if (++$i > $#char) {
6009 0 0       0 last;
6010 0         0 }
6011             if ($char[$i] eq '\E') {
6012             last;
6013             }
6014             }
6015             }
6016             elsif ($char[$i] eq '\E') {
6017             }
6018              
6019 0 0       0 # $0 --> $0
6020 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6021             if ($ignorecase) {
6022             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6023             }
6024 0 0       0 }
6025 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6026             if ($ignorecase) {
6027             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6028             }
6029             }
6030              
6031             # $$ --> $$
6032             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6033             }
6034              
6035             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6036 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6037 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6038 0         0 $char[$i] = e_capture($1);
6039             if ($ignorecase) {
6040             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6041             }
6042 0         0 }
6043 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6044 0         0 $char[$i] = e_capture($1);
6045             if ($ignorecase) {
6046             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6047             }
6048             }
6049              
6050 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6051 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) {
6052 0         0 $char[$i] = e_capture($1.'->'.$2);
6053             if ($ignorecase) {
6054             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6055             }
6056             }
6057              
6058 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6059 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) {
6060 0         0 $char[$i] = e_capture($1.'->'.$2);
6061             if ($ignorecase) {
6062             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6063             }
6064             }
6065              
6066 0         0 # $$foo
6067 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6068 0         0 $char[$i] = e_capture($1);
6069             if ($ignorecase) {
6070             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6071             }
6072             }
6073              
6074 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
6075 8         24 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6076             if ($ignorecase) {
6077             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
6078 0         0 }
6079             else {
6080             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
6081             }
6082             }
6083              
6084 8 50       23 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
6085 8         21 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6086             if ($ignorecase) {
6087             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
6088 0         0 }
6089             else {
6090             $char[$i] = '@{[Ekoi8u::MATCH()]}';
6091             }
6092             }
6093              
6094 8 50       21 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
6095 6         17 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6096             if ($ignorecase) {
6097             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
6098 0         0 }
6099             else {
6100             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
6101             }
6102             }
6103              
6104 6 0       23 # ${ foo }
6105 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) {
6106             if ($ignorecase) {
6107             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6108             }
6109             }
6110              
6111 0         0 # ${ ... }
6112 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6113 0         0 $char[$i] = e_capture($1);
6114             if ($ignorecase) {
6115             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6116             }
6117             }
6118              
6119 0         0 # $scalar or @array
6120 21 100       54 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6121 21         140 $char[$i] = e_string($char[$i]);
6122             if ($ignorecase) {
6123             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6124             }
6125             }
6126              
6127 11 100 33     37 # quote character before ? + * {
    50          
6128             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6129             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6130 138         954 }
6131 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6132 0         0 my $char = $char[$i-1];
6133             if ($char[$i] eq '{') {
6134             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
6135 0         0 }
6136             else {
6137             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
6138             }
6139 0         0 }
6140             else {
6141             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6142             }
6143             }
6144             }
6145 127         613  
6146 642 50       1170 # make regexp string
6147 642 0 0     1467 $modifier =~ tr/i//d;
6148 0         0 if ($left_e > $right_e) {
6149             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6150             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
6151 0         0 }
6152             else {
6153             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6154 0 50 33     0 }
6155 642         3839 }
6156             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6157             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
6158 0         0 }
6159             else {
6160             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6161             }
6162             }
6163              
6164             #
6165             # double quote stuff
6166 642     180 0 21590 #
6167             sub qq_stuff {
6168             my($delimiter,$end_delimiter,$stuff) = @_;
6169 180 100       277  
6170 180         360 # scalar variable or array variable
6171             if ($stuff =~ /\A [\$\@] /oxms) {
6172             return $stuff;
6173             }
6174 100         404  
  80         187  
6175 80         242 # quote by delimiter
6176 80 50       221 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
6177 80 50       147 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6178 80 50       133 next if $char eq $delimiter;
6179 80         158 next if $char eq $end_delimiter;
6180             if (not $octet{$char}) {
6181             return join '', 'qq', $char, $stuff, $char;
6182 80         337 }
6183             }
6184             return join '', 'qq', '<', $stuff, '>';
6185             }
6186              
6187             #
6188             # escape regexp (m'', qr'', and m''b, qr''b)
6189 0     10 0 0 #
6190 10   50     42 sub e_qr_q {
6191             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6192 10         42 $modifier ||= '';
6193 10 50       15  
6194 10         21 $modifier =~ tr/p//d;
6195 0         0 if ($modifier =~ /([adlu])/oxms) {
6196 0 0       0 my $line = 0;
6197 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6198 0         0 if ($filename ne __FILE__) {
6199             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6200             last;
6201 0         0 }
6202             }
6203             die qq{Unsupported modifier "$1" used at line $line.\n};
6204 0         0 }
6205              
6206             $slash = 'div';
6207 10 100       13  
    50          
6208 10         22 # literal null string pattern
6209 8         10 if ($string eq '') {
6210 8         9 $modifier =~ tr/bB//d;
6211             $modifier =~ tr/i//d;
6212             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6213             }
6214              
6215 8         37 # with /b /B modifier
6216             elsif ($modifier =~ tr/bB//d) {
6217             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6218             }
6219              
6220 0         0 # without /b /B modifier
6221             else {
6222             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6223             }
6224             }
6225              
6226             #
6227             # escape regexp (m'', qr'')
6228 2     2 0 6 #
6229             sub e_qr_qt {
6230 2 50       7 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6231              
6232             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6233 2         6  
6234             # split regexp
6235             my @char = $string =~ /\G((?>
6236             [^\\\[\$\@\/] |
6237             [\x00-\xFF] |
6238             \[\^ |
6239             \[\: (?>[a-z]+) \:\] |
6240             \[\:\^ (?>[a-z]+) \:\] |
6241             [\$\@\/] |
6242             \\ (?:$q_char) |
6243             (?:$q_char)
6244             ))/oxmsg;
6245 2         63  
6246 2 50 33     11 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
6247             for (my $i=0; $i <= $#char; $i++) {
6248             if (0) {
6249             }
6250 2         29  
6251 0         0 # open character class [...]
6252 0 0       0 elsif ($char[$i] eq '[') {
6253 0         0 my $left = $i;
6254             if ($char[$i+1] eq ']') {
6255 0         0 $i++;
6256 0 0       0 }
6257 0         0 while (1) {
6258             if (++$i > $#char) {
6259 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6260 0         0 }
6261             if ($char[$i] eq ']') {
6262             my $right = $i;
6263 0         0  
6264             # [...]
6265 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6266 0         0  
6267             $i = $left;
6268             last;
6269             }
6270             }
6271             }
6272              
6273 0         0 # open character class [^...]
6274 0 0       0 elsif ($char[$i] eq '[^') {
6275 0         0 my $left = $i;
6276             if ($char[$i+1] eq ']') {
6277 0         0 $i++;
6278 0 0       0 }
6279 0         0 while (1) {
6280             if (++$i > $#char) {
6281 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6282 0         0 }
6283             if ($char[$i] eq ']') {
6284             my $right = $i;
6285 0         0  
6286             # [^...]
6287 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6288 0         0  
6289             $i = $left;
6290             last;
6291             }
6292             }
6293             }
6294              
6295 0         0 # escape $ @ / and \
6296             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6297             $char[$i] = '\\' . $char[$i];
6298             }
6299              
6300 0         0 # rewrite character class or escape character
6301             elsif (my $char = character_class($char[$i],$modifier)) {
6302             $char[$i] = $char;
6303             }
6304              
6305 0 0       0 # /i modifier
6306 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6307             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6308             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6309 0         0 }
6310             else {
6311             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6312             }
6313             }
6314              
6315 0 0       0 # quote character before ? + * {
6316             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6317             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6318 0         0 }
6319             else {
6320             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6321             }
6322             }
6323 0         0 }
6324 2         5  
6325             $delimiter = '/';
6326 2         4 $end_delimiter = '/';
6327 2         3  
6328             $modifier =~ tr/i//d;
6329             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6330             }
6331              
6332             #
6333             # escape regexp (m''b, qr''b)
6334 2     0 0 15 #
6335             sub e_qr_qb {
6336             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6337 0         0  
6338             # split regexp
6339             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6340 0         0  
6341 0 0       0 # unescape character
    0          
6342             for (my $i=0; $i <= $#char; $i++) {
6343             if (0) {
6344             }
6345 0         0  
6346             # remain \\
6347             elsif ($char[$i] eq '\\\\') {
6348             }
6349              
6350 0         0 # escape $ @ / and \
6351             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6352             $char[$i] = '\\' . $char[$i];
6353             }
6354 0         0 }
6355 0         0  
6356 0         0 $delimiter = '/';
6357             $end_delimiter = '/';
6358             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6359             }
6360              
6361             #
6362             # escape regexp (s/here//)
6363 0     76 0 0 #
6364 76   100     260 sub e_s1 {
6365             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6366 76         388 $modifier ||= '';
6367 76 50       122  
6368 76         226 $modifier =~ tr/p//d;
6369 0         0 if ($modifier =~ /([adlu])/oxms) {
6370 0 0       0 my $line = 0;
6371 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6372 0         0 if ($filename ne __FILE__) {
6373             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6374             last;
6375 0         0 }
6376             }
6377             die qq{Unsupported modifier "$1" used at line $line.\n};
6378 0         0 }
6379              
6380             $slash = 'div';
6381 76 100       152  
    50          
6382 76         277 # literal null string pattern
6383 8         9 if ($string eq '') {
6384 8         9 $modifier =~ tr/bB//d;
6385             $modifier =~ tr/i//d;
6386             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6387             }
6388              
6389             # /b /B modifier
6390             elsif ($modifier =~ tr/bB//d) {
6391 8 0       51  
6392 0         0 # choice again delimiter
6393 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
6394 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
6395 0         0 my %octet = map {$_ => 1} @char;
6396 0         0 if (not $octet{')'}) {
6397             $delimiter = '(';
6398             $end_delimiter = ')';
6399 0         0 }
6400 0         0 elsif (not $octet{'}'}) {
6401             $delimiter = '{';
6402             $end_delimiter = '}';
6403 0         0 }
6404 0         0 elsif (not $octet{']'}) {
6405             $delimiter = '[';
6406             $end_delimiter = ']';
6407 0         0 }
6408 0         0 elsif (not $octet{'>'}) {
6409             $delimiter = '<';
6410             $end_delimiter = '>';
6411 0         0 }
6412 0 0       0 else {
6413 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6414 0         0 if (not $octet{$char}) {
6415 0         0 $delimiter = $char;
6416             $end_delimiter = $char;
6417             last;
6418             }
6419             }
6420             }
6421 0         0 }
6422 0         0  
6423             my $prematch = '';
6424             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6425 0 100       0 }
6426 68         233  
6427             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6428             my $metachar = qr/[\@\\|[\]{^]/oxms;
6429 68         263  
6430             # split regexp
6431             my @char = $string =~ /\G((?>
6432             [^\\\$\@\[\(] |
6433             \\ (?>[1-9][0-9]*) |
6434             \\g (?>\s*) (?>[1-9][0-9]*) |
6435             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6436             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6437             \\x (?>[0-9A-Fa-f]{1,2}) |
6438             \\ (?>[0-7]{2,3}) |
6439             \\c [\x40-\x5F] |
6440             \\x\{ (?>[0-9A-Fa-f]+) \} |
6441             \\o\{ (?>[0-7]+) \} |
6442             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6443             \\ $q_char |
6444             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6445             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6446             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6447             [\$\@] $qq_variable |
6448             \$ (?>\s* [0-9]+) |
6449             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6450             \$ \$ (?![\w\{]) |
6451             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6452             \[\^ |
6453             \[\: (?>[a-z]+) :\] |
6454             \[\:\^ (?>[a-z]+) :\] |
6455             \(\? |
6456             $q_char
6457             ))/oxmsg;
6458 68 50       20750  
6459 68         463 # choice again delimiter
  0         0  
6460 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
6461 0         0 my %octet = map {$_ => 1} @char;
6462 0         0 if (not $octet{')'}) {
6463             $delimiter = '(';
6464             $end_delimiter = ')';
6465 0         0 }
6466 0         0 elsif (not $octet{'}'}) {
6467             $delimiter = '{';
6468             $end_delimiter = '}';
6469 0         0 }
6470 0         0 elsif (not $octet{']'}) {
6471             $delimiter = '[';
6472             $end_delimiter = ']';
6473 0         0 }
6474 0         0 elsif (not $octet{'>'}) {
6475             $delimiter = '<';
6476             $end_delimiter = '>';
6477 0         0 }
6478 0 0       0 else {
6479 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6480 0         0 if (not $octet{$char}) {
6481 0         0 $delimiter = $char;
6482             $end_delimiter = $char;
6483             last;
6484             }
6485             }
6486             }
6487             }
6488 0         0  
  68         221  
6489             # count '('
6490 253         430 my $parens = grep { $_ eq '(' } @char;
6491 68         117  
6492 68         101 my $left_e = 0;
6493             my $right_e = 0;
6494             for (my $i=0; $i <= $#char; $i++) {
6495 68 50 33     202  
    50 33        
    100          
    100          
    50          
    50          
6496 195         2278 # "\L\u" --> "\u\L"
6497             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6498             @char[$i,$i+1] = @char[$i+1,$i];
6499             }
6500              
6501 0         0 # "\U\l" --> "\l\U"
6502             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6503             @char[$i,$i+1] = @char[$i+1,$i];
6504             }
6505              
6506 0         0 # octal escape sequence
6507             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6508             $char[$i] = Ekoi8u::octchr($1);
6509             }
6510              
6511 1         3 # hexadecimal escape sequence
6512             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6513             $char[$i] = Ekoi8u::hexchr($1);
6514             }
6515              
6516             # \b{...} --> b\{...}
6517             # \B{...} --> B\{...}
6518             # \N{CHARNAME} --> N\{CHARNAME}
6519             # \p{PROPERTY} --> p\{PROPERTY}
6520 1         3 # \P{PROPERTY} --> P\{PROPERTY}
6521             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6522             $char[$i] = $1 . '\\' . $2;
6523             }
6524              
6525 0         0 # \p, \P, \X --> p, P, X
6526             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6527             $char[$i] = $1;
6528 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          
6529              
6530             if (0) {
6531             }
6532 195         765  
6533 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6534 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6535             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)) {
6536             $char[$i] .= join '', splice @char, $i+1, 3;
6537 0         0 }
6538             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)) {
6539             $char[$i] .= join '', splice @char, $i+1, 2;
6540 0         0 }
6541             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)) {
6542             $char[$i] .= join '', splice @char, $i+1, 1;
6543             }
6544             }
6545              
6546 0         0 # open character class [...]
6547 13 50       20 elsif ($char[$i] eq '[') {
6548 13         44 my $left = $i;
6549             if ($char[$i+1] eq ']') {
6550 0         0 $i++;
6551 13 50       18 }
6552 58         104 while (1) {
6553             if (++$i > $#char) {
6554 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6555 58         204 }
6556             if ($char[$i] eq ']') {
6557             my $right = $i;
6558 13 50       31  
6559 13         82 # [...]
  0         0  
6560             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6561             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6562 0         0 }
6563             else {
6564             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6565 13         60 }
6566 13         23  
6567             $i = $left;
6568             last;
6569             }
6570             }
6571             }
6572              
6573 13         36 # open character class [^...]
6574 0 0       0 elsif ($char[$i] eq '[^') {
6575 0         0 my $left = $i;
6576             if ($char[$i+1] eq ']') {
6577 0         0 $i++;
6578 0 0       0 }
6579 0         0 while (1) {
6580             if (++$i > $#char) {
6581 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6582 0         0 }
6583             if ($char[$i] eq ']') {
6584             my $right = $i;
6585 0 0       0  
6586 0         0 # [^...]
  0         0  
6587             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6588             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6589 0         0 }
6590             else {
6591             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6592 0         0 }
6593 0         0  
6594             $i = $left;
6595             last;
6596             }
6597             }
6598             }
6599              
6600 0         0 # rewrite character class or escape character
6601             elsif (my $char = character_class($char[$i],$modifier)) {
6602             $char[$i] = $char;
6603             }
6604              
6605 7 50       16 # /i modifier
6606 3         6 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6607             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6608             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6609 3         8 }
6610             else {
6611             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6612             }
6613             }
6614              
6615 0 0       0 # \u \l \U \L \F \Q \E
6616 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6617             if ($right_e < $left_e) {
6618             $char[$i] = '\\' . $char[$i];
6619             }
6620 0         0 }
6621 0         0 elsif ($char[$i] eq '\u') {
6622             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
6623             $left_e++;
6624 0         0 }
6625 0         0 elsif ($char[$i] eq '\l') {
6626             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
6627             $left_e++;
6628 0         0 }
6629 0         0 elsif ($char[$i] eq '\U') {
6630             $char[$i] = '@{[Ekoi8u::uc qq<';
6631             $left_e++;
6632 0         0 }
6633 0         0 elsif ($char[$i] eq '\L') {
6634             $char[$i] = '@{[Ekoi8u::lc qq<';
6635             $left_e++;
6636 0         0 }
6637 0         0 elsif ($char[$i] eq '\F') {
6638             $char[$i] = '@{[Ekoi8u::fc qq<';
6639             $left_e++;
6640 0         0 }
6641 0         0 elsif ($char[$i] eq '\Q') {
6642             $char[$i] = '@{[CORE::quotemeta qq<';
6643             $left_e++;
6644 0 0       0 }
6645 0         0 elsif ($char[$i] eq '\E') {
6646 0         0 if ($right_e < $left_e) {
6647             $char[$i] = '>]}';
6648             $right_e++;
6649 0         0 }
6650             else {
6651             $char[$i] = '';
6652             }
6653 0         0 }
6654 0 0       0 elsif ($char[$i] eq '\Q') {
6655 0         0 while (1) {
6656             if (++$i > $#char) {
6657 0 0       0 last;
6658 0         0 }
6659             if ($char[$i] eq '\E') {
6660             last;
6661             }
6662             }
6663             }
6664             elsif ($char[$i] eq '\E') {
6665             }
6666              
6667             # \0 --> \0
6668             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6669             }
6670              
6671             # \g{N}, \g{-N}
6672              
6673             # P.108 Using Simple Patterns
6674             # in Chapter 7: In the World of Regular Expressions
6675             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6676              
6677             # P.221 Capturing
6678             # in Chapter 5: Pattern Matching
6679             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6680              
6681             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6682             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6683             }
6684              
6685             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6686             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6687             }
6688              
6689             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6690             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6691             }
6692              
6693             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6694             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6695             }
6696              
6697 0 0       0 # $0 --> $0
6698 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6699             if ($ignorecase) {
6700             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6701             }
6702 0 0       0 }
6703 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6704             if ($ignorecase) {
6705             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6706             }
6707             }
6708              
6709             # $$ --> $$
6710             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6711             }
6712              
6713             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6714 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6715 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6716 0         0 $char[$i] = e_capture($1);
6717             if ($ignorecase) {
6718             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6719             }
6720 0         0 }
6721 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6722 0         0 $char[$i] = e_capture($1);
6723             if ($ignorecase) {
6724             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6725             }
6726             }
6727              
6728 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6729 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) {
6730 0         0 $char[$i] = e_capture($1.'->'.$2);
6731             if ($ignorecase) {
6732             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6733             }
6734             }
6735              
6736 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6737 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) {
6738 0         0 $char[$i] = e_capture($1.'->'.$2);
6739             if ($ignorecase) {
6740             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6741             }
6742             }
6743              
6744 0         0 # $$foo
6745 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6746 0         0 $char[$i] = e_capture($1);
6747             if ($ignorecase) {
6748             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6749             }
6750             }
6751              
6752 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
6753 4         14 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6754             if ($ignorecase) {
6755             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
6756 0         0 }
6757             else {
6758             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
6759             }
6760             }
6761              
6762 4 50       14 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
6763 4         16 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6764             if ($ignorecase) {
6765             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
6766 0         0 }
6767             else {
6768             $char[$i] = '@{[Ekoi8u::MATCH()]}';
6769             }
6770             }
6771              
6772 4 50       12 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
6773 3         12 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6774             if ($ignorecase) {
6775             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
6776 0         0 }
6777             else {
6778             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
6779             }
6780             }
6781              
6782 3 0       11 # ${ foo }
6783 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) {
6784             if ($ignorecase) {
6785             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6786             }
6787             }
6788              
6789 0         0 # ${ ... }
6790 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6791 0         0 $char[$i] = e_capture($1);
6792             if ($ignorecase) {
6793             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6794             }
6795             }
6796              
6797 0         0 # $scalar or @array
6798 4 50       29 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6799 4         20 $char[$i] = e_string($char[$i]);
6800             if ($ignorecase) {
6801             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6802             }
6803             }
6804              
6805 0 50       0 # quote character before ? + * {
6806             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6807             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6808 13         64 }
6809             else {
6810             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6811             }
6812             }
6813             }
6814 13         61  
6815 68         154 # make regexp string
6816 68 50       133 my $prematch = '';
6817 68         168 $modifier =~ tr/i//d;
6818             if ($left_e > $right_e) {
6819 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6820             }
6821             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6822             }
6823              
6824             #
6825             # escape regexp (s'here'' or s'here''b)
6826 68     21 0 853 #
6827 21   100     49 sub e_s1_q {
6828             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6829 21         65 $modifier ||= '';
6830 21 50       26  
6831 21         45 $modifier =~ tr/p//d;
6832 0         0 if ($modifier =~ /([adlu])/oxms) {
6833 0 0       0 my $line = 0;
6834 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6835 0         0 if ($filename ne __FILE__) {
6836             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6837             last;
6838 0         0 }
6839             }
6840             die qq{Unsupported modifier "$1" used at line $line.\n};
6841 0         0 }
6842              
6843             $slash = 'div';
6844 21 100       31  
    50          
6845 21         54 # literal null string pattern
6846 8         9 if ($string eq '') {
6847 8         21 $modifier =~ tr/bB//d;
6848             $modifier =~ tr/i//d;
6849             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6850             }
6851              
6852 8         46 # with /b /B modifier
6853             elsif ($modifier =~ tr/bB//d) {
6854             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6855             }
6856              
6857 0         0 # without /b /B modifier
6858             else {
6859             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6860             }
6861             }
6862              
6863             #
6864             # escape regexp (s'here'')
6865 13     13 0 30 #
6866             sub e_s1_qt {
6867 13 50       27 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6868              
6869             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6870 13         26  
6871             # split regexp
6872             my @char = $string =~ /\G((?>
6873             [^\\\[\$\@\/] |
6874             [\x00-\xFF] |
6875             \[\^ |
6876             \[\: (?>[a-z]+) \:\] |
6877             \[\:\^ (?>[a-z]+) \:\] |
6878             [\$\@\/] |
6879             \\ (?:$q_char) |
6880             (?:$q_char)
6881             ))/oxmsg;
6882 13         187  
6883 13 50 33     37 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6884             for (my $i=0; $i <= $#char; $i++) {
6885             if (0) {
6886             }
6887 25         98  
6888 0         0 # open character class [...]
6889 0 0       0 elsif ($char[$i] eq '[') {
6890 0         0 my $left = $i;
6891             if ($char[$i+1] eq ']') {
6892 0         0 $i++;
6893 0 0       0 }
6894 0         0 while (1) {
6895             if (++$i > $#char) {
6896 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6897 0         0 }
6898             if ($char[$i] eq ']') {
6899             my $right = $i;
6900 0         0  
6901             # [...]
6902 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6903 0         0  
6904             $i = $left;
6905             last;
6906             }
6907             }
6908             }
6909              
6910 0         0 # open character class [^...]
6911 0 0       0 elsif ($char[$i] eq '[^') {
6912 0         0 my $left = $i;
6913             if ($char[$i+1] eq ']') {
6914 0         0 $i++;
6915 0 0       0 }
6916 0         0 while (1) {
6917             if (++$i > $#char) {
6918 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6919 0         0 }
6920             if ($char[$i] eq ']') {
6921             my $right = $i;
6922 0         0  
6923             # [^...]
6924 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6925 0         0  
6926             $i = $left;
6927             last;
6928             }
6929             }
6930             }
6931              
6932 0         0 # escape $ @ / and \
6933             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6934             $char[$i] = '\\' . $char[$i];
6935             }
6936              
6937 0         0 # rewrite character class or escape character
6938             elsif (my $char = character_class($char[$i],$modifier)) {
6939             $char[$i] = $char;
6940             }
6941              
6942 6 0       13 # /i modifier
6943 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6944             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6945             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6946 0         0 }
6947             else {
6948             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6949             }
6950             }
6951              
6952 0 0       0 # quote character before ? + * {
6953             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6954             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6955 0         0 }
6956             else {
6957             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6958             }
6959             }
6960 0         0 }
6961 13         21  
6962 13         21 $modifier =~ tr/i//d;
6963 13         13 $delimiter = '/';
6964 13         18 $end_delimiter = '/';
6965             my $prematch = '';
6966             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6967             }
6968              
6969             #
6970             # escape regexp (s'here''b)
6971 13     0 0 90 #
6972             sub e_s1_qb {
6973             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6974 0         0  
6975             # split regexp
6976             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6977 0         0  
6978 0 0       0 # unescape character
    0          
6979             for (my $i=0; $i <= $#char; $i++) {
6980             if (0) {
6981             }
6982 0         0  
6983             # remain \\
6984             elsif ($char[$i] eq '\\\\') {
6985             }
6986              
6987 0         0 # escape $ @ / and \
6988             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6989             $char[$i] = '\\' . $char[$i];
6990             }
6991 0         0 }
6992 0         0  
6993 0         0 $delimiter = '/';
6994 0         0 $end_delimiter = '/';
6995             my $prematch = '';
6996             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6997             }
6998              
6999             #
7000             # escape regexp (s''here')
7001 0     16 0 0 #
7002             sub e_s2_q {
7003 16         30 my($ope,$delimiter,$end_delimiter,$string) = @_;
7004              
7005 16         21 $slash = 'div';
7006 16         96  
7007 16 100       48 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
7008             for (my $i=0; $i <= $#char; $i++) {
7009             if (0) {
7010             }
7011 9         30  
7012             # not escape \\
7013             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
7014             }
7015              
7016 0         0 # escape $ @ / and \
7017             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7018             $char[$i] = '\\' . $char[$i];
7019             }
7020 5         15 }
7021              
7022             return join '', $ope, $delimiter, @char, $end_delimiter;
7023             }
7024              
7025             #
7026             # escape regexp (s/here/and here/modifier)
7027 16     97 0 48 #
7028 97   100     777 sub e_sub {
7029             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
7030 97         452 $modifier ||= '';
7031 97 50       187  
7032 97         291 $modifier =~ tr/p//d;
7033 0         0 if ($modifier =~ /([adlu])/oxms) {
7034 0 0       0 my $line = 0;
7035 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7036 0         0 if ($filename ne __FILE__) {
7037             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7038             last;
7039 0         0 }
7040             }
7041             die qq{Unsupported modifier "$1" used at line $line.\n};
7042 0 100       0 }
7043 97         327  
7044 36         50 if ($variable eq '') {
7045             $variable = '$_';
7046             $bind_operator = ' =~ ';
7047 36         46 }
7048              
7049             $slash = 'div';
7050              
7051             # P.128 Start of match (or end of previous match): \G
7052             # P.130 Advanced Use of \G with Perl
7053             # in Chapter 3: Overview of Regular Expression Features and Flavors
7054             # P.312 Iterative Matching: Scalar Context, with /g
7055             # in Chapter 7: Perl
7056             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
7057              
7058             # P.181 Where You Left Off: The \G Assertion
7059             # in Chapter 5: Pattern Matching
7060             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7061              
7062             # P.220 Where You Left Off: The \G Assertion
7063             # in Chapter 5: Pattern Matching
7064 97         182 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7065 97         152  
7066             my $e_modifier = $modifier =~ tr/e//d;
7067 97         138 my $r_modifier = $modifier =~ tr/r//d;
7068 97 50       138  
7069 97         239 my $my = '';
7070 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
7071 0         0 $my = $variable;
7072             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
7073             $variable =~ s/ = .+ \z//oxms;
7074 0         0 }
7075 97         247  
7076             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
7077             $variable_basename =~ s/ \s+ \z//oxms;
7078 97         174  
7079 97 100       157 # quote replacement string
7080 97         241 my $e_replacement = '';
7081 17         31 if ($e_modifier >= 1) {
7082             $e_replacement = e_qq('', '', '', $replacement);
7083             $e_modifier--;
7084 17 100       28 }
7085 80         187 else {
7086             if ($delimiter2 eq "'") {
7087             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
7088 16         38 }
7089             else {
7090             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
7091             }
7092 64         145 }
7093              
7094             my $sub = '';
7095 97 100       158  
7096 97 100       223 # with /r
7097             if ($r_modifier) {
7098             if (0) {
7099             }
7100 8         24  
7101 0 50       0 # s///gr without multibyte anchoring
7102             elsif ($modifier =~ /g/oxms) {
7103             $sub = sprintf(
7104             # 1 2 3 4 5
7105             q,
7106              
7107             $variable, # 1
7108             ($delimiter1 eq "'") ? # 2
7109             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7110             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7111             $s_matched, # 3
7112             $e_replacement, # 4
7113             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
7114             );
7115             }
7116              
7117             # s///r
7118 4         23 else {
7119              
7120 4 50       6 my $prematch = q{$`};
7121              
7122             $sub = sprintf(
7123             # 1 2 3 4 5 6 7
7124             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s"%s$Ekoi8u::re_r$'" } : %s>,
7125              
7126             $variable, # 1
7127             ($delimiter1 eq "'") ? # 2
7128             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7129             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7130             $s_matched, # 3
7131             $e_replacement, # 4
7132             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
7133             $prematch, # 6
7134             $variable, # 7
7135             );
7136             }
7137 4 50       18  
7138 8         30 # $var !~ s///r doesn't make sense
7139             if ($bind_operator =~ / !~ /oxms) {
7140             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
7141             }
7142             }
7143              
7144 0 100       0 # without /r
7145             else {
7146             if (0) {
7147             }
7148 89         212  
7149 0 100       0 # s///g without multibyte anchoring
    100          
7150             elsif ($modifier =~ /g/oxms) {
7151             $sub = sprintf(
7152             # 1 2 3 4 5 6 7 8
7153             q,
7154              
7155             $variable, # 1
7156             ($delimiter1 eq "'") ? # 2
7157             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7158             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7159             $s_matched, # 3
7160             $e_replacement, # 4
7161             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
7162             $variable, # 6
7163             $variable, # 7
7164             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
7165             );
7166             }
7167              
7168             # s///
7169 22         269 else {
7170              
7171 67 100       120 my $prematch = q{$`};
    100          
7172              
7173             $sub = sprintf(
7174              
7175             ($bind_operator =~ / =~ /oxms) ?
7176              
7177             # 1 2 3 4 5 6 7 8
7178             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s%s="%s$Ekoi8u::re_r$'"; 1 } : undef> :
7179              
7180             # 1 2 3 4 5 6 7 8
7181             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s%s="%s$Ekoi8u::re_r$'"; undef }>,
7182              
7183             $variable, # 1
7184             $bind_operator, # 2
7185             ($delimiter1 eq "'") ? # 3
7186             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7187             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7188             $s_matched, # 4
7189             $e_replacement, # 5
7190             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 6
7191             $variable, # 7
7192             $prematch, # 8
7193             );
7194             }
7195             }
7196 67 50       397  
7197 97         269 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
7198             if ($my ne '') {
7199             $sub = "($my, $sub)[1]";
7200             }
7201 0         0  
7202 97         153 # clear s/// variable
7203             $sub_variable = '';
7204 97         130 $bind_operator = '';
7205              
7206             return $sub;
7207             }
7208              
7209             #
7210             # escape regexp of split qr//
7211 97     74 0 929 #
7212 74   100     337 sub e_split {
7213             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7214 74         369 $modifier ||= '';
7215 74 50       123  
7216 74         191 $modifier =~ tr/p//d;
7217 0         0 if ($modifier =~ /([adlu])/oxms) {
7218 0 0       0 my $line = 0;
7219 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7220 0         0 if ($filename ne __FILE__) {
7221             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7222             last;
7223 0         0 }
7224             }
7225             die qq{Unsupported modifier "$1" used at line $line.\n};
7226 0         0 }
7227              
7228             $slash = 'div';
7229 74 50       130  
7230 74         156 # /b /B modifier
7231             if ($modifier =~ tr/bB//d) {
7232             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7233 0 50       0 }
7234 74         184  
7235             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7236             my $metachar = qr/[\@\\|[\]{^]/oxms;
7237 74         275  
7238             # split regexp
7239             my @char = $string =~ /\G((?>
7240             [^\\\$\@\[\(] |
7241             \\x (?>[0-9A-Fa-f]{1,2}) |
7242             \\ (?>[0-7]{2,3}) |
7243             \\c [\x40-\x5F] |
7244             \\x\{ (?>[0-9A-Fa-f]+) \} |
7245             \\o\{ (?>[0-7]+) \} |
7246             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7247             \\ $q_char |
7248             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7249             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7250             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7251             [\$\@] $qq_variable |
7252             \$ (?>\s* [0-9]+) |
7253             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7254             \$ \$ (?![\w\{]) |
7255             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7256             \[\^ |
7257             \[\: (?>[a-z]+) :\] |
7258             \[\:\^ (?>[a-z]+) :\] |
7259             \(\? |
7260             $q_char
7261 74         8962 ))/oxmsg;
7262 74         291  
7263 74         106 my $left_e = 0;
7264             my $right_e = 0;
7265             for (my $i=0; $i <= $#char; $i++) {
7266 74 50 33     390  
    50 33        
    100          
    100          
    50          
    50          
7267 249         1197 # "\L\u" --> "\u\L"
7268             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7269             @char[$i,$i+1] = @char[$i+1,$i];
7270             }
7271              
7272 0         0 # "\U\l" --> "\l\U"
7273             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7274             @char[$i,$i+1] = @char[$i+1,$i];
7275             }
7276              
7277 0         0 # octal escape sequence
7278             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7279             $char[$i] = Ekoi8u::octchr($1);
7280             }
7281              
7282 1         3 # hexadecimal escape sequence
7283             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7284             $char[$i] = Ekoi8u::hexchr($1);
7285             }
7286              
7287             # \b{...} --> b\{...}
7288             # \B{...} --> B\{...}
7289             # \N{CHARNAME} --> N\{CHARNAME}
7290             # \p{PROPERTY} --> p\{PROPERTY}
7291 1         3 # \P{PROPERTY} --> P\{PROPERTY}
7292             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7293             $char[$i] = $1 . '\\' . $2;
7294             }
7295              
7296 0         0 # \p, \P, \X --> p, P, X
7297             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7298             $char[$i] = $1;
7299 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          
7300              
7301             if (0) {
7302             }
7303 249         796  
7304 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
7305 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7306             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)) {
7307             $char[$i] .= join '', splice @char, $i+1, 3;
7308 0         0 }
7309             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)) {
7310             $char[$i] .= join '', splice @char, $i+1, 2;
7311 0         0 }
7312             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)) {
7313             $char[$i] .= join '', splice @char, $i+1, 1;
7314             }
7315             }
7316              
7317 0         0 # open character class [...]
7318 3 50       4 elsif ($char[$i] eq '[') {
7319 3         8 my $left = $i;
7320             if ($char[$i+1] eq ']') {
7321 0         0 $i++;
7322 3 50       5 }
7323 7         10 while (1) {
7324             if (++$i > $#char) {
7325 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7326 7         13 }
7327             if ($char[$i] eq ']') {
7328             my $right = $i;
7329 3 50       5  
7330 3         39 # [...]
  0         0  
7331             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7332             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7333 0         0 }
7334             else {
7335             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
7336 3         15 }
7337 3         6  
7338             $i = $left;
7339             last;
7340             }
7341             }
7342             }
7343              
7344 3         7 # open character class [^...]
7345 0 0       0 elsif ($char[$i] eq '[^') {
7346 0         0 my $left = $i;
7347             if ($char[$i+1] eq ']') {
7348 0         0 $i++;
7349 0 0       0 }
7350 0         0 while (1) {
7351             if (++$i > $#char) {
7352 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7353 0         0 }
7354             if ($char[$i] eq ']') {
7355             my $right = $i;
7356 0 0       0  
7357 0         0 # [^...]
  0         0  
7358             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7359             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7360 0         0 }
7361             else {
7362             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7363 0         0 }
7364 0         0  
7365             $i = $left;
7366             last;
7367             }
7368             }
7369             }
7370              
7371 0         0 # rewrite character class or escape character
7372             elsif (my $char = character_class($char[$i],$modifier)) {
7373             $char[$i] = $char;
7374             }
7375              
7376             # P.794 29.2.161. split
7377             # in Chapter 29: Functions
7378             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7379              
7380             # P.951 split
7381             # in Chapter 27: Functions
7382             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7383              
7384             # said "The //m modifier is assumed when you split on the pattern /^/",
7385             # but perl5.008 is not so. Therefore, this software adds //m.
7386             # (and so on)
7387              
7388 1         3 # split(m/^/) --> split(m/^/m)
7389             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7390             $modifier .= 'm';
7391             }
7392              
7393 7 0       20 # /i modifier
7394 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
7395             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
7396             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
7397 0         0 }
7398             else {
7399             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
7400             }
7401             }
7402              
7403 0 0       0 # \u \l \U \L \F \Q \E
7404 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7405             if ($right_e < $left_e) {
7406             $char[$i] = '\\' . $char[$i];
7407             }
7408 0         0 }
7409 0         0 elsif ($char[$i] eq '\u') {
7410             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
7411             $left_e++;
7412 0         0 }
7413 0         0 elsif ($char[$i] eq '\l') {
7414             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
7415             $left_e++;
7416 0         0 }
7417 0         0 elsif ($char[$i] eq '\U') {
7418             $char[$i] = '@{[Ekoi8u::uc qq<';
7419             $left_e++;
7420 0         0 }
7421 0         0 elsif ($char[$i] eq '\L') {
7422             $char[$i] = '@{[Ekoi8u::lc qq<';
7423             $left_e++;
7424 0         0 }
7425 0         0 elsif ($char[$i] eq '\F') {
7426             $char[$i] = '@{[Ekoi8u::fc qq<';
7427             $left_e++;
7428 0         0 }
7429 0         0 elsif ($char[$i] eq '\Q') {
7430             $char[$i] = '@{[CORE::quotemeta qq<';
7431             $left_e++;
7432 0 0       0 }
7433 0         0 elsif ($char[$i] eq '\E') {
7434 0         0 if ($right_e < $left_e) {
7435             $char[$i] = '>]}';
7436             $right_e++;
7437 0         0 }
7438             else {
7439             $char[$i] = '';
7440             }
7441 0         0 }
7442 0 0       0 elsif ($char[$i] eq '\Q') {
7443 0         0 while (1) {
7444             if (++$i > $#char) {
7445 0 0       0 last;
7446 0         0 }
7447             if ($char[$i] eq '\E') {
7448             last;
7449             }
7450             }
7451             }
7452             elsif ($char[$i] eq '\E') {
7453             }
7454              
7455 0 0       0 # $0 --> $0
7456 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7457             if ($ignorecase) {
7458             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7459             }
7460 0 0       0 }
7461 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7462             if ($ignorecase) {
7463             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7464             }
7465             }
7466              
7467             # $$ --> $$
7468             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7469             }
7470              
7471             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7472 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7473 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7474 0         0 $char[$i] = e_capture($1);
7475             if ($ignorecase) {
7476             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7477             }
7478 0         0 }
7479 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7480 0         0 $char[$i] = e_capture($1);
7481             if ($ignorecase) {
7482             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7483             }
7484             }
7485              
7486 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7487 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) {
7488 0         0 $char[$i] = e_capture($1.'->'.$2);
7489             if ($ignorecase) {
7490             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7491             }
7492             }
7493              
7494 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7495 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) {
7496 0         0 $char[$i] = e_capture($1.'->'.$2);
7497             if ($ignorecase) {
7498             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7499             }
7500             }
7501              
7502 0         0 # $$foo
7503 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7504 0         0 $char[$i] = e_capture($1);
7505             if ($ignorecase) {
7506             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7507             }
7508             }
7509              
7510 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
7511 12         31 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7512             if ($ignorecase) {
7513             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
7514 0         0 }
7515             else {
7516             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
7517             }
7518             }
7519              
7520 12 50       54 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
7521 12         28 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7522             if ($ignorecase) {
7523             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
7524 0         0 }
7525             else {
7526             $char[$i] = '@{[Ekoi8u::MATCH()]}';
7527             }
7528             }
7529              
7530 12 50       54 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
7531 9         31 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7532             if ($ignorecase) {
7533             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
7534 0         0 }
7535             else {
7536             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
7537             }
7538             }
7539              
7540 9 0       41 # ${ foo }
7541 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) {
7542             if ($ignorecase) {
7543             $char[$i] = '@{[Ekoi8u::ignorecase(' . $1 . ')]}';
7544             }
7545             }
7546              
7547 0         0 # ${ ... }
7548 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7549 0         0 $char[$i] = e_capture($1);
7550             if ($ignorecase) {
7551             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7552             }
7553             }
7554              
7555 0         0 # $scalar or @array
7556 3 50       10 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7557 3         12 $char[$i] = e_string($char[$i]);
7558             if ($ignorecase) {
7559             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7560             }
7561             }
7562              
7563 0 50       0 # quote character before ? + * {
7564             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7565             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7566 1         6 }
7567             else {
7568             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7569             }
7570             }
7571             }
7572 0         0  
7573 74 50       222 # make regexp string
7574 74         155 $modifier =~ tr/i//d;
7575             if ($left_e > $right_e) {
7576 0         0 return join '', 'Ekoi8u::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7577             }
7578             return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7579             }
7580              
7581             #
7582             # escape regexp of split qr''
7583 74     0 0 678 #
7584 0   0       sub e_split_q {
7585             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7586 0           $modifier ||= '';
7587 0 0          
7588 0           $modifier =~ tr/p//d;
7589 0           if ($modifier =~ /([adlu])/oxms) {
7590 0 0         my $line = 0;
7591 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7592 0           if ($filename ne __FILE__) {
7593             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7594             last;
7595 0           }
7596             }
7597             die qq{Unsupported modifier "$1" used at line $line.\n};
7598 0           }
7599              
7600             $slash = 'div';
7601 0 0          
7602 0           # /b /B modifier
7603             if ($modifier =~ tr/bB//d) {
7604             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7605 0 0         }
7606              
7607             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7608 0            
7609             # split regexp
7610             my @char = $string =~ /\G((?>
7611             [^\\\[] |
7612             [\x00-\xFF] |
7613             \[\^ |
7614             \[\: (?>[a-z]+) \:\] |
7615             \[\:\^ (?>[a-z]+) \:\] |
7616             \\ (?:$q_char) |
7617             (?:$q_char)
7618             ))/oxmsg;
7619 0            
7620 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7621             for (my $i=0; $i <= $#char; $i++) {
7622             if (0) {
7623             }
7624 0            
7625 0           # open character class [...]
7626 0 0         elsif ($char[$i] eq '[') {
7627 0           my $left = $i;
7628             if ($char[$i+1] eq ']') {
7629 0           $i++;
7630 0 0         }
7631 0           while (1) {
7632             if (++$i > $#char) {
7633 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7634 0           }
7635             if ($char[$i] eq ']') {
7636             my $right = $i;
7637 0            
7638             # [...]
7639 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
7640 0            
7641             $i = $left;
7642             last;
7643             }
7644             }
7645             }
7646              
7647 0           # open character class [^...]
7648 0 0         elsif ($char[$i] eq '[^') {
7649 0           my $left = $i;
7650             if ($char[$i+1] eq ']') {
7651 0           $i++;
7652 0 0         }
7653 0           while (1) {
7654             if (++$i > $#char) {
7655 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7656 0           }
7657             if ($char[$i] eq ']') {
7658             my $right = $i;
7659 0            
7660             # [^...]
7661 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7662 0            
7663             $i = $left;
7664             last;
7665             }
7666             }
7667             }
7668              
7669 0           # rewrite character class or escape character
7670             elsif (my $char = character_class($char[$i],$modifier)) {
7671             $char[$i] = $char;
7672             }
7673              
7674 0           # split(m/^/) --> split(m/^/m)
7675             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7676             $modifier .= 'm';
7677             }
7678              
7679 0 0         # /i modifier
7680 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
7681             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
7682             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
7683 0           }
7684             else {
7685             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
7686             }
7687             }
7688              
7689 0 0         # quote character before ? + * {
7690             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7691             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7692 0           }
7693             else {
7694             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7695             }
7696             }
7697 0           }
7698 0            
7699             $modifier =~ tr/i//d;
7700             return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7701             }
7702              
7703             #
7704             # instead of Carp::carp
7705 0     0 0   #
7706 0           sub carp {
7707             my($package,$filename,$line) = caller(1);
7708             print STDERR "@_ at $filename line $line.\n";
7709             }
7710              
7711             #
7712             # instead of Carp::croak
7713 0     0 0   #
7714 0           sub croak {
7715 0           my($package,$filename,$line) = caller(1);
7716             print STDERR "@_ at $filename line $line.\n";
7717             die "\n";
7718             }
7719              
7720             #
7721             # instead of Carp::cluck
7722 0     0 0   #
7723 0           sub cluck {
7724 0           my $i = 0;
7725 0           my @cluck = ();
7726 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7727             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7728 0           $i++;
7729 0           }
7730 0           print STDERR CORE::reverse @cluck;
7731             print STDERR "\n";
7732             print STDERR @_;
7733             }
7734              
7735             #
7736             # instead of Carp::confess
7737 0     0 0   #
7738 0           sub confess {
7739 0           my $i = 0;
7740 0           my @confess = ();
7741 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7742             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7743 0           $i++;
7744 0           }
7745 0           print STDERR CORE::reverse @confess;
7746 0           print STDERR "\n";
7747             print STDERR @_;
7748             die "\n";
7749             }
7750              
7751             1;
7752              
7753             __END__