File Coverage

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


line stmt bran cond sub pod time code
1             package Ekoi8u;
2 204     204   1364 use strict;
  204         322  
  204         27646  
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   19449 use 5.00503; # Galapagos Consensus 1998 for primetools
  204         582  
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   1246 use vars qw($VERSION);
  204         381  
  204         60468  
28             $VERSION = '1.13';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 204 50   204   1716 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 204         415 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 204         32180 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   14690 CORE::eval q{
  204     204   1600  
  204     76   486  
  204         27293  
  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       95338 if ($@) {
56 0         0 *utf8::upgrade = sub { CORE::length $_[0] };
  0         0  
57 0         0 *utf8::downgrade = sub { 1 };
  0         0  
58 0         0 *utf8::encode = sub { };
59 0         0 *utf8::decode = sub { 1 };
  0         0  
60 0         0 *utf8::is_utf8 = sub { };
61 0         0 *utf8::valid = sub { 1 };
  0         0  
62             }
63             }
64              
65             # instead of Symbol.pm
66 0         0 BEGIN {
67             sub gensym () {
68 0 0   0 0 0 if ($] < 5.006) {
69 0         0 return \do { local *_ };
  0         0  
70             }
71             else {
72 0         0 return undef;
73             }
74             }
75              
76             sub qualify ($$) {
77 0     0 0 0 my($name) = @_;
78              
79 0 0       0 if (ref $name) {
    0          
    0          
    0          
    0          
    0          
    0          
80 0         0 return $name;
81             }
82             elsif (Ekoi8u::index($name,'::') >= 0) {
83 0         0 return $name;
84             }
85             elsif (Ekoi8u::index($name,"'") >= 0) {
86 0         0 return $name;
87             }
88              
89             # special character, "^xyz"
90             elsif ($name =~ /\A \^ [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+ \z/x) {
91              
92             # RGS 2001-11-05 : translate leading ^X to control-char
93 0         0 $name =~ s{\A \^ ([ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]) }{'qq(\c'.$1.')'}xee;
  0         0  
94 0         0 return 'main::' . $name;
95             }
96              
97             # Global names
98             elsif ($name =~ /\A (?: ARGV | ARGVOUT | ENV | INC | SIG | STDERR | STDIN | STDOUT ) \z/x) {
99 0         0 return 'main::' . $name;
100             }
101              
102             # or other
103             elsif ($name =~ /\A [^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz] \z/x) {
104 0         0 return 'main::' . $name;
105             }
106              
107             elsif (defined $_[1]) {
108 0         0 return $_[1] . '::' . $name;
109             }
110             else {
111 0         0 return (caller)[0] . '::' . $name;
112             }
113             }
114              
115             sub qualify_to_ref ($;$) {
116 0 0   0 0 0 if (defined $_[1]) {
117 204     204   2811 no strict qw(refs);
  204         363  
  204         15220  
118 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
119             }
120             else {
121 204     204   1117 no strict qw(refs);
  204     0   381  
  204         37536  
122 0         0 return \*{ qualify $_[0], (caller)[0] };
  0         0  
123             }
124             }
125             }
126              
127             # P.714 29.2.39. flock
128             # in Chapter 29: Functions
129             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
130              
131             # P.863 flock
132             # in Chapter 27: Functions
133             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
134              
135             sub LOCK_SH() {1}
136             sub LOCK_EX() {2}
137             sub LOCK_UN() {8}
138             sub LOCK_NB() {4}
139              
140             # instead of Carp.pm
141             sub carp;
142             sub croak;
143             sub cluck;
144             sub confess;
145              
146             # 6.18. Matching Multiple-Byte Characters
147             # in Chapter 6. Pattern Matching
148             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
149             # (and so on)
150              
151             # regexp of character
152             my $your_char = q{[\x00-\xFF]};
153 204     204   1392 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  204         470  
  204         14519  
154 204     204   2260 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  204         431  
  204         397156  
155              
156             #
157             # KOI8-U character range per length
158             #
159             my %range_tr = ();
160              
161             #
162             # KOI8-U case conversion
163             #
164             my %lc = ();
165             @lc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
166             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
167             my %uc = ();
168             @uc{qw(a b c d e f g h i j k l m n o p q r s t u v w x y z)} =
169             qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
170             my %fc = ();
171             @fc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
172             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
173              
174             if (0) {
175             }
176              
177             elsif (__PACKAGE__ =~ / \b Ekoi8u \z/oxms) {
178             %range_tr = (
179             1 => [ [0x00..0xFF],
180             ],
181             );
182              
183             %lc = (%lc,
184             "\xB3" => "\xA3", # CYRILLIC LETTER IO
185             "\xB4" => "\xA4", # CYRILLIC LETTER UKRAINIAN IE
186             "\xB6" => "\xA6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
187             "\xB7" => "\xA7", # CYRILLIC LETTER YI (UKRAINIAN)
188             "\xBD" => "\xAD", # CYRILLIC LETTER GHE WITH UPTURN
189             "\xE0" => "\xC0", # CYRILLIC LETTER YU
190             "\xE1" => "\xC1", # CYRILLIC LETTER A
191             "\xE2" => "\xC2", # CYRILLIC LETTER BE
192             "\xE3" => "\xC3", # CYRILLIC LETTER TSE
193             "\xE4" => "\xC4", # CYRILLIC LETTER DE
194             "\xE5" => "\xC5", # CYRILLIC LETTER IE
195             "\xE6" => "\xC6", # CYRILLIC LETTER EF
196             "\xE7" => "\xC7", # CYRILLIC LETTER GHE
197             "\xE8" => "\xC8", # CYRILLIC LETTER KHA
198             "\xE9" => "\xC9", # CYRILLIC LETTER I
199             "\xEA" => "\xCA", # CYRILLIC LETTER SHORT I
200             "\xEB" => "\xCB", # CYRILLIC LETTER KA
201             "\xEC" => "\xCC", # CYRILLIC LETTER EL
202             "\xED" => "\xCD", # CYRILLIC LETTER EM
203             "\xEE" => "\xCE", # CYRILLIC LETTER EN
204             "\xEF" => "\xCF", # CYRILLIC LETTER O
205             "\xF0" => "\xD0", # CYRILLIC LETTER PE
206             "\xF1" => "\xD1", # CYRILLIC LETTER YA
207             "\xF2" => "\xD2", # CYRILLIC LETTER ER
208             "\xF3" => "\xD3", # CYRILLIC LETTER ES
209             "\xF4" => "\xD4", # CYRILLIC LETTER TE
210             "\xF5" => "\xD5", # CYRILLIC LETTER U
211             "\xF6" => "\xD6", # CYRILLIC LETTER ZHE
212             "\xF7" => "\xD7", # CYRILLIC LETTER VE
213             "\xF8" => "\xD8", # CYRILLIC LETTER SOFT SIGN
214             "\xF9" => "\xD9", # CYRILLIC LETTER YERU
215             "\xFA" => "\xDA", # CYRILLIC LETTER ZE
216             "\xFB" => "\xDB", # CYRILLIC LETTER SHA
217             "\xFC" => "\xDC", # CYRILLIC LETTER E
218             "\xFD" => "\xDD", # CYRILLIC LETTER SHCHA
219             "\xFE" => "\xDE", # CYRILLIC LETTER CHE
220             "\xFF" => "\xDF", # CYRILLIC LETTER HARD SIGN
221             );
222              
223             %uc = (%uc,
224             "\xA3" => "\xB3", # CYRILLIC LETTER IO
225             "\xA4" => "\xB4", # CYRILLIC LETTER UKRAINIAN IE
226             "\xA6" => "\xB6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
227             "\xA7" => "\xB7", # CYRILLIC LETTER YI (UKRAINIAN)
228             "\xAD" => "\xBD", # CYRILLIC LETTER GHE WITH UPTURN
229             "\xC0" => "\xE0", # CYRILLIC LETTER YU
230             "\xC1" => "\xE1", # CYRILLIC LETTER A
231             "\xC2" => "\xE2", # CYRILLIC LETTER BE
232             "\xC3" => "\xE3", # CYRILLIC LETTER TSE
233             "\xC4" => "\xE4", # CYRILLIC LETTER DE
234             "\xC5" => "\xE5", # CYRILLIC LETTER IE
235             "\xC6" => "\xE6", # CYRILLIC LETTER EF
236             "\xC7" => "\xE7", # CYRILLIC LETTER GHE
237             "\xC8" => "\xE8", # CYRILLIC LETTER KHA
238             "\xC9" => "\xE9", # CYRILLIC LETTER I
239             "\xCA" => "\xEA", # CYRILLIC LETTER SHORT I
240             "\xCB" => "\xEB", # CYRILLIC LETTER KA
241             "\xCC" => "\xEC", # CYRILLIC LETTER EL
242             "\xCD" => "\xED", # CYRILLIC LETTER EM
243             "\xCE" => "\xEE", # CYRILLIC LETTER EN
244             "\xCF" => "\xEF", # CYRILLIC LETTER O
245             "\xD0" => "\xF0", # CYRILLIC LETTER PE
246             "\xD1" => "\xF1", # CYRILLIC LETTER YA
247             "\xD2" => "\xF2", # CYRILLIC LETTER ER
248             "\xD3" => "\xF3", # CYRILLIC LETTER ES
249             "\xD4" => "\xF4", # CYRILLIC LETTER TE
250             "\xD5" => "\xF5", # CYRILLIC LETTER U
251             "\xD6" => "\xF6", # CYRILLIC LETTER ZHE
252             "\xD7" => "\xF7", # CYRILLIC LETTER VE
253             "\xD8" => "\xF8", # CYRILLIC LETTER SOFT SIGN
254             "\xD9" => "\xF9", # CYRILLIC LETTER YERU
255             "\xDA" => "\xFA", # CYRILLIC LETTER ZE
256             "\xDB" => "\xFB", # CYRILLIC LETTER SHA
257             "\xDC" => "\xFC", # CYRILLIC LETTER E
258             "\xDD" => "\xFD", # CYRILLIC LETTER SHCHA
259             "\xDE" => "\xFE", # CYRILLIC LETTER CHE
260             "\xDF" => "\xFF", # CYRILLIC LETTER HARD SIGN
261             );
262              
263             %fc = (%fc,
264             "\xB3" => "\xA3", # CYRILLIC CAPITAL LETTER IO --> CYRILLIC SMALL LETTER IO
265             "\xB4" => "\xA4", # CYRILLIC CAPITAL LETTER UKRAINIAN IE --> CYRILLIC SMALL LETTER UKRAINIAN IE
266             "\xB6" => "\xA6", # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I --> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
267             "\xB7" => "\xA7", # CYRILLIC CAPITAL LETTER YI --> CYRILLIC SMALL LETTER YI
268             "\xBD" => "\xAD", # CYRILLIC CAPITAL LETTER GHE WITH UPTURN --> CYRILLIC SMALL LETTER GHE WITH UPTURN
269             "\xE0" => "\xC0", # CYRILLIC CAPITAL LETTER YU --> CYRILLIC SMALL LETTER YU
270             "\xE1" => "\xC1", # CYRILLIC CAPITAL LETTER A --> CYRILLIC SMALL LETTER A
271             "\xE2" => "\xC2", # CYRILLIC CAPITAL LETTER BE --> CYRILLIC SMALL LETTER BE
272             "\xE3" => "\xC3", # CYRILLIC CAPITAL LETTER TSE --> CYRILLIC SMALL LETTER TSE
273             "\xE4" => "\xC4", # CYRILLIC CAPITAL LETTER DE --> CYRILLIC SMALL LETTER DE
274             "\xE5" => "\xC5", # CYRILLIC CAPITAL LETTER IE --> CYRILLIC SMALL LETTER IE
275             "\xE6" => "\xC6", # CYRILLIC CAPITAL LETTER EF --> CYRILLIC SMALL LETTER EF
276             "\xE7" => "\xC7", # CYRILLIC CAPITAL LETTER GHE --> CYRILLIC SMALL LETTER GHE
277             "\xE8" => "\xC8", # CYRILLIC CAPITAL LETTER HA --> CYRILLIC SMALL LETTER HA
278             "\xE9" => "\xC9", # CYRILLIC CAPITAL LETTER I --> CYRILLIC SMALL LETTER I
279             "\xEA" => "\xCA", # CYRILLIC CAPITAL LETTER SHORT I --> CYRILLIC SMALL LETTER SHORT I
280             "\xEB" => "\xCB", # CYRILLIC CAPITAL LETTER KA --> CYRILLIC SMALL LETTER KA
281             "\xEC" => "\xCC", # CYRILLIC CAPITAL LETTER EL --> CYRILLIC SMALL LETTER EL
282             "\xED" => "\xCD", # CYRILLIC CAPITAL LETTER EM --> CYRILLIC SMALL LETTER EM
283             "\xEE" => "\xCE", # CYRILLIC CAPITAL LETTER EN --> CYRILLIC SMALL LETTER EN
284             "\xEF" => "\xCF", # CYRILLIC CAPITAL LETTER O --> CYRILLIC SMALL LETTER O
285             "\xF0" => "\xD0", # CYRILLIC CAPITAL LETTER PE --> CYRILLIC SMALL LETTER PE
286             "\xF1" => "\xD1", # CYRILLIC CAPITAL LETTER YA --> CYRILLIC SMALL LETTER YA
287             "\xF2" => "\xD2", # CYRILLIC CAPITAL LETTER ER --> CYRILLIC SMALL LETTER ER
288             "\xF3" => "\xD3", # CYRILLIC CAPITAL LETTER ES --> CYRILLIC SMALL LETTER ES
289             "\xF4" => "\xD4", # CYRILLIC CAPITAL LETTER TE --> CYRILLIC SMALL LETTER TE
290             "\xF5" => "\xD5", # CYRILLIC CAPITAL LETTER U --> CYRILLIC SMALL LETTER U
291             "\xF6" => "\xD6", # CYRILLIC CAPITAL LETTER ZHE --> CYRILLIC SMALL LETTER ZHE
292             "\xF7" => "\xD7", # CYRILLIC CAPITAL LETTER VE --> CYRILLIC SMALL LETTER VE
293             "\xF8" => "\xD8", # CYRILLIC CAPITAL LETTER SOFT SIGN --> CYRILLIC SMALL LETTER SOFT SIGN
294             "\xF9" => "\xD9", # CYRILLIC CAPITAL LETTER YERU --> CYRILLIC SMALL LETTER YERU
295             "\xFA" => "\xDA", # CYRILLIC CAPITAL LETTER ZE --> CYRILLIC SMALL LETTER ZE
296             "\xFB" => "\xDB", # CYRILLIC CAPITAL LETTER SHA --> CYRILLIC SMALL LETTER SHA
297             "\xFC" => "\xDC", # CYRILLIC CAPITAL LETTER E --> CYRILLIC SMALL LETTER E
298             "\xFD" => "\xDD", # CYRILLIC CAPITAL LETTER SHCHA --> CYRILLIC SMALL LETTER SHCHA
299             "\xFE" => "\xDE", # CYRILLIC CAPITAL LETTER CHE --> CYRILLIC SMALL LETTER CHE
300             "\xFF" => "\xDF", # CYRILLIC CAPITAL LETTER HARD SIGN --> CYRILLIC SMALL LETTER HARD SIGN
301             );
302             }
303              
304             else {
305             croak "Don't know my package name '@{[__PACKAGE__]}'";
306             }
307              
308             #
309             # @ARGV wildcard globbing
310             #
311             sub import {
312              
313 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
314 0         0 my @argv = ();
315 0         0 for (@ARGV) {
316              
317             # has space
318 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
319 0 0       0 if (my @glob = Ekoi8u::glob(qq{"$_"})) {
320 0         0 push @argv, @glob;
321             }
322             else {
323 0         0 push @argv, $_;
324             }
325             }
326              
327             # has wildcard metachar
328             elsif (/\A (?:$q_char)*? [*?] /oxms) {
329 0 0       0 if (my @glob = Ekoi8u::glob($_)) {
330 0         0 push @argv, @glob;
331             }
332             else {
333 0         0 push @argv, $_;
334             }
335             }
336              
337             # no wildcard globbing
338             else {
339 0         0 push @argv, $_;
340             }
341             }
342 0         0 @ARGV = @argv;
343             }
344              
345 0         0 *Char::ord = \&KOI8U::ord;
346 0         0 *Char::ord_ = \&KOI8U::ord_;
347 0         0 *Char::reverse = \&KOI8U::reverse;
348 0         0 *Char::getc = \&KOI8U::getc;
349 0         0 *Char::length = \&KOI8U::length;
350 0         0 *Char::substr = \&KOI8U::substr;
351 0         0 *Char::index = \&KOI8U::index;
352 0         0 *Char::rindex = \&KOI8U::rindex;
353 0         0 *Char::eval = \&KOI8U::eval;
354 0         0 *Char::escape = \&KOI8U::escape;
355 0         0 *Char::escape_token = \&KOI8U::escape_token;
356 0         0 *Char::escape_script = \&KOI8U::escape_script;
357             }
358              
359             # P.230 Care with Prototypes
360             # in Chapter 6: Subroutines
361             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
362             #
363             # If you aren't careful, you can get yourself into trouble with prototypes.
364             # But if you are careful, you can do a lot of neat things with them. This is
365             # all very powerful, of course, and should only be used in moderation to make
366             # the world a better place.
367              
368             # P.332 Care with Prototypes
369             # in Chapter 7: Subroutines
370             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
371             #
372             # If you aren't careful, you can get yourself into trouble with prototypes.
373             # But if you are careful, you can do a lot of neat things with them. This is
374             # all very powerful, of course, and should only be used in moderation to make
375             # the world a better place.
376              
377             #
378             # Prototypes of subroutines
379             #
380       0     sub unimport {}
381             sub Ekoi8u::split(;$$$);
382             sub Ekoi8u::tr($$$$;$);
383             sub Ekoi8u::chop(@);
384             sub Ekoi8u::index($$;$);
385             sub Ekoi8u::rindex($$;$);
386             sub Ekoi8u::lcfirst(@);
387             sub Ekoi8u::lcfirst_();
388             sub Ekoi8u::lc(@);
389             sub Ekoi8u::lc_();
390             sub Ekoi8u::ucfirst(@);
391             sub Ekoi8u::ucfirst_();
392             sub Ekoi8u::uc(@);
393             sub Ekoi8u::uc_();
394             sub Ekoi8u::fc(@);
395             sub Ekoi8u::fc_();
396             sub Ekoi8u::ignorecase;
397             sub Ekoi8u::classic_character_class;
398             sub Ekoi8u::capture;
399             sub Ekoi8u::chr(;$);
400             sub Ekoi8u::chr_();
401             sub Ekoi8u::glob($);
402             sub Ekoi8u::glob_();
403              
404             sub KOI8U::ord(;$);
405             sub KOI8U::ord_();
406             sub KOI8U::reverse(@);
407             sub KOI8U::getc(;*@);
408             sub KOI8U::length(;$);
409             sub KOI8U::substr($$;$$);
410             sub KOI8U::index($$;$);
411             sub KOI8U::rindex($$;$);
412             sub KOI8U::escape(;$);
413              
414             #
415             # Regexp work
416             #
417 204         18261 use vars qw(
418             $re_a
419             $re_t
420             $re_n
421             $re_r
422 204     204   1866 );
  204         551  
423              
424             #
425             # Character class
426             #
427 204         2134670 use vars qw(
428             $dot
429             $dot_s
430             $eD
431             $eS
432             $eW
433             $eH
434             $eV
435             $eR
436             $eN
437             $not_alnum
438             $not_alpha
439             $not_ascii
440             $not_blank
441             $not_cntrl
442             $not_digit
443             $not_graph
444             $not_lower
445             $not_lower_i
446             $not_print
447             $not_punct
448             $not_space
449             $not_upper
450             $not_upper_i
451             $not_word
452             $not_xdigit
453             $eb
454             $eB
455 204     204   1444 );
  204         374  
456              
457             ${Ekoi8u::dot} = qr{(?>[^\x0A])};
458             ${Ekoi8u::dot_s} = qr{(?>[\x00-\xFF])};
459             ${Ekoi8u::eD} = qr{(?>[^0-9])};
460              
461             # Vertical tabs are now whitespace
462             # \s in a regex now matches a vertical tab in all circumstances.
463             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
464             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
465             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
466             ${Ekoi8u::eS} = qr{(?>[^\s])};
467              
468             ${Ekoi8u::eW} = qr{(?>[^0-9A-Z_a-z])};
469             ${Ekoi8u::eH} = qr{(?>[^\x09\x20])};
470             ${Ekoi8u::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
471             ${Ekoi8u::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
472             ${Ekoi8u::eN} = qr{(?>[^\x0A])};
473             ${Ekoi8u::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
474             ${Ekoi8u::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
475             ${Ekoi8u::not_ascii} = qr{(?>[^\x00-\x7F])};
476             ${Ekoi8u::not_blank} = qr{(?>[^\x09\x20])};
477             ${Ekoi8u::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
478             ${Ekoi8u::not_digit} = qr{(?>[^\x30-\x39])};
479             ${Ekoi8u::not_graph} = qr{(?>[^\x21-\x7F])};
480             ${Ekoi8u::not_lower} = qr{(?>[^\x61-\x7A])};
481             ${Ekoi8u::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
482             # ${Ekoi8u::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
483             ${Ekoi8u::not_print} = qr{(?>[^\x20-\x7F])};
484             ${Ekoi8u::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
485             ${Ekoi8u::not_space} = qr{(?>[^\s\x0B])};
486             ${Ekoi8u::not_upper} = qr{(?>[^\x41-\x5A])};
487             ${Ekoi8u::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
488             # ${Ekoi8u::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
489             ${Ekoi8u::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
490             ${Ekoi8u::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
491             ${Ekoi8u::eb} = qr{(?:\A(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[0-9A-Z_a-z])|(?<=[0-9A-Z_a-z])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]|\z))};
492             ${Ekoi8u::eB} = qr{(?:(?<=[0-9A-Z_a-z])(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]))};
493              
494             # avoid: Name "Ekoi8u::foo" used only once: possible typo at here.
495             ${Ekoi8u::dot} = ${Ekoi8u::dot};
496             ${Ekoi8u::dot_s} = ${Ekoi8u::dot_s};
497             ${Ekoi8u::eD} = ${Ekoi8u::eD};
498             ${Ekoi8u::eS} = ${Ekoi8u::eS};
499             ${Ekoi8u::eW} = ${Ekoi8u::eW};
500             ${Ekoi8u::eH} = ${Ekoi8u::eH};
501             ${Ekoi8u::eV} = ${Ekoi8u::eV};
502             ${Ekoi8u::eR} = ${Ekoi8u::eR};
503             ${Ekoi8u::eN} = ${Ekoi8u::eN};
504             ${Ekoi8u::not_alnum} = ${Ekoi8u::not_alnum};
505             ${Ekoi8u::not_alpha} = ${Ekoi8u::not_alpha};
506             ${Ekoi8u::not_ascii} = ${Ekoi8u::not_ascii};
507             ${Ekoi8u::not_blank} = ${Ekoi8u::not_blank};
508             ${Ekoi8u::not_cntrl} = ${Ekoi8u::not_cntrl};
509             ${Ekoi8u::not_digit} = ${Ekoi8u::not_digit};
510             ${Ekoi8u::not_graph} = ${Ekoi8u::not_graph};
511             ${Ekoi8u::not_lower} = ${Ekoi8u::not_lower};
512             ${Ekoi8u::not_lower_i} = ${Ekoi8u::not_lower_i};
513             ${Ekoi8u::not_print} = ${Ekoi8u::not_print};
514             ${Ekoi8u::not_punct} = ${Ekoi8u::not_punct};
515             ${Ekoi8u::not_space} = ${Ekoi8u::not_space};
516             ${Ekoi8u::not_upper} = ${Ekoi8u::not_upper};
517             ${Ekoi8u::not_upper_i} = ${Ekoi8u::not_upper_i};
518             ${Ekoi8u::not_word} = ${Ekoi8u::not_word};
519             ${Ekoi8u::not_xdigit} = ${Ekoi8u::not_xdigit};
520             ${Ekoi8u::eb} = ${Ekoi8u::eb};
521             ${Ekoi8u::eB} = ${Ekoi8u::eB};
522              
523             #
524             # KOI8-U split
525             #
526             sub Ekoi8u::split(;$$$) {
527              
528             # P.794 29.2.161. split
529             # in Chapter 29: Functions
530             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
531              
532             # P.951 split
533             # in Chapter 27: Functions
534             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
535              
536 0     0 0 0 my $pattern = $_[0];
537 0         0 my $string = $_[1];
538 0         0 my $limit = $_[2];
539              
540             # if $pattern is also omitted or is the literal space, " "
541 0 0       0 if (not defined $pattern) {
542 0         0 $pattern = ' ';
543             }
544              
545             # if $string is omitted, the function splits the $_ string
546 0 0       0 if (not defined $string) {
547 0 0       0 if (defined $_) {
548 0         0 $string = $_;
549             }
550             else {
551 0         0 $string = '';
552             }
553             }
554              
555 0         0 my @split = ();
556              
557             # when string is empty
558 0 0       0 if ($string eq '') {
    0          
559              
560             # resulting list value in list context
561 0 0       0 if (wantarray) {
562 0         0 return @split;
563             }
564              
565             # count of substrings in scalar context
566             else {
567 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
568 0         0 @_ = @split;
569 0         0 return scalar @_;
570             }
571             }
572              
573             # split's first argument is more consistently interpreted
574             #
575             # After some changes earlier in v5.17, split's behavior has been simplified:
576             # if the PATTERN argument evaluates to a string containing one space, it is
577             # treated the way that a literal string containing one space once was.
578             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
579              
580             # if $pattern is also omitted or is the literal space, " ", the function splits
581             # on whitespace, /\s+/, after skipping any leading whitespace
582             # (and so on)
583              
584             elsif ($pattern eq ' ') {
585 0 0       0 if (not defined $limit) {
586 0         0 return CORE::split(' ', $string);
587             }
588             else {
589 0         0 return CORE::split(' ', $string, $limit);
590             }
591             }
592              
593             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
594 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
595              
596             # a pattern capable of matching either the null string or something longer than the
597             # null string will split the value of $string into separate characters wherever it
598             # matches the null string between characters
599             # (and so on)
600              
601 0 0       0 if ('' =~ / \A $pattern \z /xms) {
602 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
603 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
604              
605             # P.1024 Appendix W.10 Multibyte Processing
606             # of ISBN 1-56592-224-7 CJKV Information Processing
607             # (and so on)
608              
609             # the //m modifier is assumed when you split on the pattern /^/
610             # (and so on)
611              
612             # V
613 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
614              
615             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
616             # is included in the resulting list, interspersed with the fields that are ordinarily returned
617             # (and so on)
618              
619 0         0 local $@;
620 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
621 0         0 push @split, CORE::eval('$' . $digit);
622             }
623             }
624             }
625              
626             else {
627 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
628              
629             # V
630 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
631 0         0 local $@;
632 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
633 0         0 push @split, CORE::eval('$' . $digit);
634             }
635             }
636             }
637             }
638              
639             elsif ($limit > 0) {
640 0 0       0 if ('' =~ / \A $pattern \z /xms) {
641 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
642 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
643              
644             # V
645 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
646 0         0 local $@;
647 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
648 0         0 push @split, CORE::eval('$' . $digit);
649             }
650             }
651             }
652             }
653             else {
654 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
655 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
656              
657             # V
658 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
659 0         0 local $@;
660 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
661 0         0 push @split, CORE::eval('$' . $digit);
662             }
663             }
664             }
665             }
666             }
667              
668 0 0       0 if (CORE::length($string) > 0) {
669 0         0 push @split, $string;
670             }
671              
672             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
673 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
674 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
675 0         0 pop @split;
676             }
677             }
678              
679             # resulting list value in list context
680 0 0       0 if (wantarray) {
681 0         0 return @split;
682             }
683              
684             # count of substrings in scalar context
685             else {
686 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
687 0         0 @_ = @split;
688 0         0 return scalar @_;
689             }
690             }
691              
692             #
693             # get last subexpression offsets
694             #
695             sub _last_subexpression_offsets {
696 0     0   0 my $pattern = $_[0];
697              
698             # remove comment
699 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
700              
701 0         0 my $modifier = '';
702 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
703 0         0 $modifier = $1;
704 0         0 $modifier =~ s/-[A-Za-z]*//;
705             }
706              
707             # with /x modifier
708 0         0 my @char = ();
709 0 0       0 if ($modifier =~ /x/oxms) {
710 0         0 @char = $pattern =~ /\G((?>
711             [^\\\#\[\(] |
712             \\ $q_char |
713             \# (?>[^\n]*) $ |
714             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
715             \(\? |
716             $q_char
717             ))/oxmsg;
718             }
719              
720             # without /x modifier
721             else {
722 0         0 @char = $pattern =~ /\G((?>
723             [^\\\[\(] |
724             \\ $q_char |
725             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
726             \(\? |
727             $q_char
728             ))/oxmsg;
729             }
730              
731 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
732             }
733              
734             #
735             # KOI8-U transliteration (tr///)
736             #
737             sub Ekoi8u::tr($$$$;$) {
738              
739 0     0 0 0 my $bind_operator = $_[1];
740 0         0 my $searchlist = $_[2];
741 0         0 my $replacementlist = $_[3];
742 0   0     0 my $modifier = $_[4] || '';
743              
744 0 0       0 if ($modifier =~ /r/oxms) {
745 0 0       0 if ($bind_operator =~ / !~ /oxms) {
746 0         0 croak "Using !~ with tr///r doesn't make sense";
747             }
748             }
749              
750 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
751 0         0 my @searchlist = _charlist_tr($searchlist);
752 0         0 my @replacementlist = _charlist_tr($replacementlist);
753              
754 0         0 my %tr = ();
755 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
756 0 0       0 if (not exists $tr{$searchlist[$i]}) {
757 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
758 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
759             }
760             elsif ($modifier =~ /d/oxms) {
761 0         0 $tr{$searchlist[$i]} = '';
762             }
763             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
764 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
765             }
766             else {
767 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
768             }
769             }
770             }
771              
772 0         0 my $tr = 0;
773 0         0 my $replaced = '';
774 0 0       0 if ($modifier =~ /c/oxms) {
775 0         0 while (defined(my $char = shift @char)) {
776 0 0       0 if (not exists $tr{$char}) {
777 0 0       0 if (defined $replacementlist[0]) {
778 0         0 $replaced .= $replacementlist[0];
779             }
780 0         0 $tr++;
781 0 0       0 if ($modifier =~ /s/oxms) {
782 0   0     0 while (@char and (not exists $tr{$char[0]})) {
783 0         0 shift @char;
784 0         0 $tr++;
785             }
786             }
787             }
788             else {
789 0         0 $replaced .= $char;
790             }
791             }
792             }
793             else {
794 0         0 while (defined(my $char = shift @char)) {
795 0 0       0 if (exists $tr{$char}) {
796 0         0 $replaced .= $tr{$char};
797 0         0 $tr++;
798 0 0       0 if ($modifier =~ /s/oxms) {
799 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
800 0         0 shift @char;
801 0         0 $tr++;
802             }
803             }
804             }
805             else {
806 0         0 $replaced .= $char;
807             }
808             }
809             }
810              
811 0 0       0 if ($modifier =~ /r/oxms) {
812 0         0 return $replaced;
813             }
814             else {
815 0         0 $_[0] = $replaced;
816 0 0       0 if ($bind_operator =~ / !~ /oxms) {
817 0         0 return not $tr;
818             }
819             else {
820 0         0 return $tr;
821             }
822             }
823             }
824              
825             #
826             # KOI8-U chop
827             #
828             sub Ekoi8u::chop(@) {
829              
830 0     0 0 0 my $chop;
831 0 0       0 if (@_ == 0) {
832 0         0 my @char = /\G (?>$q_char) /oxmsg;
833 0         0 $chop = pop @char;
834 0         0 $_ = join '', @char;
835             }
836             else {
837 0         0 for (@_) {
838 0         0 my @char = /\G (?>$q_char) /oxmsg;
839 0         0 $chop = pop @char;
840 0         0 $_ = join '', @char;
841             }
842             }
843 0         0 return $chop;
844             }
845              
846             #
847             # KOI8-U index by octet
848             #
849             sub Ekoi8u::index($$;$) {
850              
851 0     0 1 0 my($str,$substr,$position) = @_;
852 0   0     0 $position ||= 0;
853 0         0 my $pos = 0;
854              
855 0         0 while ($pos < CORE::length($str)) {
856 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
857 0 0       0 if ($pos >= $position) {
858 0         0 return $pos;
859             }
860             }
861 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
862 0         0 $pos += CORE::length($1);
863             }
864             else {
865 0         0 $pos += 1;
866             }
867             }
868 0         0 return -1;
869             }
870              
871             #
872             # KOI8-U reverse index
873             #
874             sub Ekoi8u::rindex($$;$) {
875              
876 0     0 0 0 my($str,$substr,$position) = @_;
877 0   0     0 $position ||= CORE::length($str) - 1;
878 0         0 my $pos = 0;
879 0         0 my $rindex = -1;
880              
881 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
882 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
883 0         0 $rindex = $pos;
884             }
885 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
886 0         0 $pos += CORE::length($1);
887             }
888             else {
889 0         0 $pos += 1;
890             }
891             }
892 0         0 return $rindex;
893             }
894              
895             #
896             # KOI8-U lower case first with parameter
897             #
898             sub Ekoi8u::lcfirst(@) {
899 0 0   0 0 0 if (@_) {
900 0         0 my $s = shift @_;
901 0 0 0     0 if (@_ and wantarray) {
902 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
903             }
904             else {
905 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
906             }
907             }
908             else {
909 0         0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
910             }
911             }
912              
913             #
914             # KOI8-U lower case first without parameter
915             #
916             sub Ekoi8u::lcfirst_() {
917 0     0 0 0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
918             }
919              
920             #
921             # KOI8-U lower case with parameter
922             #
923             sub Ekoi8u::lc(@) {
924 0 0   0 0 0 if (@_) {
925 0         0 my $s = shift @_;
926 0 0 0     0 if (@_ and wantarray) {
927 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
928             }
929             else {
930 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
931             }
932             }
933             else {
934 0         0 return Ekoi8u::lc_();
935             }
936             }
937              
938             #
939             # KOI8-U lower case without parameter
940             #
941             sub Ekoi8u::lc_() {
942 0     0 0 0 my $s = $_;
943 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
944             }
945              
946             #
947             # KOI8-U upper case first with parameter
948             #
949             sub Ekoi8u::ucfirst(@) {
950 0 0   0 0 0 if (@_) {
951 0         0 my $s = shift @_;
952 0 0 0     0 if (@_ and wantarray) {
953 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
954             }
955             else {
956 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
957             }
958             }
959             else {
960 0         0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
961             }
962             }
963              
964             #
965             # KOI8-U upper case first without parameter
966             #
967             sub Ekoi8u::ucfirst_() {
968 0     0 0 0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
969             }
970              
971             #
972             # KOI8-U upper case with parameter
973             #
974             sub Ekoi8u::uc(@) {
975 0 50   174 0 0 if (@_) {
976 174         302 my $s = shift @_;
977 174 50 33     227 if (@_ and wantarray) {
978 174 0       371 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
979             }
980             else {
981 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         556  
982             }
983             }
984             else {
985 174         616 return Ekoi8u::uc_();
986             }
987             }
988              
989             #
990             # KOI8-U upper case without parameter
991             #
992             sub Ekoi8u::uc_() {
993 0     0 0 0 my $s = $_;
994 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
995             }
996              
997             #
998             # KOI8-U fold case with parameter
999             #
1000             sub Ekoi8u::fc(@) {
1001 0 50   197 0 0 if (@_) {
1002 197         278 my $s = shift @_;
1003 197 50 33     232 if (@_ and wantarray) {
1004 197 0       351 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1005             }
1006             else {
1007 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         563  
1008             }
1009             }
1010             else {
1011 197         1147 return Ekoi8u::fc_();
1012             }
1013             }
1014              
1015             #
1016             # KOI8-U fold case without parameter
1017             #
1018             sub Ekoi8u::fc_() {
1019 0     0 0 0 my $s = $_;
1020 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1021             }
1022              
1023             #
1024             # KOI8-U regexp capture
1025             #
1026             {
1027             sub Ekoi8u::capture {
1028 0     0 1 0 return $_[0];
1029             }
1030             }
1031              
1032             #
1033             # KOI8-U regexp ignore case modifier
1034             #
1035             sub Ekoi8u::ignorecase {
1036              
1037 0     0 0 0 my @string = @_;
1038 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1039              
1040             # ignore case of $scalar or @array
1041 0         0 for my $string (@string) {
1042              
1043             # split regexp
1044 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1045              
1046             # unescape character
1047 0         0 for (my $i=0; $i <= $#char; $i++) {
1048 0 0       0 next if not defined $char[$i];
1049              
1050             # open character class [...]
1051 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1052 0         0 my $left = $i;
1053              
1054             # [] make die "unmatched [] in regexp ...\n"
1055              
1056 0 0       0 if ($char[$i+1] eq ']') {
1057 0         0 $i++;
1058             }
1059              
1060 0         0 while (1) {
1061 0 0       0 if (++$i > $#char) {
1062 0         0 croak "Unmatched [] in regexp";
1063             }
1064 0 0       0 if ($char[$i] eq ']') {
1065 0         0 my $right = $i;
1066 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1067              
1068             # escape character
1069 0         0 for my $char (@charlist) {
1070 0 0       0 if (0) {
1071             }
1072              
1073 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1074 0         0 $char = '\\' . $char;
1075             }
1076             }
1077              
1078             # [...]
1079 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1080              
1081 0         0 $i = $left;
1082 0         0 last;
1083             }
1084             }
1085             }
1086              
1087             # open character class [^...]
1088             elsif ($char[$i] eq '[^') {
1089 0         0 my $left = $i;
1090              
1091             # [^] make die "unmatched [] in regexp ...\n"
1092              
1093 0 0       0 if ($char[$i+1] eq ']') {
1094 0         0 $i++;
1095             }
1096              
1097 0         0 while (1) {
1098 0 0       0 if (++$i > $#char) {
1099 0         0 croak "Unmatched [] in regexp";
1100             }
1101 0 0       0 if ($char[$i] eq ']') {
1102 0         0 my $right = $i;
1103 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1104              
1105             # escape character
1106 0         0 for my $char (@charlist) {
1107 0 0       0 if (0) {
1108             }
1109              
1110 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1111 0         0 $char = '\\' . $char;
1112             }
1113             }
1114              
1115             # [^...]
1116 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1117              
1118 0         0 $i = $left;
1119 0         0 last;
1120             }
1121             }
1122             }
1123              
1124             # rewrite classic character class or escape character
1125             elsif (my $char = classic_character_class($char[$i])) {
1126 0         0 $char[$i] = $char;
1127             }
1128              
1129             # with /i modifier
1130             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1131 0         0 my $uc = Ekoi8u::uc($char[$i]);
1132 0         0 my $fc = Ekoi8u::fc($char[$i]);
1133 0 0       0 if ($uc ne $fc) {
1134 0 0       0 if (CORE::length($fc) == 1) {
1135 0         0 $char[$i] = '[' . $uc . $fc . ']';
1136             }
1137             else {
1138 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1139             }
1140             }
1141             }
1142             }
1143              
1144             # characterize
1145 0         0 for (my $i=0; $i <= $#char; $i++) {
1146 0 0       0 next if not defined $char[$i];
1147              
1148 0 0       0 if (0) {
1149             }
1150              
1151             # quote character before ? + * {
1152 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1153 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1154 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1155             }
1156             }
1157             }
1158              
1159 0         0 $string = join '', @char;
1160             }
1161              
1162             # make regexp string
1163 0         0 return @string;
1164             }
1165              
1166             #
1167             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1168             #
1169             sub Ekoi8u::classic_character_class {
1170 0     1867 0 0 my($char) = @_;
1171              
1172             return {
1173             '\D' => '${Ekoi8u::eD}',
1174             '\S' => '${Ekoi8u::eS}',
1175             '\W' => '${Ekoi8u::eW}',
1176             '\d' => '[0-9]',
1177              
1178             # Before Perl 5.6, \s only matched the five whitespace characters
1179             # tab, newline, form-feed, carriage return, and the space character
1180             # itself, which, taken together, is the character class [\t\n\f\r ].
1181              
1182             # Vertical tabs are now whitespace
1183             # \s in a regex now matches a vertical tab in all circumstances.
1184             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1185             # \t \n \v \f \r space
1186             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1187             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1188             '\s' => '\s',
1189              
1190             '\w' => '[0-9A-Z_a-z]',
1191             '\C' => '[\x00-\xFF]',
1192             '\X' => 'X',
1193              
1194             # \h \v \H \V
1195              
1196             # P.114 Character Class Shortcuts
1197             # in Chapter 7: In the World of Regular Expressions
1198             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1199              
1200             # P.357 13.2.3 Whitespace
1201             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1202             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1203             #
1204             # 0x00009 CHARACTER TABULATION h s
1205             # 0x0000a LINE FEED (LF) vs
1206             # 0x0000b LINE TABULATION v
1207             # 0x0000c FORM FEED (FF) vs
1208             # 0x0000d CARRIAGE RETURN (CR) vs
1209             # 0x00020 SPACE h s
1210              
1211             # P.196 Table 5-9. Alphanumeric regex metasymbols
1212             # in Chapter 5. Pattern Matching
1213             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1214              
1215             # (and so on)
1216              
1217             '\H' => '${Ekoi8u::eH}',
1218             '\V' => '${Ekoi8u::eV}',
1219             '\h' => '[\x09\x20]',
1220             '\v' => '[\x0A\x0B\x0C\x0D]',
1221             '\R' => '${Ekoi8u::eR}',
1222              
1223             # \N
1224             #
1225             # http://perldoc.perl.org/perlre.html
1226             # Character Classes and other Special Escapes
1227             # Any character but \n (experimental). Not affected by /s modifier
1228              
1229             '\N' => '${Ekoi8u::eN}',
1230              
1231             # \b \B
1232              
1233             # P.180 Boundaries: The \b and \B Assertions
1234             # in Chapter 5: Pattern Matching
1235             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1236              
1237             # P.219 Boundaries: The \b and \B Assertions
1238             # in Chapter 5: Pattern Matching
1239             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1240              
1241             # \b really means (?:(?<=\w)(?!\w)|(?
1242             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1243             '\b' => '${Ekoi8u::eb}',
1244              
1245             # \B really means (?:(?<=\w)(?=\w)|(?
1246             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1247             '\B' => '${Ekoi8u::eB}',
1248              
1249 1867   100     2880 }->{$char} || '';
1250             }
1251              
1252             #
1253             # prepare KOI8-U characters per length
1254             #
1255              
1256             # 1 octet characters
1257             my @chars1 = ();
1258             sub chars1 {
1259 1867 0   0 0 70265 if (@chars1) {
1260 0         0 return @chars1;
1261             }
1262 0 0       0 if (exists $range_tr{1}) {
1263 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1264 0         0 while (my @range = splice(@ranges,0,1)) {
1265 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1266 0         0 push @chars1, pack 'C', $oct0;
1267             }
1268             }
1269             }
1270 0         0 return @chars1;
1271             }
1272              
1273             # 2 octets characters
1274             my @chars2 = ();
1275             sub chars2 {
1276 0 0   0 0 0 if (@chars2) {
1277 0         0 return @chars2;
1278             }
1279 0 0       0 if (exists $range_tr{2}) {
1280 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1281 0         0 while (my @range = splice(@ranges,0,2)) {
1282 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1283 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1284 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1285             }
1286             }
1287             }
1288             }
1289 0         0 return @chars2;
1290             }
1291              
1292             # 3 octets characters
1293             my @chars3 = ();
1294             sub chars3 {
1295 0 0   0 0 0 if (@chars3) {
1296 0         0 return @chars3;
1297             }
1298 0 0       0 if (exists $range_tr{3}) {
1299 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1300 0         0 while (my @range = splice(@ranges,0,3)) {
1301 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1302 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1303 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1304 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1305             }
1306             }
1307             }
1308             }
1309             }
1310 0         0 return @chars3;
1311             }
1312              
1313             # 4 octets characters
1314             my @chars4 = ();
1315             sub chars4 {
1316 0 0   0 0 0 if (@chars4) {
1317 0         0 return @chars4;
1318             }
1319 0 0       0 if (exists $range_tr{4}) {
1320 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1321 0         0 while (my @range = splice(@ranges,0,4)) {
1322 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1323 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1324 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1325 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1326 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1327             }
1328             }
1329             }
1330             }
1331             }
1332             }
1333 0         0 return @chars4;
1334             }
1335              
1336             #
1337             # KOI8-U open character list for tr
1338             #
1339             sub _charlist_tr {
1340              
1341 0     0   0 local $_ = shift @_;
1342              
1343             # unescape character
1344 0         0 my @char = ();
1345 0         0 while (not /\G \z/oxmsgc) {
1346 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1347 0         0 push @char, '\-';
1348             }
1349             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1350 0         0 push @char, CORE::chr(oct $1);
1351             }
1352             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1353 0         0 push @char, CORE::chr(hex $1);
1354             }
1355             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1356 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1357             }
1358             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1359             push @char, {
1360             '\0' => "\0",
1361             '\n' => "\n",
1362             '\r' => "\r",
1363             '\t' => "\t",
1364             '\f' => "\f",
1365             '\b' => "\x08", # \b means backspace in character class
1366             '\a' => "\a",
1367             '\e' => "\e",
1368 0         0 }->{$1};
1369             }
1370             elsif (/\G \\ ($q_char) /oxmsgc) {
1371 0         0 push @char, $1;
1372             }
1373             elsif (/\G ($q_char) /oxmsgc) {
1374 0         0 push @char, $1;
1375             }
1376             }
1377              
1378             # join separated multiple-octet
1379 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1380              
1381             # unescape '-'
1382 0         0 my @i = ();
1383 0         0 for my $i (0 .. $#char) {
1384 0 0       0 if ($char[$i] eq '\-') {
    0          
1385 0         0 $char[$i] = '-';
1386             }
1387             elsif ($char[$i] eq '-') {
1388 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1389 0         0 push @i, $i;
1390             }
1391             }
1392             }
1393              
1394             # open character list (reverse for splice)
1395 0         0 for my $i (CORE::reverse @i) {
1396 0         0 my @range = ();
1397              
1398             # range error
1399 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1400 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1401             }
1402              
1403             # range of multiple-octet code
1404 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1405 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1406 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1407             }
1408             elsif (CORE::length($char[$i+1]) == 2) {
1409 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1410 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1411             }
1412             elsif (CORE::length($char[$i+1]) == 3) {
1413 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1414 0         0 push @range, chars2();
1415 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1416             }
1417             elsif (CORE::length($char[$i+1]) == 4) {
1418 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1419 0         0 push @range, chars2();
1420 0         0 push @range, chars3();
1421 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1422             }
1423             else {
1424 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1425             }
1426             }
1427             elsif (CORE::length($char[$i-1]) == 2) {
1428 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1429 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1430             }
1431             elsif (CORE::length($char[$i+1]) == 3) {
1432 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1433 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1434             }
1435             elsif (CORE::length($char[$i+1]) == 4) {
1436 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1437 0         0 push @range, chars3();
1438 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1439             }
1440             else {
1441 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1442             }
1443             }
1444             elsif (CORE::length($char[$i-1]) == 3) {
1445 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1446 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1447             }
1448             elsif (CORE::length($char[$i+1]) == 4) {
1449 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1450 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1451             }
1452             else {
1453 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1454             }
1455             }
1456             elsif (CORE::length($char[$i-1]) == 4) {
1457 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1458 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1459             }
1460             else {
1461 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1462             }
1463             }
1464             else {
1465 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1466             }
1467              
1468 0         0 splice @char, $i-1, 3, @range;
1469             }
1470              
1471 0         0 return @char;
1472             }
1473              
1474             #
1475             # KOI8-U open character class
1476             #
1477             sub _cc {
1478 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1479 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1480             }
1481             elsif (scalar(@_) == 1) {
1482 0         0 return sprintf('\x%02X',$_[0]);
1483             }
1484             elsif (scalar(@_) == 2) {
1485 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1486 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1487             }
1488             elsif ($_[0] == $_[1]) {
1489 0         0 return sprintf('\x%02X',$_[0]);
1490             }
1491             elsif (($_[0]+1) == $_[1]) {
1492 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1493             }
1494             else {
1495 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1496             }
1497             }
1498             else {
1499 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1500             }
1501             }
1502              
1503             #
1504             # KOI8-U octet range
1505             #
1506             sub _octets {
1507 0     182   0 my $length = shift @_;
1508              
1509 182 50       503 if ($length == 1) {
1510 182         449 my($a1) = unpack 'C', $_[0];
1511 182         521 my($z1) = unpack 'C', $_[1];
1512              
1513 182 50       330 if ($a1 > $z1) {
1514 182         375 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1515             }
1516              
1517 0 50       0 if ($a1 == $z1) {
    50          
1518 182         602 return sprintf('\x%02X',$a1);
1519             }
1520             elsif (($a1+1) == $z1) {
1521 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1522             }
1523             else {
1524 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1525             }
1526             }
1527             else {
1528 182         1334 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1529             }
1530             }
1531              
1532             #
1533             # KOI8-U range regexp
1534             #
1535             sub _range_regexp {
1536 0     182   0 my($length,$first,$last) = @_;
1537              
1538 182         401 my @range_regexp = ();
1539 182 50       252 if (not exists $range_tr{$length}) {
1540 182         461 return @range_regexp;
1541             }
1542              
1543 0         0 my @ranges = @{ $range_tr{$length} };
  182         315  
1544 182         444 while (my @range = splice(@ranges,0,$length)) {
1545 182         1118 my $min = '';
1546 182         423 my $max = '';
1547 182         251 for (my $i=0; $i < $length; $i++) {
1548 182         482 $min .= pack 'C', $range[$i][0];
1549 182         764 $max .= pack 'C', $range[$i][-1];
1550             }
1551              
1552             # min___max
1553             # FIRST_____________LAST
1554             # (nothing)
1555              
1556 182 50 33     576 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1557             }
1558              
1559             # **********
1560             # min_________max
1561             # FIRST_____________LAST
1562             # **********
1563              
1564             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1565 182         2125 push @range_regexp, _octets($length,$first,$max,$min,$max);
1566             }
1567              
1568             # **********************
1569             # min________________max
1570             # FIRST_____________LAST
1571             # **********************
1572              
1573             elsif (($min eq $first) and ($max eq $last)) {
1574 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1575             }
1576              
1577             # *********
1578             # min___max
1579             # FIRST_____________LAST
1580             # *********
1581              
1582             elsif (($first le $min) and ($max le $last)) {
1583 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1584             }
1585              
1586             # **********************
1587             # min__________________________max
1588             # FIRST_____________LAST
1589             # **********************
1590              
1591             elsif (($min le $first) and ($last le $max)) {
1592 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1593             }
1594              
1595             # *********
1596             # min________max
1597             # FIRST_____________LAST
1598             # *********
1599              
1600             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1601 182         471 push @range_regexp, _octets($length,$min,$last,$min,$max);
1602             }
1603              
1604             # min___max
1605             # FIRST_____________LAST
1606             # (nothing)
1607              
1608             elsif ($last lt $min) {
1609             }
1610              
1611             else {
1612 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1613             }
1614             }
1615              
1616 0         0 return @range_regexp;
1617             }
1618              
1619             #
1620             # KOI8-U open character list for qr and not qr
1621             #
1622             sub _charlist {
1623              
1624 182     358   714 my $modifier = pop @_;
1625 358         556 my @char = @_;
1626              
1627 358 100       824 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1628              
1629             # unescape character
1630 358         878 for (my $i=0; $i <= $#char; $i++) {
1631              
1632             # escape - to ...
1633 358 100 100     1351 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1634 1125 100 100     8772 if ((0 < $i) and ($i < $#char)) {
1635 206         934 $char[$i] = '...';
1636             }
1637             }
1638              
1639             # octal escape sequence
1640             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1641 182         396 $char[$i] = octchr($1);
1642             }
1643              
1644             # hexadecimal escape sequence
1645             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1646 0         0 $char[$i] = hexchr($1);
1647             }
1648              
1649             # \b{...} --> b\{...}
1650             # \B{...} --> B\{...}
1651             # \N{CHARNAME} --> N\{CHARNAME}
1652             # \p{PROPERTY} --> p\{PROPERTY}
1653             # \P{PROPERTY} --> P\{PROPERTY}
1654             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1655 0         0 $char[$i] = $1 . '\\' . $2;
1656             }
1657              
1658             # \p, \P, \X --> p, P, X
1659             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1660 0         0 $char[$i] = $1;
1661             }
1662              
1663             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1664 0         0 $char[$i] = CORE::chr oct $1;
1665             }
1666             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1667 0         0 $char[$i] = CORE::chr hex $1;
1668             }
1669             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1670 22         109 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1671             }
1672             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1673             $char[$i] = {
1674             '\0' => "\0",
1675             '\n' => "\n",
1676             '\r' => "\r",
1677             '\t' => "\t",
1678             '\f' => "\f",
1679             '\b' => "\x08", # \b means backspace in character class
1680             '\a' => "\a",
1681             '\e' => "\e",
1682             '\d' => '[0-9]',
1683              
1684             # Vertical tabs are now whitespace
1685             # \s in a regex now matches a vertical tab in all circumstances.
1686             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1687             # \t \n \v \f \r space
1688             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1689             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1690             '\s' => '\s',
1691              
1692             '\w' => '[0-9A-Z_a-z]',
1693             '\D' => '${Ekoi8u::eD}',
1694             '\S' => '${Ekoi8u::eS}',
1695             '\W' => '${Ekoi8u::eW}',
1696              
1697             '\H' => '${Ekoi8u::eH}',
1698             '\V' => '${Ekoi8u::eV}',
1699             '\h' => '[\x09\x20]',
1700             '\v' => '[\x0A\x0B\x0C\x0D]',
1701             '\R' => '${Ekoi8u::eR}',
1702              
1703 0         0 }->{$1};
1704             }
1705              
1706             # POSIX-style character classes
1707             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1708             $char[$i] = {
1709              
1710             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1711             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1712             '[:^lower:]' => '${Ekoi8u::not_lower_i}',
1713             '[:^upper:]' => '${Ekoi8u::not_upper_i}',
1714              
1715 25         430 }->{$1};
1716             }
1717             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1718             $char[$i] = {
1719              
1720             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1721             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1722             '[:ascii:]' => '[\x00-\x7F]',
1723             '[:blank:]' => '[\x09\x20]',
1724             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1725             '[:digit:]' => '[\x30-\x39]',
1726             '[:graph:]' => '[\x21-\x7F]',
1727             '[:lower:]' => '[\x61-\x7A]',
1728             '[:print:]' => '[\x20-\x7F]',
1729             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1730              
1731             # P.174 POSIX-Style Character Classes
1732             # in Chapter 5: Pattern Matching
1733             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1734              
1735             # P.311 11.2.4 Character Classes and other Special Escapes
1736             # in Chapter 11: perlre: Perl regular expressions
1737             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1738              
1739             # P.210 POSIX-Style Character Classes
1740             # in Chapter 5: Pattern Matching
1741             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1742              
1743             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1744              
1745             '[:upper:]' => '[\x41-\x5A]',
1746             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1747             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1748             '[:^alnum:]' => '${Ekoi8u::not_alnum}',
1749             '[:^alpha:]' => '${Ekoi8u::not_alpha}',
1750             '[:^ascii:]' => '${Ekoi8u::not_ascii}',
1751             '[:^blank:]' => '${Ekoi8u::not_blank}',
1752             '[:^cntrl:]' => '${Ekoi8u::not_cntrl}',
1753             '[:^digit:]' => '${Ekoi8u::not_digit}',
1754             '[:^graph:]' => '${Ekoi8u::not_graph}',
1755             '[:^lower:]' => '${Ekoi8u::not_lower}',
1756             '[:^print:]' => '${Ekoi8u::not_print}',
1757             '[:^punct:]' => '${Ekoi8u::not_punct}',
1758             '[:^space:]' => '${Ekoi8u::not_space}',
1759             '[:^upper:]' => '${Ekoi8u::not_upper}',
1760             '[:^word:]' => '${Ekoi8u::not_word}',
1761             '[:^xdigit:]' => '${Ekoi8u::not_xdigit}',
1762              
1763 8         90 }->{$1};
1764             }
1765             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1766 70         1913 $char[$i] = $1;
1767             }
1768             }
1769              
1770             # open character list
1771 7         29 my @singleoctet = ();
1772 358         719 my @multipleoctet = ();
1773 358         520 for (my $i=0; $i <= $#char; ) {
1774              
1775             # escaped -
1776 358 100 100     805 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1777 943         4073 $i += 1;
1778 182         242 next;
1779             }
1780              
1781             # make range regexp
1782             elsif ($char[$i] eq '...') {
1783              
1784             # range error
1785 182 50       334 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1786 182         826 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1787             }
1788             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1789 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1790 182         552 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1791             }
1792             }
1793              
1794             # make range regexp per length
1795 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1796 182         673 my @regexp = ();
1797              
1798             # is first and last
1799 182 50 33     270 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1800 182         763 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1801             }
1802              
1803             # is first
1804             elsif ($length == CORE::length($char[$i-1])) {
1805 182         563 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1806             }
1807              
1808             # is inside in first and last
1809             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1810 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1811             }
1812              
1813             # is last
1814             elsif ($length == CORE::length($char[$i+1])) {
1815 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1816             }
1817              
1818             else {
1819 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1820             }
1821              
1822 0 50       0 if ($length == 1) {
1823 182         377 push @singleoctet, @regexp;
1824             }
1825             else {
1826 182         499 push @multipleoctet, @regexp;
1827             }
1828             }
1829              
1830 0         0 $i += 2;
1831             }
1832              
1833             # with /i modifier
1834             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1835 182 100       445 if ($modifier =~ /i/oxms) {
1836 493         712 my $uc = Ekoi8u::uc($char[$i]);
1837 24         47 my $fc = Ekoi8u::fc($char[$i]);
1838 24 100       53 if ($uc ne $fc) {
1839 24 50       38 if (CORE::length($fc) == 1) {
1840 12         25 push @singleoctet, $uc, $fc;
1841             }
1842             else {
1843 12         19 push @singleoctet, $uc;
1844 0         0 push @multipleoctet, $fc;
1845             }
1846             }
1847             else {
1848 0         0 push @singleoctet, $char[$i];
1849             }
1850             }
1851             else {
1852 12         27 push @singleoctet, $char[$i];
1853             }
1854 469         1810 $i += 1;
1855             }
1856              
1857             # single character of single octet code
1858             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1859 493         803 push @singleoctet, "\t", "\x20";
1860 0         0 $i += 1;
1861             }
1862             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1863 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1864 0         0 $i += 1;
1865             }
1866             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1867 0         0 push @singleoctet, $char[$i];
1868 2         31 $i += 1;
1869             }
1870              
1871             # single character of multiple-octet code
1872             else {
1873 2         11 push @multipleoctet, $char[$i];
1874 84         177 $i += 1;
1875             }
1876             }
1877              
1878             # quote metachar
1879 84         296 for (@singleoctet) {
1880 358 50       829 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1881 689         3156 $_ = '-';
1882             }
1883             elsif (/\A \n \z/oxms) {
1884 0         0 $_ = '\n';
1885             }
1886             elsif (/\A \r \z/oxms) {
1887 8         14 $_ = '\r';
1888             }
1889             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1890 8         17 $_ = sprintf('\x%02X', CORE::ord $1);
1891             }
1892             elsif (/\A [\x00-\xFF] \z/oxms) {
1893 60         195 $_ = quotemeta $_;
1894             }
1895             }
1896              
1897             # return character list
1898 429         682 return \@singleoctet, \@multipleoctet;
1899             }
1900              
1901             #
1902             # KOI8-U octal escape sequence
1903             #
1904             sub octchr {
1905 358     5 0 1481 my($octdigit) = @_;
1906              
1907 5         14 my @binary = ();
1908 5         7 for my $octal (split(//,$octdigit)) {
1909             push @binary, {
1910             '0' => '000',
1911             '1' => '001',
1912             '2' => '010',
1913             '3' => '011',
1914             '4' => '100',
1915             '5' => '101',
1916             '6' => '110',
1917             '7' => '111',
1918 5         25 }->{$octal};
1919             }
1920 50         175 my $binary = join '', @binary;
1921              
1922             my $octchr = {
1923             # 1234567
1924             1 => pack('B*', "0000000$binary"),
1925             2 => pack('B*', "000000$binary"),
1926             3 => pack('B*', "00000$binary"),
1927             4 => pack('B*', "0000$binary"),
1928             5 => pack('B*', "000$binary"),
1929             6 => pack('B*', "00$binary"),
1930             7 => pack('B*', "0$binary"),
1931             0 => pack('B*', "$binary"),
1932              
1933 5         15 }->{CORE::length($binary) % 8};
1934              
1935 5         55 return $octchr;
1936             }
1937              
1938             #
1939             # KOI8-U hexadecimal escape sequence
1940             #
1941             sub hexchr {
1942 5     5 0 20 my($hexdigit) = @_;
1943              
1944             my $hexchr = {
1945             1 => pack('H*', "0$hexdigit"),
1946             0 => pack('H*', "$hexdigit"),
1947              
1948 5         18 }->{CORE::length($_[0]) % 2};
1949              
1950 5         113 return $hexchr;
1951             }
1952              
1953             #
1954             # KOI8-U open character list for qr
1955             #
1956             sub charlist_qr {
1957              
1958 5     314 0 21 my $modifier = pop @_;
1959 314         779 my @char = @_;
1960              
1961 314         815 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1962 314         909 my @singleoctet = @$singleoctet;
1963 314         902 my @multipleoctet = @$multipleoctet;
1964              
1965             # return character list
1966 314 100       566 if (scalar(@singleoctet) >= 1) {
1967              
1968             # with /i modifier
1969 314 100       715 if ($modifier =~ m/i/oxms) {
1970 236         686 my %singleoctet_ignorecase = ();
1971 22         32 for (@singleoctet) {
1972 22   100     37 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1973 46         200 for my $ord (hex($1) .. hex($2)) {
1974 46         143 my $char = CORE::chr($ord);
1975 66         94 my $uc = Ekoi8u::uc($char);
1976 66         97 my $fc = Ekoi8u::fc($char);
1977 66 100       102 if ($uc eq $fc) {
1978 66         114 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1979             }
1980             else {
1981 12 50       78 if (CORE::length($fc) == 1) {
1982 54         79 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1983 54         115 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1984             }
1985             else {
1986 54         188 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1987 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1988             }
1989             }
1990             }
1991             }
1992 0 50       0 if ($_ ne '') {
1993 46         114 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1994             }
1995             }
1996 0         0 my $i = 0;
1997 22         28 my @singleoctet_ignorecase = ();
1998 22         29 for my $ord (0 .. 255) {
1999 22 100       47 if (exists $singleoctet_ignorecase{$ord}) {
2000 5632         22340 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         96  
2001             }
2002             else {
2003 96         208 $i++;
2004             }
2005             }
2006 5536         5535 @singleoctet = ();
2007 22         42 for my $range (@singleoctet_ignorecase) {
2008 22 100       64 if (ref $range) {
2009 3648 100       5414 if (scalar(@{$range}) == 1) {
  56 50       53  
2010 56         87 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         43  
2011             }
2012 36         116 elsif (scalar(@{$range}) == 2) {
2013 20         28 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2014             }
2015             else {
2016 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         22  
  20         26  
2017             }
2018             }
2019             }
2020             }
2021              
2022 20         120 my $not_anchor = '';
2023              
2024 236         390 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2025             }
2026 236 100       678 if (scalar(@multipleoctet) >= 2) {
2027 314         827 return '(?:' . join('|', @multipleoctet) . ')';
2028             }
2029             else {
2030 6         89 return $multipleoctet[0];
2031             }
2032             }
2033              
2034             #
2035             # KOI8-U open character list for not qr
2036             #
2037             sub charlist_not_qr {
2038              
2039 308     44 0 1488 my $modifier = pop @_;
2040 44         80 my @char = @_;
2041              
2042 44         108 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2043 44         155 my @singleoctet = @$singleoctet;
2044 44         97 my @multipleoctet = @$multipleoctet;
2045              
2046             # with /i modifier
2047 44 100       114 if ($modifier =~ m/i/oxms) {
2048 44         116 my %singleoctet_ignorecase = ();
2049 10         84 for (@singleoctet) {
2050 10   66     17 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2051 10         50 for my $ord (hex($1) .. hex($2)) {
2052 10         38 my $char = CORE::chr($ord);
2053 30         47 my $uc = Ekoi8u::uc($char);
2054 30         51 my $fc = Ekoi8u::fc($char);
2055 30 50       41 if ($uc eq $fc) {
2056 30         50 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2057             }
2058             else {
2059 0 50       0 if (CORE::length($fc) == 1) {
2060 30         40 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2061 30         76 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2062             }
2063             else {
2064 30         323 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2065 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2066             }
2067             }
2068             }
2069             }
2070 0 50       0 if ($_ ne '') {
2071 10         25 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2072             }
2073             }
2074 0         0 my $i = 0;
2075 10         13 my @singleoctet_ignorecase = ();
2076 10         13 for my $ord (0 .. 255) {
2077 10 100       19 if (exists $singleoctet_ignorecase{$ord}) {
2078 2560         3341 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         55  
2079             }
2080             else {
2081 60         321 $i++;
2082             }
2083             }
2084 2500         3572 @singleoctet = ();
2085 10         17 for my $range (@singleoctet_ignorecase) {
2086 10 100       29 if (ref $range) {
2087 960 50       2471 if (scalar(@{$range}) == 1) {
  20 50       20  
2088 20         40 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2089             }
2090 0         0 elsif (scalar(@{$range}) == 2) {
2091 20         30 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2092             }
2093             else {
2094 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         28  
  20         26  
2095             }
2096             }
2097             }
2098             }
2099              
2100             # return character list
2101 20 50       116 if (scalar(@multipleoctet) >= 1) {
2102 44 0       151 if (scalar(@singleoctet) >= 1) {
2103              
2104             # any character other than multiple-octet and single octet character class
2105 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2106             }
2107             else {
2108              
2109             # any character other than multiple-octet character class
2110 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2111             }
2112             }
2113             else {
2114 0 50       0 if (scalar(@singleoctet) >= 1) {
2115              
2116             # any character other than single octet character class
2117 44         100 return '(?:[^' . join('', @singleoctet) . '])';
2118             }
2119             else {
2120              
2121             # any character
2122 44         327 return "(?:$your_char)";
2123             }
2124             }
2125             }
2126              
2127             #
2128             # open file in read mode
2129             #
2130             sub _open_r {
2131 0     408   0 my(undef,$file) = @_;
2132 204     204   2498 use Fcntl qw(O_RDONLY);
  204         697  
  204         31305  
2133 408         3507 return CORE::sysopen($_[0], $file, &O_RDONLY);
2134             }
2135              
2136             #
2137             # open file in append mode
2138             #
2139             sub _open_a {
2140 408     204   18563 my(undef,$file) = @_;
2141 204     204   1612 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  204         505  
  204         675182  
2142 204         614 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2143             }
2144              
2145             #
2146             # safe system
2147             #
2148             sub _systemx {
2149              
2150             # P.707 29.2.33. exec
2151             # in Chapter 29: Functions
2152             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2153             #
2154             # Be aware that in older releases of Perl, exec (and system) did not flush
2155             # your output buffer, so you needed to enable command buffering by setting $|
2156             # on one or more filehandles to avoid lost output in the case of exec, or
2157             # misordererd output in the case of system. This situation was largely remedied
2158             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2159              
2160             # P.855 exec
2161             # in Chapter 27: Functions
2162             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2163             #
2164             # In very old release of Perl (before v5.6), exec (and system) did not flush
2165             # your output buffer, so you needed to enable command buffering by setting $|
2166             # on one or more filehandles to avoid lost output with exec or misordered
2167             # output with system.
2168              
2169 204     204   50935 $| = 1;
2170              
2171             # P.565 23.1.2. Cleaning Up Your Environment
2172             # in Chapter 23: Security
2173             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2174              
2175             # P.656 Cleaning Up Your Environment
2176             # in Chapter 20: Security
2177             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2178              
2179             # local $ENV{'PATH'} = '.';
2180 204         707 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2181              
2182             # P.707 29.2.33. exec
2183             # in Chapter 29: Functions
2184             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2185             #
2186             # As we mentioned earlier, exec treats a discrete list of arguments as an
2187             # indication that it should bypass shell processing. However, there is one
2188             # place where you might still get tripped up. The exec call (and system, too)
2189             # will not distinguish between a single scalar argument and an array containing
2190             # only one element.
2191             #
2192             # @args = ("echo surprise"); # just one element in list
2193             # exec @args # still subject to shell escapes
2194             # or die "exec: $!"; # because @args == 1
2195             #
2196             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2197             # first argument as the pathname, which forces the rest of the arguments to be
2198             # interpreted as a list, even if there is only one of them:
2199             #
2200             # exec { $args[0] } @args # safe even with one-argument list
2201             # or die "can't exec @args: $!";
2202              
2203             # P.855 exec
2204             # in Chapter 27: Functions
2205             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2206             #
2207             # As we mentioned earlier, exec treats a discrete list of arguments as a
2208             # directive to bypass shell processing. However, there is one place where
2209             # you might still get tripped up. The exec call (and system, too) cannot
2210             # distinguish between a single scalar argument and an array containing
2211             # only one element.
2212             #
2213             # @args = ("echo surprise"); # just one element in list
2214             # exec @args # still subject to shell escapes
2215             # || die "exec: $!"; # because @args == 1
2216             #
2217             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2218             # argument as the pathname, which forces the rest of the arguments to be
2219             # interpreted as a list, even if there is only one of them:
2220             #
2221             # exec { $args[0] } @args # safe even with one-argument list
2222             # || die "can't exec @args: $!";
2223              
2224 204         1857 return CORE::system { $_[0] } @_; # safe even with one-argument list
  204         571  
2225             }
2226              
2227             #
2228             # KOI8-U order to character (with parameter)
2229             #
2230             sub Ekoi8u::chr(;$) {
2231              
2232 204 0   0 0 20213227 my $c = @_ ? $_[0] : $_;
2233              
2234 0 0       0 if ($c == 0x00) {
2235 0         0 return "\x00";
2236             }
2237             else {
2238 0         0 my @chr = ();
2239 0         0 while ($c > 0) {
2240 0         0 unshift @chr, ($c % 0x100);
2241 0         0 $c = int($c / 0x100);
2242             }
2243 0         0 return pack 'C*', @chr;
2244             }
2245             }
2246              
2247             #
2248             # KOI8-U order to character (without parameter)
2249             #
2250             sub Ekoi8u::chr_() {
2251              
2252 0     0 0 0 my $c = $_;
2253              
2254 0 0       0 if ($c == 0x00) {
2255 0         0 return "\x00";
2256             }
2257             else {
2258 0         0 my @chr = ();
2259 0         0 while ($c > 0) {
2260 0         0 unshift @chr, ($c % 0x100);
2261 0         0 $c = int($c / 0x100);
2262             }
2263 0         0 return pack 'C*', @chr;
2264             }
2265             }
2266              
2267             #
2268             # KOI8-U path globbing (with parameter)
2269             #
2270             sub Ekoi8u::glob($) {
2271              
2272 0 0   0 0 0 if (wantarray) {
2273 0         0 my @glob = _DOS_like_glob(@_);
2274 0         0 for my $glob (@glob) {
2275 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2276             }
2277 0         0 return @glob;
2278             }
2279             else {
2280 0         0 my $glob = _DOS_like_glob(@_);
2281 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2282 0         0 return $glob;
2283             }
2284             }
2285              
2286             #
2287             # KOI8-U path globbing (without parameter)
2288             #
2289             sub Ekoi8u::glob_() {
2290              
2291 0 0   0 0 0 if (wantarray) {
2292 0         0 my @glob = _DOS_like_glob();
2293 0         0 for my $glob (@glob) {
2294 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2295             }
2296 0         0 return @glob;
2297             }
2298             else {
2299 0         0 my $glob = _DOS_like_glob();
2300 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2301 0         0 return $glob;
2302             }
2303             }
2304              
2305             #
2306             # KOI8-U path globbing via File::DosGlob 1.10
2307             #
2308             # Often I confuse "_dosglob" and "_doglob".
2309             # So, I renamed "_dosglob" to "_DOS_like_glob".
2310             #
2311             my %iter;
2312             my %entries;
2313             sub _DOS_like_glob {
2314              
2315             # context (keyed by second cxix argument provided by core)
2316 0     0   0 my($expr,$cxix) = @_;
2317              
2318             # glob without args defaults to $_
2319 0 0       0 $expr = $_ if not defined $expr;
2320              
2321             # represents the current user's home directory
2322             #
2323             # 7.3. Expanding Tildes in Filenames
2324             # in Chapter 7. File Access
2325             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2326             #
2327             # and File::HomeDir, File::HomeDir::Windows module
2328              
2329             # DOS-like system
2330 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2331 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2332             { my_home_MSWin32() }oxmse;
2333             }
2334              
2335             # UNIX-like system
2336 0 0 0     0 else {
  0         0  
2337             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2338             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2339             }
2340 0 0       0  
2341 0 0       0 # assume global context if not provided one
2342             $cxix = '_G_' if not defined $cxix;
2343             $iter{$cxix} = 0 if not exists $iter{$cxix};
2344 0 0       0  
2345 0         0 # if we're just beginning, do it all first
2346             if ($iter{$cxix} == 0) {
2347             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2348             }
2349 0 0       0  
2350 0         0 # chuck it all out, quick or slow
2351 0         0 if (wantarray) {
  0         0  
2352             delete $iter{$cxix};
2353             return @{delete $entries{$cxix}};
2354 0 0       0 }
  0         0  
2355 0         0 else {
  0         0  
2356             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2357             return shift @{$entries{$cxix}};
2358             }
2359 0         0 else {
2360 0         0 # return undef for EOL
2361 0         0 delete $iter{$cxix};
2362             delete $entries{$cxix};
2363             return undef;
2364             }
2365             }
2366             }
2367              
2368             #
2369             # KOI8-U path globbing subroutine
2370             #
2371 0     0   0 sub _do_glob {
2372 0         0  
2373 0         0 my($cond,@expr) = @_;
2374             my @glob = ();
2375             my $fix_drive_relative_paths = 0;
2376 0         0  
2377 0 0       0 OUTER:
2378 0 0       0 for my $expr (@expr) {
2379             next OUTER if not defined $expr;
2380 0         0 next OUTER if $expr eq '';
2381 0         0  
2382 0         0 my @matched = ();
2383 0         0 my @globdir = ();
2384 0         0 my $head = '.';
2385             my $pathsep = '/';
2386             my $tail;
2387 0 0       0  
2388 0         0 # if argument is within quotes strip em and do no globbing
2389 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2390 0 0       0 $expr = $1;
2391 0         0 if ($cond eq 'd') {
2392             if (-d $expr) {
2393             push @glob, $expr;
2394             }
2395 0 0       0 }
2396 0         0 else {
2397             if (-e $expr) {
2398             push @glob, $expr;
2399 0         0 }
2400             }
2401             next OUTER;
2402             }
2403              
2404 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2405 0 0       0 # to h:./*.pm to expand correctly
2406 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2407             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2408             $fix_drive_relative_paths = 1;
2409             }
2410 0 0       0 }
2411 0 0       0  
2412 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2413 0         0 if ($tail eq '') {
2414             push @glob, $expr;
2415 0 0       0 next OUTER;
2416 0 0       0 }
2417 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2418 0         0 if (@globdir = _do_glob('d', $head)) {
2419             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2420             next OUTER;
2421 0 0 0     0 }
2422 0         0 }
2423             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2424 0         0 $head .= $pathsep;
2425             }
2426             $expr = $tail;
2427             }
2428 0 0       0  
2429 0 0       0 # If file component has no wildcards, we can avoid opendir
2430 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2431             if ($head eq '.') {
2432 0 0 0     0 $head = '';
2433 0         0 }
2434             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2435 0         0 $head .= $pathsep;
2436 0 0       0 }
2437 0 0       0 $head .= $expr;
2438 0         0 if ($cond eq 'd') {
2439             if (-d $head) {
2440             push @glob, $head;
2441             }
2442 0 0       0 }
2443 0         0 else {
2444             if (-e $head) {
2445             push @glob, $head;
2446 0         0 }
2447             }
2448 0 0       0 next OUTER;
2449 0         0 }
2450 0         0 opendir(*DIR, $head) or next OUTER;
2451             my @leaf = readdir DIR;
2452 0 0       0 closedir DIR;
2453 0         0  
2454             if ($head eq '.') {
2455 0 0 0     0 $head = '';
2456 0         0 }
2457             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2458             $head .= $pathsep;
2459 0         0 }
2460 0         0  
2461 0         0 my $pattern = '';
2462             while ($expr =~ / \G ($q_char) /oxgc) {
2463             my $char = $1;
2464              
2465             # 6.9. Matching Shell Globs as Regular Expressions
2466             # in Chapter 6. Pattern Matching
2467             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2468 0 0       0 # (and so on)
    0          
    0          
2469 0         0  
2470             if ($char eq '*') {
2471             $pattern .= "(?:$your_char)*",
2472 0         0 }
2473             elsif ($char eq '?') {
2474             $pattern .= "(?:$your_char)?", # DOS style
2475             # $pattern .= "(?:$your_char)", # UNIX style
2476 0         0 }
2477             elsif ((my $fc = Ekoi8u::fc($char)) ne $char) {
2478             $pattern .= $fc;
2479 0         0 }
2480             else {
2481             $pattern .= quotemeta $char;
2482 0     0   0 }
  0         0  
2483             }
2484             my $matchsub = sub { Ekoi8u::fc($_[0]) =~ /\A $pattern \z/xms };
2485              
2486             # if ($@) {
2487             # print STDERR "$0: $@\n";
2488             # next OUTER;
2489             # }
2490 0         0  
2491 0 0 0     0 INNER:
2492 0         0 for my $leaf (@leaf) {
2493             if ($leaf eq '.' or $leaf eq '..') {
2494 0 0 0     0 next INNER;
2495 0         0 }
2496             if ($cond eq 'd' and not -d "$head$leaf") {
2497             next INNER;
2498 0 0       0 }
2499 0         0  
2500 0         0 if (&$matchsub($leaf)) {
2501             push @matched, "$head$leaf";
2502             next INNER;
2503             }
2504              
2505             # [DOS compatibility special case]
2506 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2507              
2508             if (Ekoi8u::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2509             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2510 0 0       0 Ekoi8u::index($pattern,'\\.') != -1 # pattern has a dot.
2511 0         0 ) {
2512 0         0 if (&$matchsub("$leaf.")) {
2513             push @matched, "$head$leaf";
2514             next INNER;
2515             }
2516 0 0       0 }
2517 0         0 }
2518             if (@matched) {
2519             push @glob, @matched;
2520 0 0       0 }
2521 0         0 }
2522 0         0 if ($fix_drive_relative_paths) {
2523             for my $glob (@glob) {
2524             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2525 0         0 }
2526             }
2527             return @glob;
2528             }
2529              
2530             #
2531             # KOI8-U parse line
2532             #
2533 0     0   0 sub _parse_line {
2534              
2535 0         0 my($line) = @_;
2536 0         0  
2537 0         0 $line .= ' ';
2538             my @piece = ();
2539             while ($line =~ /
2540             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2541             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2542 0 0       0 /oxmsg
2543             ) {
2544 0         0 push @piece, defined($1) ? $1 : $2;
2545             }
2546             return @piece;
2547             }
2548              
2549             #
2550             # KOI8-U parse path
2551             #
2552 0     0   0 sub _parse_path {
2553              
2554 0         0 my($path,$pathsep) = @_;
2555 0         0  
2556 0         0 $path .= '/';
2557             my @subpath = ();
2558             while ($path =~ /
2559             ((?: [^\/\\] )+?) [\/\\]
2560 0         0 /oxmsg
2561             ) {
2562             push @subpath, $1;
2563 0         0 }
2564 0         0  
2565 0         0 my $tail = pop @subpath;
2566             my $head = join $pathsep, @subpath;
2567             return $head, $tail;
2568             }
2569              
2570             #
2571             # via File::HomeDir::Windows 1.00
2572             #
2573             sub my_home_MSWin32 {
2574              
2575             # A lot of unix people and unix-derived tools rely on
2576 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2577 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2578             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2579             return $ENV{'HOME'};
2580             }
2581              
2582 0         0 # Do we have a user profile?
2583             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2584             return $ENV{'USERPROFILE'};
2585             }
2586              
2587 0         0 # Some Windows use something like $ENV{'HOME'}
2588             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2589             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2590 0         0 }
2591              
2592             return undef;
2593             }
2594              
2595             #
2596             # via File::HomeDir::Unix 1.00
2597 0     0 0 0 #
2598             sub my_home {
2599 0 0 0     0 my $home;
    0 0        
2600 0         0  
2601             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2602             $home = $ENV{'HOME'};
2603             }
2604              
2605             # This is from the original code, but I'm guessing
2606 0         0 # it means "login directory" and exists on some Unixes.
2607             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2608             $home = $ENV{'LOGDIR'};
2609             }
2610              
2611             ### More-desperate methods
2612              
2613 0         0 # Light desperation on any (Unixish) platform
2614             else {
2615             $home = CORE::eval q{ (getpwuid($<))[7] };
2616             }
2617              
2618 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2619 0         0 # For example, "nobody"-like users might use /nonexistant
2620             if (defined $home and ! -d($home)) {
2621 0         0 $home = undef;
2622             }
2623             return $home;
2624             }
2625              
2626             #
2627             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2628 0     0 0 0 #
2629             sub Ekoi8u::PREMATCH {
2630             return $`;
2631             }
2632              
2633             #
2634             # ${^MATCH}, $MATCH, $& the string that matched
2635 0     0 0 0 #
2636             sub Ekoi8u::MATCH {
2637             return $&;
2638             }
2639              
2640             #
2641             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2642 0     0 0 0 #
2643             sub Ekoi8u::POSTMATCH {
2644             return $';
2645             }
2646              
2647             #
2648             # KOI8-U character to order (with parameter)
2649             #
2650 0 0   0 1 0 sub KOI8U::ord(;$) {
2651              
2652 0 0       0 local $_ = shift if @_;
2653 0         0  
2654 0         0 if (/\A ($q_char) /oxms) {
2655 0         0 my @ord = unpack 'C*', $1;
2656 0         0 my $ord = 0;
2657             while (my $o = shift @ord) {
2658 0         0 $ord = $ord * 0x100 + $o;
2659             }
2660             return $ord;
2661 0         0 }
2662             else {
2663             return CORE::ord $_;
2664             }
2665             }
2666              
2667             #
2668             # KOI8-U character to order (without parameter)
2669             #
2670 0 0   0 0 0 sub KOI8U::ord_() {
2671 0         0  
2672 0         0 if (/\A ($q_char) /oxms) {
2673 0         0 my @ord = unpack 'C*', $1;
2674 0         0 my $ord = 0;
2675             while (my $o = shift @ord) {
2676 0         0 $ord = $ord * 0x100 + $o;
2677             }
2678             return $ord;
2679 0         0 }
2680             else {
2681             return CORE::ord $_;
2682             }
2683             }
2684              
2685             #
2686             # KOI8-U reverse
2687             #
2688 0 0   0 0 0 sub KOI8U::reverse(@) {
2689 0         0  
2690             if (wantarray) {
2691             return CORE::reverse @_;
2692             }
2693             else {
2694              
2695             # One of us once cornered Larry in an elevator and asked him what
2696             # problem he was solving with this, but he looked as far off into
2697             # the distance as he could in an elevator and said, "It seemed like
2698 0         0 # a good idea at the time."
2699              
2700             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2701             }
2702             }
2703              
2704             #
2705             # KOI8-U getc (with parameter, without parameter)
2706             #
2707 0     0 0 0 sub KOI8U::getc(;*@) {
2708 0 0       0  
2709 0 0 0     0 my($package) = caller;
2710             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2711 0         0 croak 'Too many arguments for KOI8U::getc' if @_ and not wantarray;
  0         0  
2712 0         0  
2713 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2714 0         0 my $getc = '';
2715 0 0       0 for my $length ($length[0] .. $length[-1]) {
2716 0 0       0 $getc .= CORE::getc($fh);
2717 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2718             if ($getc =~ /\A ${Ekoi8u::dot_s} \z/oxms) {
2719             return wantarray ? ($getc,@_) : $getc;
2720             }
2721 0 0       0 }
2722             }
2723             return wantarray ? ($getc,@_) : $getc;
2724             }
2725              
2726             #
2727             # KOI8-U length by character
2728             #
2729 0 0   0 1 0 sub KOI8U::length(;$) {
2730              
2731 0         0 local $_ = shift if @_;
2732 0         0  
2733             local @_ = /\G ($q_char) /oxmsg;
2734             return scalar @_;
2735             }
2736              
2737             #
2738             # KOI8-U substr by character
2739             #
2740             BEGIN {
2741              
2742             # P.232 The lvalue Attribute
2743             # in Chapter 6: Subroutines
2744             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2745              
2746             # P.336 The lvalue Attribute
2747             # in Chapter 7: Subroutines
2748             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2749              
2750             # P.144 8.4 Lvalue subroutines
2751             # in Chapter 8: perlsub: Perl subroutines
2752 204 50 0 204 1 139345 # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
  0 0   0   0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
2753              
2754             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2755             # vv----------------------*******
2756             sub KOI8U::substr($$;$$) %s {
2757              
2758             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2759              
2760             # If the substring is beyond either end of the string, substr() returns the undefined
2761             # value and produces a warning. When used as an lvalue, specifying a substring that
2762             # is entirely outside the string raises an exception.
2763             # http://perldoc.perl.org/functions/substr.html
2764              
2765             # A return with no argument returns the scalar value undef in scalar context,
2766             # an empty list () in list context, and (naturally) nothing at all in void
2767             # context.
2768              
2769             my $offset = $_[1];
2770             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2771             return;
2772             }
2773              
2774             # substr($string,$offset,$length,$replacement)
2775             if (@_ == 4) {
2776             my(undef,undef,$length,$replacement) = @_;
2777             my $substr = join '', splice(@char, $offset, $length, $replacement);
2778             $_[0] = join '', @char;
2779              
2780             # return $substr; this doesn't work, don't say "return"
2781             $substr;
2782             }
2783              
2784             # substr($string,$offset,$length)
2785             elsif (@_ == 3) {
2786             my(undef,undef,$length) = @_;
2787             my $octet_offset = 0;
2788             my $octet_length = 0;
2789             if ($offset == 0) {
2790             $octet_offset = 0;
2791             }
2792             elsif ($offset > 0) {
2793             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2794             }
2795             else {
2796             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2797             }
2798             if ($length == 0) {
2799             $octet_length = 0;
2800             }
2801             elsif ($length > 0) {
2802             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2803             }
2804             else {
2805             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2806             }
2807             CORE::substr($_[0], $octet_offset, $octet_length);
2808             }
2809              
2810             # substr($string,$offset)
2811             else {
2812             my $octet_offset = 0;
2813             if ($offset == 0) {
2814             $octet_offset = 0;
2815             }
2816             elsif ($offset > 0) {
2817             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2818             }
2819             else {
2820             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2821             }
2822             CORE::substr($_[0], $octet_offset);
2823             }
2824             }
2825             END
2826             }
2827              
2828             #
2829             # KOI8-U index by character
2830             #
2831 0     0 1 0 sub KOI8U::index($$;$) {
2832 0 0       0  
2833 0         0 my $index;
2834             if (@_ == 3) {
2835             $index = Ekoi8u::index($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2836 0         0 }
2837             else {
2838             $index = Ekoi8u::index($_[0], $_[1]);
2839 0 0       0 }
2840 0         0  
2841             if ($index == -1) {
2842             return -1;
2843 0         0 }
2844             else {
2845             return KOI8U::length(CORE::substr $_[0], 0, $index);
2846             }
2847             }
2848              
2849             #
2850             # KOI8-U rindex by character
2851             #
2852 0     0 1 0 sub KOI8U::rindex($$;$) {
2853 0 0       0  
2854 0         0 my $rindex;
2855             if (@_ == 3) {
2856             $rindex = Ekoi8u::rindex($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2857 0         0 }
2858             else {
2859             $rindex = Ekoi8u::rindex($_[0], $_[1]);
2860 0 0       0 }
2861 0         0  
2862             if ($rindex == -1) {
2863             return -1;
2864 0         0 }
2865             else {
2866             return KOI8U::length(CORE::substr $_[0], 0, $rindex);
2867             }
2868             }
2869              
2870 204     204   2191 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  204         432  
  204         23674  
2871             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2872             use vars qw($slash); $slash = 'm//';
2873              
2874             # ord() to ord() or KOI8U::ord()
2875             my $function_ord = 'ord';
2876              
2877             # ord to ord or KOI8U::ord_
2878             my $function_ord_ = 'ord';
2879              
2880             # reverse to reverse or KOI8U::reverse
2881             my $function_reverse = 'reverse';
2882              
2883             # getc to getc or KOI8U::getc
2884             my $function_getc = 'getc';
2885              
2886             # P.1023 Appendix W.9 Multibyte Anchoring
2887             # of ISBN 1-56592-224-7 CJKV Information Processing
2888              
2889 204     204   1612 my $anchor = '';
  204     0   860  
  204         9850189  
2890              
2891             use vars qw($nest);
2892              
2893             # regexp of nested parens in qqXX
2894              
2895             # P.340 Matching Nested Constructs with Embedded Code
2896             # in Chapter 7: Perl
2897             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2898              
2899             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2900             [^\\()] |
2901             \( (?{$nest++}) |
2902             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2903             \\ [^c] |
2904             \\c[\x40-\x5F] |
2905             [\x00-\xFF]
2906             }xms;
2907              
2908             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2909             [^\\{}] |
2910             \{ (?{$nest++}) |
2911             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2912             \\ [^c] |
2913             \\c[\x40-\x5F] |
2914             [\x00-\xFF]
2915             }xms;
2916              
2917             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2918             [^\\\[\]] |
2919             \[ (?{$nest++}) |
2920             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2921             \\ [^c] |
2922             \\c[\x40-\x5F] |
2923             [\x00-\xFF]
2924             }xms;
2925              
2926             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2927             [^\\<>] |
2928             \< (?{$nest++}) |
2929             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2930             \\ [^c] |
2931             \\c[\x40-\x5F] |
2932             [\x00-\xFF]
2933             }xms;
2934              
2935             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2936             (?: ::)? (?:
2937             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2938             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2939             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2940             ))
2941             }xms;
2942              
2943             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2944             (?: ::)? (?:
2945             (?>[0-9]+) |
2946             [^a-zA-Z_0-9\[\]] |
2947             ^[A-Z] |
2948             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2949             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2950             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2951             ))
2952             }xms;
2953              
2954             my $qq_substr = qr{(?> Char::substr | KOI8U::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2955             }xms;
2956              
2957             # regexp of nested parens in qXX
2958             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2959             [^()] |
2960             \( (?{$nest++}) |
2961             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2962             [\x00-\xFF]
2963             }xms;
2964              
2965             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2966             [^\{\}] |
2967             \{ (?{$nest++}) |
2968             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2969             [\x00-\xFF]
2970             }xms;
2971              
2972             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2973             [^\[\]] |
2974             \[ (?{$nest++}) |
2975             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2976             [\x00-\xFF]
2977             }xms;
2978              
2979             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2980             [^<>] |
2981             \< (?{$nest++}) |
2982             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2983             [\x00-\xFF]
2984             }xms;
2985              
2986             my $matched = '';
2987             my $s_matched = '';
2988              
2989             my $tr_variable = ''; # variable of tr///
2990             my $sub_variable = ''; # variable of s///
2991             my $bind_operator = ''; # =~ or !~
2992              
2993             my @heredoc = (); # here document
2994             my @heredoc_delimiter = ();
2995             my $here_script = ''; # here script
2996              
2997             #
2998             # escape KOI8-U script
2999 0 50   204 0 0 #
3000             sub KOI8U::escape(;$) {
3001             local($_) = $_[0] if @_;
3002              
3003             # P.359 The Study Function
3004             # in Chapter 7: Perl
3005 204         674 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3006              
3007             study $_; # Yes, I studied study yesterday.
3008              
3009             # while all script
3010              
3011             # 6.14. Matching from Where the Last Pattern Left Off
3012             # in Chapter 6. Pattern Matching
3013             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3014             # (and so on)
3015              
3016             # one member of Tag-team
3017             #
3018             # P.128 Start of match (or end of previous match): \G
3019             # P.130 Advanced Use of \G with Perl
3020             # in Chapter 3: Overview of Regular Expression Features and Flavors
3021             # P.255 Use leading anchors
3022             # P.256 Expose ^ and \G at the front expressions
3023             # in Chapter 6: Crafting an Efficient Expression
3024             # P.315 "Tag-team" matching with /gc
3025             # in Chapter 7: Perl
3026 204         377 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3027 204         465  
3028 204         761 my $e_script = '';
3029             while (not /\G \z/oxgc) { # member
3030             $e_script .= KOI8U::escape_token();
3031 74753         132894 }
3032              
3033             return $e_script;
3034             }
3035              
3036             #
3037             # escape KOI8-U token of script
3038             #
3039             sub KOI8U::escape_token {
3040              
3041 204     74753 0 2806 # \n output here document
3042              
3043             my $ignore_modules = join('|', qw(
3044             utf8
3045             bytes
3046             charnames
3047             I18N::Japanese
3048             I18N::Collate
3049             I18N::JExt
3050             File::DosGlob
3051             Wild
3052             Wildcard
3053             Japanese
3054             ));
3055              
3056             # another member of Tag-team
3057             #
3058             # P.315 "Tag-team" matching with /gc
3059             # in Chapter 7: Perl
3060 74753 100 100     93350 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
    100 66        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
3061 74753         3058955  
3062 12522 100       15765 if (/\G ( \n ) /oxgc) { # another member (and so on)
3063 12522         24681 my $heredoc = '';
3064             if (scalar(@heredoc_delimiter) >= 1) {
3065 174         285 $slash = 'm//';
3066 174         321  
3067             $heredoc = join '', @heredoc;
3068             @heredoc = ();
3069 174         283  
3070 174         382 # skip here document
3071             for my $heredoc_delimiter (@heredoc_delimiter) {
3072 174         1077 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3073             }
3074 174         329 @heredoc_delimiter = ();
3075              
3076 174         272 $here_script = '';
3077             }
3078             return "\n" . $heredoc;
3079             }
3080 12522         37986  
3081             # ignore space, comment
3082             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3083              
3084             # if (, elsif (, unless (, while (, until (, given (, and when (
3085              
3086             # given, when
3087              
3088             # P.225 The given Statement
3089             # in Chapter 15: Smart Matching and given-when
3090             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3091              
3092             # P.133 The given Statement
3093             # in Chapter 4: Statements and Declarations
3094             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3095 17974         56033  
3096 1401         2335 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3097             $slash = 'm//';
3098             return $1;
3099             }
3100              
3101             # scalar variable ($scalar = ...) =~ tr///;
3102             # scalar variable ($scalar = ...) =~ s///;
3103              
3104             # state
3105              
3106             # P.68 Persistent, Private Variables
3107             # in Chapter 4: Subroutines
3108             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3109              
3110             # P.160 Persistent Lexically Scoped Variables: state
3111             # in Chapter 4: Statements and Declarations
3112             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3113              
3114             # (and so on)
3115 1401         4529  
3116             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3117 86 50       184 my $e_string = e_string($1);
    50          
3118 86         2055  
3119 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3120 0         0 $tr_variable = $e_string . e_string($1);
3121 0         0 $bind_operator = $2;
3122             $slash = 'm//';
3123             return '';
3124 0         0 }
3125 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3126 0         0 $sub_variable = $e_string . e_string($1);
3127 0         0 $bind_operator = $2;
3128             $slash = 'm//';
3129             return '';
3130 0         0 }
3131 86         146 else {
3132             $slash = 'div';
3133             return $e_string;
3134             }
3135             }
3136              
3137 86         285 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
3138 4         9 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3139             $slash = 'div';
3140             return q{Ekoi8u::PREMATCH()};
3141             }
3142              
3143 4         12 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
3144 28         52 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3145             $slash = 'div';
3146             return q{Ekoi8u::MATCH()};
3147             }
3148              
3149 28         86 # $', ${'} --> $', ${'}
3150 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3151             $slash = 'div';
3152             return $1;
3153             }
3154              
3155 1         3 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
3156 3         7 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3157             $slash = 'div';
3158             return q{Ekoi8u::POSTMATCH()};
3159             }
3160              
3161             # scalar variable $scalar =~ tr///;
3162             # scalar variable $scalar =~ s///;
3163             # substr() =~ tr///;
3164 3         10 # substr() =~ s///;
3165             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3166 1671 100       3648 my $scalar = e_string($1);
    100          
3167 1671         7188  
3168 1         2 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3169 1         2 $tr_variable = $scalar;
3170 1         2 $bind_operator = $1;
3171             $slash = 'm//';
3172             return '';
3173 1         3 }
3174 61         122 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3175 61         117 $sub_variable = $scalar;
3176 61         98 $bind_operator = $1;
3177             $slash = 'm//';
3178             return '';
3179 61         175 }
3180 1609         2595 else {
3181             $slash = 'div';
3182             return $scalar;
3183             }
3184             }
3185              
3186 1609         4506 # end of statement
3187             elsif (/\G ( [,;] ) /oxgc) {
3188             $slash = 'm//';
3189 4998         7878  
3190             # clear tr/// variable
3191             $tr_variable = '';
3192 4998         7002  
3193             # clear s/// variable
3194 4998         5852 $sub_variable = '';
3195              
3196 4998         5803 $bind_operator = '';
3197              
3198             return $1;
3199             }
3200              
3201 4998         18300 # bareword
3202             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3203             return $1;
3204             }
3205              
3206 0         0 # $0 --> $0
3207 2         5 elsif (/\G ( \$ 0 ) /oxmsgc) {
3208             $slash = 'div';
3209             return $1;
3210 2         8 }
3211 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3212             $slash = 'div';
3213             return $1;
3214             }
3215              
3216 0         0 # $$ --> $$
3217 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3218             $slash = 'div';
3219             return $1;
3220             }
3221              
3222             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3223 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
3224 4         5 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3225             $slash = 'div';
3226             return e_capture($1);
3227 4         8 }
3228 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3229             $slash = 'div';
3230             return e_capture($1);
3231             }
3232              
3233 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3234 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3235             $slash = 'div';
3236             return e_capture($1.'->'.$2);
3237             }
3238              
3239 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3240 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3241             $slash = 'div';
3242             return e_capture($1.'->'.$2);
3243             }
3244              
3245 0         0 # $$foo
3246 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3247             $slash = 'div';
3248             return e_capture($1);
3249             }
3250              
3251 0         0 # ${ foo }
3252 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3253             $slash = 'div';
3254             return '${' . $1 . '}';
3255             }
3256              
3257 0         0 # ${ ... }
3258 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3259             $slash = 'div';
3260             return e_capture($1);
3261             }
3262              
3263             # variable or function
3264 0         0 # $ @ % & * $ #
3265 42         72 elsif (/\G ( (?: [\$\@\%\&\*] | \$\# | -> | \b sub \b) (?>\s*) (?: split | chop | index | rindex | lc | uc | fc | chr | ord | reverse | getc | tr | y | q | qq | qx | qw | m | s | qr | glob | lstat | opendir | stat | unlink | chdir ) ) \b /oxmsgc) {
3266             $slash = 'div';
3267             return $1;
3268             }
3269             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3270 42         129 # $ @ # \ ' " / ? ( ) [ ] < >
3271 62         117 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3272             $slash = 'div';
3273             return $1;
3274             }
3275              
3276 62         194 # while ()
3277             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3278             return $1;
3279             }
3280              
3281             # while () --- glob
3282              
3283             # avoid "Error: Runtime exception" of perl version 5.005_03
3284 0         0  
3285             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3286             return 'while ($_ = Ekoi8u::glob("' . $1 . '"))';
3287             }
3288              
3289 0         0 # while (glob)
3290             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3291             return 'while ($_ = Ekoi8u::glob_)';
3292             }
3293              
3294 0         0 # while (glob(WILDCARD))
3295             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3296             return 'while ($_ = Ekoi8u::glob';
3297             }
3298 0         0  
  248         721  
3299             # doit if, doit unless, doit while, doit until, doit for, doit when
3300             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3301 248         1521  
  19         36  
3302 19         63 # subroutines of package Ekoi8u
  0         0  
3303 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         20  
3304 13         32 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3305 0         0 elsif (/\G \b KOI8U::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         186  
3306 114         309 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         5  
3307 2         6 elsif (/\G \b KOI8U::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval KOI8U::escape'; }
  0         0  
3308 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         4  
3309 2         6 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chop'; }
  0         0  
3310 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3311 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3312 0         0 elsif (/\G \b KOI8U::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::index'; }
  2         4  
3313 2         7 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::index'; }
  0         0  
3314 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3315 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3316 0         0 elsif (/\G \b KOI8U::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::rindex'; }
  1         2  
3317 1         3 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::rindex'; }
  0         0  
3318 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc'; }
  1         2  
3319 1         3 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst'; }
  0         0  
3320 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc'; }
  6         11  
3321             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst'; }
3322             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc'; }
3323 6         15  
  0         0  
3324 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3325 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3326 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3327 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3328 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3329 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3330             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3331 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3332 0         0  
  0         0  
3333 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3334 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3335 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3336 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3337 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3338             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3339             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3340 0         0  
  0         0  
3341 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3342 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3343 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3344             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3345 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         5  
3346 2         5  
  2         5  
3347 2         5 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         75  
3348 36         117 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         5  
3349 2         6 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr'; }
  8         17  
3350 8         21 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3351 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3352 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob'; }
  0         0  
3353 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc_'; }
  0         0  
3354 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst_'; }
  0         0  
3355 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc_'; }
  0         0  
3356 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst_'; }
  0         0  
3357             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc_'; }
3358 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3359 0         0  
  0         0  
3360 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3361 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3362 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr_'; }
  0         0  
3363 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3364 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3365 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob_'; }
  8         18  
3366             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3367             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3368 8         26 # split
3369             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3370 87         228 $slash = 'm//';
3371 87         140  
3372 87         569 my $e = '';
3373             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3374             $e .= $1;
3375             }
3376 85 100       338  
  87 100       6597  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3377             # end of split
3378             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8u::split' . $e; }
3379 2         9  
3380             # split scalar value
3381             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Ekoi8u::split' . $e . e_string($1); }
3382 1         6  
3383 0         0 # split literal space
3384 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {qq$1 $2}; }
3385 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3386 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3387 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3388 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3389 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3390 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {q$1 $2}; }
3391 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3392 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3393 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3394 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3395 10         41 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3396             elsif (/\G ' [ ] ' /oxgc) { return 'Ekoi8u::split' . $e . qq {' '}; }
3397             elsif (/\G " [ ] " /oxgc) { return 'Ekoi8u::split' . $e . qq {" "}; }
3398              
3399 0 0       0 # split qq//
  0         0  
3400             elsif (/\G \b (qq) \b /oxgc) {
3401 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3402 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3403 0         0 while (not /\G \z/oxgc) {
3404 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3405 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3406 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3407 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3408 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3409             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3410 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3411             }
3412             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3413             }
3414             }
3415              
3416 0 50       0 # split qr//
  12         596  
3417             elsif (/\G \b (qr) \b /oxgc) {
3418 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3419 12 50       215 else {
  12 50       3768  
    50          
    50          
    50          
    50          
    50          
    50          
3420 0         0 while (not /\G \z/oxgc) {
3421 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3422 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3423 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3424 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3425 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3426 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3427             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3428 12         84 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3429             }
3430             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3431             }
3432             }
3433              
3434 0 0       0 # split q//
  0         0  
3435             elsif (/\G \b (q) \b /oxgc) {
3436 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3437 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3438 0         0 while (not /\G \z/oxgc) {
3439 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3440 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3441 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3442 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3443 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3444             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3445 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3446             }
3447             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3448             }
3449             }
3450              
3451 0 50       0 # split m//
  18         489  
3452             elsif (/\G \b (m) \b /oxgc) {
3453 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3454 18 50       85 else {
  18 50       4719  
    50          
    50          
    50          
    50          
    50          
    50          
3455 0         0 while (not /\G \z/oxgc) {
3456 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3457 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3458 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3459 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3460 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3461 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3462             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3463 18         150 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3464             }
3465             die __FILE__, ": Search pattern not terminated\n";
3466             }
3467             }
3468              
3469 0         0 # split ''
3470 0         0 elsif (/\G (\') /oxgc) {
3471 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3472 0         0 while (not /\G \z/oxgc) {
3473 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3474 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3475             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3476 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3477             }
3478             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3479             }
3480              
3481 0         0 # split ""
3482 0         0 elsif (/\G (\") /oxgc) {
3483 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3484 0         0 while (not /\G \z/oxgc) {
3485 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3486 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3487             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3488 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3489             }
3490             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3491             }
3492              
3493 0         0 # split //
3494 44         109 elsif (/\G (\/) /oxgc) {
3495 44 50       208 my $regexp = '';
  381 50       1569  
    100          
    50          
3496 0         0 while (not /\G \z/oxgc) {
3497 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3498 44         182 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3499             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3500 337         675 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3501             }
3502             die __FILE__, ": Search pattern not terminated\n";
3503             }
3504             }
3505              
3506             # tr/// or y///
3507              
3508             # about [cdsrbB]* (/B modifier)
3509             #
3510             # P.559 appendix C
3511             # of ISBN 4-89052-384-7 Programming perl
3512             # (Japanese title is: Perl puroguramingu)
3513 0         0  
3514             elsif (/\G \b ( tr | y ) \b /oxgc) {
3515             my $ope = $1;
3516 3 50       7  
3517 3         39 # $1 $2 $3 $4 $5 $6
3518 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3519             my @tr = ($tr_variable,$2);
3520             return e_tr(@tr,'',$4,$6);
3521 0         0 }
3522 3         5 else {
3523 3 50       8 my $e = '';
  3 50       219  
    50          
    50          
    50          
    50          
3524             while (not /\G \z/oxgc) {
3525 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3526 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3527 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3528 0         0 while (not /\G \z/oxgc) {
3529 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3530 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3531 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3532 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3533             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3534 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3535             }
3536             die __FILE__, ": Transliteration replacement not terminated\n";
3537 0         0 }
3538 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3539 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3540 0         0 while (not /\G \z/oxgc) {
3541 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3542 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3543 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3544 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3545             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3546 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3547             }
3548             die __FILE__, ": Transliteration replacement not terminated\n";
3549 0         0 }
3550 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3551 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3552 0         0 while (not /\G \z/oxgc) {
3553 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3554 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3555 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3556 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3557             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3558 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3559             }
3560             die __FILE__, ": Transliteration replacement not terminated\n";
3561 0         0 }
3562 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3563 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3564 0         0 while (not /\G \z/oxgc) {
3565 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3566 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3567 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3568 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3569             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3570 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3571             }
3572             die __FILE__, ": Transliteration replacement not terminated\n";
3573             }
3574 0         0 # $1 $2 $3 $4 $5 $6
3575 3         11 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3576             my @tr = ($tr_variable,$2);
3577             return e_tr(@tr,'',$4,$6);
3578 3         8 }
3579             }
3580             die __FILE__, ": Transliteration pattern not terminated\n";
3581             }
3582             }
3583              
3584 0         0 # qq//
3585             elsif (/\G \b (qq) \b /oxgc) {
3586             my $ope = $1;
3587 2180 50       5283  
3588 2180         4118 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3589 0         0 if (/\G (\#) /oxgc) { # qq# #
3590 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3591 0         0 while (not /\G \z/oxgc) {
3592 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3593 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3594             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3595 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3596             }
3597             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3598             }
3599 0         0  
3600 2180         22969 else {
3601 2180 50       5199 my $e = '';
  2180 50       8805  
    100          
    50          
    50          
    0          
3602             while (not /\G \z/oxgc) {
3603             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3604              
3605 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3606 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3607 0         0 my $qq_string = '';
3608 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3609 0         0 while (not /\G \z/oxgc) {
3610 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3611             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3612 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3613 0         0 elsif (/\G (\)) /oxgc) {
3614             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3615 0         0 else { $qq_string .= $1; }
3616             }
3617 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3618             }
3619             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3620             }
3621              
3622 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3623 2150         3263 elsif (/\G (\{) /oxgc) { # qq { }
3624 2150         3460 my $qq_string = '';
3625 2150 100       4554 local $nest = 1;
  83993 50       276135  
    100          
    100          
    50          
3626 722         1839 while (not /\G \z/oxgc) {
3627 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         1616  
3628             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3629 1153 100       1920 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         5518  
3630 2150         4473 elsif (/\G (\}) /oxgc) {
3631             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3632 1153         2141 else { $qq_string .= $1; }
3633             }
3634 78815         179796 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3635             }
3636             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3637             }
3638              
3639 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3640 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3641 0         0 my $qq_string = '';
3642 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3643 0         0 while (not /\G \z/oxgc) {
3644 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3645             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3646 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3647 0         0 elsif (/\G (\]) /oxgc) {
3648             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3649 0         0 else { $qq_string .= $1; }
3650             }
3651 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3652             }
3653             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3654             }
3655              
3656 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3657 30         48 elsif (/\G (\<) /oxgc) { # qq < >
3658 30         49 my $qq_string = '';
3659 30 100       139 local $nest = 1;
  1166 50       8285  
    50          
    100          
    50          
3660 22         51 while (not /\G \z/oxgc) {
3661 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3662             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3663 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         65  
3664 30         66 elsif (/\G (\>) /oxgc) {
3665             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3666 0         0 else { $qq_string .= $1; }
3667             }
3668 1114         2352 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3669             }
3670             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3671             }
3672              
3673 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3674 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3675 0         0 my $delimiter = $1;
3676 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3677 0         0 while (not /\G \z/oxgc) {
3678 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3679 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3680             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3681 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3682             }
3683             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3684 0         0 }
3685             }
3686             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3687             }
3688             }
3689              
3690 0         0 # qr//
3691 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3692 0         0 my $ope = $1;
3693             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3694             return e_qr($ope,$1,$3,$2,$4);
3695 0         0 }
3696 0         0 else {
3697 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3698 0         0 while (not /\G \z/oxgc) {
3699 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3700 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3701 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3702 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3703 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3704 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3705             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3706 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3707             }
3708             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3709             }
3710             }
3711              
3712 0         0 # qw//
3713 16 50       48 elsif (/\G \b (qw) \b /oxgc) {
3714 16         74 my $ope = $1;
3715             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3716             return e_qw($ope,$1,$3,$2);
3717 0         0 }
3718 16         31 else {
3719 16 50       53 my $e = '';
  16 50       100  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3720             while (not /\G \z/oxgc) {
3721 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3722 16         59  
3723             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3724 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3725 0         0  
3726             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3727 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3728 0         0  
3729             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3730 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3731 0         0  
3732             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3733 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3734 0         0  
3735             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3736 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3737             }
3738             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3739             }
3740             }
3741              
3742 0         0 # qx//
3743 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3744 0         0 my $ope = $1;
3745             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3746             return e_qq($ope,$1,$3,$2);
3747 0         0 }
3748 0         0 else {
3749 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3750 0         0 while (not /\G \z/oxgc) {
3751 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3752 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3753 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3754 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3755 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3756             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3757 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3758             }
3759             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3760             }
3761             }
3762              
3763 0         0 # q//
3764             elsif (/\G \b (q) \b /oxgc) {
3765             my $ope = $1;
3766              
3767             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3768              
3769             # avoid "Error: Runtime exception" of perl version 5.005_03
3770 410 50       1274 # (and so on)
3771 410         2000  
3772 0         0 if (/\G (\#) /oxgc) { # q# #
3773 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3774 0         0 while (not /\G \z/oxgc) {
3775 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3776 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3777             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3778 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3779             }
3780             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3781             }
3782 0         0  
3783 410         644 else {
3784 410 50       1206 my $e = '';
  410 50       2046  
    100          
    50          
    100          
    50          
3785             while (not /\G \z/oxgc) {
3786             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3787              
3788 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3789 0         0 elsif (/\G (\() /oxgc) { # q ( )
3790 0         0 my $q_string = '';
3791 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3792 0         0 while (not /\G \z/oxgc) {
3793 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3794 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3795             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3796 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3797 0         0 elsif (/\G (\)) /oxgc) {
3798             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3799 0         0 else { $q_string .= $1; }
3800             }
3801 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3802             }
3803             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3804             }
3805              
3806 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3807 404         659 elsif (/\G (\{) /oxgc) { # q { }
3808 404         643 my $q_string = '';
3809 404 50       1045 local $nest = 1;
  6757 50       23834  
    50          
    100          
    100          
    50          
3810 0         0 while (not /\G \z/oxgc) {
3811 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3812 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         176  
3813             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3814 107 100       178 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         1222  
3815 404         1065 elsif (/\G (\}) /oxgc) {
3816             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3817 107         235 else { $q_string .= $1; }
3818             }
3819 6139         11521 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3820             }
3821             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3822             }
3823              
3824 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3825 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3826 0         0 my $q_string = '';
3827 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3828 0         0 while (not /\G \z/oxgc) {
3829 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3830 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3831             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3832 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3833 0         0 elsif (/\G (\]) /oxgc) {
3834             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3835 0         0 else { $q_string .= $1; }
3836             }
3837 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3838             }
3839             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3840             }
3841              
3842 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3843 5         11 elsif (/\G (\<) /oxgc) { # q < >
3844 5         12 my $q_string = '';
3845 5 50       18 local $nest = 1;
  88 50       368  
    50          
    50          
    100          
    50          
3846 0         0 while (not /\G \z/oxgc) {
3847 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3848 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3849             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3850 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         26  
3851 5         18 elsif (/\G (\>) /oxgc) {
3852             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3853 0         0 else { $q_string .= $1; }
3854             }
3855 83         160 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3856             }
3857             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3858             }
3859              
3860 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3861 1         2 elsif (/\G (\S) /oxgc) { # q * *
3862 1         3 my $delimiter = $1;
3863 1 50       4 my $q_string = '';
  14 50       65  
    100          
    50          
3864 0         0 while (not /\G \z/oxgc) {
3865 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3866 1         3 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3867             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3868 13         27 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3869             }
3870             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3871 0         0 }
3872             }
3873             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3874             }
3875             }
3876              
3877 0         0 # m//
3878 209 50       604 elsif (/\G \b (m) \b /oxgc) {
3879 209         1474 my $ope = $1;
3880             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3881             return e_qr($ope,$1,$3,$2,$4);
3882 0         0 }
3883 209         344 else {
3884 209 50       669 my $e = '';
  209 50       12618  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3885 0         0 while (not /\G \z/oxgc) {
3886 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3887 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3888 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3889 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3890 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3891 10         30 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3892 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3893             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3894 199         667 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3895             }
3896             die __FILE__, ": Search pattern not terminated\n";
3897             }
3898             }
3899              
3900             # s///
3901              
3902             # about [cegimosxpradlunbB]* (/cg modifier)
3903             #
3904             # P.67 Pattern-Matching Operators
3905             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3906 0         0  
3907             elsif (/\G \b (s) \b /oxgc) {
3908             my $ope = $1;
3909 97 100       262  
3910 97         1641 # $1 $2 $3 $4 $5 $6
3911             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3912             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3913 1         14 }
3914 96         185 else {
3915 96 50       340 my $e = '';
  96 50       13334  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3916             while (not /\G \z/oxgc) {
3917 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3918 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3919 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3920             while (not /\G \z/oxgc) {
3921 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3922 0         0 # $1 $2 $3 $4
3923 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3924 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3925 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3926 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3927 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3928 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3929 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3930             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3931 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3932             }
3933             die __FILE__, ": Substitution replacement not terminated\n";
3934 0         0 }
3935 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3936 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3937             while (not /\G \z/oxgc) {
3938 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3939 0         0 # $1 $2 $3 $4
3940 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3941 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3942 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3943 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3944 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3945 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3946 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3947             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3948 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3949             }
3950             die __FILE__, ": Substitution replacement not terminated\n";
3951 0         0 }
3952 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3953 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3954             while (not /\G \z/oxgc) {
3955 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3956 0         0 # $1 $2 $3 $4
3957 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3958 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3960 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3961 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3962             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3963 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3964             }
3965             die __FILE__, ": Substitution replacement not terminated\n";
3966 0         0 }
3967 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3968 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3969             while (not /\G \z/oxgc) {
3970 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3971 0         0 # $1 $2 $3 $4
3972 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3973 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3974 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3975 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3976 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3977 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3978 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3979             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3980 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3981             }
3982             die __FILE__, ": Substitution replacement not terminated\n";
3983             }
3984 0         0 # $1 $2 $3 $4 $5 $6
3985             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3986             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3987             }
3988 21         67 # $1 $2 $3 $4 $5 $6
3989             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3990             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3991             }
3992 0         0 # $1 $2 $3 $4 $5 $6
3993             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3994             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3995             }
3996 0         0 # $1 $2 $3 $4 $5 $6
3997             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3998             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3999 75         353 }
4000             }
4001             die __FILE__, ": Substitution pattern not terminated\n";
4002             }
4003             }
4004 0         0  
4005 0         0 # require ignore module
4006 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
4007             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
4008             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4009 0         0  
4010 37         300 # use strict; --> use strict; no strict qw(refs);
4011 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4012             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4013             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4014              
4015 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
4016 2         21 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4017             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4018             return "use $1; no strict qw(refs);";
4019 0         0 }
4020             else {
4021             return "use $1;";
4022             }
4023 2 0 0     11 }
      0        
4024 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4025             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4026             return "use $1; no strict qw(refs);";
4027 0         0 }
4028             else {
4029             return "use $1;";
4030             }
4031             }
4032 0         0  
4033 2         15 # ignore use module
4034 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4035             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4036             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4037 0         0  
4038 0         0 # ignore no module
4039 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4040             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4041             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4042 0         0  
4043             # use else
4044             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4045 0         0  
4046             # use else
4047             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4048              
4049 2         9 # ''
4050 848         2127 elsif (/\G (?
4051 848 100       2307 my $q_string = '';
  8241 100       25504  
    100          
    50          
4052 4         9 while (not /\G \z/oxgc) {
4053 48         88 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4054 848         1956 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4055             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4056 7341         16947 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4057             }
4058             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4059             }
4060              
4061 0         0 # ""
4062 1804         4093 elsif (/\G (\") /oxgc) {
4063 1804 100       4611 my $qq_string = '';
  34992 100       99974  
    100          
    50          
4064 67         156 while (not /\G \z/oxgc) {
4065 12         25 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4066 1804         3959 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4067             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4068 33109         66766 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4069             }
4070             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4071             }
4072              
4073 0         0 # ``
4074 1         3 elsif (/\G (\`) /oxgc) {
4075 1 50       4 my $qx_string = '';
  19 50       68  
    100          
    50          
4076 0         0 while (not /\G \z/oxgc) {
4077 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4078 1         4 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4079             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4080 18         30 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4081             }
4082             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4083             }
4084              
4085 0         0 # // --- not divide operator (num / num), not defined-or
4086 453         1888 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4087 453 50       1355 my $regexp = '';
  4496 50       16167  
    100          
    50          
4088 0         0 while (not /\G \z/oxgc) {
4089 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4090 453         1501 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4091             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4092 4043         8747 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4093             }
4094             die __FILE__, ": Search pattern not terminated\n";
4095             }
4096              
4097 0         0 # ?? --- not conditional operator (condition ? then : else)
4098 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4099 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4100 0         0 while (not /\G \z/oxgc) {
4101 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4102 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4103             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4104 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4105             }
4106             die __FILE__, ": Search pattern not terminated\n";
4107             }
4108 0         0  
  0         0  
4109             # <<>> (a safer ARGV)
4110             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4111 0         0  
  0         0  
4112             # << (bit shift) --- not here document
4113             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4114              
4115 0         0 # <<~'HEREDOC'
4116 6         11 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4117 6         12 $slash = 'm//';
4118             my $here_quote = $1;
4119             my $delimiter = $2;
4120 6 50       9  
4121 6         13 # get here document
4122 6         34 if ($here_script eq '') {
4123             $here_script = CORE::substr $_, pos $_;
4124 6 50       30 $here_script =~ s/.*?\n//oxm;
4125 6         52 }
4126 6         15 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4127 6         10 my $heredoc = $1;
4128 6         42 my $indent = $2;
4129 6         16 $heredoc =~ s{^$indent}{}msg; # no /ox
4130             push @heredoc, $heredoc . qq{\n$delimiter\n};
4131             push @heredoc_delimiter, qq{\\s*$delimiter};
4132 6         12 }
4133             else {
4134 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4135             }
4136             return qq{<<'$delimiter'};
4137             }
4138              
4139             # <<~\HEREDOC
4140              
4141             # P.66 2.6.6. "Here" Documents
4142             # in Chapter 2: Bits and Pieces
4143             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4144              
4145             # P.73 "Here" Documents
4146             # in Chapter 2: Bits and Pieces
4147             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4148 6         22  
4149 3         7 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4150 3         6 $slash = 'm//';
4151             my $here_quote = $1;
4152             my $delimiter = $2;
4153 3 50       6  
4154 3         8 # get here document
4155 3         10 if ($here_script eq '') {
4156             $here_script = CORE::substr $_, pos $_;
4157 3 50       22 $here_script =~ s/.*?\n//oxm;
4158 3         37 }
4159 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4160 3         10 my $heredoc = $1;
4161 3         34 my $indent = $2;
4162 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
4163             push @heredoc, $heredoc . qq{\n$delimiter\n};
4164             push @heredoc_delimiter, qq{\\s*$delimiter};
4165 3         6 }
4166             else {
4167 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4168             }
4169             return qq{<<\\$delimiter};
4170             }
4171              
4172 3         13 # <<~"HEREDOC"
4173 6         13 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4174 6         10 $slash = 'm//';
4175             my $here_quote = $1;
4176             my $delimiter = $2;
4177 6 50       9  
4178 6         13 # get here document
4179 6         27 if ($here_script eq '') {
4180             $here_script = CORE::substr $_, pos $_;
4181 6 50       32 $here_script =~ s/.*?\n//oxm;
4182 6         66 }
4183 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4184 6         7 my $heredoc = $1;
4185 6         55 my $indent = $2;
4186 6         15 $heredoc =~ s{^$indent}{}msg; # no /ox
4187             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4188             push @heredoc_delimiter, qq{\\s*$delimiter};
4189 6         14 }
4190             else {
4191 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4192             }
4193             return qq{<<"$delimiter"};
4194             }
4195              
4196 6         23 # <<~HEREDOC
4197 3         8 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4198 3         8 $slash = 'm//';
4199             my $here_quote = $1;
4200             my $delimiter = $2;
4201 3 50       6  
4202 3         8 # get here document
4203 3         11 if ($here_script eq '') {
4204             $here_script = CORE::substr $_, pos $_;
4205 3 50       26 $here_script =~ s/.*?\n//oxm;
4206 3         46 }
4207 3         9 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4208 3         5 my $heredoc = $1;
4209 3         40 my $indent = $2;
4210 3         11 $heredoc =~ s{^$indent}{}msg; # no /ox
4211             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4212             push @heredoc_delimiter, qq{\\s*$delimiter};
4213 3         7 }
4214             else {
4215 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4216             }
4217             return qq{<<$delimiter};
4218             }
4219              
4220 3         14 # <<~`HEREDOC`
4221 6         37 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4222 6         14 $slash = 'm//';
4223             my $here_quote = $1;
4224             my $delimiter = $2;
4225 6 50       8  
4226 6         11 # get here document
4227 6         18 if ($here_script eq '') {
4228             $here_script = CORE::substr $_, pos $_;
4229 6 50       33 $here_script =~ s/.*?\n//oxm;
4230 6         54 }
4231 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4232 6         8 my $heredoc = $1;
4233 6         45 my $indent = $2;
4234 6         15 $heredoc =~ s{^$indent}{}msg; # no /ox
4235             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4236             push @heredoc_delimiter, qq{\\s*$delimiter};
4237 6         10 }
4238             else {
4239 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4240             }
4241             return qq{<<`$delimiter`};
4242             }
4243              
4244 6         23 # <<'HEREDOC'
4245 72         129 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4246 72         318 $slash = 'm//';
4247             my $here_quote = $1;
4248             my $delimiter = $2;
4249 72 50       105  
4250 72         135 # get here document
4251 72         338 if ($here_script eq '') {
4252             $here_script = CORE::substr $_, pos $_;
4253 72 50       368 $here_script =~ s/.*?\n//oxm;
4254 72         569 }
4255 72         228 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4256             push @heredoc, $1 . qq{\n$delimiter\n};
4257             push @heredoc_delimiter, $delimiter;
4258 72         103 }
4259             else {
4260 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4261             }
4262             return $here_quote;
4263             }
4264              
4265             # <<\HEREDOC
4266              
4267             # P.66 2.6.6. "Here" Documents
4268             # in Chapter 2: Bits and Pieces
4269             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4270              
4271             # P.73 "Here" Documents
4272             # in Chapter 2: Bits and Pieces
4273             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4274 72         265  
4275 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4276 0         0 $slash = 'm//';
4277             my $here_quote = $1;
4278             my $delimiter = $2;
4279 0 0       0  
4280 0         0 # get here document
4281 0         0 if ($here_script eq '') {
4282             $here_script = CORE::substr $_, pos $_;
4283 0 0       0 $here_script =~ s/.*?\n//oxm;
4284 0         0 }
4285 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4286             push @heredoc, $1 . qq{\n$delimiter\n};
4287             push @heredoc_delimiter, $delimiter;
4288 0         0 }
4289             else {
4290 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4291             }
4292             return $here_quote;
4293             }
4294              
4295 0         0 # <<"HEREDOC"
4296 36         84 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4297 36         78 $slash = 'm//';
4298             my $here_quote = $1;
4299             my $delimiter = $2;
4300 36 50       68  
4301 36         88 # get here document
4302 36         253 if ($here_script eq '') {
4303             $here_script = CORE::substr $_, pos $_;
4304 36 50       199 $here_script =~ s/.*?\n//oxm;
4305 36         496 }
4306 36         121 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4307             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4308             push @heredoc_delimiter, $delimiter;
4309 36         81 }
4310             else {
4311 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4312             }
4313             return $here_quote;
4314             }
4315              
4316 36         142 # <
4317 42         101 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4318 42         89 $slash = 'm//';
4319             my $here_quote = $1;
4320             my $delimiter = $2;
4321 42 50       81  
4322 42         673 # get here document
4323 42         292 if ($here_script eq '') {
4324             $here_script = CORE::substr $_, pos $_;
4325 42 50       309 $here_script =~ s/.*?\n//oxm;
4326 42         582 }
4327 42         219 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4328             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4329             push @heredoc_delimiter, $delimiter;
4330 42         95 }
4331             else {
4332 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4333             }
4334             return $here_quote;
4335             }
4336              
4337 42         173 # <<`HEREDOC`
4338 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4339 0         0 $slash = 'm//';
4340             my $here_quote = $1;
4341             my $delimiter = $2;
4342 0 0       0  
4343 0         0 # get here document
4344 0         0 if ($here_script eq '') {
4345             $here_script = CORE::substr $_, pos $_;
4346 0 0       0 $here_script =~ s/.*?\n//oxm;
4347 0         0 }
4348 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4349             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4350             push @heredoc_delimiter, $delimiter;
4351 0         0 }
4352             else {
4353 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4354             }
4355             return $here_quote;
4356             }
4357              
4358 0         0 # <<= <=> <= < operator
4359             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4360             return $1;
4361             }
4362              
4363 12         59 #
4364             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4365             return $1;
4366             }
4367              
4368             # --- glob
4369              
4370             # avoid "Error: Runtime exception" of perl version 5.005_03
4371 0         0  
4372             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4373             return 'Ekoi8u::glob("' . $1 . '")';
4374             }
4375 0         0  
4376             # __DATA__
4377             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4378 0         0  
4379             # __END__
4380             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4381              
4382             # \cD Control-D
4383              
4384             # P.68 2.6.8. Other Literal Tokens
4385             # in Chapter 2: Bits and Pieces
4386             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4387              
4388             # P.76 Other Literal Tokens
4389             # in Chapter 2: Bits and Pieces
4390 204         1560 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4391              
4392             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4393 0         0  
4394             # \cZ Control-Z
4395             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4396              
4397             # any operator before div
4398             elsif (/\G (
4399             -- | \+\+ |
4400 0         0 [\)\}\]]
  5081         11066  
4401              
4402             ) /oxgc) { $slash = 'div'; return $1; }
4403              
4404             # yada-yada or triple-dot operator
4405             elsif (/\G (
4406 5081         24606 \.\.\.
  7         10  
4407              
4408             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4409              
4410             # any operator before m//
4411              
4412             # //, //= (defined-or)
4413              
4414             # P.164 Logical Operators
4415             # in Chapter 10: More Control Structures
4416             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4417              
4418             # P.119 C-Style Logical (Short-Circuit) Operators
4419             # in Chapter 3: Unary and Binary Operators
4420             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4421              
4422             # (and so on)
4423              
4424             # ~~
4425              
4426             # P.221 The Smart Match Operator
4427             # in Chapter 15: Smart Matching and given-when
4428             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4429              
4430             # P.112 Smartmatch Operator
4431             # in Chapter 3: Unary and Binary Operators
4432             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4433              
4434             # (and so on)
4435              
4436             elsif (/\G ((?>
4437              
4438             !~~ | !~ | != | ! |
4439             %= | % |
4440             &&= | && | &= | &\.= | &\. | & |
4441             -= | -> | - |
4442             :(?>\s*)= |
4443             : |
4444             <<>> |
4445             <<= | <=> | <= | < |
4446             == | => | =~ | = |
4447             >>= | >> | >= | > |
4448             \*\*= | \*\* | \*= | \* |
4449             \+= | \+ |
4450             \.\. | \.= | \. |
4451             \/\/= | \/\/ |
4452             \/= | \/ |
4453             \? |
4454             \\ |
4455             \^= | \^\.= | \^\. | \^ |
4456             \b x= |
4457             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4458             ~~ | ~\. | ~ |
4459             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4460             \b(?: print )\b |
4461              
4462 7         27 [,;\(\{\[]
  8846         17659  
4463              
4464             )) /oxgc) { $slash = 'm//'; return $1; }
4465 8846         56329  
  15013         30388  
4466             # other any character
4467             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4468              
4469 15013         71105 # system error
4470             else {
4471             die __FILE__, ": Oops, this shouldn't happen!\n";
4472             }
4473             }
4474              
4475 0     1786 0 0 # escape KOI8-U string
4476 1786         4815 sub e_string {
4477             my($string) = @_;
4478 1786         2695 my $e_string = '';
4479              
4480             local $slash = 'm//';
4481              
4482             # P.1024 Appendix W.10 Multibyte Processing
4483             # of ISBN 1-56592-224-7 CJKV Information Processing
4484 1786         2790 # (and so on)
4485              
4486             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4487 1786 100 66     14923  
4488 1786 50       8928 # without { ... }
4489 1769         4400 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4490             if ($string !~ /<
4491             return $string;
4492             }
4493             }
4494 1769         4956  
4495 17 50       64 E_STRING_LOOP:
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
4496             while ($string !~ /\G \z/oxgc) {
4497             if (0) {
4498             }
4499 190         11802  
4500 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Ekoi8u::PREMATCH()]}
4501 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4502             $e_string .= q{Ekoi8u::PREMATCH()};
4503             $slash = 'div';
4504             }
4505              
4506 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Ekoi8u::MATCH()]}
4507 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4508             $e_string .= q{Ekoi8u::MATCH()};
4509             $slash = 'div';
4510             }
4511              
4512 0         0 # $', ${'} --> $', ${'}
4513 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4514             $e_string .= $1;
4515             $slash = 'div';
4516             }
4517              
4518 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Ekoi8u::POSTMATCH()]}
4519 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4520             $e_string .= q{Ekoi8u::POSTMATCH()};
4521             $slash = 'div';
4522             }
4523              
4524 0         0 # bareword
4525 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4526             $e_string .= $1;
4527             $slash = 'div';
4528             }
4529              
4530 0         0 # $0 --> $0
4531 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4532             $e_string .= $1;
4533             $slash = 'div';
4534 0         0 }
4535 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4536             $e_string .= $1;
4537             $slash = 'div';
4538             }
4539              
4540 0         0 # $$ --> $$
4541 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4542             $e_string .= $1;
4543             $slash = 'div';
4544             }
4545              
4546             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4547 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4548 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4549             $e_string .= e_capture($1);
4550             $slash = 'div';
4551 0         0 }
4552 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4553             $e_string .= e_capture($1);
4554             $slash = 'div';
4555             }
4556              
4557 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4558 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4559             $e_string .= e_capture($1.'->'.$2);
4560             $slash = 'div';
4561             }
4562              
4563 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4564 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4565             $e_string .= e_capture($1.'->'.$2);
4566             $slash = 'div';
4567             }
4568              
4569 0         0 # $$foo
4570 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4571             $e_string .= e_capture($1);
4572             $slash = 'div';
4573             }
4574              
4575 0         0 # ${ foo }
4576 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4577             $e_string .= '${' . $1 . '}';
4578             $slash = 'div';
4579             }
4580              
4581 0         0 # ${ ... }
4582 3         8 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4583             $e_string .= e_capture($1);
4584             $slash = 'div';
4585             }
4586              
4587             # variable or function
4588 3         25 # $ @ % & * $ #
4589 7         19 elsif ($string =~ /\G ( (?: [\$\@\%\&\*] | \$\# | -> | \b sub \b) (?>\s*) (?: split | chop | index | rindex | lc | uc | fc | chr | ord | reverse | getc | tr | y | q | qq | qx | qw | m | s | qr | glob | lstat | opendir | stat | unlink | chdir ) ) \b /oxmsgc) {
4590             $e_string .= $1;
4591             $slash = 'div';
4592             }
4593             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4594 7         21 # $ @ # \ ' " / ? ( ) [ ] < >
4595 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4596             $e_string .= $1;
4597             $slash = 'div';
4598             }
4599 0         0  
  0         0  
4600 0         0 # subroutines of package Ekoi8u
  0         0  
4601 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4602 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4603 0         0 elsif ($string =~ /\G \b KOI8U::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4604 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4605 0         0 elsif ($string =~ /\G \b KOI8U::eval \b /oxgc) { $e_string .= 'eval KOI8U::escape'; $slash = 'm//'; }
  0         0  
4606 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4607 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Ekoi8u::chop'; $slash = 'm//'; }
  0         0  
4608 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4609 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4610 0         0 elsif ($string =~ /\G \b KOI8U::index \b /oxgc) { $e_string .= 'KOI8U::index'; $slash = 'm//'; }
  0         0  
4611 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Ekoi8u::index'; $slash = 'm//'; }
  0         0  
4612 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4613 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4614 0         0 elsif ($string =~ /\G \b KOI8U::rindex \b /oxgc) { $e_string .= 'KOI8U::rindex'; $slash = 'm//'; }
  0         0  
4615 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Ekoi8u::rindex'; $slash = 'm//'; }
  0         0  
4616 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::lc'; $slash = 'm//'; }
  0         0  
4617 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::lcfirst'; $slash = 'm//'; }
  0         0  
4618 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::uc'; $slash = 'm//'; }
  0         0  
4619             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::ucfirst'; $slash = 'm//'; }
4620             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::fc'; $slash = 'm//'; }
4621 0         0  
  0         0  
4622 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4623 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4624 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4625 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4626 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4627 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4628             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
4629 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4630 0         0  
  0         0  
4631 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4632 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4633 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4634 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4635 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4636             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4637             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4638 0         0  
  0         0  
4639 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
4640 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4641 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4642             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
4643 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4644 0         0  
  0         0  
4645 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4646 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4647 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::chr'; $slash = 'm//'; }
  0         0  
4648 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4649 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4650 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::glob'; $slash = 'm//'; }
  0         0  
4651 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Ekoi8u::lc_'; $slash = 'm//'; }
  0         0  
4652 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Ekoi8u::lcfirst_'; $slash = 'm//'; }
  0         0  
4653 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Ekoi8u::uc_'; $slash = 'm//'; }
  0         0  
4654 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Ekoi8u::ucfirst_'; $slash = 'm//'; }
  0         0  
4655             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Ekoi8u::fc_'; $slash = 'm//'; }
4656 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4657 0         0  
  0         0  
4658 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4659 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4660 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Ekoi8u::chr_'; $slash = 'm//'; }
  0         0  
4661 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4662 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4663 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Ekoi8u::glob_'; $slash = 'm//'; }
  0         0  
4664             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
4665             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
4666 0         0 # split
4667             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4668 0         0 $slash = 'm//';
4669 0         0  
4670 0         0 my $e = '';
4671             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4672             $e .= $1;
4673             }
4674 0 0       0  
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
4675             # end of split
4676             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8u::split' . $e; }
4677 0         0  
  0         0  
4678             # split scalar value
4679             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . e_string($1); next E_STRING_LOOP; }
4680 0         0  
  0         0  
4681 0         0 # split literal space
  0         0  
4682 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4683 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4684 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4685 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4686 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4687 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4688 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4689 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4690 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4691 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4692 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4693 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4694             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {' '}; next E_STRING_LOOP; }
4695             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {" "}; next E_STRING_LOOP; }
4696              
4697 0 0       0 # split qq//
  0         0  
  0         0  
4698             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4699 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
4700 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4701 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4702 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4703 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq ( ) --> qr ( )
  0         0  
4704 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq { } --> qr { }
  0         0  
4705 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq [ ] --> qr [ ]
  0         0  
4706 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq < > --> qr < >
  0         0  
4707             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
4708 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq * * --> qr * *
4709             }
4710             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4711             }
4712             }
4713              
4714 0 0       0 # split qr//
  0         0  
  0         0  
4715             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4716 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
4717 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4718 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4719 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4720 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ( )
  0         0  
4721 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr { }
  0         0  
4722 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr [ ]
  0         0  
4723 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr < >
  0         0  
4724 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ' '
  0         0  
4725             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
4726 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr * *
4727             }
4728             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4729             }
4730             }
4731              
4732 0 0       0 # split q//
  0         0  
  0         0  
4733             elsif ($string =~ /\G \b (q) \b /oxgc) {
4734 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
4735 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4736 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4737 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4738 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q ( ) --> qr ( )
  0         0  
4739 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q { } --> qr { }
  0         0  
4740 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q [ ] --> qr [ ]
  0         0  
4741 0         0 elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q < > --> qr < >
  0         0  
4742             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
4743 0         0 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q * * --> qr * *
4744             }
4745             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4746             }
4747             }
4748              
4749 0 0       0 # split m//
  0         0  
  0         0  
4750             elsif ($string =~ /\G \b (m) \b /oxgc) {
4751 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # m# # --> qr # #
4752 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4753 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4754 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4755 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ( ) --> qr ( )
  0         0  
4756 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m { } --> qr { }
  0         0  
4757 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m [ ] --> qr [ ]
  0         0  
4758 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m < > --> qr < >
  0         0  
4759 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ' ' --> qr ' '
  0         0  
4760             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
4761 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m * * --> qr * *
4762             }
4763             die __FILE__, ": Search pattern not terminated\n";
4764             }
4765             }
4766              
4767 0         0 # split ''
4768 0         0 elsif ($string =~ /\G (\') /oxgc) {
4769 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
4770 0         0 while ($string !~ /\G \z/oxgc) {
4771 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
4772 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4773             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
4774 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4775             }
4776             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4777             }
4778              
4779 0         0 # split ""
4780 0         0 elsif ($string =~ /\G (\") /oxgc) {
4781 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
4782 0         0 while ($string !~ /\G \z/oxgc) {
4783 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
4784 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4785             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
4786 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4787             }
4788             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4789             }
4790              
4791 0         0 # split //
4792 0         0 elsif ($string =~ /\G (\/) /oxgc) {
4793 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4794 0         0 while ($string !~ /\G \z/oxgc) {
4795 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
4796 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4797             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
4798 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4799             }
4800             die __FILE__, ": Search pattern not terminated\n";
4801             }
4802             }
4803              
4804 0         0 # qq//
4805 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4806 0         0 my $ope = $1;
4807             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4808             $e_string .= e_qq($ope,$1,$3,$2);
4809 0         0 }
4810 0         0 else {
4811 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4812 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4813 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4814 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4815 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4816 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4817             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4818 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4819             }
4820             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4821             }
4822             }
4823              
4824 0         0 # qx//
4825 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4826 0         0 my $ope = $1;
4827             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4828             $e_string .= e_qq($ope,$1,$3,$2);
4829 0         0 }
4830 0         0 else {
4831 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4832 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4833 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4834 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4835 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4836 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4837 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4838             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4839 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4840             }
4841             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4842             }
4843             }
4844              
4845 0         0 # q//
4846 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4847 0         0 my $ope = $1;
4848             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4849             $e_string .= e_q($ope,$1,$3,$2);
4850 0         0 }
4851 0         0 else {
4852 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4853 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4854 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4855 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4856 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4857 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4858             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4859 0         0 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q * *
4860             }
4861             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4862             }
4863             }
4864 0         0  
4865             # ''
4866             elsif ($string =~ /\G (?
4867 0         0  
4868             # ""
4869             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4870 0         0  
4871             # ``
4872             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4873 0         0  
4874             # <<>> (a safer ARGV)
4875             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4876 0         0  
4877             # <<= <=> <= < operator
4878             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4879 0         0  
4880             #
4881             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4882              
4883 0         0 # --- glob
4884             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4885             $e_string .= 'Ekoi8u::glob("' . $1 . '")';
4886             }
4887              
4888 0         0 # << (bit shift) --- not here document
4889 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
4890             $slash = 'm//';
4891             $e_string .= $1;
4892             }
4893              
4894 0         0 # <<~'HEREDOC'
4895 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4896 0         0 $slash = 'm//';
4897             my $here_quote = $1;
4898             my $delimiter = $2;
4899 0 0       0  
4900 0         0 # get here document
4901 0         0 if ($here_script eq '') {
4902             $here_script = CORE::substr $_, pos $_;
4903 0 0       0 $here_script =~ s/.*?\n//oxm;
4904 0         0 }
4905 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4906 0         0 my $heredoc = $1;
4907 0         0 my $indent = $2;
4908 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4909             push @heredoc, $heredoc . qq{\n$delimiter\n};
4910             push @heredoc_delimiter, qq{\\s*$delimiter};
4911 0         0 }
4912             else {
4913 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4914             }
4915             $e_string .= qq{<<'$delimiter'};
4916             }
4917              
4918 0         0 # <<~\HEREDOC
4919 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4920 0         0 $slash = 'm//';
4921             my $here_quote = $1;
4922             my $delimiter = $2;
4923 0 0       0  
4924 0         0 # get here document
4925 0         0 if ($here_script eq '') {
4926             $here_script = CORE::substr $_, pos $_;
4927 0 0       0 $here_script =~ s/.*?\n//oxm;
4928 0         0 }
4929 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4930 0         0 my $heredoc = $1;
4931 0         0 my $indent = $2;
4932 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4933             push @heredoc, $heredoc . qq{\n$delimiter\n};
4934             push @heredoc_delimiter, qq{\\s*$delimiter};
4935 0         0 }
4936             else {
4937 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4938             }
4939             $e_string .= qq{<<\\$delimiter};
4940             }
4941              
4942 0         0 # <<~"HEREDOC"
4943 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4944 0         0 $slash = 'm//';
4945             my $here_quote = $1;
4946             my $delimiter = $2;
4947 0 0       0  
4948 0         0 # get here document
4949 0         0 if ($here_script eq '') {
4950             $here_script = CORE::substr $_, pos $_;
4951 0 0       0 $here_script =~ s/.*?\n//oxm;
4952 0         0 }
4953 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4954 0         0 my $heredoc = $1;
4955 0         0 my $indent = $2;
4956 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4957             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4958             push @heredoc_delimiter, qq{\\s*$delimiter};
4959 0         0 }
4960             else {
4961 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4962             }
4963             $e_string .= qq{<<"$delimiter"};
4964             }
4965              
4966 0         0 # <<~HEREDOC
4967 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4968 0         0 $slash = 'm//';
4969             my $here_quote = $1;
4970             my $delimiter = $2;
4971 0 0       0  
4972 0         0 # get here document
4973 0         0 if ($here_script eq '') {
4974             $here_script = CORE::substr $_, pos $_;
4975 0 0       0 $here_script =~ s/.*?\n//oxm;
4976 0         0 }
4977 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4978 0         0 my $heredoc = $1;
4979 0         0 my $indent = $2;
4980 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4981             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4982             push @heredoc_delimiter, qq{\\s*$delimiter};
4983 0         0 }
4984             else {
4985 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4986             }
4987             $e_string .= qq{<<$delimiter};
4988             }
4989              
4990 0         0 # <<~`HEREDOC`
4991 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4992 0         0 $slash = 'm//';
4993             my $here_quote = $1;
4994             my $delimiter = $2;
4995 0 0       0  
4996 0         0 # get here document
4997 0         0 if ($here_script eq '') {
4998             $here_script = CORE::substr $_, pos $_;
4999 0 0       0 $here_script =~ s/.*?\n//oxm;
5000 0         0 }
5001 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5002 0         0 my $heredoc = $1;
5003 0         0 my $indent = $2;
5004 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
5005             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5006             push @heredoc_delimiter, qq{\\s*$delimiter};
5007 0         0 }
5008             else {
5009 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5010             }
5011             $e_string .= qq{<<`$delimiter`};
5012             }
5013              
5014 0         0 # <<'HEREDOC'
5015 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
5016 0         0 $slash = 'm//';
5017             my $here_quote = $1;
5018             my $delimiter = $2;
5019 0 0       0  
5020 0         0 # get here document
5021 0         0 if ($here_script eq '') {
5022             $here_script = CORE::substr $_, pos $_;
5023 0 0       0 $here_script =~ s/.*?\n//oxm;
5024 0         0 }
5025 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5026             push @heredoc, $1 . qq{\n$delimiter\n};
5027             push @heredoc_delimiter, $delimiter;
5028 0         0 }
5029             else {
5030 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5031             }
5032             $e_string .= $here_quote;
5033             }
5034              
5035 0         0 # <<\HEREDOC
5036 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5037 0         0 $slash = 'm//';
5038             my $here_quote = $1;
5039             my $delimiter = $2;
5040 0 0       0  
5041 0         0 # get here document
5042 0         0 if ($here_script eq '') {
5043             $here_script = CORE::substr $_, pos $_;
5044 0 0       0 $here_script =~ s/.*?\n//oxm;
5045 0         0 }
5046 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5047             push @heredoc, $1 . qq{\n$delimiter\n};
5048             push @heredoc_delimiter, $delimiter;
5049 0         0 }
5050             else {
5051 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5052             }
5053             $e_string .= $here_quote;
5054             }
5055              
5056 0         0 # <<"HEREDOC"
5057 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5058 0         0 $slash = 'm//';
5059             my $here_quote = $1;
5060             my $delimiter = $2;
5061 0 0       0  
5062 0         0 # get here document
5063 0         0 if ($here_script eq '') {
5064             $here_script = CORE::substr $_, pos $_;
5065 0 0       0 $here_script =~ s/.*?\n//oxm;
5066 0         0 }
5067 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5068             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5069             push @heredoc_delimiter, $delimiter;
5070 0         0 }
5071             else {
5072 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5073             }
5074             $e_string .= $here_quote;
5075             }
5076              
5077 0         0 # <
5078 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5079 0         0 $slash = 'm//';
5080             my $here_quote = $1;
5081             my $delimiter = $2;
5082 0 0       0  
5083 0         0 # get here document
5084 0         0 if ($here_script eq '') {
5085             $here_script = CORE::substr $_, pos $_;
5086 0 0       0 $here_script =~ s/.*?\n//oxm;
5087 0         0 }
5088 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5089             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5090             push @heredoc_delimiter, $delimiter;
5091 0         0 }
5092             else {
5093 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5094             }
5095             $e_string .= $here_quote;
5096             }
5097              
5098 0         0 # <<`HEREDOC`
5099 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5100 0         0 $slash = 'm//';
5101             my $here_quote = $1;
5102             my $delimiter = $2;
5103 0 0       0  
5104 0         0 # get here document
5105 0         0 if ($here_script eq '') {
5106             $here_script = CORE::substr $_, pos $_;
5107 0 0       0 $here_script =~ s/.*?\n//oxm;
5108 0         0 }
5109 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5110             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5111             push @heredoc_delimiter, $delimiter;
5112 0         0 }
5113             else {
5114 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5115             }
5116             $e_string .= $here_quote;
5117             }
5118              
5119             # any operator before div
5120             elsif ($string =~ /\G (
5121             -- | \+\+ |
5122 0         0 [\)\}\]]
  18         37  
5123              
5124             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
5125              
5126             # yada-yada or triple-dot operator
5127             elsif ($string =~ /\G (
5128 18         53 \.\.\.
  0         0  
5129              
5130             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
5131              
5132             # any operator before m//
5133             elsif ($string =~ /\G ((?>
5134              
5135             !~~ | !~ | != | ! |
5136             %= | % |
5137             &&= | && | &= | &\.= | &\. | & |
5138             -= | -> | - |
5139             :(?>\s*)= |
5140             : |
5141             <<>> |
5142             <<= | <=> | <= | < |
5143             == | => | =~ | = |
5144             >>= | >> | >= | > |
5145             \*\*= | \*\* | \*= | \* |
5146             \+= | \+ |
5147             \.\. | \.= | \. |
5148             \/\/= | \/\/ |
5149             \/= | \/ |
5150             \? |
5151             \\ |
5152             \^= | \^\.= | \^\. | \^ |
5153             \b x= |
5154             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
5155             ~~ | ~\. | ~ |
5156             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
5157             \b(?: print )\b |
5158              
5159 0         0 [,;\(\{\[]
  31         61  
5160              
5161             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
5162 31         107  
5163             # other any character
5164             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
5165              
5166 131         392 # system error
5167             else {
5168             die __FILE__, ": Oops, this shouldn't happen!\n";
5169             }
5170 0         0 }
5171              
5172             return $e_string;
5173             }
5174              
5175             #
5176             # character class
5177 17     1919 0 76 #
5178             sub character_class {
5179 1919 100       3786 my($char,$modifier) = @_;
5180 1919 100       3442  
5181 52         102 if ($char eq '.') {
5182             if ($modifier =~ /s/) {
5183             return '${Ekoi8u::dot_s}';
5184 17         40 }
5185             else {
5186             return '${Ekoi8u::dot}';
5187             }
5188 35         80 }
5189             else {
5190             return Ekoi8u::classic_character_class($char);
5191             }
5192             }
5193              
5194             #
5195             # escape capture ($1, $2, $3, ...)
5196             #
5197 1867     212 0 3289 sub e_capture {
5198              
5199             return join '', '${', $_[0], '}';
5200             }
5201              
5202             #
5203             # escape transliteration (tr/// or y///)
5204 212     3 0 876 #
5205 3         16 sub e_tr {
5206 3   50     9 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
5207             my $e_tr = '';
5208 3         7 $modifier ||= '';
5209              
5210             $slash = 'div';
5211 3         4  
5212             # quote character class 1
5213             $charclass = q_tr($charclass);
5214 3         5  
5215             # quote character class 2
5216             $charclass2 = q_tr($charclass2);
5217 3 50       5  
5218 3 0       9 # /b /B modifier
5219 0         0 if ($modifier =~ tr/bB//d) {
5220             if ($variable eq '') {
5221             $e_tr = qq{tr$charclass$e$charclass2$modifier};
5222 0         0 }
5223             else {
5224             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
5225             }
5226 0 100       0 }
5227 3         6 else {
5228             if ($variable eq '') {
5229             $e_tr = qq{Ekoi8u::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
5230 2         6 }
5231             else {
5232             $e_tr = qq{Ekoi8u::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
5233             }
5234             }
5235 1         4  
5236 3         6 # clear tr/// variable
5237             $tr_variable = '';
5238 3         3 $bind_operator = '';
5239              
5240             return $e_tr;
5241             }
5242              
5243             #
5244             # quote for escape transliteration (tr/// or y///)
5245 3     6 0 14 #
5246             sub q_tr {
5247             my($charclass) = @_;
5248 6 50       8  
    0          
    0          
    0          
    0          
    0          
5249 6         13 # quote character class
5250             if ($charclass !~ /'/oxms) {
5251             return e_q('', "'", "'", $charclass); # --> q' '
5252 6         7 }
5253             elsif ($charclass !~ /\//oxms) {
5254             return e_q('q', '/', '/', $charclass); # --> q/ /
5255 0         0 }
5256             elsif ($charclass !~ /\#/oxms) {
5257             return e_q('q', '#', '#', $charclass); # --> q# #
5258 0         0 }
5259             elsif ($charclass !~ /[\<\>]/oxms) {
5260             return e_q('q', '<', '>', $charclass); # --> q< >
5261 0         0 }
5262             elsif ($charclass !~ /[\(\)]/oxms) {
5263             return e_q('q', '(', ')', $charclass); # --> q( )
5264 0         0 }
5265             elsif ($charclass !~ /[\{\}]/oxms) {
5266             return e_q('q', '{', '}', $charclass); # --> q{ }
5267 0         0 }
5268 0 0       0 else {
5269 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5270             if ($charclass !~ /\Q$char\E/xms) {
5271             return e_q('q', $char, $char, $charclass);
5272             }
5273             }
5274 0         0 }
5275              
5276             return e_q('q', '{', '}', $charclass);
5277             }
5278              
5279             #
5280             # escape q string (q//, '')
5281 0     1264 0 0 #
5282             sub e_q {
5283 1264         3137 my($ope,$delimiter,$end_delimiter,$string) = @_;
5284              
5285 1264         1644 $slash = 'div';
5286              
5287             return join '', $ope, $delimiter, $string, $end_delimiter;
5288             }
5289              
5290             #
5291             # escape qq string (qq//, "", qx//, ``)
5292 1264     4066 0 18666 #
5293             sub e_qq {
5294 4066         9148 my($ope,$delimiter,$end_delimiter,$string) = @_;
5295              
5296 4066         6011 $slash = 'div';
5297 4066         4868  
5298             my $left_e = 0;
5299             my $right_e = 0;
5300 4066         4503  
5301             # split regexp
5302             my @char = $string =~ /\G((?>
5303             [^\\\$] |
5304             \\x\{ (?>[0-9A-Fa-f]+) \} |
5305             \\o\{ (?>[0-7]+) \} |
5306             \\N\{ (?>[^0-9\}][^\}]*) \} |
5307             \\ $q_char |
5308             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5309             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5310             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5311             \$ (?>\s* [0-9]+) |
5312             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5313             \$ \$ (?![\w\{]) |
5314             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5315             $q_char
5316 4066         140079 ))/oxmsg;
5317              
5318             for (my $i=0; $i <= $#char; $i++) {
5319 4066 50 33     13144  
    50 33        
    100          
    100          
    50          
5320 113632         400590 # "\L\u" --> "\u\L"
5321             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5322             @char[$i,$i+1] = @char[$i+1,$i];
5323             }
5324              
5325 0         0 # "\U\l" --> "\l\U"
5326             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5327             @char[$i,$i+1] = @char[$i+1,$i];
5328             }
5329              
5330 0         0 # octal escape sequence
5331             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5332             $char[$i] = Ekoi8u::octchr($1);
5333             }
5334              
5335 1         4 # hexadecimal escape sequence
5336             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5337             $char[$i] = Ekoi8u::hexchr($1);
5338             }
5339              
5340 1         6 # \N{CHARNAME} --> N{CHARNAME}
5341             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5342             $char[$i] = $1;
5343 0 100       0 }
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5344              
5345             if (0) {
5346             }
5347              
5348             # \F
5349             #
5350             # P.69 Table 2-6. Translation escapes
5351             # in Chapter 2: Bits and Pieces
5352             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5353             # (and so on)
5354 113632         998069  
5355 0 50       0 # \u \l \U \L \F \Q \E
5356 484         1025 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5357             if ($right_e < $left_e) {
5358             $char[$i] = '\\' . $char[$i];
5359             }
5360             }
5361             elsif ($char[$i] eq '\u') {
5362              
5363             # "STRING @{[ LIST EXPR ]} MORE STRING"
5364              
5365             # P.257 Other Tricks You Can Do with Hard References
5366             # in Chapter 8: References
5367             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5368              
5369             # P.353 Other Tricks You Can Do with Hard References
5370             # in Chapter 8: References
5371             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5372              
5373 0         0 # (and so on)
5374 0         0  
5375             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5376             $left_e++;
5377 0         0 }
5378 0         0 elsif ($char[$i] eq '\l') {
5379             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5380             $left_e++;
5381 0         0 }
5382 0         0 elsif ($char[$i] eq '\U') {
5383             $char[$i] = '@{[Ekoi8u::uc qq<';
5384             $left_e++;
5385 0         0 }
5386 0         0 elsif ($char[$i] eq '\L') {
5387             $char[$i] = '@{[Ekoi8u::lc qq<';
5388             $left_e++;
5389 0         0 }
5390 24         36 elsif ($char[$i] eq '\F') {
5391             $char[$i] = '@{[Ekoi8u::fc qq<';
5392             $left_e++;
5393 24         43 }
5394 0         0 elsif ($char[$i] eq '\Q') {
5395             $char[$i] = '@{[CORE::quotemeta qq<';
5396             $left_e++;
5397 0 50       0 }
5398 24         43 elsif ($char[$i] eq '\E') {
5399 24         35 if ($right_e < $left_e) {
5400             $char[$i] = '>]}';
5401             $right_e++;
5402 24         38 }
5403             else {
5404             $char[$i] = '';
5405             }
5406 0         0 }
5407 0 0       0 elsif ($char[$i] eq '\Q') {
5408 0         0 while (1) {
5409             if (++$i > $#char) {
5410 0 0       0 last;
5411 0         0 }
5412             if ($char[$i] eq '\E') {
5413             last;
5414             }
5415             }
5416             }
5417             elsif ($char[$i] eq '\E') {
5418             }
5419              
5420             # $0 --> $0
5421             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5422             }
5423             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5424             }
5425              
5426             # $$ --> $$
5427             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5428             }
5429              
5430             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5431 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5432             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5433             $char[$i] = e_capture($1);
5434 205         375 }
5435             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5436             $char[$i] = e_capture($1);
5437             }
5438              
5439 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5440             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5441             $char[$i] = e_capture($1.'->'.$2);
5442             }
5443              
5444 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5445             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5446             $char[$i] = e_capture($1.'->'.$2);
5447             }
5448              
5449 0         0 # $$foo
5450             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5451             $char[$i] = e_capture($1);
5452             }
5453              
5454 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5455             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5456             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5457             }
5458              
5459 44         109 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5460             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5461             $char[$i] = '@{[Ekoi8u::MATCH()]}';
5462             }
5463              
5464 45         154 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5465             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5466             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5467             }
5468              
5469             # ${ foo } --> ${ foo }
5470             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5471             }
5472              
5473 33         90 # ${ ... }
5474             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5475             $char[$i] = e_capture($1);
5476             }
5477             }
5478 0 50       0  
5479 4066         8073 # return string
5480             if ($left_e > $right_e) {
5481 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5482             }
5483             return join '', $ope, $delimiter, @char, $end_delimiter;
5484             }
5485              
5486             #
5487             # escape qw string (qw//)
5488 4066     16 0 33823 #
5489             sub e_qw {
5490 16         120 my($ope,$delimiter,$end_delimiter,$string) = @_;
5491              
5492             $slash = 'div';
5493 16         36  
  16         205  
5494 483 50       807 # choice again delimiter
    0          
    0          
    0          
    0          
5495 16         111 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5496             if (not $octet{$end_delimiter}) {
5497             return join '', $ope, $delimiter, $string, $end_delimiter;
5498 16         150 }
5499             elsif (not $octet{')'}) {
5500             return join '', $ope, '(', $string, ')';
5501 0         0 }
5502             elsif (not $octet{'}'}) {
5503             return join '', $ope, '{', $string, '}';
5504 0         0 }
5505             elsif (not $octet{']'}) {
5506             return join '', $ope, '[', $string, ']';
5507 0         0 }
5508             elsif (not $octet{'>'}) {
5509             return join '', $ope, '<', $string, '>';
5510 0         0 }
5511 0 0       0 else {
5512 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5513             if (not $octet{$char}) {
5514             return join '', $ope, $char, $string, $char;
5515             }
5516             }
5517             }
5518 0         0  
5519 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5520 0         0 my @string = CORE::split(/\s+/, $string);
5521 0         0 for my $string (@string) {
5522 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5523 0         0 for my $octet (@octet) {
5524             if ($octet =~ /\A (['\\]) \z/oxms) {
5525             $octet = '\\' . $1;
5526 0         0 }
5527             }
5528 0         0 $string = join '', @octet;
  0         0  
5529             }
5530             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5531             }
5532              
5533             #
5534             # escape here document (<<"HEREDOC", <
5535 0     93 0 0 #
5536             sub e_heredoc {
5537 93         273 my($string) = @_;
5538              
5539 93         157 $slash = 'm//';
5540              
5541 93         332 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5542 93         141  
5543             my $left_e = 0;
5544             my $right_e = 0;
5545 93         176  
5546             # split regexp
5547             my @char = $string =~ /\G((?>
5548             [^\\\$] |
5549             \\x\{ (?>[0-9A-Fa-f]+) \} |
5550             \\o\{ (?>[0-7]+) \} |
5551             \\N\{ (?>[^0-9\}][^\}]*) \} |
5552             \\ $q_char |
5553             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5554             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5555             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5556             \$ (?>\s* [0-9]+) |
5557             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5558             \$ \$ (?![\w\{]) |
5559             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5560             $q_char
5561 93         8362 ))/oxmsg;
5562              
5563             for (my $i=0; $i <= $#char; $i++) {
5564 93 50 33     614  
    50 33        
    100          
    100          
    50          
5565 3151         9406 # "\L\u" --> "\u\L"
5566             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5567             @char[$i,$i+1] = @char[$i+1,$i];
5568             }
5569              
5570 0         0 # "\U\l" --> "\l\U"
5571             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5572             @char[$i,$i+1] = @char[$i+1,$i];
5573             }
5574              
5575 0         0 # octal escape sequence
5576             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5577             $char[$i] = Ekoi8u::octchr($1);
5578             }
5579              
5580 1         3 # hexadecimal escape sequence
5581             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5582             $char[$i] = Ekoi8u::hexchr($1);
5583             }
5584              
5585 1         5 # \N{CHARNAME} --> N{CHARNAME}
5586             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5587             $char[$i] = $1;
5588 0 50       0 }
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5589              
5590             if (0) {
5591             }
5592 3151         25214  
5593 0 0       0 # \u \l \U \L \F \Q \E
5594 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5595             if ($right_e < $left_e) {
5596             $char[$i] = '\\' . $char[$i];
5597             }
5598 0         0 }
5599 0         0 elsif ($char[$i] eq '\u') {
5600             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5601             $left_e++;
5602 0         0 }
5603 0         0 elsif ($char[$i] eq '\l') {
5604             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5605             $left_e++;
5606 0         0 }
5607 0         0 elsif ($char[$i] eq '\U') {
5608             $char[$i] = '@{[Ekoi8u::uc qq<';
5609             $left_e++;
5610 0         0 }
5611 0         0 elsif ($char[$i] eq '\L') {
5612             $char[$i] = '@{[Ekoi8u::lc qq<';
5613             $left_e++;
5614 0         0 }
5615 0         0 elsif ($char[$i] eq '\F') {
5616             $char[$i] = '@{[Ekoi8u::fc qq<';
5617             $left_e++;
5618 0         0 }
5619 0         0 elsif ($char[$i] eq '\Q') {
5620             $char[$i] = '@{[CORE::quotemeta qq<';
5621             $left_e++;
5622 0 0       0 }
5623 0         0 elsif ($char[$i] eq '\E') {
5624 0         0 if ($right_e < $left_e) {
5625             $char[$i] = '>]}';
5626             $right_e++;
5627 0         0 }
5628             else {
5629             $char[$i] = '';
5630             }
5631 0         0 }
5632 0 0       0 elsif ($char[$i] eq '\Q') {
5633 0         0 while (1) {
5634             if (++$i > $#char) {
5635 0 0       0 last;
5636 0         0 }
5637             if ($char[$i] eq '\E') {
5638             last;
5639             }
5640             }
5641             }
5642             elsif ($char[$i] eq '\E') {
5643             }
5644              
5645             # $0 --> $0
5646             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5647             }
5648             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5649             }
5650              
5651             # $$ --> $$
5652             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5653             }
5654              
5655             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5656 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5657             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5658             $char[$i] = e_capture($1);
5659 0         0 }
5660             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5661             $char[$i] = e_capture($1);
5662             }
5663              
5664 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5665             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5666             $char[$i] = e_capture($1.'->'.$2);
5667             }
5668              
5669 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5670             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5671             $char[$i] = e_capture($1.'->'.$2);
5672             }
5673              
5674 0         0 # $$foo
5675             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5676             $char[$i] = e_capture($1);
5677             }
5678              
5679 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5680             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5681             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5682             }
5683              
5684 8         47 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5685             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5686             $char[$i] = '@{[Ekoi8u::MATCH()]}';
5687             }
5688              
5689 8         90 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5690             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5691             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5692             }
5693              
5694             # ${ foo } --> ${ foo }
5695             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5696             }
5697              
5698 6         32 # ${ ... }
5699             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5700             $char[$i] = e_capture($1);
5701             }
5702             }
5703 0 50       0  
5704 93         225 # return string
5705             if ($left_e > $right_e) {
5706 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5707             }
5708             return join '', @char;
5709             }
5710              
5711             #
5712             # escape regexp (m//, qr//)
5713 93     652 0 944 #
5714 652   100     3248 sub e_qr {
5715             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5716 652         2910 $modifier ||= '';
5717 652 50       1446  
5718 652         1680 $modifier =~ tr/p//d;
5719 0         0 if ($modifier =~ /([adlu])/oxms) {
5720 0 0       0 my $line = 0;
5721 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5722 0         0 if ($filename ne __FILE__) {
5723             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5724             last;
5725 0         0 }
5726             }
5727             die qq{Unsupported modifier "$1" used at line $line.\n};
5728 0         0 }
5729              
5730             $slash = 'div';
5731 652 100       1167  
    100          
5732 652         1953 # literal null string pattern
5733 8         15 if ($string eq '') {
5734 8         11 $modifier =~ tr/bB//d;
5735             $modifier =~ tr/i//d;
5736             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5737             }
5738              
5739             # /b /B modifier
5740             elsif ($modifier =~ tr/bB//d) {
5741 8 50       51  
5742 2         6 # choice again delimiter
5743 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5744 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5745 0         0 my %octet = map {$_ => 1} @char;
5746 0         0 if (not $octet{')'}) {
5747             $delimiter = '(';
5748             $end_delimiter = ')';
5749 0         0 }
5750 0         0 elsif (not $octet{'}'}) {
5751             $delimiter = '{';
5752             $end_delimiter = '}';
5753 0         0 }
5754 0         0 elsif (not $octet{']'}) {
5755             $delimiter = '[';
5756             $end_delimiter = ']';
5757 0         0 }
5758 0         0 elsif (not $octet{'>'}) {
5759             $delimiter = '<';
5760             $end_delimiter = '>';
5761 0         0 }
5762 0 0       0 else {
5763 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5764 0         0 if (not $octet{$char}) {
5765 0         0 $delimiter = $char;
5766             $end_delimiter = $char;
5767             last;
5768             }
5769             }
5770             }
5771 0 50 33     0 }
5772 2         9  
5773             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5774             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5775 0         0 }
5776             else {
5777             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5778             }
5779 2 100       10 }
5780 642         1555  
5781             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5782             my $metachar = qr/[\@\\|[\]{^]/oxms;
5783 642         2477  
5784             # split regexp
5785             my @char = $string =~ /\G((?>
5786             [^\\\$\@\[\(] |
5787             \\x (?>[0-9A-Fa-f]{1,2}) |
5788             \\ (?>[0-7]{2,3}) |
5789             \\c [\x40-\x5F] |
5790             \\x\{ (?>[0-9A-Fa-f]+) \} |
5791             \\o\{ (?>[0-7]+) \} |
5792             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5793             \\ $q_char |
5794             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5795             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5796             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5797             [\$\@] $qq_variable |
5798             \$ (?>\s* [0-9]+) |
5799             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5800             \$ \$ (?![\w\{]) |
5801             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5802             \[\^ |
5803             \[\: (?>[a-z]+) :\] |
5804             \[\:\^ (?>[a-z]+) :\] |
5805             \(\? |
5806             $q_char
5807             ))/oxmsg;
5808 642 50       69204  
5809 642         2985 # choice again delimiter
  0         0  
5810 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5811 0         0 my %octet = map {$_ => 1} @char;
5812 0         0 if (not $octet{')'}) {
5813             $delimiter = '(';
5814             $end_delimiter = ')';
5815 0         0 }
5816 0         0 elsif (not $octet{'}'}) {
5817             $delimiter = '{';
5818             $end_delimiter = '}';
5819 0         0 }
5820 0         0 elsif (not $octet{']'}) {
5821             $delimiter = '[';
5822             $end_delimiter = ']';
5823 0         0 }
5824 0         0 elsif (not $octet{'>'}) {
5825             $delimiter = '<';
5826             $end_delimiter = '>';
5827 0         0 }
5828 0 0       0 else {
5829 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5830 0         0 if (not $octet{$char}) {
5831 0         0 $delimiter = $char;
5832             $end_delimiter = $char;
5833             last;
5834             }
5835             }
5836             }
5837 0         0 }
5838 642         1030  
5839 642         1973 my $left_e = 0;
5840             my $right_e = 0;
5841             for (my $i=0; $i <= $#char; $i++) {
5842 642 50 66     1768  
    50 66        
    100          
    100          
    100          
    100          
5843 1872         10394 # "\L\u" --> "\u\L"
5844             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5845             @char[$i,$i+1] = @char[$i+1,$i];
5846             }
5847              
5848 0         0 # "\U\l" --> "\l\U"
5849             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5850             @char[$i,$i+1] = @char[$i+1,$i];
5851             }
5852              
5853 0         0 # octal escape sequence
5854             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5855             $char[$i] = Ekoi8u::octchr($1);
5856             }
5857              
5858 1         3 # hexadecimal escape sequence
5859             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5860             $char[$i] = Ekoi8u::hexchr($1);
5861             }
5862              
5863             # \b{...} --> b\{...}
5864             # \B{...} --> B\{...}
5865             # \N{CHARNAME} --> N\{CHARNAME}
5866             # \p{PROPERTY} --> p\{PROPERTY}
5867 1         5 # \P{PROPERTY} --> P\{PROPERTY}
5868             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5869             $char[$i] = $1 . '\\' . $2;
5870             }
5871              
5872 6         18 # \p, \P, \X --> p, P, X
5873             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5874             $char[$i] = $1;
5875 4 100 100     9 }
    100 100        
    100 100        
    100          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
5876              
5877             if (0) {
5878             }
5879 1872         5641  
5880 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5881 6         169 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5882             if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
5883             $char[$i] .= join '', splice @char, $i+1, 3;
5884 0         0 }
5885             elsif (($i+2 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+2]) == 2) and (CORE::eval(sprintf '"%s%s%s"', @char[$i..$i+2]) =~ /\A $q_char \z/oxms)) {
5886             $char[$i] .= join '', splice @char, $i+1, 2;
5887 0         0 }
5888             elsif (($i+1 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, $char[$i+1 ]) == 1) and (CORE::eval(sprintf '"%s%s"', @char[$i..$i+1]) =~ /\A $q_char \z/oxms)) {
5889             $char[$i] .= join '', splice @char, $i+1, 1;
5890             }
5891             }
5892              
5893 0         0 # open character class [...]
5894             elsif ($char[$i] eq '[') {
5895             my $left = $i;
5896              
5897             # [] make die "Unmatched [] in regexp ...\n"
5898 328 100       469 # (and so on)
5899 328         1314  
5900             if ($char[$i+1] eq ']') {
5901             $i++;
5902 3         5 }
5903 328 50       475  
5904 1379         2069 while (1) {
5905             if (++$i > $#char) {
5906 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5907 1379         2153 }
5908             if ($char[$i] eq ']') {
5909             my $right = $i;
5910 328 100       456  
5911 328         1804 # [...]
  30         78  
5912             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5913             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5914 90         136 }
5915             else {
5916             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
5917 298         1127 }
5918 328         579  
5919             $i = $left;
5920             last;
5921             }
5922             }
5923             }
5924              
5925 328         951 # open character class [^...]
5926             elsif ($char[$i] eq '[^') {
5927             my $left = $i;
5928              
5929             # [^] make die "Unmatched [] in regexp ...\n"
5930 74 100       165 # (and so on)
5931 74         166  
5932             if ($char[$i+1] eq ']') {
5933             $i++;
5934 4         7 }
5935 74 50       86  
5936 272         407 while (1) {
5937             if (++$i > $#char) {
5938 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5939 272         486 }
5940             if ($char[$i] eq ']') {
5941             my $right = $i;
5942 74 100       156  
5943 74         364 # [^...]
  30         69  
5944             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5945             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5946 90         137 }
5947             else {
5948             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5949 44         160 }
5950 74         187  
5951             $i = $left;
5952             last;
5953             }
5954             }
5955             }
5956              
5957 74         310 # rewrite character class or escape character
5958             elsif (my $char = character_class($char[$i],$modifier)) {
5959             $char[$i] = $char;
5960             }
5961              
5962 139 50       348 # /i modifier
5963 20         33 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
5964             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
5965             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
5966 20         31 }
5967             else {
5968             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
5969             }
5970             }
5971              
5972 0 50       0 # \u \l \U \L \F \Q \E
5973 1         4 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5974             if ($right_e < $left_e) {
5975             $char[$i] = '\\' . $char[$i];
5976             }
5977 0         0 }
5978 0         0 elsif ($char[$i] eq '\u') {
5979             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5980             $left_e++;
5981 0         0 }
5982 0         0 elsif ($char[$i] eq '\l') {
5983             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5984             $left_e++;
5985 0         0 }
5986 1         4 elsif ($char[$i] eq '\U') {
5987             $char[$i] = '@{[Ekoi8u::uc qq<';
5988             $left_e++;
5989 1         3 }
5990 1         3 elsif ($char[$i] eq '\L') {
5991             $char[$i] = '@{[Ekoi8u::lc qq<';
5992             $left_e++;
5993 1         4 }
5994 18         29 elsif ($char[$i] eq '\F') {
5995             $char[$i] = '@{[Ekoi8u::fc qq<';
5996             $left_e++;
5997 18         43 }
5998 1         3 elsif ($char[$i] eq '\Q') {
5999             $char[$i] = '@{[CORE::quotemeta qq<';
6000             $left_e++;
6001 1 50       2 }
6002 21         44 elsif ($char[$i] eq '\E') {
6003 21         27 if ($right_e < $left_e) {
6004             $char[$i] = '>]}';
6005             $right_e++;
6006 21         42 }
6007             else {
6008             $char[$i] = '';
6009             }
6010 0         0 }
6011 0 0       0 elsif ($char[$i] eq '\Q') {
6012 0         0 while (1) {
6013             if (++$i > $#char) {
6014 0 0       0 last;
6015 0         0 }
6016             if ($char[$i] eq '\E') {
6017             last;
6018             }
6019             }
6020             }
6021             elsif ($char[$i] eq '\E') {
6022             }
6023              
6024 0 0       0 # $0 --> $0
6025 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6026             if ($ignorecase) {
6027             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6028             }
6029 0 0       0 }
6030 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6031             if ($ignorecase) {
6032             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6033             }
6034             }
6035              
6036             # $$ --> $$
6037             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6038             }
6039              
6040             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6041 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6042 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6043 0         0 $char[$i] = e_capture($1);
6044             if ($ignorecase) {
6045             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6046             }
6047 0         0 }
6048 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6049 0         0 $char[$i] = e_capture($1);
6050             if ($ignorecase) {
6051             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6052             }
6053             }
6054              
6055 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6056 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
6057 0         0 $char[$i] = e_capture($1.'->'.$2);
6058             if ($ignorecase) {
6059             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6060             }
6061             }
6062              
6063 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6064 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
6065 0         0 $char[$i] = e_capture($1.'->'.$2);
6066             if ($ignorecase) {
6067             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6068             }
6069             }
6070              
6071 0         0 # $$foo
6072 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6073 0         0 $char[$i] = e_capture($1);
6074             if ($ignorecase) {
6075             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6076             }
6077             }
6078              
6079 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
6080 8         19 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6081             if ($ignorecase) {
6082             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
6083 0         0 }
6084             else {
6085             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
6086             }
6087             }
6088              
6089 8 50       26 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
6090 8         19 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6091             if ($ignorecase) {
6092             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
6093 0         0 }
6094             else {
6095             $char[$i] = '@{[Ekoi8u::MATCH()]}';
6096             }
6097             }
6098              
6099 8 50       23 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
6100 6         16 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6101             if ($ignorecase) {
6102             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
6103 0         0 }
6104             else {
6105             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
6106             }
6107             }
6108              
6109 6 0       18 # ${ foo }
6110 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
6111             if ($ignorecase) {
6112             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6113             }
6114             }
6115              
6116 0         0 # ${ ... }
6117 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6118 0         0 $char[$i] = e_capture($1);
6119             if ($ignorecase) {
6120             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6121             }
6122             }
6123              
6124 0         0 # $scalar or @array
6125 21 100       57 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6126 21         112 $char[$i] = e_string($char[$i]);
6127             if ($ignorecase) {
6128             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6129             }
6130             }
6131              
6132 11 100 33     36 # quote character before ? + * {
    50          
6133             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6134             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6135 138         1050 }
6136 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6137 0         0 my $char = $char[$i-1];
6138             if ($char[$i] eq '{') {
6139             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
6140 0         0 }
6141             else {
6142             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
6143             }
6144 0         0 }
6145             else {
6146             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6147             }
6148             }
6149             }
6150 127         487  
6151 642 50       1270 # make regexp string
6152 642 0 0     1414 $modifier =~ tr/i//d;
6153 0         0 if ($left_e > $right_e) {
6154             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6155             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
6156 0         0 }
6157             else {
6158             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6159 0 50 33     0 }
6160 642         3635 }
6161             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6162             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
6163 0         0 }
6164             else {
6165             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6166             }
6167             }
6168              
6169             #
6170             # double quote stuff
6171 642     180 0 6270 #
6172             sub qq_stuff {
6173             my($delimiter,$end_delimiter,$stuff) = @_;
6174 180 100       260  
6175 180         400 # scalar variable or array variable
6176             if ($stuff =~ /\A [\$\@] /oxms) {
6177             return $stuff;
6178             }
6179 100         328  
  80         186  
6180 80         217 # quote by delimiter
6181 80 50       195 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
6182 80 50       129 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6183 80 50       119 next if $char eq $delimiter;
6184 80         163 next if $char eq $end_delimiter;
6185             if (not $octet{$char}) {
6186             return join '', 'qq', $char, $stuff, $char;
6187 80         362 }
6188             }
6189             return join '', 'qq', '<', $stuff, '>';
6190             }
6191              
6192             #
6193             # escape regexp (m'', qr'', and m''b, qr''b)
6194 0     10 0 0 #
6195 10   50     51 sub e_qr_q {
6196             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6197 10         44 $modifier ||= '';
6198 10 50       18  
6199 10         23 $modifier =~ tr/p//d;
6200 0         0 if ($modifier =~ /([adlu])/oxms) {
6201 0 0       0 my $line = 0;
6202 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6203 0         0 if ($filename ne __FILE__) {
6204             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6205             last;
6206 0         0 }
6207             }
6208             die qq{Unsupported modifier "$1" used at line $line.\n};
6209 0         0 }
6210              
6211             $slash = 'div';
6212 10 100       95  
    50          
6213 10         24 # literal null string pattern
6214 8         12 if ($string eq '') {
6215 8         10 $modifier =~ tr/bB//d;
6216             $modifier =~ tr/i//d;
6217             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6218             }
6219              
6220 8         41 # with /b /B modifier
6221             elsif ($modifier =~ tr/bB//d) {
6222             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6223             }
6224              
6225 0         0 # without /b /B modifier
6226             else {
6227             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6228             }
6229             }
6230              
6231             #
6232             # escape regexp (m'', qr'')
6233 2     2 0 10 #
6234             sub e_qr_qt {
6235 2 50       6 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6236              
6237             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6238 2         6  
6239             # split regexp
6240             my @char = $string =~ /\G((?>
6241             [^\\\[\$\@\/] |
6242             [\x00-\xFF] |
6243             \[\^ |
6244             \[\: (?>[a-z]+) \:\] |
6245             \[\:\^ (?>[a-z]+) \:\] |
6246             [\$\@\/] |
6247             \\ (?:$q_char) |
6248             (?:$q_char)
6249             ))/oxmsg;
6250 2         68  
6251 2 50 33     11 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
6252             for (my $i=0; $i <= $#char; $i++) {
6253             if (0) {
6254             }
6255 2         37  
6256 0         0 # open character class [...]
6257 0 0       0 elsif ($char[$i] eq '[') {
6258 0         0 my $left = $i;
6259             if ($char[$i+1] eq ']') {
6260 0         0 $i++;
6261 0 0       0 }
6262 0         0 while (1) {
6263             if (++$i > $#char) {
6264 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6265 0         0 }
6266             if ($char[$i] eq ']') {
6267             my $right = $i;
6268 0         0  
6269             # [...]
6270 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6271 0         0  
6272             $i = $left;
6273             last;
6274             }
6275             }
6276             }
6277              
6278 0         0 # open character class [^...]
6279 0 0       0 elsif ($char[$i] eq '[^') {
6280 0         0 my $left = $i;
6281             if ($char[$i+1] eq ']') {
6282 0         0 $i++;
6283 0 0       0 }
6284 0         0 while (1) {
6285             if (++$i > $#char) {
6286 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6287 0         0 }
6288             if ($char[$i] eq ']') {
6289             my $right = $i;
6290 0         0  
6291             # [^...]
6292 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6293 0         0  
6294             $i = $left;
6295             last;
6296             }
6297             }
6298             }
6299              
6300 0         0 # escape $ @ / and \
6301             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6302             $char[$i] = '\\' . $char[$i];
6303             }
6304              
6305 0         0 # rewrite character class or escape character
6306             elsif (my $char = character_class($char[$i],$modifier)) {
6307             $char[$i] = $char;
6308             }
6309              
6310 0 0       0 # /i modifier
6311 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6312             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6313             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6314 0         0 }
6315             else {
6316             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6317             }
6318             }
6319              
6320 0 0       0 # quote character before ? + * {
6321             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6322             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6323 0         0 }
6324             else {
6325             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6326             }
6327             }
6328 0         0 }
6329 2         6  
6330             $delimiter = '/';
6331 2         4 $end_delimiter = '/';
6332 2         3  
6333             $modifier =~ tr/i//d;
6334             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6335             }
6336              
6337             #
6338             # escape regexp (m''b, qr''b)
6339 2     0 0 17 #
6340             sub e_qr_qb {
6341             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6342 0         0  
6343             # split regexp
6344             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6345 0         0  
6346 0 0       0 # unescape character
    0          
6347             for (my $i=0; $i <= $#char; $i++) {
6348             if (0) {
6349             }
6350 0         0  
6351             # remain \\
6352             elsif ($char[$i] eq '\\\\') {
6353             }
6354              
6355 0         0 # escape $ @ / and \
6356             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6357             $char[$i] = '\\' . $char[$i];
6358             }
6359 0         0 }
6360 0         0  
6361 0         0 $delimiter = '/';
6362             $end_delimiter = '/';
6363             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6364             }
6365              
6366             #
6367             # escape regexp (s/here//)
6368 0     76 0 0 #
6369 76   100     312 sub e_s1 {
6370             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6371 76         340 $modifier ||= '';
6372 76 50       117  
6373 76         230 $modifier =~ tr/p//d;
6374 0         0 if ($modifier =~ /([adlu])/oxms) {
6375 0 0       0 my $line = 0;
6376 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6377 0         0 if ($filename ne __FILE__) {
6378             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6379             last;
6380 0         0 }
6381             }
6382             die qq{Unsupported modifier "$1" used at line $line.\n};
6383 0         0 }
6384              
6385             $slash = 'div';
6386 76 100       146  
    50          
6387 76         277 # literal null string pattern
6388 8         12 if ($string eq '') {
6389 8         10 $modifier =~ tr/bB//d;
6390             $modifier =~ tr/i//d;
6391             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6392             }
6393              
6394             # /b /B modifier
6395             elsif ($modifier =~ tr/bB//d) {
6396 8 0       67  
6397 0         0 # choice again delimiter
6398 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
6399 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
6400 0         0 my %octet = map {$_ => 1} @char;
6401 0         0 if (not $octet{')'}) {
6402             $delimiter = '(';
6403             $end_delimiter = ')';
6404 0         0 }
6405 0         0 elsif (not $octet{'}'}) {
6406             $delimiter = '{';
6407             $end_delimiter = '}';
6408 0         0 }
6409 0         0 elsif (not $octet{']'}) {
6410             $delimiter = '[';
6411             $end_delimiter = ']';
6412 0         0 }
6413 0         0 elsif (not $octet{'>'}) {
6414             $delimiter = '<';
6415             $end_delimiter = '>';
6416 0         0 }
6417 0 0       0 else {
6418 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6419 0         0 if (not $octet{$char}) {
6420 0         0 $delimiter = $char;
6421             $end_delimiter = $char;
6422             last;
6423             }
6424             }
6425             }
6426 0         0 }
6427 0         0  
6428             my $prematch = '';
6429             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6430 0 100       0 }
6431 68         189  
6432             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6433             my $metachar = qr/[\@\\|[\]{^]/oxms;
6434 68         311  
6435             # split regexp
6436             my @char = $string =~ /\G((?>
6437             [^\\\$\@\[\(] |
6438             \\ (?>[1-9][0-9]*) |
6439             \\g (?>\s*) (?>[1-9][0-9]*) |
6440             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6441             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6442             \\x (?>[0-9A-Fa-f]{1,2}) |
6443             \\ (?>[0-7]{2,3}) |
6444             \\c [\x40-\x5F] |
6445             \\x\{ (?>[0-9A-Fa-f]+) \} |
6446             \\o\{ (?>[0-7]+) \} |
6447             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6448             \\ $q_char |
6449             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6450             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6451             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6452             [\$\@] $qq_variable |
6453             \$ (?>\s* [0-9]+) |
6454             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6455             \$ \$ (?![\w\{]) |
6456             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6457             \[\^ |
6458             \[\: (?>[a-z]+) :\] |
6459             \[\:\^ (?>[a-z]+) :\] |
6460             \(\? |
6461             $q_char
6462             ))/oxmsg;
6463 68 50       18840  
6464 68         543 # choice again delimiter
  0         0  
6465 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
6466 0         0 my %octet = map {$_ => 1} @char;
6467 0         0 if (not $octet{')'}) {
6468             $delimiter = '(';
6469             $end_delimiter = ')';
6470 0         0 }
6471 0         0 elsif (not $octet{'}'}) {
6472             $delimiter = '{';
6473             $end_delimiter = '}';
6474 0         0 }
6475 0         0 elsif (not $octet{']'}) {
6476             $delimiter = '[';
6477             $end_delimiter = ']';
6478 0         0 }
6479 0         0 elsif (not $octet{'>'}) {
6480             $delimiter = '<';
6481             $end_delimiter = '>';
6482 0         0 }
6483 0 0       0 else {
6484 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6485 0         0 if (not $octet{$char}) {
6486 0         0 $delimiter = $char;
6487             $end_delimiter = $char;
6488             last;
6489             }
6490             }
6491             }
6492             }
6493 0         0  
  68         136  
6494             # count '('
6495 253         450 my $parens = grep { $_ eq '(' } @char;
6496 68         107  
6497 68         96 my $left_e = 0;
6498             my $right_e = 0;
6499             for (my $i=0; $i <= $#char; $i++) {
6500 68 50 33     213  
    50 33        
    100          
    100          
    50          
    50          
6501 195         1293 # "\L\u" --> "\u\L"
6502             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6503             @char[$i,$i+1] = @char[$i+1,$i];
6504             }
6505              
6506 0         0 # "\U\l" --> "\l\U"
6507             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6508             @char[$i,$i+1] = @char[$i+1,$i];
6509             }
6510              
6511 0         0 # octal escape sequence
6512             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6513             $char[$i] = Ekoi8u::octchr($1);
6514             }
6515              
6516 1         3 # hexadecimal escape sequence
6517             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6518             $char[$i] = Ekoi8u::hexchr($1);
6519             }
6520              
6521             # \b{...} --> b\{...}
6522             # \B{...} --> B\{...}
6523             # \N{CHARNAME} --> N\{CHARNAME}
6524             # \p{PROPERTY} --> p\{PROPERTY}
6525 1         5 # \P{PROPERTY} --> P\{PROPERTY}
6526             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6527             $char[$i] = $1 . '\\' . $2;
6528             }
6529              
6530 0         0 # \p, \P, \X --> p, P, X
6531             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6532             $char[$i] = $1;
6533 0 50 66     0 }
    100 66        
    50 100        
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
6534              
6535             if (0) {
6536             }
6537 195         742  
6538 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6539 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6540             if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
6541             $char[$i] .= join '', splice @char, $i+1, 3;
6542 0         0 }
6543             elsif (($i+2 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+2]) == 2) and (CORE::eval(sprintf '"%s%s%s"', @char[$i..$i+2]) =~ /\A $q_char \z/oxms)) {
6544             $char[$i] .= join '', splice @char, $i+1, 2;
6545 0         0 }
6546             elsif (($i+1 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, $char[$i+1 ]) == 1) and (CORE::eval(sprintf '"%s%s"', @char[$i..$i+1]) =~ /\A $q_char \z/oxms)) {
6547             $char[$i] .= join '', splice @char, $i+1, 1;
6548             }
6549             }
6550              
6551 0         0 # open character class [...]
6552 13 50       22 elsif ($char[$i] eq '[') {
6553 13         65 my $left = $i;
6554             if ($char[$i+1] eq ']') {
6555 0         0 $i++;
6556 13 50       19 }
6557 58         109 while (1) {
6558             if (++$i > $#char) {
6559 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6560 58         180 }
6561             if ($char[$i] eq ']') {
6562             my $right = $i;
6563 13 50       20  
6564 13         146 # [...]
  0         0  
6565             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6566             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6567 0         0 }
6568             else {
6569             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6570 13         63 }
6571 13         23  
6572             $i = $left;
6573             last;
6574             }
6575             }
6576             }
6577              
6578 13         36 # open character class [^...]
6579 0 0       0 elsif ($char[$i] eq '[^') {
6580 0         0 my $left = $i;
6581             if ($char[$i+1] eq ']') {
6582 0         0 $i++;
6583 0 0       0 }
6584 0         0 while (1) {
6585             if (++$i > $#char) {
6586 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6587 0         0 }
6588             if ($char[$i] eq ']') {
6589             my $right = $i;
6590 0 0       0  
6591 0         0 # [^...]
  0         0  
6592             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6593             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6594 0         0 }
6595             else {
6596             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6597 0         0 }
6598 0         0  
6599             $i = $left;
6600             last;
6601             }
6602             }
6603             }
6604              
6605 0         0 # rewrite character class or escape character
6606             elsif (my $char = character_class($char[$i],$modifier)) {
6607             $char[$i] = $char;
6608             }
6609              
6610 7 50       14 # /i modifier
6611 3         5 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6612             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6613             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6614 3         4 }
6615             else {
6616             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6617             }
6618             }
6619              
6620 0 0       0 # \u \l \U \L \F \Q \E
6621 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6622             if ($right_e < $left_e) {
6623             $char[$i] = '\\' . $char[$i];
6624             }
6625 0         0 }
6626 0         0 elsif ($char[$i] eq '\u') {
6627             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
6628             $left_e++;
6629 0         0 }
6630 0         0 elsif ($char[$i] eq '\l') {
6631             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
6632             $left_e++;
6633 0         0 }
6634 0         0 elsif ($char[$i] eq '\U') {
6635             $char[$i] = '@{[Ekoi8u::uc qq<';
6636             $left_e++;
6637 0         0 }
6638 0         0 elsif ($char[$i] eq '\L') {
6639             $char[$i] = '@{[Ekoi8u::lc qq<';
6640             $left_e++;
6641 0         0 }
6642 0         0 elsif ($char[$i] eq '\F') {
6643             $char[$i] = '@{[Ekoi8u::fc qq<';
6644             $left_e++;
6645 0         0 }
6646 0         0 elsif ($char[$i] eq '\Q') {
6647             $char[$i] = '@{[CORE::quotemeta qq<';
6648             $left_e++;
6649 0 0       0 }
6650 0         0 elsif ($char[$i] eq '\E') {
6651 0         0 if ($right_e < $left_e) {
6652             $char[$i] = '>]}';
6653             $right_e++;
6654 0         0 }
6655             else {
6656             $char[$i] = '';
6657             }
6658 0         0 }
6659 0 0       0 elsif ($char[$i] eq '\Q') {
6660 0         0 while (1) {
6661             if (++$i > $#char) {
6662 0 0       0 last;
6663 0         0 }
6664             if ($char[$i] eq '\E') {
6665             last;
6666             }
6667             }
6668             }
6669             elsif ($char[$i] eq '\E') {
6670             }
6671              
6672             # \0 --> \0
6673             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6674             }
6675              
6676             # \g{N}, \g{-N}
6677              
6678             # P.108 Using Simple Patterns
6679             # in Chapter 7: In the World of Regular Expressions
6680             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6681              
6682             # P.221 Capturing
6683             # in Chapter 5: Pattern Matching
6684             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6685              
6686             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6687             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6688             }
6689              
6690             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6691             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6692             }
6693              
6694             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6695             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6696             }
6697              
6698             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6699             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6700             }
6701              
6702 0 0       0 # $0 --> $0
6703 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6704             if ($ignorecase) {
6705             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6706             }
6707 0 0       0 }
6708 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6709             if ($ignorecase) {
6710             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6711             }
6712             }
6713              
6714             # $$ --> $$
6715             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6716             }
6717              
6718             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6719 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6720 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6721 0         0 $char[$i] = e_capture($1);
6722             if ($ignorecase) {
6723             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6724             }
6725 0         0 }
6726 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6727 0         0 $char[$i] = e_capture($1);
6728             if ($ignorecase) {
6729             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6730             }
6731             }
6732              
6733 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6734 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
6735 0         0 $char[$i] = e_capture($1.'->'.$2);
6736             if ($ignorecase) {
6737             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6738             }
6739             }
6740              
6741 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6742 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
6743 0         0 $char[$i] = e_capture($1.'->'.$2);
6744             if ($ignorecase) {
6745             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6746             }
6747             }
6748              
6749 0         0 # $$foo
6750 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6751 0         0 $char[$i] = e_capture($1);
6752             if ($ignorecase) {
6753             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6754             }
6755             }
6756              
6757 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
6758 4         15 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6759             if ($ignorecase) {
6760             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
6761 0         0 }
6762             else {
6763             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
6764             }
6765             }
6766              
6767 4 50       13 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
6768 4         14 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6769             if ($ignorecase) {
6770             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
6771 0         0 }
6772             else {
6773             $char[$i] = '@{[Ekoi8u::MATCH()]}';
6774             }
6775             }
6776              
6777 4 50       14 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
6778 3         9 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6779             if ($ignorecase) {
6780             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
6781 0         0 }
6782             else {
6783             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
6784             }
6785             }
6786              
6787 3 0       12 # ${ foo }
6788 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
6789             if ($ignorecase) {
6790             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6791             }
6792             }
6793              
6794 0         0 # ${ ... }
6795 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6796 0         0 $char[$i] = e_capture($1);
6797             if ($ignorecase) {
6798             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6799             }
6800             }
6801              
6802 0         0 # $scalar or @array
6803 4 50       18 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6804 4         19 $char[$i] = e_string($char[$i]);
6805             if ($ignorecase) {
6806             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6807             }
6808             }
6809              
6810 0 50       0 # quote character before ? + * {
6811             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6812             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6813 13         67 }
6814             else {
6815             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6816             }
6817             }
6818             }
6819 13         111  
6820 68         162 # make regexp string
6821 68 50       244 my $prematch = '';
6822 68         189 $modifier =~ tr/i//d;
6823             if ($left_e > $right_e) {
6824 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6825             }
6826             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6827             }
6828              
6829             #
6830             # escape regexp (s'here'' or s'here''b)
6831 68     21 0 763 #
6832 21   100     56 sub e_s1_q {
6833             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6834 21         74 $modifier ||= '';
6835 21 50       27  
6836 21         49 $modifier =~ tr/p//d;
6837 0         0 if ($modifier =~ /([adlu])/oxms) {
6838 0 0       0 my $line = 0;
6839 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6840 0         0 if ($filename ne __FILE__) {
6841             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6842             last;
6843 0         0 }
6844             }
6845             die qq{Unsupported modifier "$1" used at line $line.\n};
6846 0         0 }
6847              
6848             $slash = 'div';
6849 21 100       32  
    50          
6850 21         62 # literal null string pattern
6851 8         10 if ($string eq '') {
6852 8         13 $modifier =~ tr/bB//d;
6853             $modifier =~ tr/i//d;
6854             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6855             }
6856              
6857 8         49 # with /b /B modifier
6858             elsif ($modifier =~ tr/bB//d) {
6859             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6860             }
6861              
6862 0         0 # without /b /B modifier
6863             else {
6864             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6865             }
6866             }
6867              
6868             #
6869             # escape regexp (s'here'')
6870 13     13 0 34 #
6871             sub e_s1_qt {
6872 13 50       31 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6873              
6874             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6875 13         26  
6876             # split regexp
6877             my @char = $string =~ /\G((?>
6878             [^\\\[\$\@\/] |
6879             [\x00-\xFF] |
6880             \[\^ |
6881             \[\: (?>[a-z]+) \:\] |
6882             \[\:\^ (?>[a-z]+) \:\] |
6883             [\$\@\/] |
6884             \\ (?:$q_char) |
6885             (?:$q_char)
6886             ))/oxmsg;
6887 13         307  
6888 13 50 33     48 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6889             for (my $i=0; $i <= $#char; $i++) {
6890             if (0) {
6891             }
6892 25         100  
6893 0         0 # open character class [...]
6894 0 0       0 elsif ($char[$i] eq '[') {
6895 0         0 my $left = $i;
6896             if ($char[$i+1] eq ']') {
6897 0         0 $i++;
6898 0 0       0 }
6899 0         0 while (1) {
6900             if (++$i > $#char) {
6901 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6902 0         0 }
6903             if ($char[$i] eq ']') {
6904             my $right = $i;
6905 0         0  
6906             # [...]
6907 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6908 0         0  
6909             $i = $left;
6910             last;
6911             }
6912             }
6913             }
6914              
6915 0         0 # open character class [^...]
6916 0 0       0 elsif ($char[$i] eq '[^') {
6917 0         0 my $left = $i;
6918             if ($char[$i+1] eq ']') {
6919 0         0 $i++;
6920 0 0       0 }
6921 0         0 while (1) {
6922             if (++$i > $#char) {
6923 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6924 0         0 }
6925             if ($char[$i] eq ']') {
6926             my $right = $i;
6927 0         0  
6928             # [^...]
6929 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6930 0         0  
6931             $i = $left;
6932             last;
6933             }
6934             }
6935             }
6936              
6937 0         0 # escape $ @ / and \
6938             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6939             $char[$i] = '\\' . $char[$i];
6940             }
6941              
6942 0         0 # rewrite character class or escape character
6943             elsif (my $char = character_class($char[$i],$modifier)) {
6944             $char[$i] = $char;
6945             }
6946              
6947 6 0       14 # /i modifier
6948 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6949             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6950             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6951 0         0 }
6952             else {
6953             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6954             }
6955             }
6956              
6957 0 0       0 # quote character before ? + * {
6958             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6959             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6960 0         0 }
6961             else {
6962             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6963             }
6964             }
6965 0         0 }
6966 13         29  
6967 13         20 $modifier =~ tr/i//d;
6968 13         16 $delimiter = '/';
6969 13         19 $end_delimiter = '/';
6970             my $prematch = '';
6971             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6972             }
6973              
6974             #
6975             # escape regexp (s'here''b)
6976 13     0 0 109 #
6977             sub e_s1_qb {
6978             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6979 0         0  
6980             # split regexp
6981             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6982 0         0  
6983 0 0       0 # unescape character
    0          
6984             for (my $i=0; $i <= $#char; $i++) {
6985             if (0) {
6986             }
6987 0         0  
6988             # remain \\
6989             elsif ($char[$i] eq '\\\\') {
6990             }
6991              
6992 0         0 # escape $ @ / and \
6993             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6994             $char[$i] = '\\' . $char[$i];
6995             }
6996 0         0 }
6997 0         0  
6998 0         0 $delimiter = '/';
6999 0         0 $end_delimiter = '/';
7000             my $prematch = '';
7001             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
7002             }
7003              
7004             #
7005             # escape regexp (s''here')
7006 0     16 0 0 #
7007             sub e_s2_q {
7008 16         36 my($ope,$delimiter,$end_delimiter,$string) = @_;
7009              
7010 16         21 $slash = 'div';
7011 16         103  
7012 16 100       48 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
7013             for (my $i=0; $i <= $#char; $i++) {
7014             if (0) {
7015             }
7016 9         35  
7017             # not escape \\
7018             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
7019             }
7020              
7021 0         0 # escape $ @ / and \
7022             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7023             $char[$i] = '\\' . $char[$i];
7024             }
7025 5         13 }
7026              
7027             return join '', $ope, $delimiter, @char, $end_delimiter;
7028             }
7029              
7030             #
7031             # escape regexp (s/here/and here/modifier)
7032 16     97 0 51 #
7033 97   100     1057 sub e_sub {
7034             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
7035 97         414 $modifier ||= '';
7036 97 50       253  
7037 97         410 $modifier =~ tr/p//d;
7038 0         0 if ($modifier =~ /([adlu])/oxms) {
7039 0 0       0 my $line = 0;
7040 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7041 0         0 if ($filename ne __FILE__) {
7042             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7043             last;
7044 0         0 }
7045             }
7046             die qq{Unsupported modifier "$1" used at line $line.\n};
7047 0 100       0 }
7048 97         384  
7049 36         48 if ($variable eq '') {
7050             $variable = '$_';
7051             $bind_operator = ' =~ ';
7052 36         155 }
7053              
7054             $slash = 'div';
7055              
7056             # P.128 Start of match (or end of previous match): \G
7057             # P.130 Advanced Use of \G with Perl
7058             # in Chapter 3: Overview of Regular Expression Features and Flavors
7059             # P.312 Iterative Matching: Scalar Context, with /g
7060             # in Chapter 7: Perl
7061             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
7062              
7063             # P.181 Where You Left Off: The \G Assertion
7064             # in Chapter 5: Pattern Matching
7065             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7066              
7067             # P.220 Where You Left Off: The \G Assertion
7068             # in Chapter 5: Pattern Matching
7069 97         157 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7070 97         162  
7071             my $e_modifier = $modifier =~ tr/e//d;
7072 97         181 my $r_modifier = $modifier =~ tr/r//d;
7073 97 50       160  
7074 97         258 my $my = '';
7075 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
7076 0         0 $my = $variable;
7077             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
7078             $variable =~ s/ = .+ \z//oxms;
7079 0         0 }
7080 97         239  
7081             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
7082             $variable_basename =~ s/ \s+ \z//oxms;
7083 97         173  
7084 97 100       160 # quote replacement string
7085 97         414 my $e_replacement = '';
7086 17         32 if ($e_modifier >= 1) {
7087             $e_replacement = e_qq('', '', '', $replacement);
7088             $e_modifier--;
7089 17 100       30 }
7090 80         202 else {
7091             if ($delimiter2 eq "'") {
7092             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
7093 16         36 }
7094             else {
7095             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
7096             }
7097 64         161 }
7098              
7099             my $sub = '';
7100 97 100       158  
7101 97 100       196 # with /r
7102             if ($r_modifier) {
7103             if (0) {
7104             }
7105 8         19  
7106 0 50       0 # s///gr without multibyte anchoring
7107             elsif ($modifier =~ /g/oxms) {
7108             $sub = sprintf(
7109             # 1 2 3 4 5
7110             q,
7111              
7112             $variable, # 1
7113             ($delimiter1 eq "'") ? # 2
7114             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7115             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7116             $s_matched, # 3
7117             $e_replacement, # 4
7118             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
7119             );
7120             }
7121              
7122             # s///r
7123 4         14 else {
7124              
7125 4 50       8 my $prematch = q{$`};
7126              
7127             $sub = sprintf(
7128             # 1 2 3 4 5 6 7
7129             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s"%s$Ekoi8u::re_r$'" } : %s>,
7130              
7131             $variable, # 1
7132             ($delimiter1 eq "'") ? # 2
7133             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7134             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7135             $s_matched, # 3
7136             $e_replacement, # 4
7137             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
7138             $prematch, # 6
7139             $variable, # 7
7140             );
7141             }
7142 4 50       23  
7143 8         21 # $var !~ s///r doesn't make sense
7144             if ($bind_operator =~ / !~ /oxms) {
7145             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
7146             }
7147             }
7148              
7149 0 100       0 # without /r
7150             else {
7151             if (0) {
7152             }
7153 89         222  
7154 0 100       0 # s///g without multibyte anchoring
    100          
7155             elsif ($modifier =~ /g/oxms) {
7156             $sub = sprintf(
7157             # 1 2 3 4 5 6 7 8
7158             q,
7159              
7160             $variable, # 1
7161             ($delimiter1 eq "'") ? # 2
7162             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7163             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7164             $s_matched, # 3
7165             $e_replacement, # 4
7166             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
7167             $variable, # 6
7168             $variable, # 7
7169             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
7170             );
7171             }
7172              
7173             # s///
7174 22         108 else {
7175              
7176 67 100       120 my $prematch = q{$`};
    100          
7177              
7178             $sub = sprintf(
7179              
7180             ($bind_operator =~ / =~ /oxms) ?
7181              
7182             # 1 2 3 4 5 6 7 8
7183             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s%s="%s$Ekoi8u::re_r$'"; 1 } : undef> :
7184              
7185             # 1 2 3 4 5 6 7 8
7186             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s%s="%s$Ekoi8u::re_r$'"; undef }>,
7187              
7188             $variable, # 1
7189             $bind_operator, # 2
7190             ($delimiter1 eq "'") ? # 3
7191             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7192             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7193             $s_matched, # 4
7194             $e_replacement, # 5
7195             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 6
7196             $variable, # 7
7197             $prematch, # 8
7198             );
7199             }
7200             }
7201 67 50       430  
7202 97         280 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
7203             if ($my ne '') {
7204             $sub = "($my, $sub)[1]";
7205             }
7206 0         0  
7207 97         156 # clear s/// variable
7208             $sub_variable = '';
7209 97         137 $bind_operator = '';
7210              
7211             return $sub;
7212             }
7213              
7214             #
7215             # escape regexp of split qr//
7216 97     74 0 1048 #
7217 74   100     345 sub e_split {
7218             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7219 74         386 $modifier ||= '';
7220 74 50       141  
7221 74         191 $modifier =~ tr/p//d;
7222 0         0 if ($modifier =~ /([adlu])/oxms) {
7223 0 0       0 my $line = 0;
7224 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7225 0         0 if ($filename ne __FILE__) {
7226             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7227             last;
7228 0         0 }
7229             }
7230             die qq{Unsupported modifier "$1" used at line $line.\n};
7231 0         0 }
7232              
7233             $slash = 'div';
7234 74 50       140  
7235 74         162 # /b /B modifier
7236             if ($modifier =~ tr/bB//d) {
7237             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7238 0 50       0 }
7239 74         315  
7240             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7241             my $metachar = qr/[\@\\|[\]{^]/oxms;
7242 74         276  
7243             # split regexp
7244             my @char = $string =~ /\G((?>
7245             [^\\\$\@\[\(] |
7246             \\x (?>[0-9A-Fa-f]{1,2}) |
7247             \\ (?>[0-7]{2,3}) |
7248             \\c [\x40-\x5F] |
7249             \\x\{ (?>[0-9A-Fa-f]+) \} |
7250             \\o\{ (?>[0-7]+) \} |
7251             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7252             \\ $q_char |
7253             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7254             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7255             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7256             [\$\@] $qq_variable |
7257             \$ (?>\s* [0-9]+) |
7258             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7259             \$ \$ (?![\w\{]) |
7260             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7261             \[\^ |
7262             \[\: (?>[a-z]+) :\] |
7263             \[\:\^ (?>[a-z]+) :\] |
7264             \(\? |
7265             $q_char
7266 74         9843 ))/oxmsg;
7267 74         266  
7268 74         105 my $left_e = 0;
7269             my $right_e = 0;
7270             for (my $i=0; $i <= $#char; $i++) {
7271 74 50 33     366  
    50 33        
    100          
    100          
    50          
    50          
7272 249         1255 # "\L\u" --> "\u\L"
7273             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7274             @char[$i,$i+1] = @char[$i+1,$i];
7275             }
7276              
7277 0         0 # "\U\l" --> "\l\U"
7278             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7279             @char[$i,$i+1] = @char[$i+1,$i];
7280             }
7281              
7282 0         0 # octal escape sequence
7283             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7284             $char[$i] = Ekoi8u::octchr($1);
7285             }
7286              
7287 1         3 # hexadecimal escape sequence
7288             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7289             $char[$i] = Ekoi8u::hexchr($1);
7290             }
7291              
7292             # \b{...} --> b\{...}
7293             # \B{...} --> B\{...}
7294             # \N{CHARNAME} --> N\{CHARNAME}
7295             # \p{PROPERTY} --> p\{PROPERTY}
7296 1         5 # \P{PROPERTY} --> P\{PROPERTY}
7297             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7298             $char[$i] = $1 . '\\' . $2;
7299             }
7300              
7301 0         0 # \p, \P, \X --> p, P, X
7302             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7303             $char[$i] = $1;
7304 0 50 100     0 }
    100 33        
    50 33        
    100 100        
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
7305              
7306             if (0) {
7307             }
7308 249         826  
7309 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
7310 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7311             if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
7312             $char[$i] .= join '', splice @char, $i+1, 3;
7313 0         0 }
7314             elsif (($i+2 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+2]) == 2) and (CORE::eval(sprintf '"%s%s%s"', @char[$i..$i+2]) =~ /\A $q_char \z/oxms)) {
7315             $char[$i] .= join '', splice @char, $i+1, 2;
7316 0         0 }
7317             elsif (($i+1 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, $char[$i+1 ]) == 1) and (CORE::eval(sprintf '"%s%s"', @char[$i..$i+1]) =~ /\A $q_char \z/oxms)) {
7318             $char[$i] .= join '', splice @char, $i+1, 1;
7319             }
7320             }
7321              
7322 0         0 # open character class [...]
7323 3 50       5 elsif ($char[$i] eq '[') {
7324 3         8 my $left = $i;
7325             if ($char[$i+1] eq ']') {
7326 0         0 $i++;
7327 3 50       4 }
7328 7         21 while (1) {
7329             if (++$i > $#char) {
7330 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7331 7         11 }
7332             if ($char[$i] eq ']') {
7333             my $right = $i;
7334 3 50       4  
7335 3         14 # [...]
  0         0  
7336             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7337             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7338 0         0 }
7339             else {
7340             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
7341 3         14 }
7342 3         6  
7343             $i = $left;
7344             last;
7345             }
7346             }
7347             }
7348              
7349 3         8 # open character class [^...]
7350 0 0       0 elsif ($char[$i] eq '[^') {
7351 0         0 my $left = $i;
7352             if ($char[$i+1] eq ']') {
7353 0         0 $i++;
7354 0 0       0 }
7355 0         0 while (1) {
7356             if (++$i > $#char) {
7357 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7358 0         0 }
7359             if ($char[$i] eq ']') {
7360             my $right = $i;
7361 0 0       0  
7362 0         0 # [^...]
  0         0  
7363             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7364             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8u::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7365 0         0 }
7366             else {
7367             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7368 0         0 }
7369 0         0  
7370             $i = $left;
7371             last;
7372             }
7373             }
7374             }
7375              
7376 0         0 # rewrite character class or escape character
7377             elsif (my $char = character_class($char[$i],$modifier)) {
7378             $char[$i] = $char;
7379             }
7380              
7381             # P.794 29.2.161. split
7382             # in Chapter 29: Functions
7383             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7384              
7385             # P.951 split
7386             # in Chapter 27: Functions
7387             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7388              
7389             # said "The //m modifier is assumed when you split on the pattern /^/",
7390             # but perl5.008 is not so. Therefore, this software adds //m.
7391             # (and so on)
7392              
7393 1         2 # split(m/^/) --> split(m/^/m)
7394             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7395             $modifier .= 'm';
7396             }
7397              
7398 7 0       20 # /i modifier
7399 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
7400             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
7401             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
7402 0         0 }
7403             else {
7404             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
7405             }
7406             }
7407              
7408 0 0       0 # \u \l \U \L \F \Q \E
7409 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7410             if ($right_e < $left_e) {
7411             $char[$i] = '\\' . $char[$i];
7412             }
7413 0         0 }
7414 0         0 elsif ($char[$i] eq '\u') {
7415             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
7416             $left_e++;
7417 0         0 }
7418 0         0 elsif ($char[$i] eq '\l') {
7419             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
7420             $left_e++;
7421 0         0 }
7422 0         0 elsif ($char[$i] eq '\U') {
7423             $char[$i] = '@{[Ekoi8u::uc qq<';
7424             $left_e++;
7425 0         0 }
7426 0         0 elsif ($char[$i] eq '\L') {
7427             $char[$i] = '@{[Ekoi8u::lc qq<';
7428             $left_e++;
7429 0         0 }
7430 0         0 elsif ($char[$i] eq '\F') {
7431             $char[$i] = '@{[Ekoi8u::fc qq<';
7432             $left_e++;
7433 0         0 }
7434 0         0 elsif ($char[$i] eq '\Q') {
7435             $char[$i] = '@{[CORE::quotemeta qq<';
7436             $left_e++;
7437 0 0       0 }
7438 0         0 elsif ($char[$i] eq '\E') {
7439 0         0 if ($right_e < $left_e) {
7440             $char[$i] = '>]}';
7441             $right_e++;
7442 0         0 }
7443             else {
7444             $char[$i] = '';
7445             }
7446 0         0 }
7447 0 0       0 elsif ($char[$i] eq '\Q') {
7448 0         0 while (1) {
7449             if (++$i > $#char) {
7450 0 0       0 last;
7451 0         0 }
7452             if ($char[$i] eq '\E') {
7453             last;
7454             }
7455             }
7456             }
7457             elsif ($char[$i] eq '\E') {
7458             }
7459              
7460 0 0       0 # $0 --> $0
7461 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7462             if ($ignorecase) {
7463             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7464             }
7465 0 0       0 }
7466 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7467             if ($ignorecase) {
7468             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7469             }
7470             }
7471              
7472             # $$ --> $$
7473             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7474             }
7475              
7476             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7477 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7478 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7479 0         0 $char[$i] = e_capture($1);
7480             if ($ignorecase) {
7481             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7482             }
7483 0         0 }
7484 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7485 0         0 $char[$i] = e_capture($1);
7486             if ($ignorecase) {
7487             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7488             }
7489             }
7490              
7491 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7492 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7493 0         0 $char[$i] = e_capture($1.'->'.$2);
7494             if ($ignorecase) {
7495             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7496             }
7497             }
7498              
7499 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7500 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
7501 0         0 $char[$i] = e_capture($1.'->'.$2);
7502             if ($ignorecase) {
7503             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7504             }
7505             }
7506              
7507 0         0 # $$foo
7508 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7509 0         0 $char[$i] = e_capture($1);
7510             if ($ignorecase) {
7511             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7512             }
7513             }
7514              
7515 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
7516 12         37 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7517             if ($ignorecase) {
7518             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
7519 0         0 }
7520             else {
7521             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
7522             }
7523             }
7524              
7525 12 50       53 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
7526 12         43 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7527             if ($ignorecase) {
7528             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
7529 0         0 }
7530             else {
7531             $char[$i] = '@{[Ekoi8u::MATCH()]}';
7532             }
7533             }
7534              
7535 12 50       126 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
7536 9         26 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7537             if ($ignorecase) {
7538             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
7539 0         0 }
7540             else {
7541             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
7542             }
7543             }
7544              
7545 9 0       40 # ${ foo }
7546 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
7547             if ($ignorecase) {
7548             $char[$i] = '@{[Ekoi8u::ignorecase(' . $1 . ')]}';
7549             }
7550             }
7551              
7552 0         0 # ${ ... }
7553 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7554 0         0 $char[$i] = e_capture($1);
7555             if ($ignorecase) {
7556             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7557             }
7558             }
7559              
7560 0         0 # $scalar or @array
7561 3 50       9 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7562 3         11 $char[$i] = e_string($char[$i]);
7563             if ($ignorecase) {
7564             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7565             }
7566             }
7567              
7568 0 50       0 # quote character before ? + * {
7569             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7570             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7571 1         6 }
7572             else {
7573             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7574             }
7575             }
7576             }
7577 0         0  
7578 74 50       216 # make regexp string
7579 74         170 $modifier =~ tr/i//d;
7580             if ($left_e > $right_e) {
7581 0         0 return join '', 'Ekoi8u::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7582             }
7583             return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7584             }
7585              
7586             #
7587             # escape regexp of split qr''
7588 74     0 0 700 #
7589 0   0       sub e_split_q {
7590             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7591 0           $modifier ||= '';
7592 0 0          
7593 0           $modifier =~ tr/p//d;
7594 0           if ($modifier =~ /([adlu])/oxms) {
7595 0 0         my $line = 0;
7596 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7597 0           if ($filename ne __FILE__) {
7598             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7599             last;
7600 0           }
7601             }
7602             die qq{Unsupported modifier "$1" used at line $line.\n};
7603 0           }
7604              
7605             $slash = 'div';
7606 0 0          
7607 0           # /b /B modifier
7608             if ($modifier =~ tr/bB//d) {
7609             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7610 0 0         }
7611              
7612             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7613 0            
7614             # split regexp
7615             my @char = $string =~ /\G((?>
7616             [^\\\[] |
7617             [\x00-\xFF] |
7618             \[\^ |
7619             \[\: (?>[a-z]+) \:\] |
7620             \[\:\^ (?>[a-z]+) \:\] |
7621             \\ (?:$q_char) |
7622             (?:$q_char)
7623             ))/oxmsg;
7624 0            
7625 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7626             for (my $i=0; $i <= $#char; $i++) {
7627             if (0) {
7628             }
7629 0            
7630 0           # open character class [...]
7631 0 0         elsif ($char[$i] eq '[') {
7632 0           my $left = $i;
7633             if ($char[$i+1] eq ']') {
7634 0           $i++;
7635 0 0         }
7636 0           while (1) {
7637             if (++$i > $#char) {
7638 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7639 0           }
7640             if ($char[$i] eq ']') {
7641             my $right = $i;
7642 0            
7643             # [...]
7644 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
7645 0            
7646             $i = $left;
7647             last;
7648             }
7649             }
7650             }
7651              
7652 0           # open character class [^...]
7653 0 0         elsif ($char[$i] eq '[^') {
7654 0           my $left = $i;
7655             if ($char[$i+1] eq ']') {
7656 0           $i++;
7657 0 0         }
7658 0           while (1) {
7659             if (++$i > $#char) {
7660 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7661 0           }
7662             if ($char[$i] eq ']') {
7663             my $right = $i;
7664 0            
7665             # [^...]
7666 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7667 0            
7668             $i = $left;
7669             last;
7670             }
7671             }
7672             }
7673              
7674 0           # rewrite character class or escape character
7675             elsif (my $char = character_class($char[$i],$modifier)) {
7676             $char[$i] = $char;
7677             }
7678              
7679 0           # split(m/^/) --> split(m/^/m)
7680             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7681             $modifier .= 'm';
7682             }
7683              
7684 0 0         # /i modifier
7685 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
7686             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
7687             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
7688 0           }
7689             else {
7690             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
7691             }
7692             }
7693              
7694 0 0         # quote character before ? + * {
7695             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7696             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7697 0           }
7698             else {
7699             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7700             }
7701             }
7702 0           }
7703 0            
7704             $modifier =~ tr/i//d;
7705             return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7706             }
7707              
7708             #
7709             # instead of Carp::carp
7710 0     0 0   #
7711 0           sub carp {
7712             my($package,$filename,$line) = caller(1);
7713             print STDERR "@_ at $filename line $line.\n";
7714             }
7715              
7716             #
7717             # instead of Carp::croak
7718 0     0 0   #
7719 0           sub croak {
7720 0           my($package,$filename,$line) = caller(1);
7721             print STDERR "@_ at $filename line $line.\n";
7722             die "\n";
7723             }
7724              
7725             #
7726             # instead of Carp::cluck
7727 0     0 0   #
7728 0           sub cluck {
7729 0           my $i = 0;
7730 0           my @cluck = ();
7731 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7732             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7733 0           $i++;
7734 0           }
7735 0           print STDERR CORE::reverse @cluck;
7736             print STDERR "\n";
7737             print STDERR @_;
7738             }
7739              
7740             #
7741             # instead of Carp::confess
7742 0     0 0   #
7743 0           sub confess {
7744 0           my $i = 0;
7745 0           my @confess = ();
7746 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7747             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7748 0           $i++;
7749 0           }
7750 0           print STDERR CORE::reverse @confess;
7751 0           print STDERR "\n";
7752             print STDERR @_;
7753             die "\n";
7754             }
7755              
7756             1;
7757              
7758             __END__