File Coverage

blib/lib/Ekoi8u.pm
Criterion Covered Total %
statement 865 3080 28.0
branch 944 2674 35.3
condition 99 373 26.5
subroutine 67 125 53.6
pod 7 74 9.4
total 1982 6326 31.3


line stmt bran cond sub pod time code
1             package Ekoi8u;
2             ######################################################################
3             #
4             # Ekoi8u - Run-time routines for KOI8U.pm
5             #
6             # http://search.cpan.org/dist/Char-KOI8U/
7             #
8             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 INABA Hitoshi
9             ######################################################################
10              
11 200     200   3345 use 5.00503; # Galapagos Consensus 1998 for primetools
  200         660  
12             # use 5.008001; # Lancaster Consensus 2013 for toolchains
13              
14             # 12.3. Delaying use Until Runtime
15             # in Chapter 12. Packages, Libraries, and Modules
16             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
17             # (and so on)
18              
19             # Version numbers should be boring
20             # http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
21             # For the impatient, the disinterested or those who just want to follow
22             # a recipe, my advice for all modules is this:
23             # our $VERSION = "0.001"; # or "0.001_001" for a dev release
24             # $VERSION = eval $VERSION;
25              
26 200     200   12561 BEGIN { CORE::eval q{ use vars qw($VERSION) } }
  200     200   9828  
  200         292  
  200         29019  
27             $VERSION = '1.08';
28             $VERSION = CORE::eval $VERSION;
29              
30             BEGIN {
31 200 50   200   1153 if ($^X =~ / jperl /oxmsi) {
32 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
33             }
34 200         266 if (CORE::ord('A') == 193) {
35             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
36             }
37 200         25618 if (CORE::ord('A') != 0x41) {
38             die __FILE__, ": is not US-ASCII script (must be US-ASCII script).\n";
39             }
40             }
41              
42             BEGIN {
43              
44             # instead of utf8.pm
45 200     200   12718 CORE::eval q{
  200     200   1013  
  200     81   309  
  200         22465  
  57         5480  
  41         3482  
  46         4111  
  56         5050  
46             no warnings qw(redefine);
47             *utf8::upgrade = sub { CORE::length $_[0] };
48             *utf8::downgrade = sub { 1 };
49             *utf8::encode = sub { };
50             *utf8::decode = sub { 1 };
51             *utf8::is_utf8 = sub { };
52             *utf8::valid = sub { 1 };
53             };
54 200 50       98340 if ($@) {
55 0         0 *utf8::upgrade = sub { CORE::length $_[0] };
  0         0  
56 0         0 *utf8::downgrade = sub { 1 };
  0         0  
57 0         0 *utf8::encode = sub { };
58 0         0 *utf8::decode = sub { 1 };
  0         0  
59 0         0 *utf8::is_utf8 = sub { };
60 0         0 *utf8::valid = sub { 1 };
  0         0  
61             }
62             }
63              
64             # instead of Symbol.pm
65 0         0 BEGIN {
66 200     200   456 my $genpkg = "Symbol::";
67 200         8608 my $genseq = 0;
68              
69             sub gensym () {
70 0     0 0 0 my $name = "GEN" . $genseq++;
71              
72             # here, no strict qw(refs); if strict.pm exists
73              
74 0         0 my $ref = \*{$genpkg . $name};
  0         0  
75 0         0 delete $$genpkg{$name};
76 0         0 return $ref;
77             }
78              
79             sub qualify ($;$) {
80 0     0 0 0 my ($name) = @_;
81 0 0 0     0 if (!ref($name) && (Ekoi8u::index($name, '::') == -1) && (Ekoi8u::index($name, "'") == -1)) {
      0        
82 0         0 my $pkg;
83 0         0 my %global = map {$_ => 1} qw(ARGV ARGVOUT ENV INC SIG STDERR STDIN STDOUT DATA);
  0         0  
84              
85             # Global names: special character, "^xyz", or other.
86 0 0 0     0 if ($name =~ /^(([^a-z])|(\^[a-z_]+))\z/i || $global{$name}) {
87             # RGS 2001-11-05 : translate leading ^X to control-char
88 0         0 $name =~ s/^\^([a-z_])/'qq(\c'.$1.')'/eei;
  0         0  
89 0         0 $pkg = "main";
90             }
91             else {
92 0 0       0 $pkg = (@_ > 1) ? $_[1] : caller;
93             }
94 0         0 $name = $pkg . "::" . $name;
95             }
96 0         0 return $name;
97             }
98              
99             sub qualify_to_ref ($;$) {
100              
101             # here, no strict qw(refs); if strict.pm exists
102              
103 0 0   0 0 0 return \*{ qualify $_[0], @_ > 1 ? $_[1] : caller };
  0         0  
104             }
105             }
106              
107             # Column: local $@
108             # in Chapter 9. Osaete okitai Perl no kiso
109             # of ISBN 10: 4798119172 | ISBN 13: 978-4798119175 MODAN Perl NYUMON
110             # (and so on)
111              
112             # use strict; if strict.pm exists
113             BEGIN {
114 200 50   200   447 if (CORE::eval { local $@; CORE::require strict }) {
  200         314  
  200         1874  
115 200         22994 strict::->import;
116             }
117             }
118              
119             # P.714 29.2.39. flock
120             # in Chapter 29: Functions
121             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
122              
123             # P.863 flock
124             # in Chapter 27: Functions
125             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
126              
127             sub LOCK_SH() {1}
128             sub LOCK_EX() {2}
129             sub LOCK_UN() {8}
130             sub LOCK_NB() {4}
131              
132             # instead of Carp.pm
133             sub carp;
134             sub croak;
135             sub cluck;
136             sub confess;
137              
138             # 6.18. Matching Multiple-Byte Characters
139             # in Chapter 6. Pattern Matching
140             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
141             # (and so on)
142              
143             # regexp of character
144 200     200   13390 BEGIN { CORE::eval q{ use vars qw($your_char) } } $your_char = q{[\x00-\xFF]};
  200     200   970  
  200         290  
  200         11003  
145 200     200   11376 BEGIN { CORE::eval q{ use vars qw($qq_char ) } } $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  200     200   926  
  200         271  
  200         11475  
146 200     200   11559 BEGIN { CORE::eval q{ use vars qw($q_char ) } } $q_char = qr/$your_char/oxms;
  200     200   1138  
  200         435  
  200         14038  
147              
148             #
149             # KOI8-U character range per length
150             #
151             my %range_tr = ();
152              
153             #
154             # alias of encoding name
155             #
156 200     200   11691 BEGIN { CORE::eval q{ use vars qw($encoding_alias) } }
  200     200   959  
  200         280  
  200         327080  
157              
158             #
159             # KOI8-U case conversion
160             #
161             my %lc = ();
162             @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)} =
163             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
164             my %uc = ();
165             @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)} =
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 %fc = ();
168             @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)} =
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              
171             if (0) {
172             }
173              
174             elsif (__PACKAGE__ =~ / \b Ekoi8u \z/oxms) {
175             %range_tr = (
176             1 => [ [0x00..0xFF],
177             ],
178             );
179             $encoding_alias = qr/ \b (?: koi8-?u ) \b /oxmsi;
180              
181             %lc = (%lc,
182             "\xB3" => "\xA3", # CYRILLIC LETTER IO
183             "\xB4" => "\xA4", # CYRILLIC LETTER UKRAINIAN IE
184             "\xB6" => "\xA6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
185             "\xB7" => "\xA7", # CYRILLIC LETTER YI (UKRAINIAN)
186             "\xBD" => "\xAD", # CYRILLIC LETTER GHE WITH UPTURN
187             "\xE0" => "\xC0", # CYRILLIC LETTER YU
188             "\xE1" => "\xC1", # CYRILLIC LETTER A
189             "\xE2" => "\xC2", # CYRILLIC LETTER BE
190             "\xE3" => "\xC3", # CYRILLIC LETTER TSE
191             "\xE4" => "\xC4", # CYRILLIC LETTER DE
192             "\xE5" => "\xC5", # CYRILLIC LETTER IE
193             "\xE6" => "\xC6", # CYRILLIC LETTER EF
194             "\xE7" => "\xC7", # CYRILLIC LETTER GHE
195             "\xE8" => "\xC8", # CYRILLIC LETTER KHA
196             "\xE9" => "\xC9", # CYRILLIC LETTER I
197             "\xEA" => "\xCA", # CYRILLIC LETTER SHORT I
198             "\xEB" => "\xCB", # CYRILLIC LETTER KA
199             "\xEC" => "\xCC", # CYRILLIC LETTER EL
200             "\xED" => "\xCD", # CYRILLIC LETTER EM
201             "\xEE" => "\xCE", # CYRILLIC LETTER EN
202             "\xEF" => "\xCF", # CYRILLIC LETTER O
203             "\xF0" => "\xD0", # CYRILLIC LETTER PE
204             "\xF1" => "\xD1", # CYRILLIC LETTER YA
205             "\xF2" => "\xD2", # CYRILLIC LETTER ER
206             "\xF3" => "\xD3", # CYRILLIC LETTER ES
207             "\xF4" => "\xD4", # CYRILLIC LETTER TE
208             "\xF5" => "\xD5", # CYRILLIC LETTER U
209             "\xF6" => "\xD6", # CYRILLIC LETTER ZHE
210             "\xF7" => "\xD7", # CYRILLIC LETTER VE
211             "\xF8" => "\xD8", # CYRILLIC LETTER SOFT SIGN
212             "\xF9" => "\xD9", # CYRILLIC LETTER YERU
213             "\xFA" => "\xDA", # CYRILLIC LETTER ZE
214             "\xFB" => "\xDB", # CYRILLIC LETTER SHA
215             "\xFC" => "\xDC", # CYRILLIC LETTER E
216             "\xFD" => "\xDD", # CYRILLIC LETTER SHCHA
217             "\xFE" => "\xDE", # CYRILLIC LETTER CHE
218             "\xFF" => "\xDF", # CYRILLIC LETTER HARD SIGN
219             );
220              
221             %uc = (%uc,
222             "\xA3" => "\xB3", # CYRILLIC LETTER IO
223             "\xA4" => "\xB4", # CYRILLIC LETTER UKRAINIAN IE
224             "\xA6" => "\xB6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
225             "\xA7" => "\xB7", # CYRILLIC LETTER YI (UKRAINIAN)
226             "\xAD" => "\xBD", # CYRILLIC LETTER GHE WITH UPTURN
227             "\xC0" => "\xE0", # CYRILLIC LETTER YU
228             "\xC1" => "\xE1", # CYRILLIC LETTER A
229             "\xC2" => "\xE2", # CYRILLIC LETTER BE
230             "\xC3" => "\xE3", # CYRILLIC LETTER TSE
231             "\xC4" => "\xE4", # CYRILLIC LETTER DE
232             "\xC5" => "\xE5", # CYRILLIC LETTER IE
233             "\xC6" => "\xE6", # CYRILLIC LETTER EF
234             "\xC7" => "\xE7", # CYRILLIC LETTER GHE
235             "\xC8" => "\xE8", # CYRILLIC LETTER KHA
236             "\xC9" => "\xE9", # CYRILLIC LETTER I
237             "\xCA" => "\xEA", # CYRILLIC LETTER SHORT I
238             "\xCB" => "\xEB", # CYRILLIC LETTER KA
239             "\xCC" => "\xEC", # CYRILLIC LETTER EL
240             "\xCD" => "\xED", # CYRILLIC LETTER EM
241             "\xCE" => "\xEE", # CYRILLIC LETTER EN
242             "\xCF" => "\xEF", # CYRILLIC LETTER O
243             "\xD0" => "\xF0", # CYRILLIC LETTER PE
244             "\xD1" => "\xF1", # CYRILLIC LETTER YA
245             "\xD2" => "\xF2", # CYRILLIC LETTER ER
246             "\xD3" => "\xF3", # CYRILLIC LETTER ES
247             "\xD4" => "\xF4", # CYRILLIC LETTER TE
248             "\xD5" => "\xF5", # CYRILLIC LETTER U
249             "\xD6" => "\xF6", # CYRILLIC LETTER ZHE
250             "\xD7" => "\xF7", # CYRILLIC LETTER VE
251             "\xD8" => "\xF8", # CYRILLIC LETTER SOFT SIGN
252             "\xD9" => "\xF9", # CYRILLIC LETTER YERU
253             "\xDA" => "\xFA", # CYRILLIC LETTER ZE
254             "\xDB" => "\xFB", # CYRILLIC LETTER SHA
255             "\xDC" => "\xFC", # CYRILLIC LETTER E
256             "\xDD" => "\xFD", # CYRILLIC LETTER SHCHA
257             "\xDE" => "\xFE", # CYRILLIC LETTER CHE
258             "\xDF" => "\xFF", # CYRILLIC LETTER HARD SIGN
259             );
260              
261             %fc = (%fc,
262             "\xB3" => "\xA3", # CYRILLIC CAPITAL LETTER IO --> CYRILLIC SMALL LETTER IO
263             "\xB4" => "\xA4", # CYRILLIC CAPITAL LETTER UKRAINIAN IE --> CYRILLIC SMALL LETTER UKRAINIAN IE
264             "\xB6" => "\xA6", # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I --> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
265             "\xB7" => "\xA7", # CYRILLIC CAPITAL LETTER YI --> CYRILLIC SMALL LETTER YI
266             "\xBD" => "\xAD", # CYRILLIC CAPITAL LETTER GHE WITH UPTURN --> CYRILLIC SMALL LETTER GHE WITH UPTURN
267             "\xE0" => "\xC0", # CYRILLIC CAPITAL LETTER YU --> CYRILLIC SMALL LETTER YU
268             "\xE1" => "\xC1", # CYRILLIC CAPITAL LETTER A --> CYRILLIC SMALL LETTER A
269             "\xE2" => "\xC2", # CYRILLIC CAPITAL LETTER BE --> CYRILLIC SMALL LETTER BE
270             "\xE3" => "\xC3", # CYRILLIC CAPITAL LETTER TSE --> CYRILLIC SMALL LETTER TSE
271             "\xE4" => "\xC4", # CYRILLIC CAPITAL LETTER DE --> CYRILLIC SMALL LETTER DE
272             "\xE5" => "\xC5", # CYRILLIC CAPITAL LETTER IE --> CYRILLIC SMALL LETTER IE
273             "\xE6" => "\xC6", # CYRILLIC CAPITAL LETTER EF --> CYRILLIC SMALL LETTER EF
274             "\xE7" => "\xC7", # CYRILLIC CAPITAL LETTER GHE --> CYRILLIC SMALL LETTER GHE
275             "\xE8" => "\xC8", # CYRILLIC CAPITAL LETTER HA --> CYRILLIC SMALL LETTER HA
276             "\xE9" => "\xC9", # CYRILLIC CAPITAL LETTER I --> CYRILLIC SMALL LETTER I
277             "\xEA" => "\xCA", # CYRILLIC CAPITAL LETTER SHORT I --> CYRILLIC SMALL LETTER SHORT I
278             "\xEB" => "\xCB", # CYRILLIC CAPITAL LETTER KA --> CYRILLIC SMALL LETTER KA
279             "\xEC" => "\xCC", # CYRILLIC CAPITAL LETTER EL --> CYRILLIC SMALL LETTER EL
280             "\xED" => "\xCD", # CYRILLIC CAPITAL LETTER EM --> CYRILLIC SMALL LETTER EM
281             "\xEE" => "\xCE", # CYRILLIC CAPITAL LETTER EN --> CYRILLIC SMALL LETTER EN
282             "\xEF" => "\xCF", # CYRILLIC CAPITAL LETTER O --> CYRILLIC SMALL LETTER O
283             "\xF0" => "\xD0", # CYRILLIC CAPITAL LETTER PE --> CYRILLIC SMALL LETTER PE
284             "\xF1" => "\xD1", # CYRILLIC CAPITAL LETTER YA --> CYRILLIC SMALL LETTER YA
285             "\xF2" => "\xD2", # CYRILLIC CAPITAL LETTER ER --> CYRILLIC SMALL LETTER ER
286             "\xF3" => "\xD3", # CYRILLIC CAPITAL LETTER ES --> CYRILLIC SMALL LETTER ES
287             "\xF4" => "\xD4", # CYRILLIC CAPITAL LETTER TE --> CYRILLIC SMALL LETTER TE
288             "\xF5" => "\xD5", # CYRILLIC CAPITAL LETTER U --> CYRILLIC SMALL LETTER U
289             "\xF6" => "\xD6", # CYRILLIC CAPITAL LETTER ZHE --> CYRILLIC SMALL LETTER ZHE
290             "\xF7" => "\xD7", # CYRILLIC CAPITAL LETTER VE --> CYRILLIC SMALL LETTER VE
291             "\xF8" => "\xD8", # CYRILLIC CAPITAL LETTER SOFT SIGN --> CYRILLIC SMALL LETTER SOFT SIGN
292             "\xF9" => "\xD9", # CYRILLIC CAPITAL LETTER YERU --> CYRILLIC SMALL LETTER YERU
293             "\xFA" => "\xDA", # CYRILLIC CAPITAL LETTER ZE --> CYRILLIC SMALL LETTER ZE
294             "\xFB" => "\xDB", # CYRILLIC CAPITAL LETTER SHA --> CYRILLIC SMALL LETTER SHA
295             "\xFC" => "\xDC", # CYRILLIC CAPITAL LETTER E --> CYRILLIC SMALL LETTER E
296             "\xFD" => "\xDD", # CYRILLIC CAPITAL LETTER SHCHA --> CYRILLIC SMALL LETTER SHCHA
297             "\xFE" => "\xDE", # CYRILLIC CAPITAL LETTER CHE --> CYRILLIC SMALL LETTER CHE
298             "\xFF" => "\xDF", # CYRILLIC CAPITAL LETTER HARD SIGN --> CYRILLIC SMALL LETTER HARD SIGN
299             );
300             }
301              
302             else {
303             croak "Don't know my package name '@{[__PACKAGE__]}'";
304             }
305              
306             #
307             # @ARGV wildcard globbing
308             #
309             sub import {
310              
311 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
312 0         0 my @argv = ();
313 0         0 for (@ARGV) {
314              
315             # has space
316 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
317 0 0       0 if (my @glob = Ekoi8u::glob(qq{"$_"})) {
318 0         0 push @argv, @glob;
319             }
320             else {
321 0         0 push @argv, $_;
322             }
323             }
324              
325             # has wildcard metachar
326             elsif (/\A (?:$q_char)*? [*?] /oxms) {
327 0 0       0 if (my @glob = Ekoi8u::glob($_)) {
328 0         0 push @argv, @glob;
329             }
330             else {
331 0         0 push @argv, $_;
332             }
333             }
334              
335             # no wildcard globbing
336             else {
337 0         0 push @argv, $_;
338             }
339             }
340 0         0 @ARGV = @argv;
341             }
342              
343 0         0 *Char::ord = \&KOI8U::ord;
344 0         0 *Char::ord_ = \&KOI8U::ord_;
345 0         0 *Char::reverse = \&KOI8U::reverse;
346 0         0 *Char::getc = \&KOI8U::getc;
347 0         0 *Char::length = \&KOI8U::length;
348 0         0 *Char::substr = \&KOI8U::substr;
349 0         0 *Char::index = \&KOI8U::index;
350 0         0 *Char::rindex = \&KOI8U::rindex;
351 0         0 *Char::eval = \&KOI8U::eval;
352 0         0 *Char::escape = \&KOI8U::escape;
353 0         0 *Char::escape_token = \&KOI8U::escape_token;
354 0         0 *Char::escape_script = \&KOI8U::escape_script;
355             }
356              
357             # P.230 Care with Prototypes
358             # in Chapter 6: Subroutines
359             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
360             #
361             # If you aren't careful, you can get yourself into trouble with prototypes.
362             # But if you are careful, you can do a lot of neat things with them. This is
363             # all very powerful, of course, and should only be used in moderation to make
364             # the world a better place.
365              
366             # P.332 Care with Prototypes
367             # in Chapter 7: Subroutines
368             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
369             #
370             # If you aren't careful, you can get yourself into trouble with prototypes.
371             # But if you are careful, you can do a lot of neat things with them. This is
372             # all very powerful, of course, and should only be used in moderation to make
373             # the world a better place.
374              
375             #
376             # Prototypes of subroutines
377             #
378       0     sub unimport {}
379             sub Ekoi8u::split(;$$$);
380             sub Ekoi8u::tr($$$$;$);
381             sub Ekoi8u::chop(@);
382             sub Ekoi8u::index($$;$);
383             sub Ekoi8u::rindex($$;$);
384             sub Ekoi8u::lcfirst(@);
385             sub Ekoi8u::lcfirst_();
386             sub Ekoi8u::lc(@);
387             sub Ekoi8u::lc_();
388             sub Ekoi8u::ucfirst(@);
389             sub Ekoi8u::ucfirst_();
390             sub Ekoi8u::uc(@);
391             sub Ekoi8u::uc_();
392             sub Ekoi8u::fc(@);
393             sub Ekoi8u::fc_();
394             sub Ekoi8u::ignorecase;
395             sub Ekoi8u::classic_character_class;
396             sub Ekoi8u::capture;
397             sub Ekoi8u::chr(;$);
398             sub Ekoi8u::chr_();
399             sub Ekoi8u::glob($);
400             sub Ekoi8u::glob_();
401              
402             sub KOI8U::ord(;$);
403             sub KOI8U::ord_();
404             sub KOI8U::reverse(@);
405             sub KOI8U::getc(;*@);
406             sub KOI8U::length(;$);
407             sub KOI8U::substr($$;$$);
408             sub KOI8U::index($$;$);
409             sub KOI8U::rindex($$;$);
410             sub KOI8U::escape(;$);
411              
412             #
413             # Regexp work
414             #
415 200     200   14717 BEGIN { CORE::eval q{ use vars qw(
  200     200   1080  
  200         338  
  200         70640  
416             $KOI8U::re_a
417             $KOI8U::re_t
418             $KOI8U::re_n
419             $KOI8U::re_r
420             ) } }
421              
422             #
423             # Character class
424             #
425 200     200   14303 BEGIN { CORE::eval q{ use vars qw(
  200     200   1055  
  200         299  
  200         2493987  
426             $dot
427             $dot_s
428             $eD
429             $eS
430             $eW
431             $eH
432             $eV
433             $eR
434             $eN
435             $not_alnum
436             $not_alpha
437             $not_ascii
438             $not_blank
439             $not_cntrl
440             $not_digit
441             $not_graph
442             $not_lower
443             $not_lower_i
444             $not_print
445             $not_punct
446             $not_space
447             $not_upper
448             $not_upper_i
449             $not_word
450             $not_xdigit
451             $eb
452             $eB
453             ) } }
454              
455             ${Ekoi8u::dot} = qr{(?>[^\x0A])};
456             ${Ekoi8u::dot_s} = qr{(?>[\x00-\xFF])};
457             ${Ekoi8u::eD} = qr{(?>[^0-9])};
458              
459             # Vertical tabs are now whitespace
460             # \s in a regex now matches a vertical tab in all circumstances.
461             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
462             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
463             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
464             ${Ekoi8u::eS} = qr{(?>[^\s])};
465              
466             ${Ekoi8u::eW} = qr{(?>[^0-9A-Z_a-z])};
467             ${Ekoi8u::eH} = qr{(?>[^\x09\x20])};
468             ${Ekoi8u::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
469             ${Ekoi8u::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
470             ${Ekoi8u::eN} = qr{(?>[^\x0A])};
471             ${Ekoi8u::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
472             ${Ekoi8u::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
473             ${Ekoi8u::not_ascii} = qr{(?>[^\x00-\x7F])};
474             ${Ekoi8u::not_blank} = qr{(?>[^\x09\x20])};
475             ${Ekoi8u::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
476             ${Ekoi8u::not_digit} = qr{(?>[^\x30-\x39])};
477             ${Ekoi8u::not_graph} = qr{(?>[^\x21-\x7F])};
478             ${Ekoi8u::not_lower} = qr{(?>[^\x61-\x7A])};
479             ${Ekoi8u::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
480             # ${Ekoi8u::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
481             ${Ekoi8u::not_print} = qr{(?>[^\x20-\x7F])};
482             ${Ekoi8u::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
483             ${Ekoi8u::not_space} = qr{(?>[^\s\x0B])};
484             ${Ekoi8u::not_upper} = qr{(?>[^\x41-\x5A])};
485             ${Ekoi8u::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
486             # ${Ekoi8u::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
487             ${Ekoi8u::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
488             ${Ekoi8u::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
489             ${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))};
490             ${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]))};
491              
492             # avoid: Name "Ekoi8u::foo" used only once: possible typo at here.
493             ${Ekoi8u::dot} = ${Ekoi8u::dot};
494             ${Ekoi8u::dot_s} = ${Ekoi8u::dot_s};
495             ${Ekoi8u::eD} = ${Ekoi8u::eD};
496             ${Ekoi8u::eS} = ${Ekoi8u::eS};
497             ${Ekoi8u::eW} = ${Ekoi8u::eW};
498             ${Ekoi8u::eH} = ${Ekoi8u::eH};
499             ${Ekoi8u::eV} = ${Ekoi8u::eV};
500             ${Ekoi8u::eR} = ${Ekoi8u::eR};
501             ${Ekoi8u::eN} = ${Ekoi8u::eN};
502             ${Ekoi8u::not_alnum} = ${Ekoi8u::not_alnum};
503             ${Ekoi8u::not_alpha} = ${Ekoi8u::not_alpha};
504             ${Ekoi8u::not_ascii} = ${Ekoi8u::not_ascii};
505             ${Ekoi8u::not_blank} = ${Ekoi8u::not_blank};
506             ${Ekoi8u::not_cntrl} = ${Ekoi8u::not_cntrl};
507             ${Ekoi8u::not_digit} = ${Ekoi8u::not_digit};
508             ${Ekoi8u::not_graph} = ${Ekoi8u::not_graph};
509             ${Ekoi8u::not_lower} = ${Ekoi8u::not_lower};
510             ${Ekoi8u::not_lower_i} = ${Ekoi8u::not_lower_i};
511             ${Ekoi8u::not_print} = ${Ekoi8u::not_print};
512             ${Ekoi8u::not_punct} = ${Ekoi8u::not_punct};
513             ${Ekoi8u::not_space} = ${Ekoi8u::not_space};
514             ${Ekoi8u::not_upper} = ${Ekoi8u::not_upper};
515             ${Ekoi8u::not_upper_i} = ${Ekoi8u::not_upper_i};
516             ${Ekoi8u::not_word} = ${Ekoi8u::not_word};
517             ${Ekoi8u::not_xdigit} = ${Ekoi8u::not_xdigit};
518             ${Ekoi8u::eb} = ${Ekoi8u::eb};
519             ${Ekoi8u::eB} = ${Ekoi8u::eB};
520              
521             #
522             # KOI8-U split
523             #
524             sub Ekoi8u::split(;$$$) {
525              
526             # P.794 29.2.161. split
527             # in Chapter 29: Functions
528             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
529              
530             # P.951 split
531             # in Chapter 27: Functions
532             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
533              
534 0     0 0 0 my $pattern = $_[0];
535 0         0 my $string = $_[1];
536 0         0 my $limit = $_[2];
537              
538             # if $pattern is also omitted or is the literal space, " "
539 0 0       0 if (not defined $pattern) {
540 0         0 $pattern = ' ';
541             }
542              
543             # if $string is omitted, the function splits the $_ string
544 0 0       0 if (not defined $string) {
545 0 0       0 if (defined $_) {
546 0         0 $string = $_;
547             }
548             else {
549 0         0 $string = '';
550             }
551             }
552              
553 0         0 my @split = ();
554              
555             # when string is empty
556 0 0       0 if ($string eq '') {
    0          
557              
558             # resulting list value in list context
559 0 0       0 if (wantarray) {
560 0         0 return @split;
561             }
562              
563             # count of substrings in scalar context
564             else {
565 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
566 0         0 @_ = @split;
567 0         0 return scalar @_;
568             }
569             }
570              
571             # split's first argument is more consistently interpreted
572             #
573             # After some changes earlier in v5.17, split's behavior has been simplified:
574             # if the PATTERN argument evaluates to a string containing one space, it is
575             # treated the way that a literal string containing one space once was.
576             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
577              
578             # if $pattern is also omitted or is the literal space, " ", the function splits
579             # on whitespace, /\s+/, after skipping any leading whitespace
580             # (and so on)
581              
582             elsif ($pattern eq ' ') {
583 0 0       0 if (not defined $limit) {
584 0         0 return CORE::split(' ', $string);
585             }
586             else {
587 0         0 return CORE::split(' ', $string, $limit);
588             }
589             }
590              
591             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
592 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
593              
594             # a pattern capable of matching either the null string or something longer than the
595             # null string will split the value of $string into separate characters wherever it
596             # matches the null string between characters
597             # (and so on)
598              
599 0 0       0 if ('' =~ / \A $pattern \z /xms) {
600 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
601 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
602              
603             # P.1024 Appendix W.10 Multibyte Processing
604             # of ISBN 1-56592-224-7 CJKV Information Processing
605             # (and so on)
606              
607             # the //m modifier is assumed when you split on the pattern /^/
608             # (and so on)
609              
610             # V
611 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
612              
613             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
614             # is included in the resulting list, interspersed with the fields that are ordinarily returned
615             # (and so on)
616              
617 0         0 local $@;
618 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
619 0         0 push @split, CORE::eval('$' . $digit);
620             }
621             }
622             }
623              
624             else {
625 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
626              
627             # V
628 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
629 0         0 local $@;
630 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
631 0         0 push @split, CORE::eval('$' . $digit);
632             }
633             }
634             }
635             }
636              
637             elsif ($limit > 0) {
638 0 0       0 if ('' =~ / \A $pattern \z /xms) {
639 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
640 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
641              
642             # V
643 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
644 0         0 local $@;
645 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
646 0         0 push @split, CORE::eval('$' . $digit);
647             }
648             }
649             }
650             }
651             else {
652 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
653 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
654              
655             # V
656 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
657 0         0 local $@;
658 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
659 0         0 push @split, CORE::eval('$' . $digit);
660             }
661             }
662             }
663             }
664             }
665              
666 0 0       0 if (CORE::length($string) > 0) {
667 0         0 push @split, $string;
668             }
669              
670             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
671 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
672 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
673 0         0 pop @split;
674             }
675             }
676              
677             # resulting list value in list context
678 0 0       0 if (wantarray) {
679 0         0 return @split;
680             }
681              
682             # count of substrings in scalar context
683             else {
684 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
685 0         0 @_ = @split;
686 0         0 return scalar @_;
687             }
688             }
689              
690             #
691             # get last subexpression offsets
692             #
693             sub _last_subexpression_offsets {
694 0     0   0 my $pattern = $_[0];
695              
696             # remove comment
697 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
698              
699 0         0 my $modifier = '';
700 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
701 0         0 $modifier = $1;
702 0         0 $modifier =~ s/-[A-Za-z]*//;
703             }
704              
705             # with /x modifier
706 0         0 my @char = ();
707 0 0       0 if ($modifier =~ /x/oxms) {
708 0         0 @char = $pattern =~ /\G((?>
709             [^\\\#\[\(] |
710             \\ $q_char |
711             \# (?>[^\n]*) $ |
712             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
713             \(\? |
714             $q_char
715             ))/oxmsg;
716             }
717              
718             # without /x modifier
719             else {
720 0         0 @char = $pattern =~ /\G((?>
721             [^\\\[\(] |
722             \\ $q_char |
723             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
724             \(\? |
725             $q_char
726             ))/oxmsg;
727             }
728              
729 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
730             }
731              
732             #
733             # KOI8-U transliteration (tr///)
734             #
735             sub Ekoi8u::tr($$$$;$) {
736              
737 0     0 0 0 my $bind_operator = $_[1];
738 0         0 my $searchlist = $_[2];
739 0         0 my $replacementlist = $_[3];
740 0   0     0 my $modifier = $_[4] || '';
741              
742 0 0       0 if ($modifier =~ /r/oxms) {
743 0 0       0 if ($bind_operator =~ / !~ /oxms) {
744 0         0 croak "Using !~ with tr///r doesn't make sense";
745             }
746             }
747              
748 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
749 0         0 my @searchlist = _charlist_tr($searchlist);
750 0         0 my @replacementlist = _charlist_tr($replacementlist);
751              
752 0         0 my %tr = ();
753 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
754 0 0       0 if (not exists $tr{$searchlist[$i]}) {
755 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
756 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
757             }
758             elsif ($modifier =~ /d/oxms) {
759 0         0 $tr{$searchlist[$i]} = '';
760             }
761             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
762 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
763             }
764             else {
765 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
766             }
767             }
768             }
769              
770 0         0 my $tr = 0;
771 0         0 my $replaced = '';
772 0 0       0 if ($modifier =~ /c/oxms) {
773 0         0 while (defined(my $char = shift @char)) {
774 0 0       0 if (not exists $tr{$char}) {
775 0 0       0 if (defined $replacementlist[0]) {
776 0         0 $replaced .= $replacementlist[0];
777             }
778 0         0 $tr++;
779 0 0       0 if ($modifier =~ /s/oxms) {
780 0   0     0 while (@char and (not exists $tr{$char[0]})) {
781 0         0 shift @char;
782 0         0 $tr++;
783             }
784             }
785             }
786             else {
787 0         0 $replaced .= $char;
788             }
789             }
790             }
791             else {
792 0         0 while (defined(my $char = shift @char)) {
793 0 0       0 if (exists $tr{$char}) {
794 0         0 $replaced .= $tr{$char};
795 0         0 $tr++;
796 0 0       0 if ($modifier =~ /s/oxms) {
797 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
798 0         0 shift @char;
799 0         0 $tr++;
800             }
801             }
802             }
803             else {
804 0         0 $replaced .= $char;
805             }
806             }
807             }
808              
809 0 0       0 if ($modifier =~ /r/oxms) {
810 0         0 return $replaced;
811             }
812             else {
813 0         0 $_[0] = $replaced;
814 0 0       0 if ($bind_operator =~ / !~ /oxms) {
815 0         0 return not $tr;
816             }
817             else {
818 0         0 return $tr;
819             }
820             }
821             }
822              
823             #
824             # KOI8-U chop
825             #
826             sub Ekoi8u::chop(@) {
827              
828 0     0 0 0 my $chop;
829 0 0       0 if (@_ == 0) {
830 0         0 my @char = /\G (?>$q_char) /oxmsg;
831 0         0 $chop = pop @char;
832 0         0 $_ = join '', @char;
833             }
834             else {
835 0         0 for (@_) {
836 0         0 my @char = /\G (?>$q_char) /oxmsg;
837 0         0 $chop = pop @char;
838 0         0 $_ = join '', @char;
839             }
840             }
841 0         0 return $chop;
842             }
843              
844             #
845             # KOI8-U index by octet
846             #
847             sub Ekoi8u::index($$;$) {
848              
849 0     0 1 0 my($str,$substr,$position) = @_;
850 0   0     0 $position ||= 0;
851 0         0 my $pos = 0;
852              
853 0         0 while ($pos < CORE::length($str)) {
854 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
855 0 0       0 if ($pos >= $position) {
856 0         0 return $pos;
857             }
858             }
859 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
860 0         0 $pos += CORE::length($1);
861             }
862             else {
863 0         0 $pos += 1;
864             }
865             }
866 0         0 return -1;
867             }
868              
869             #
870             # KOI8-U reverse index
871             #
872             sub Ekoi8u::rindex($$;$) {
873              
874 0     0 0 0 my($str,$substr,$position) = @_;
875 0   0     0 $position ||= CORE::length($str) - 1;
876 0         0 my $pos = 0;
877 0         0 my $rindex = -1;
878              
879 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
880 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
881 0         0 $rindex = $pos;
882             }
883 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
884 0         0 $pos += CORE::length($1);
885             }
886             else {
887 0         0 $pos += 1;
888             }
889             }
890 0         0 return $rindex;
891             }
892              
893             #
894             # KOI8-U lower case first with parameter
895             #
896             sub Ekoi8u::lcfirst(@) {
897 0 0   0 0 0 if (@_) {
898 0         0 my $s = shift @_;
899 0 0 0     0 if (@_ and wantarray) {
900 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
901             }
902             else {
903 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
904             }
905             }
906             else {
907 0         0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
908             }
909             }
910              
911             #
912             # KOI8-U lower case first without parameter
913             #
914             sub Ekoi8u::lcfirst_() {
915 0     0 0 0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
916             }
917              
918             #
919             # KOI8-U lower case with parameter
920             #
921             sub Ekoi8u::lc(@) {
922 0 0   0 0 0 if (@_) {
923 0         0 my $s = shift @_;
924 0 0 0     0 if (@_ and wantarray) {
925 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
926             }
927             else {
928 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
929             }
930             }
931             else {
932 0         0 return Ekoi8u::lc_();
933             }
934             }
935              
936             #
937             # KOI8-U lower case without parameter
938             #
939             sub Ekoi8u::lc_() {
940 0     0 0 0 my $s = $_;
941 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
942             }
943              
944             #
945             # KOI8-U upper case first with parameter
946             #
947             sub Ekoi8u::ucfirst(@) {
948 0 0   0 0 0 if (@_) {
949 0         0 my $s = shift @_;
950 0 0 0     0 if (@_ and wantarray) {
951 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
952             }
953             else {
954 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
955             }
956             }
957             else {
958 0         0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
959             }
960             }
961              
962             #
963             # KOI8-U upper case first without parameter
964             #
965             sub Ekoi8u::ucfirst_() {
966 0     0 0 0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
967             }
968              
969             #
970             # KOI8-U upper case with parameter
971             #
972             sub Ekoi8u::uc(@) {
973 174 50   174 0 243 if (@_) {
974 174         165 my $s = shift @_;
975 174 50 33     347 if (@_ and wantarray) {
976 0 0       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
977             }
978             else {
979 174 100       557 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         589  
980             }
981             }
982             else {
983 0         0 return Ekoi8u::uc_();
984             }
985             }
986              
987             #
988             # KOI8-U upper case without parameter
989             #
990             sub Ekoi8u::uc_() {
991 0     0 0 0 my $s = $_;
992 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
993             }
994              
995             #
996             # KOI8-U fold case with parameter
997             #
998             sub Ekoi8u::fc(@) {
999 197 50   197 0 247 if (@_) {
1000 197         167 my $s = shift @_;
1001 197 50 33     360 if (@_ and wantarray) {
1002 0 0       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1003             }
1004             else {
1005 197 100       442 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         1063  
1006             }
1007             }
1008             else {
1009 0         0 return Ekoi8u::fc_();
1010             }
1011             }
1012              
1013             #
1014             # KOI8-U fold case without parameter
1015             #
1016             sub Ekoi8u::fc_() {
1017 0     0 0 0 my $s = $_;
1018 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1019             }
1020              
1021             #
1022             # KOI8-U regexp capture
1023             #
1024             {
1025             sub Ekoi8u::capture {
1026 0     0 1 0 return $_[0];
1027             }
1028             }
1029              
1030             #
1031             # KOI8-U regexp ignore case modifier
1032             #
1033             sub Ekoi8u::ignorecase {
1034              
1035 0     0 0 0 my @string = @_;
1036 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1037              
1038             # ignore case of $scalar or @array
1039 0         0 for my $string (@string) {
1040              
1041             # split regexp
1042 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1043              
1044             # unescape character
1045 0         0 for (my $i=0; $i <= $#char; $i++) {
1046 0 0       0 next if not defined $char[$i];
1047              
1048             # open character class [...]
1049 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1050 0         0 my $left = $i;
1051              
1052             # [] make die "unmatched [] in regexp ...\n"
1053              
1054 0 0       0 if ($char[$i+1] eq ']') {
1055 0         0 $i++;
1056             }
1057              
1058 0         0 while (1) {
1059 0 0       0 if (++$i > $#char) {
1060 0         0 croak "Unmatched [] in regexp";
1061             }
1062 0 0       0 if ($char[$i] eq ']') {
1063 0         0 my $right = $i;
1064 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1065              
1066             # escape character
1067 0         0 for my $char (@charlist) {
1068 0 0       0 if (0) {
1069             }
1070              
1071 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1072 0         0 $char = '\\' . $char;
1073             }
1074             }
1075              
1076             # [...]
1077 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1078              
1079 0         0 $i = $left;
1080 0         0 last;
1081             }
1082             }
1083             }
1084              
1085             # open character class [^...]
1086             elsif ($char[$i] eq '[^') {
1087 0         0 my $left = $i;
1088              
1089             # [^] make die "unmatched [] in regexp ...\n"
1090              
1091 0 0       0 if ($char[$i+1] eq ']') {
1092 0         0 $i++;
1093             }
1094              
1095 0         0 while (1) {
1096 0 0       0 if (++$i > $#char) {
1097 0         0 croak "Unmatched [] in regexp";
1098             }
1099 0 0       0 if ($char[$i] eq ']') {
1100 0         0 my $right = $i;
1101 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1102              
1103             # escape character
1104 0         0 for my $char (@charlist) {
1105 0 0       0 if (0) {
1106             }
1107              
1108 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1109 0         0 $char = '\\' . $char;
1110             }
1111             }
1112              
1113             # [^...]
1114 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1115              
1116 0         0 $i = $left;
1117 0         0 last;
1118             }
1119             }
1120             }
1121              
1122             # rewrite classic character class or escape character
1123             elsif (my $char = classic_character_class($char[$i])) {
1124 0         0 $char[$i] = $char;
1125             }
1126              
1127             # with /i modifier
1128             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1129 0         0 my $uc = Ekoi8u::uc($char[$i]);
1130 0         0 my $fc = Ekoi8u::fc($char[$i]);
1131 0 0       0 if ($uc ne $fc) {
1132 0 0       0 if (CORE::length($fc) == 1) {
1133 0         0 $char[$i] = '[' . $uc . $fc . ']';
1134             }
1135             else {
1136 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1137             }
1138             }
1139             }
1140             }
1141              
1142             # characterize
1143 0         0 for (my $i=0; $i <= $#char; $i++) {
1144 0 0       0 next if not defined $char[$i];
1145              
1146 0 0       0 if (0) {
1147             }
1148              
1149             # quote character before ? + * {
1150 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1151 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1152 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1153             }
1154             }
1155             }
1156              
1157 0         0 $string = join '', @char;
1158             }
1159              
1160             # make regexp string
1161 0         0 return @string;
1162             }
1163              
1164             #
1165             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1166             #
1167             sub Ekoi8u::classic_character_class {
1168 1862     1862 0 1789 my($char) = @_;
1169              
1170             return {
1171             '\D' => '${Ekoi8u::eD}',
1172             '\S' => '${Ekoi8u::eS}',
1173             '\W' => '${Ekoi8u::eW}',
1174             '\d' => '[0-9]',
1175              
1176             # Before Perl 5.6, \s only matched the five whitespace characters
1177             # tab, newline, form-feed, carriage return, and the space character
1178             # itself, which, taken together, is the character class [\t\n\f\r ].
1179              
1180             # Vertical tabs are now whitespace
1181             # \s in a regex now matches a vertical tab in all circumstances.
1182             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1183             # \t \n \v \f \r space
1184             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1185             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1186             '\s' => '\s',
1187              
1188             '\w' => '[0-9A-Z_a-z]',
1189             '\C' => '[\x00-\xFF]',
1190             '\X' => 'X',
1191              
1192             # \h \v \H \V
1193              
1194             # P.114 Character Class Shortcuts
1195             # in Chapter 7: In the World of Regular Expressions
1196             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1197              
1198             # P.357 13.2.3 Whitespace
1199             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1200             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1201             #
1202             # 0x00009 CHARACTER TABULATION h s
1203             # 0x0000a LINE FEED (LF) vs
1204             # 0x0000b LINE TABULATION v
1205             # 0x0000c FORM FEED (FF) vs
1206             # 0x0000d CARRIAGE RETURN (CR) vs
1207             # 0x00020 SPACE h s
1208              
1209             # P.196 Table 5-9. Alphanumeric regex metasymbols
1210             # in Chapter 5. Pattern Matching
1211             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1212              
1213             # (and so on)
1214              
1215             '\H' => '${Ekoi8u::eH}',
1216             '\V' => '${Ekoi8u::eV}',
1217             '\h' => '[\x09\x20]',
1218             '\v' => '[\x0A\x0B\x0C\x0D]',
1219             '\R' => '${Ekoi8u::eR}',
1220              
1221             # \N
1222             #
1223             # http://perldoc.perl.org/perlre.html
1224             # Character Classes and other Special Escapes
1225             # Any character but \n (experimental). Not affected by /s modifier
1226              
1227             '\N' => '${Ekoi8u::eN}',
1228              
1229             # \b \B
1230              
1231             # P.180 Boundaries: The \b and \B Assertions
1232             # in Chapter 5: Pattern Matching
1233             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1234              
1235             # P.219 Boundaries: The \b and \B Assertions
1236             # in Chapter 5: Pattern Matching
1237             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1238              
1239             # \b really means (?:(?<=\w)(?!\w)|(?
1240             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1241             '\b' => '${Ekoi8u::eb}',
1242              
1243             # \B really means (?:(?<=\w)(?=\w)|(?
1244             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1245             '\B' => '${Ekoi8u::eB}',
1246              
1247 1862   100     81758 }->{$char} || '';
1248             }
1249              
1250             #
1251             # prepare KOI8-U characters per length
1252             #
1253              
1254             # 1 octet characters
1255             my @chars1 = ();
1256             sub chars1 {
1257 0 0   0 0 0 if (@chars1) {
1258 0         0 return @chars1;
1259             }
1260 0 0       0 if (exists $range_tr{1}) {
1261 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1262 0         0 while (my @range = splice(@ranges,0,1)) {
1263 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1264 0         0 push @chars1, pack 'C', $oct0;
1265             }
1266             }
1267             }
1268 0         0 return @chars1;
1269             }
1270              
1271             # 2 octets characters
1272             my @chars2 = ();
1273             sub chars2 {
1274 0 0   0 0 0 if (@chars2) {
1275 0         0 return @chars2;
1276             }
1277 0 0       0 if (exists $range_tr{2}) {
1278 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1279 0         0 while (my @range = splice(@ranges,0,2)) {
1280 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1281 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1282 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1283             }
1284             }
1285             }
1286             }
1287 0         0 return @chars2;
1288             }
1289              
1290             # 3 octets characters
1291             my @chars3 = ();
1292             sub chars3 {
1293 0 0   0 0 0 if (@chars3) {
1294 0         0 return @chars3;
1295             }
1296 0 0       0 if (exists $range_tr{3}) {
1297 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1298 0         0 while (my @range = splice(@ranges,0,3)) {
1299 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1300 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1301 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1302 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1303             }
1304             }
1305             }
1306             }
1307             }
1308 0         0 return @chars3;
1309             }
1310              
1311             # 4 octets characters
1312             my @chars4 = ();
1313             sub chars4 {
1314 0 0   0 0 0 if (@chars4) {
1315 0         0 return @chars4;
1316             }
1317 0 0       0 if (exists $range_tr{4}) {
1318 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1319 0         0 while (my @range = splice(@ranges,0,4)) {
1320 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1321 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1322 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1323 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1324 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1325             }
1326             }
1327             }
1328             }
1329             }
1330             }
1331 0         0 return @chars4;
1332             }
1333              
1334             #
1335             # KOI8-U open character list for tr
1336             #
1337             sub _charlist_tr {
1338              
1339 0     0   0 local $_ = shift @_;
1340              
1341             # unescape character
1342 0         0 my @char = ();
1343 0         0 while (not /\G \z/oxmsgc) {
1344 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1345 0         0 push @char, '\-';
1346             }
1347             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1348 0         0 push @char, CORE::chr(oct $1);
1349             }
1350             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1351 0         0 push @char, CORE::chr(hex $1);
1352             }
1353             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1354 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1355             }
1356             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1357             push @char, {
1358             '\0' => "\0",
1359             '\n' => "\n",
1360             '\r' => "\r",
1361             '\t' => "\t",
1362             '\f' => "\f",
1363             '\b' => "\x08", # \b means backspace in character class
1364             '\a' => "\a",
1365             '\e' => "\e",
1366 0         0 }->{$1};
1367             }
1368             elsif (/\G \\ ($q_char) /oxmsgc) {
1369 0         0 push @char, $1;
1370             }
1371             elsif (/\G ($q_char) /oxmsgc) {
1372 0         0 push @char, $1;
1373             }
1374             }
1375              
1376             # join separated multiple-octet
1377 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1378              
1379             # unescape '-'
1380 0         0 my @i = ();
1381 0         0 for my $i (0 .. $#char) {
1382 0 0       0 if ($char[$i] eq '\-') {
    0          
1383 0         0 $char[$i] = '-';
1384             }
1385             elsif ($char[$i] eq '-') {
1386 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1387 0         0 push @i, $i;
1388             }
1389             }
1390             }
1391              
1392             # open character list (reverse for splice)
1393 0         0 for my $i (CORE::reverse @i) {
1394 0         0 my @range = ();
1395              
1396             # range error
1397 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1398 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1399             }
1400              
1401             # range of multiple-octet code
1402 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1403 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1404 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1405             }
1406             elsif (CORE::length($char[$i+1]) == 2) {
1407 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1408 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1409             }
1410             elsif (CORE::length($char[$i+1]) == 3) {
1411 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1412 0         0 push @range, chars2();
1413 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1414             }
1415             elsif (CORE::length($char[$i+1]) == 4) {
1416 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1417 0         0 push @range, chars2();
1418 0         0 push @range, chars3();
1419 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1420             }
1421             else {
1422 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1423             }
1424             }
1425             elsif (CORE::length($char[$i-1]) == 2) {
1426 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1427 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1428             }
1429             elsif (CORE::length($char[$i+1]) == 3) {
1430 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1431 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1432             }
1433             elsif (CORE::length($char[$i+1]) == 4) {
1434 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1435 0         0 push @range, chars3();
1436 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1437             }
1438             else {
1439 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1440             }
1441             }
1442             elsif (CORE::length($char[$i-1]) == 3) {
1443 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1444 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1445             }
1446             elsif (CORE::length($char[$i+1]) == 4) {
1447 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1448 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1449             }
1450             else {
1451 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1452             }
1453             }
1454             elsif (CORE::length($char[$i-1]) == 4) {
1455 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1456 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1457             }
1458             else {
1459 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1460             }
1461             }
1462             else {
1463 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1464             }
1465              
1466 0         0 splice @char, $i-1, 3, @range;
1467             }
1468              
1469 0         0 return @char;
1470             }
1471              
1472             #
1473             # KOI8-U open character class
1474             #
1475             sub _cc {
1476 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1477 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1478             }
1479             elsif (scalar(@_) == 1) {
1480 0         0 return sprintf('\x%02X',$_[0]);
1481             }
1482             elsif (scalar(@_) == 2) {
1483 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1484 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1485             }
1486             elsif ($_[0] == $_[1]) {
1487 0         0 return sprintf('\x%02X',$_[0]);
1488             }
1489             elsif (($_[0]+1) == $_[1]) {
1490 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1491             }
1492             else {
1493 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1494             }
1495             }
1496             else {
1497 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1498             }
1499             }
1500              
1501             #
1502             # KOI8-U octet range
1503             #
1504             sub _octets {
1505 182     182   312 my $length = shift @_;
1506              
1507 182 50       552 if ($length == 1) {
1508 182         597 my($a1) = unpack 'C', $_[0];
1509 182         394 my($z1) = unpack 'C', $_[1];
1510              
1511 182 50       394 if ($a1 > $z1) {
1512 0         0 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1513             }
1514              
1515 182 50       540 if ($a1 == $z1) {
    50          
1516 0         0 return sprintf('\x%02X',$a1);
1517             }
1518             elsif (($a1+1) == $z1) {
1519 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1520             }
1521             else {
1522 182         1430 return sprintf('\x%02X-\x%02X',$a1,$z1);
1523             }
1524             }
1525             else {
1526 0         0 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1527             }
1528             }
1529              
1530             #
1531             # KOI8-U range regexp
1532             #
1533             sub _range_regexp {
1534 182     182   309 my($length,$first,$last) = @_;
1535              
1536 182         244 my @range_regexp = ();
1537 182 50       541 if (not exists $range_tr{$length}) {
1538 0         0 return @range_regexp;
1539             }
1540              
1541 182         188 my @ranges = @{ $range_tr{$length} };
  182         512  
1542 182         719 while (my @range = splice(@ranges,0,$length)) {
1543 182         236 my $min = '';
1544 182         199 my $max = '';
1545 182         499 for (my $i=0; $i < $length; $i++) {
1546 182         821 $min .= pack 'C', $range[$i][0];
1547 182         573 $max .= pack 'C', $range[$i][-1];
1548             }
1549              
1550             # min___max
1551             # FIRST_____________LAST
1552             # (nothing)
1553              
1554 182 50 33     2568 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1555             }
1556              
1557             # **********
1558             # min_________max
1559             # FIRST_____________LAST
1560             # **********
1561              
1562             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1563 0         0 push @range_regexp, _octets($length,$first,$max,$min,$max);
1564             }
1565              
1566             # **********************
1567             # min________________max
1568             # FIRST_____________LAST
1569             # **********************
1570              
1571             elsif (($min eq $first) and ($max eq $last)) {
1572 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1573             }
1574              
1575             # *********
1576             # min___max
1577             # FIRST_____________LAST
1578             # *********
1579              
1580             elsif (($first le $min) and ($max le $last)) {
1581 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1582             }
1583              
1584             # **********************
1585             # min__________________________max
1586             # FIRST_____________LAST
1587             # **********************
1588              
1589             elsif (($min le $first) and ($last le $max)) {
1590 182         488 push @range_regexp, _octets($length,$first,$last,$min,$max);
1591             }
1592              
1593             # *********
1594             # min________max
1595             # FIRST_____________LAST
1596             # *********
1597              
1598             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1599 0         0 push @range_regexp, _octets($length,$min,$last,$min,$max);
1600             }
1601              
1602             # min___max
1603             # FIRST_____________LAST
1604             # (nothing)
1605              
1606             elsif ($last lt $min) {
1607             }
1608              
1609             else {
1610 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1611             }
1612             }
1613              
1614 182         400 return @range_regexp;
1615             }
1616              
1617             #
1618             # KOI8-U open character list for qr and not qr
1619             #
1620             sub _charlist {
1621              
1622 358     358   558 my $modifier = pop @_;
1623 358         744 my @char = @_;
1624              
1625 358 100       869 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1626              
1627             # unescape character
1628 358         1146 for (my $i=0; $i <= $#char; $i++) {
1629              
1630             # escape - to ...
1631 1125 100 100     10672 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1632 206 100 100     1036 if ((0 < $i) and ($i < $#char)) {
1633 182         453 $char[$i] = '...';
1634             }
1635             }
1636              
1637             # octal escape sequence
1638             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1639 0         0 $char[$i] = octchr($1);
1640             }
1641              
1642             # hexadecimal escape sequence
1643             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1644 0         0 $char[$i] = hexchr($1);
1645             }
1646              
1647             # \b{...} --> b\{...}
1648             # \B{...} --> B\{...}
1649             # \N{CHARNAME} --> N\{CHARNAME}
1650             # \p{PROPERTY} --> p\{PROPERTY}
1651             # \P{PROPERTY} --> P\{PROPERTY}
1652             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1653 0         0 $char[$i] = $1 . '\\' . $2;
1654             }
1655              
1656             # \p, \P, \X --> p, P, X
1657             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1658 0         0 $char[$i] = $1;
1659             }
1660              
1661             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1662 0         0 $char[$i] = CORE::chr oct $1;
1663             }
1664             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1665 22         133 $char[$i] = CORE::chr hex $1;
1666             }
1667             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1668 0         0 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1669             }
1670             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1671             $char[$i] = {
1672             '\0' => "\0",
1673             '\n' => "\n",
1674             '\r' => "\r",
1675             '\t' => "\t",
1676             '\f' => "\f",
1677             '\b' => "\x08", # \b means backspace in character class
1678             '\a' => "\a",
1679             '\e' => "\e",
1680             '\d' => '[0-9]',
1681              
1682             # Vertical tabs are now whitespace
1683             # \s in a regex now matches a vertical tab in all circumstances.
1684             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1685             # \t \n \v \f \r space
1686             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1687             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1688             '\s' => '\s',
1689              
1690             '\w' => '[0-9A-Z_a-z]',
1691             '\D' => '${Ekoi8u::eD}',
1692             '\S' => '${Ekoi8u::eS}',
1693             '\W' => '${Ekoi8u::eW}',
1694              
1695             '\H' => '${Ekoi8u::eH}',
1696             '\V' => '${Ekoi8u::eV}',
1697             '\h' => '[\x09\x20]',
1698             '\v' => '[\x0A\x0B\x0C\x0D]',
1699             '\R' => '${Ekoi8u::eR}',
1700              
1701 25         453 }->{$1};
1702             }
1703              
1704             # POSIX-style character classes
1705             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1706             $char[$i] = {
1707              
1708             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1709             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1710             '[:^lower:]' => '${Ekoi8u::not_lower_i}',
1711             '[:^upper:]' => '${Ekoi8u::not_upper_i}',
1712              
1713 8         56 }->{$1};
1714             }
1715             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1716             $char[$i] = {
1717              
1718             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1719             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1720             '[:ascii:]' => '[\x00-\x7F]',
1721             '[:blank:]' => '[\x09\x20]',
1722             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1723             '[:digit:]' => '[\x30-\x39]',
1724             '[:graph:]' => '[\x21-\x7F]',
1725             '[:lower:]' => '[\x61-\x7A]',
1726             '[:print:]' => '[\x20-\x7F]',
1727             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1728              
1729             # P.174 POSIX-Style Character Classes
1730             # in Chapter 5: Pattern Matching
1731             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1732              
1733             # P.311 11.2.4 Character Classes and other Special Escapes
1734             # in Chapter 11: perlre: Perl regular expressions
1735             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1736              
1737             # P.210 POSIX-Style Character Classes
1738             # in Chapter 5: Pattern Matching
1739             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1740              
1741             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1742              
1743             '[:upper:]' => '[\x41-\x5A]',
1744             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1745             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1746             '[:^alnum:]' => '${Ekoi8u::not_alnum}',
1747             '[:^alpha:]' => '${Ekoi8u::not_alpha}',
1748             '[:^ascii:]' => '${Ekoi8u::not_ascii}',
1749             '[:^blank:]' => '${Ekoi8u::not_blank}',
1750             '[:^cntrl:]' => '${Ekoi8u::not_cntrl}',
1751             '[:^digit:]' => '${Ekoi8u::not_digit}',
1752             '[:^graph:]' => '${Ekoi8u::not_graph}',
1753             '[:^lower:]' => '${Ekoi8u::not_lower}',
1754             '[:^print:]' => '${Ekoi8u::not_print}',
1755             '[:^punct:]' => '${Ekoi8u::not_punct}',
1756             '[:^space:]' => '${Ekoi8u::not_space}',
1757             '[:^upper:]' => '${Ekoi8u::not_upper}',
1758             '[:^word:]' => '${Ekoi8u::not_word}',
1759             '[:^xdigit:]' => '${Ekoi8u::not_xdigit}',
1760              
1761 70         1874 }->{$1};
1762             }
1763             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1764 7         30 $char[$i] = $1;
1765             }
1766             }
1767              
1768             # open character list
1769 358         639 my @singleoctet = ();
1770 358         529 my @multipleoctet = ();
1771 358         940 for (my $i=0; $i <= $#char; ) {
1772              
1773             # escaped -
1774 943 100 100     4882 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1775 182         199 $i += 1;
1776 182         378 next;
1777             }
1778              
1779             # make range regexp
1780             elsif ($char[$i] eq '...') {
1781              
1782             # range error
1783 182 50       913 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1784 0         0 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1785             }
1786             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1787 182 50       556 if ($char[$i-1] gt $char[$i+1]) {
1788 0         0 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1789             }
1790             }
1791              
1792             # make range regexp per length
1793 182         789 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1794 182         253 my @regexp = ();
1795              
1796             # is first and last
1797 182 50 33     940 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1798 182         634 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1799             }
1800              
1801             # is first
1802             elsif ($length == CORE::length($char[$i-1])) {
1803 0         0 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1804             }
1805              
1806             # is inside in first and last
1807             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1808 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1809             }
1810              
1811             # is last
1812             elsif ($length == CORE::length($char[$i+1])) {
1813 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1814             }
1815              
1816             else {
1817 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1818             }
1819              
1820 182 50       442 if ($length == 1) {
1821 182         419 push @singleoctet, @regexp;
1822             }
1823             else {
1824 0         0 push @multipleoctet, @regexp;
1825             }
1826             }
1827              
1828 182         434 $i += 2;
1829             }
1830              
1831             # with /i modifier
1832             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1833 493 100       606 if ($modifier =~ /i/oxms) {
1834 24         50 my $uc = Ekoi8u::uc($char[$i]);
1835 24         49 my $fc = Ekoi8u::fc($char[$i]);
1836 24 100       38 if ($uc ne $fc) {
1837 12 50       28 if (CORE::length($fc) == 1) {
1838 12         21 push @singleoctet, $uc, $fc;
1839             }
1840             else {
1841 0         0 push @singleoctet, $uc;
1842 0         0 push @multipleoctet, $fc;
1843             }
1844             }
1845             else {
1846 12         20 push @singleoctet, $char[$i];
1847             }
1848             }
1849             else {
1850 469         586 push @singleoctet, $char[$i];
1851             }
1852 493         739 $i += 1;
1853             }
1854              
1855             # single character of single octet code
1856             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1857 0         0 push @singleoctet, "\t", "\x20";
1858 0         0 $i += 1;
1859             }
1860             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1861 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1862 0         0 $i += 1;
1863             }
1864             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1865 2         6 push @singleoctet, $char[$i];
1866 2         8 $i += 1;
1867             }
1868              
1869             # single character of multiple-octet code
1870             else {
1871 84         152 push @multipleoctet, $char[$i];
1872 84         210 $i += 1;
1873             }
1874             }
1875              
1876             # quote metachar
1877 358         736 for (@singleoctet) {
1878 689 50       3707 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1879 0         0 $_ = '-';
1880             }
1881             elsif (/\A \n \z/oxms) {
1882 8         17 $_ = '\n';
1883             }
1884             elsif (/\A \r \z/oxms) {
1885 8         15 $_ = '\r';
1886             }
1887             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1888 60         187 $_ = sprintf('\x%02X', CORE::ord $1);
1889             }
1890             elsif (/\A [\x00-\xFF] \z/oxms) {
1891 429         500 $_ = quotemeta $_;
1892             }
1893             }
1894              
1895             # return character list
1896 358         1113 return \@singleoctet, \@multipleoctet;
1897             }
1898              
1899             #
1900             # KOI8-U octal escape sequence
1901             #
1902             sub octchr {
1903 5     5 0 10 my($octdigit) = @_;
1904              
1905 5         7 my @binary = ();
1906 5         19 for my $octal (split(//,$octdigit)) {
1907             push @binary, {
1908             '0' => '000',
1909             '1' => '001',
1910             '2' => '010',
1911             '3' => '011',
1912             '4' => '100',
1913             '5' => '101',
1914             '6' => '110',
1915             '7' => '111',
1916 50         172 }->{$octal};
1917             }
1918 5         15 my $binary = join '', @binary;
1919              
1920             my $octchr = {
1921             # 1234567
1922             1 => pack('B*', "0000000$binary"),
1923             2 => pack('B*', "000000$binary"),
1924             3 => pack('B*', "00000$binary"),
1925             4 => pack('B*', "0000$binary"),
1926             5 => pack('B*', "000$binary"),
1927             6 => pack('B*', "00$binary"),
1928             7 => pack('B*', "0$binary"),
1929             0 => pack('B*', "$binary"),
1930              
1931 5         68 }->{CORE::length($binary) % 8};
1932              
1933 5         20 return $octchr;
1934             }
1935              
1936             #
1937             # KOI8-U hexadecimal escape sequence
1938             #
1939             sub hexchr {
1940 5     5 0 13 my($hexdigit) = @_;
1941              
1942             my $hexchr = {
1943             1 => pack('H*', "0$hexdigit"),
1944             0 => pack('H*', "$hexdigit"),
1945              
1946 5         59 }->{CORE::length($_[0]) % 2};
1947              
1948 5         19 return $hexchr;
1949             }
1950              
1951             #
1952             # KOI8-U open character list for qr
1953             #
1954             sub charlist_qr {
1955              
1956 314     314 0 586 my $modifier = pop @_;
1957 314         882 my @char = @_;
1958              
1959 314         859 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1960 314         641 my @singleoctet = @$singleoctet;
1961 314         488 my @multipleoctet = @$multipleoctet;
1962              
1963             # return character list
1964 314 100       777 if (scalar(@singleoctet) >= 1) {
1965              
1966             # with /i modifier
1967 236 100       526 if ($modifier =~ m/i/oxms) {
1968 22         38 my %singleoctet_ignorecase = ();
1969 22         39 for (@singleoctet) {
1970 46   100     222 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1971 46         138 for my $ord (hex($1) .. hex($2)) {
1972 66         88 my $char = CORE::chr($ord);
1973 66         94 my $uc = Ekoi8u::uc($char);
1974 66         97 my $fc = Ekoi8u::fc($char);
1975 66 100       103 if ($uc eq $fc) {
1976 12         101 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1977             }
1978             else {
1979 54 50       76 if (CORE::length($fc) == 1) {
1980 54         125 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1981 54         234 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1982             }
1983             else {
1984 0         0 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1985 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1986             }
1987             }
1988             }
1989             }
1990 46 50       93 if ($_ ne '') {
1991 0         0 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1992             }
1993             }
1994 22         52 my $i = 0;
1995 22         40 my @singleoctet_ignorecase = ();
1996 22         39 for my $ord (0 .. 255) {
1997 5632 100       5801 if (exists $singleoctet_ignorecase{$ord}) {
1998 96         94 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         202  
1999             }
2000             else {
2001 5536         4191 $i++;
2002             }
2003             }
2004 22         46 @singleoctet = ();
2005 22         65 for my $range (@singleoctet_ignorecase) {
2006 3648 100       5625 if (ref $range) {
2007 56 100       47 if (scalar(@{$range}) == 1) {
  56 50       87  
2008 36         30 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         122  
2009             }
2010 20         33 elsif (scalar(@{$range}) == 2) {
2011 0         0 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2012             }
2013             else {
2014 20         20 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         26  
  20         111  
2015             }
2016             }
2017             }
2018             }
2019              
2020 236         329 my $not_anchor = '';
2021              
2022 236         678 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2023             }
2024 314 100       667 if (scalar(@multipleoctet) >= 2) {
2025 6         30 return '(?:' . join('|', @multipleoctet) . ')';
2026             }
2027             else {
2028 308         1400 return $multipleoctet[0];
2029             }
2030             }
2031              
2032             #
2033             # KOI8-U open character list for not qr
2034             #
2035             sub charlist_not_qr {
2036              
2037 44     44 0 82 my $modifier = pop @_;
2038 44         111 my @char = @_;
2039              
2040 44         121 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2041 44         100 my @singleoctet = @$singleoctet;
2042 44         67 my @multipleoctet = @$multipleoctet;
2043              
2044             # with /i modifier
2045 44 100       122 if ($modifier =~ m/i/oxms) {
2046 10         22 my %singleoctet_ignorecase = ();
2047 10         33 for (@singleoctet) {
2048 10   66     63 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2049 10         52 for my $ord (hex($1) .. hex($2)) {
2050 30         48 my $char = CORE::chr($ord);
2051 30         54 my $uc = Ekoi8u::uc($char);
2052 30         59 my $fc = Ekoi8u::fc($char);
2053 30 50       60 if ($uc eq $fc) {
2054 0         0 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2055             }
2056             else {
2057 30 50       42 if (CORE::length($fc) == 1) {
2058 30         92 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2059 30         152 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2060             }
2061             else {
2062 0         0 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2063 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2064             }
2065             }
2066             }
2067             }
2068 10 50       31 if ($_ ne '') {
2069 0         0 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2070             }
2071             }
2072 10         12 my $i = 0;
2073 10         17 my @singleoctet_ignorecase = ();
2074 10         24 for my $ord (0 .. 255) {
2075 2560 100       2843 if (exists $singleoctet_ignorecase{$ord}) {
2076 60         49 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         122  
2077             }
2078             else {
2079 2500         2098 $i++;
2080             }
2081             }
2082 10         24 @singleoctet = ();
2083 10         33 for my $range (@singleoctet_ignorecase) {
2084 960 100       1834 if (ref $range) {
2085 20 50       17 if (scalar(@{$range}) == 1) {
  20 50       44  
2086 0         0 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2087             }
2088 20         31 elsif (scalar(@{$range}) == 2) {
2089 0         0 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2090             }
2091             else {
2092 20         26 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         26  
  20         127  
2093             }
2094             }
2095             }
2096             }
2097              
2098             # return character list
2099 44 50       124 if (scalar(@multipleoctet) >= 1) {
2100 0 0       0 if (scalar(@singleoctet) >= 1) {
2101              
2102             # any character other than multiple-octet and single octet character class
2103 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2104             }
2105             else {
2106              
2107             # any character other than multiple-octet character class
2108 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2109             }
2110             }
2111             else {
2112 44 50       98 if (scalar(@singleoctet) >= 1) {
2113              
2114             # any character other than single octet character class
2115 44         283 return '(?:[^' . join('', @singleoctet) . '])';
2116             }
2117             else {
2118              
2119             # any character
2120 0         0 return "(?:$your_char)";
2121             }
2122             }
2123             }
2124              
2125             #
2126             # open file in read mode
2127             #
2128             sub _open_r {
2129 400     400   1829 my(undef,$file) = @_;
2130 400         1242 $file =~ s#\A (\s) #./$1#oxms;
2131 400   33     34657 return CORE::eval(q{open($_[0],'<',$_[1])}) ||
2132             open($_[0],"< $file\0");
2133             }
2134              
2135             #
2136             # open file in write mode
2137             #
2138             sub _open_w {
2139 0     0   0 my(undef,$file) = @_;
2140 0         0 $file =~ s#\A (\s) #./$1#oxms;
2141 0   0     0 return CORE::eval(q{open($_[0],'>',$_[1])}) ||
2142             open($_[0],"> $file\0");
2143             }
2144              
2145             #
2146             # open file in append mode
2147             #
2148             sub _open_a {
2149 0     0   0 my(undef,$file) = @_;
2150 0         0 $file =~ s#\A (\s) #./$1#oxms;
2151 0   0     0 return CORE::eval(q{open($_[0],'>>',$_[1])}) ||
2152             open($_[0],">> $file\0");
2153             }
2154              
2155             #
2156             # safe system
2157             #
2158             sub _systemx {
2159              
2160             # P.707 29.2.33. exec
2161             # in Chapter 29: Functions
2162             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2163             #
2164             # Be aware that in older releases of Perl, 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 in the case of exec, or
2167             # misordererd output in the case of system. This situation was largely remedied
2168             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2169              
2170             # P.855 exec
2171             # in Chapter 27: Functions
2172             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2173             #
2174             # In very old release of Perl (before v5.6), exec (and system) did not flush
2175             # your output buffer, so you needed to enable command buffering by setting $|
2176             # on one or more filehandles to avoid lost output with exec or misordered
2177             # output with system.
2178              
2179 200     200   799 $| = 1;
2180              
2181             # P.565 23.1.2. Cleaning Up Your Environment
2182             # in Chapter 23: Security
2183             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2184              
2185             # P.656 Cleaning Up Your Environment
2186             # in Chapter 20: Security
2187             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2188              
2189             # local $ENV{'PATH'} = '.';
2190 200         1833 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2191              
2192             # P.707 29.2.33. exec
2193             # in Chapter 29: Functions
2194             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2195             #
2196             # As we mentioned earlier, exec treats a discrete list of arguments as an
2197             # indication that it should bypass shell processing. However, there is one
2198             # place where you might still get tripped up. The exec call (and system, too)
2199             # will not distinguish between a single scalar argument and an array containing
2200             # only one element.
2201             #
2202             # @args = ("echo surprise"); # just one element in list
2203             # exec @args # still subject to shell escapes
2204             # or die "exec: $!"; # because @args == 1
2205             #
2206             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2207             # first argument as the pathname, which forces the rest of the arguments to be
2208             # interpreted as a list, even if there is only one of them:
2209             #
2210             # exec { $args[0] } @args # safe even with one-argument list
2211             # or die "can't exec @args: $!";
2212              
2213             # P.855 exec
2214             # in Chapter 27: Functions
2215             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2216             #
2217             # As we mentioned earlier, exec treats a discrete list of arguments as a
2218             # directive to bypass shell processing. However, there is one place where
2219             # you might still get tripped up. The exec call (and system, too) cannot
2220             # distinguish between a single scalar argument and an array containing
2221             # only one element.
2222             #
2223             # @args = ("echo surprise"); # just one element in list
2224             # exec @args # still subject to shell escapes
2225             # || die "exec: $!"; # because @args == 1
2226             #
2227             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2228             # argument as the pathname, which forces the rest of the arguments to be
2229             # interpreted as a list, even if there is only one of them:
2230             #
2231             # exec { $args[0] } @args # safe even with one-argument list
2232             # || die "can't exec @args: $!";
2233              
2234 200         360 return CORE::system { $_[0] } @_; # safe even with one-argument list
  200         17227524  
2235             }
2236              
2237             #
2238             # KOI8-U order to character (with parameter)
2239             #
2240             sub Ekoi8u::chr(;$) {
2241              
2242 0 0   0 0 0 my $c = @_ ? $_[0] : $_;
2243              
2244 0 0       0 if ($c == 0x00) {
2245 0         0 return "\x00";
2246             }
2247             else {
2248 0         0 my @chr = ();
2249 0         0 while ($c > 0) {
2250 0         0 unshift @chr, ($c % 0x100);
2251 0         0 $c = int($c / 0x100);
2252             }
2253 0         0 return pack 'C*', @chr;
2254             }
2255             }
2256              
2257             #
2258             # KOI8-U order to character (without parameter)
2259             #
2260             sub Ekoi8u::chr_() {
2261              
2262 0     0 0 0 my $c = $_;
2263              
2264 0 0       0 if ($c == 0x00) {
2265 0         0 return "\x00";
2266             }
2267             else {
2268 0         0 my @chr = ();
2269 0         0 while ($c > 0) {
2270 0         0 unshift @chr, ($c % 0x100);
2271 0         0 $c = int($c / 0x100);
2272             }
2273 0         0 return pack 'C*', @chr;
2274             }
2275             }
2276              
2277             #
2278             # KOI8-U path globbing (with parameter)
2279             #
2280             sub Ekoi8u::glob($) {
2281              
2282 0 0   0 0 0 if (wantarray) {
2283 0         0 my @glob = _DOS_like_glob(@_);
2284 0         0 for my $glob (@glob) {
2285 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2286             }
2287 0         0 return @glob;
2288             }
2289             else {
2290 0         0 my $glob = _DOS_like_glob(@_);
2291 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2292 0         0 return $glob;
2293             }
2294             }
2295              
2296             #
2297             # KOI8-U path globbing (without parameter)
2298             #
2299             sub Ekoi8u::glob_() {
2300              
2301 0 0   0 0 0 if (wantarray) {
2302 0         0 my @glob = _DOS_like_glob();
2303 0         0 for my $glob (@glob) {
2304 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2305             }
2306 0         0 return @glob;
2307             }
2308             else {
2309 0         0 my $glob = _DOS_like_glob();
2310 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2311 0         0 return $glob;
2312             }
2313             }
2314              
2315             #
2316             # KOI8-U path globbing via File::DosGlob 1.10
2317             #
2318             # Often I confuse "_dosglob" and "_doglob".
2319             # So, I renamed "_dosglob" to "_DOS_like_glob".
2320             #
2321             my %iter;
2322             my %entries;
2323             sub _DOS_like_glob {
2324              
2325             # context (keyed by second cxix argument provided by core)
2326 0     0   0 my($expr,$cxix) = @_;
2327              
2328             # glob without args defaults to $_
2329 0 0       0 $expr = $_ if not defined $expr;
2330              
2331             # represents the current user's home directory
2332             #
2333             # 7.3. Expanding Tildes in Filenames
2334             # in Chapter 7. File Access
2335             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2336             #
2337             # and File::HomeDir, File::HomeDir::Windows module
2338              
2339             # DOS-like system
2340 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2341 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
2342 0         0 { my_home_MSWin32() }oxmse;
2343             }
2344              
2345             # UNIX-like system
2346             else {
2347 0         0 $expr =~ s{ \A ~ ( (?:[^/])* ) }
2348 0 0 0     0 { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2349             }
2350              
2351             # assume global context if not provided one
2352 0 0       0 $cxix = '_G_' if not defined $cxix;
2353 0 0       0 $iter{$cxix} = 0 if not exists $iter{$cxix};
2354              
2355             # if we're just beginning, do it all first
2356 0 0       0 if ($iter{$cxix} == 0) {
2357 0         0 $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2358             }
2359              
2360             # chuck it all out, quick or slow
2361 0 0       0 if (wantarray) {
2362 0         0 delete $iter{$cxix};
2363 0         0 return @{delete $entries{$cxix}};
  0         0  
2364             }
2365             else {
2366 0 0       0 if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
  0         0  
2367 0         0 return shift @{$entries{$cxix}};
  0         0  
2368             }
2369             else {
2370             # return undef for EOL
2371 0         0 delete $iter{$cxix};
2372 0         0 delete $entries{$cxix};
2373 0         0 return undef;
2374             }
2375             }
2376             }
2377              
2378             #
2379             # KOI8-U path globbing subroutine
2380             #
2381             sub _do_glob {
2382              
2383 0     0   0 my($cond,@expr) = @_;
2384 0         0 my @glob = ();
2385 0         0 my $fix_drive_relative_paths = 0;
2386              
2387             OUTER:
2388 0         0 for my $expr (@expr) {
2389 0 0       0 next OUTER if not defined $expr;
2390 0 0       0 next OUTER if $expr eq '';
2391              
2392 0         0 my @matched = ();
2393 0         0 my @globdir = ();
2394 0         0 my $head = '.';
2395 0         0 my $pathsep = '/';
2396 0         0 my $tail;
2397              
2398             # if argument is within quotes strip em and do no globbing
2399 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2400 0         0 $expr = $1;
2401 0 0       0 if ($cond eq 'd') {
2402 0 0       0 if (-d $expr) {
2403 0         0 push @glob, $expr;
2404             }
2405             }
2406             else {
2407 0 0       0 if (-e $expr) {
2408 0         0 push @glob, $expr;
2409             }
2410             }
2411 0         0 next OUTER;
2412             }
2413              
2414             # wildcards with a drive prefix such as h:*.pm must be changed
2415             # to h:./*.pm to expand correctly
2416 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2417 0 0       0 if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2418 0         0 $fix_drive_relative_paths = 1;
2419             }
2420             }
2421              
2422 0 0       0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2423 0 0       0 if ($tail eq '') {
2424 0         0 push @glob, $expr;
2425 0         0 next OUTER;
2426             }
2427 0 0       0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
2428 0 0       0 if (@globdir = _do_glob('d', $head)) {
2429 0         0 push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
  0         0  
2430 0         0 next OUTER;
2431             }
2432             }
2433 0 0 0     0 if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2434 0         0 $head .= $pathsep;
2435             }
2436 0         0 $expr = $tail;
2437             }
2438              
2439             # If file component has no wildcards, we can avoid opendir
2440 0 0       0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2441 0 0       0 if ($head eq '.') {
2442 0         0 $head = '';
2443             }
2444 0 0 0     0 if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2445 0         0 $head .= $pathsep;
2446             }
2447 0         0 $head .= $expr;
2448 0 0       0 if ($cond eq 'd') {
2449 0 0       0 if (-d $head) {
2450 0         0 push @glob, $head;
2451             }
2452             }
2453             else {
2454 0 0       0 if (-e $head) {
2455 0         0 push @glob, $head;
2456             }
2457             }
2458 0         0 next OUTER;
2459             }
2460 0 0       0 opendir(*DIR, $head) or next OUTER;
2461 0         0 my @leaf = readdir DIR;
2462 0         0 closedir DIR;
2463              
2464 0 0       0 if ($head eq '.') {
2465 0         0 $head = '';
2466             }
2467 0 0 0     0 if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2468 0         0 $head .= $pathsep;
2469             }
2470              
2471 0         0 my $pattern = '';
2472 0         0 while ($expr =~ / \G ($q_char) /oxgc) {
2473 0         0 my $char = $1;
2474              
2475             # 6.9. Matching Shell Globs as Regular Expressions
2476             # in Chapter 6. Pattern Matching
2477             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2478             # (and so on)
2479              
2480 0 0       0 if ($char eq '*') {
    0          
    0          
2481 0         0 $pattern .= "(?:$your_char)*",
2482             }
2483             elsif ($char eq '?') {
2484 0         0 $pattern .= "(?:$your_char)?", # DOS style
2485             # $pattern .= "(?:$your_char)", # UNIX style
2486             }
2487             elsif ((my $fc = Ekoi8u::fc($char)) ne $char) {
2488 0         0 $pattern .= $fc;
2489             }
2490             else {
2491 0         0 $pattern .= quotemeta $char;
2492             }
2493             }
2494 0     0   0 my $matchsub = sub { Ekoi8u::fc($_[0]) =~ /\A $pattern \z/xms };
  0         0  
2495              
2496             # if ($@) {
2497             # print STDERR "$0: $@\n";
2498             # next OUTER;
2499             # }
2500              
2501             INNER:
2502 0         0 for my $leaf (@leaf) {
2503 0 0 0     0 if ($leaf eq '.' or $leaf eq '..') {
2504 0         0 next INNER;
2505             }
2506 0 0 0     0 if ($cond eq 'd' and not -d "$head$leaf") {
2507 0         0 next INNER;
2508             }
2509              
2510 0 0       0 if (&$matchsub($leaf)) {
2511 0         0 push @matched, "$head$leaf";
2512 0         0 next INNER;
2513             }
2514              
2515             # [DOS compatibility special case]
2516             # Failed, add a trailing dot and try again, but only...
2517              
2518 0 0 0     0 if (Ekoi8u::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
      0        
2519             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2520             Ekoi8u::index($pattern,'\\.') != -1 # pattern has a dot.
2521             ) {
2522 0 0       0 if (&$matchsub("$leaf.")) {
2523 0         0 push @matched, "$head$leaf";
2524 0         0 next INNER;
2525             }
2526             }
2527             }
2528 0 0       0 if (@matched) {
2529 0         0 push @glob, @matched;
2530             }
2531             }
2532 0 0       0 if ($fix_drive_relative_paths) {
2533 0         0 for my $glob (@glob) {
2534 0         0 $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2535             }
2536             }
2537 0         0 return @glob;
2538             }
2539              
2540             #
2541             # KOI8-U parse line
2542             #
2543             sub _parse_line {
2544              
2545 0     0   0 my($line) = @_;
2546              
2547 0         0 $line .= ' ';
2548 0         0 my @piece = ();
2549 0         0 while ($line =~ /
2550             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2551             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2552             /oxmsg
2553             ) {
2554 0 0       0 push @piece, defined($1) ? $1 : $2;
2555             }
2556 0         0 return @piece;
2557             }
2558              
2559             #
2560             # KOI8-U parse path
2561             #
2562             sub _parse_path {
2563              
2564 0     0   0 my($path,$pathsep) = @_;
2565              
2566 0         0 $path .= '/';
2567 0         0 my @subpath = ();
2568 0         0 while ($path =~ /
2569             ((?: [^\/\\] )+?) [\/\\]
2570             /oxmsg
2571             ) {
2572 0         0 push @subpath, $1;
2573             }
2574              
2575 0         0 my $tail = pop @subpath;
2576 0         0 my $head = join $pathsep, @subpath;
2577 0         0 return $head, $tail;
2578             }
2579              
2580             #
2581             # via File::HomeDir::Windows 1.00
2582             #
2583             sub my_home_MSWin32 {
2584              
2585             # A lot of unix people and unix-derived tools rely on
2586             # the ability to overload HOME. We will support it too
2587             # so that they can replace raw HOME calls with File::HomeDir.
2588 0 0 0 0 0 0 if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
    0 0        
    0 0        
      0        
      0        
2589 0         0 return $ENV{'HOME'};
2590             }
2591              
2592             # Do we have a user profile?
2593             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2594 0         0 return $ENV{'USERPROFILE'};
2595             }
2596              
2597             # Some Windows use something like $ENV{'HOME'}
2598             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2599 0         0 return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2600             }
2601              
2602 0         0 return undef;
2603             }
2604              
2605             #
2606             # via File::HomeDir::Unix 1.00
2607             #
2608             sub my_home {
2609 0     0 0 0 my $home;
2610              
2611 0 0 0     0 if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
    0 0        
2612 0         0 $home = $ENV{'HOME'};
2613             }
2614              
2615             # This is from the original code, but I'm guessing
2616             # it means "login directory" and exists on some Unixes.
2617             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2618 0         0 $home = $ENV{'LOGDIR'};
2619             }
2620              
2621             ### More-desperate methods
2622              
2623             # Light desperation on any (Unixish) platform
2624             else {
2625 0         0 $home = CORE::eval q{ (getpwuid($<))[7] };
2626             }
2627              
2628             # On Unix in general, a non-existant home means "no home"
2629             # For example, "nobody"-like users might use /nonexistant
2630 0 0 0     0 if (defined $home and ! -d($home)) {
2631 0         0 $home = undef;
2632             }
2633 0         0 return $home;
2634             }
2635              
2636             #
2637             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2638             #
2639             sub Ekoi8u::PREMATCH {
2640 0     0 0 0 return $`;
2641             }
2642              
2643             #
2644             # ${^MATCH}, $MATCH, $& the string that matched
2645             #
2646             sub Ekoi8u::MATCH {
2647 0     0 0 0 return $&;
2648             }
2649              
2650             #
2651             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2652             #
2653             sub Ekoi8u::POSTMATCH {
2654 0     0 0 0 return $';
2655             }
2656              
2657             #
2658             # KOI8-U character to order (with parameter)
2659             #
2660             sub KOI8U::ord(;$) {
2661              
2662 0 0   0 1 0 local $_ = shift if @_;
2663              
2664 0 0       0 if (/\A ($q_char) /oxms) {
2665 0         0 my @ord = unpack 'C*', $1;
2666 0         0 my $ord = 0;
2667 0         0 while (my $o = shift @ord) {
2668 0         0 $ord = $ord * 0x100 + $o;
2669             }
2670 0         0 return $ord;
2671             }
2672             else {
2673 0         0 return CORE::ord $_;
2674             }
2675             }
2676              
2677             #
2678             # KOI8-U character to order (without parameter)
2679             #
2680             sub KOI8U::ord_() {
2681              
2682 0 0   0 0 0 if (/\A ($q_char) /oxms) {
2683 0         0 my @ord = unpack 'C*', $1;
2684 0         0 my $ord = 0;
2685 0         0 while (my $o = shift @ord) {
2686 0         0 $ord = $ord * 0x100 + $o;
2687             }
2688 0         0 return $ord;
2689             }
2690             else {
2691 0         0 return CORE::ord $_;
2692             }
2693             }
2694              
2695             #
2696             # KOI8-U reverse
2697             #
2698             sub KOI8U::reverse(@) {
2699              
2700 0 0   0 0 0 if (wantarray) {
2701 0         0 return CORE::reverse @_;
2702             }
2703             else {
2704              
2705             # One of us once cornered Larry in an elevator and asked him what
2706             # problem he was solving with this, but he looked as far off into
2707             # the distance as he could in an elevator and said, "It seemed like
2708             # a good idea at the time."
2709              
2710 0         0 return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2711             }
2712             }
2713              
2714             #
2715             # KOI8-U getc (with parameter, without parameter)
2716             #
2717             sub KOI8U::getc(;*@) {
2718              
2719 0     0 0 0 my($package) = caller;
2720 0 0       0 my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2721 0 0 0     0 croak 'Too many arguments for KOI8U::getc' if @_ and not wantarray;
2722              
2723 0         0 my @length = sort { $a <=> $b } keys %range_tr;
  0         0  
2724 0         0 my $getc = '';
2725 0         0 for my $length ($length[0] .. $length[-1]) {
2726 0         0 $getc .= CORE::getc($fh);
2727 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2728 0 0       0 if ($getc =~ /\A ${Ekoi8u::dot_s} \z/oxms) {
2729 0 0       0 return wantarray ? ($getc,@_) : $getc;
2730             }
2731             }
2732             }
2733 0 0       0 return wantarray ? ($getc,@_) : $getc;
2734             }
2735              
2736             #
2737             # KOI8-U length by character
2738             #
2739             sub KOI8U::length(;$) {
2740              
2741 0 0   0 1 0 local $_ = shift if @_;
2742              
2743 0         0 local @_ = /\G ($q_char) /oxmsg;
2744 0         0 return scalar @_;
2745             }
2746              
2747             #
2748             # KOI8-U substr by character
2749             #
2750             BEGIN {
2751              
2752             # P.232 The lvalue Attribute
2753             # in Chapter 6: Subroutines
2754             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2755              
2756             # P.336 The lvalue Attribute
2757             # in Chapter 7: Subroutines
2758             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2759              
2760             # P.144 8.4 Lvalue subroutines
2761             # in Chapter 8: perlsub: Perl subroutines
2762             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
2763              
2764 200 50 0 200 1 119400 CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
  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  
2765             # vv----------------------*******
2766             sub KOI8U::substr($$;$$) %s {
2767              
2768             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2769              
2770             # If the substring is beyond either end of the string, substr() returns the undefined
2771             # value and produces a warning. When used as an lvalue, specifying a substring that
2772             # is entirely outside the string raises an exception.
2773             # http://perldoc.perl.org/functions/substr.html
2774              
2775             # A return with no argument returns the scalar value undef in scalar context,
2776             # an empty list () in list context, and (naturally) nothing at all in void
2777             # context.
2778              
2779             my $offset = $_[1];
2780             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2781             return;
2782             }
2783              
2784             # substr($string,$offset,$length,$replacement)
2785             if (@_ == 4) {
2786             my(undef,undef,$length,$replacement) = @_;
2787             my $substr = join '', splice(@char, $offset, $length, $replacement);
2788             $_[0] = join '', @char;
2789              
2790             # return $substr; this doesn't work, don't say "return"
2791             $substr;
2792             }
2793              
2794             # substr($string,$offset,$length)
2795             elsif (@_ == 3) {
2796             my(undef,undef,$length) = @_;
2797             my $octet_offset = 0;
2798             my $octet_length = 0;
2799             if ($offset == 0) {
2800             $octet_offset = 0;
2801             }
2802             elsif ($offset > 0) {
2803             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2804             }
2805             else {
2806             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2807             }
2808             if ($length == 0) {
2809             $octet_length = 0;
2810             }
2811             elsif ($length > 0) {
2812             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2813             }
2814             else {
2815             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2816             }
2817             CORE::substr($_[0], $octet_offset, $octet_length);
2818             }
2819              
2820             # substr($string,$offset)
2821             else {
2822             my $octet_offset = 0;
2823             if ($offset == 0) {
2824             $octet_offset = 0;
2825             }
2826             elsif ($offset > 0) {
2827             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2828             }
2829             else {
2830             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2831             }
2832             CORE::substr($_[0], $octet_offset);
2833             }
2834             }
2835             END
2836             }
2837              
2838             #
2839             # KOI8-U index by character
2840             #
2841             sub KOI8U::index($$;$) {
2842              
2843 0     0 1 0 my $index;
2844 0 0       0 if (@_ == 3) {
2845 0         0 $index = Ekoi8u::index($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2846             }
2847             else {
2848 0         0 $index = Ekoi8u::index($_[0], $_[1]);
2849             }
2850              
2851 0 0       0 if ($index == -1) {
2852 0         0 return -1;
2853             }
2854             else {
2855 0         0 return KOI8U::length(CORE::substr $_[0], 0, $index);
2856             }
2857             }
2858              
2859             #
2860             # KOI8-U rindex by character
2861             #
2862             sub KOI8U::rindex($$;$) {
2863              
2864 0     0 1 0 my $rindex;
2865 0 0       0 if (@_ == 3) {
2866 0         0 $rindex = Ekoi8u::rindex($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2867             }
2868             else {
2869 0         0 $rindex = Ekoi8u::rindex($_[0], $_[1]);
2870             }
2871              
2872 0 0       0 if ($rindex == -1) {
2873 0         0 return -1;
2874             }
2875             else {
2876 0         0 return KOI8U::length(CORE::substr $_[0], 0, $rindex);
2877             }
2878             }
2879              
2880             # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
2881             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2882 200     200   15233 BEGIN { CORE::eval q{ use vars qw($slash) } } $slash = 'm//';
  200     200   1701  
  200         401  
  200         13206  
2883              
2884             # ord() to ord() or KOI8U::ord()
2885 200     200   12209 BEGIN { CORE::eval q{ use vars qw($function_ord) } } $function_ord = 'ord';
  200     200   1037  
  200         381  
  200         10722  
2886              
2887             # ord to ord or KOI8U::ord_
2888 200     200   11268 BEGIN { CORE::eval q{ use vars qw($function_ord_) } } $function_ord_ = 'ord';
  200     200   1040  
  200         326  
  200         10572  
2889              
2890             # reverse to reverse or KOI8U::reverse
2891 200     200   11254 BEGIN { CORE::eval q{ use vars qw($function_reverse) } } $function_reverse = 'reverse';
  200     200   1137  
  200         337  
  200         10823  
2892              
2893             # getc to getc or KOI8U::getc
2894 200     200   10343 BEGIN { CORE::eval q{ use vars qw($function_getc) } } $function_getc = 'getc';
  200     200   976  
  200         307  
  200         11566  
2895              
2896             # P.1023 Appendix W.9 Multibyte Anchoring
2897             # of ISBN 1-56592-224-7 CJKV Information Processing
2898              
2899             my $anchor = '';
2900              
2901 200     200   10882 BEGIN { CORE::eval q{ use vars qw($nest) } }
  200     200   945  
  200         313  
  200         8676011  
2902              
2903             # regexp of nested parens in qqXX
2904              
2905             # P.340 Matching Nested Constructs with Embedded Code
2906             # in Chapter 7: Perl
2907             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2908              
2909             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2910             [^\\()] |
2911             \( (?{$nest++}) |
2912             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2913             \\ [^c] |
2914             \\c[\x40-\x5F] |
2915             [\x00-\xFF]
2916             }xms;
2917              
2918             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2919             [^\\{}] |
2920             \{ (?{$nest++}) |
2921             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2922             \\ [^c] |
2923             \\c[\x40-\x5F] |
2924             [\x00-\xFF]
2925             }xms;
2926              
2927             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2928             [^\\\[\]] |
2929             \[ (?{$nest++}) |
2930             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2931             \\ [^c] |
2932             \\c[\x40-\x5F] |
2933             [\x00-\xFF]
2934             }xms;
2935              
2936             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2937             [^\\<>] |
2938             \< (?{$nest++}) |
2939             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2940             \\ [^c] |
2941             \\c[\x40-\x5F] |
2942             [\x00-\xFF]
2943             }xms;
2944              
2945             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2946             (?: ::)? (?:
2947             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2948             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2949             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2950             ))
2951             }xms;
2952              
2953             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2954             (?: ::)? (?:
2955             (?>[0-9]+) |
2956             [^a-zA-Z_0-9\[\]] |
2957             ^[A-Z] |
2958             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2959             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2960             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2961             ))
2962             }xms;
2963              
2964             my $qq_substr = qr{(?> Char::substr | KOI8U::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2965             }xms;
2966              
2967             # regexp of nested parens in qXX
2968             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2969             [^()] |
2970             \( (?{$nest++}) |
2971             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2972             [\x00-\xFF]
2973             }xms;
2974              
2975             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2976             [^\{\}] |
2977             \{ (?{$nest++}) |
2978             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2979             [\x00-\xFF]
2980             }xms;
2981              
2982             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2983             [^\[\]] |
2984             \[ (?{$nest++}) |
2985             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2986             [\x00-\xFF]
2987             }xms;
2988              
2989             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2990             [^<>] |
2991             \< (?{$nest++}) |
2992             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2993             [\x00-\xFF]
2994             }xms;
2995              
2996             my $matched = '';
2997             my $s_matched = '';
2998              
2999             my $tr_variable = ''; # variable of tr///
3000             my $sub_variable = ''; # variable of s///
3001             my $bind_operator = ''; # =~ or !~
3002              
3003             my @heredoc = (); # here document
3004             my @heredoc_delimiter = ();
3005             my $here_script = ''; # here script
3006              
3007             #
3008             # escape KOI8-U script
3009             #
3010             sub KOI8U::escape(;$) {
3011 200 50   200 0 655 local($_) = $_[0] if @_;
3012              
3013             # P.359 The Study Function
3014             # in Chapter 7: Perl
3015             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3016              
3017 200         365 study $_; # Yes, I studied study yesterday.
3018              
3019             # while all script
3020              
3021             # 6.14. Matching from Where the Last Pattern Left Off
3022             # in Chapter 6. Pattern Matching
3023             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3024             # (and so on)
3025              
3026             # one member of Tag-team
3027             #
3028             # P.128 Start of match (or end of previous match): \G
3029             # P.130 Advanced Use of \G with Perl
3030             # in Chapter 3: Overview of Regular Expression Features and Flavors
3031             # P.255 Use leading anchors
3032             # P.256 Expose ^ and \G at the front expressions
3033             # in Chapter 6: Crafting an Efficient Expression
3034             # P.315 "Tag-team" matching with /gc
3035             # in Chapter 7: Perl
3036             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3037              
3038 200         340 my $e_script = '';
3039 200         883 while (not /\G \z/oxgc) { # member
3040 71770         90580 $e_script .= KOI8U::escape_token();
3041             }
3042              
3043 200         2342 return $e_script;
3044             }
3045              
3046             #
3047             # escape KOI8-U token of script
3048             #
3049             sub KOI8U::escape_token {
3050              
3051             # \n output here document
3052              
3053 71770     71770 0 60294 my $ignore_modules = join('|', qw(
3054             utf8
3055             bytes
3056             charnames
3057             I18N::Japanese
3058             I18N::Collate
3059             I18N::JExt
3060             File::DosGlob
3061             Wild
3062             Wildcard
3063             Japanese
3064             ));
3065              
3066             # another member of Tag-team
3067             #
3068             # P.315 "Tag-team" matching with /gc
3069             # in Chapter 7: Perl
3070             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3071              
3072 71770 100 100     3948340 if (/\G ( \n ) /oxgc) { # another member (and so on)
    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          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
3073 12075         10391 my $heredoc = '';
3074 12075 100       21980 if (scalar(@heredoc_delimiter) >= 1) {
3075 150         176 $slash = 'm//';
3076              
3077 150         274 $heredoc = join '', @heredoc;
3078 150         265 @heredoc = ();
3079              
3080             # skip here document
3081 150         290 for my $heredoc_delimiter (@heredoc_delimiter) {
3082 150         1166 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3083             }
3084 150         245 @heredoc_delimiter = ();
3085              
3086 150         187 $here_script = '';
3087             }
3088 12075         36052 return "\n" . $heredoc;
3089             }
3090              
3091             # ignore space, comment
3092 17272         51008 elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3093              
3094             # if (, elsif (, unless (, while (, until (, given (, and when (
3095              
3096             # given, when
3097              
3098             # P.225 The given Statement
3099             # in Chapter 15: Smart Matching and given-when
3100             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3101              
3102             # P.133 The given Statement
3103             # in Chapter 4: Statements and Declarations
3104             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3105              
3106             elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3107 1373         1734 $slash = 'm//';
3108 1373         4703 return $1;
3109             }
3110              
3111             # scalar variable ($scalar = ...) =~ tr///;
3112             # scalar variable ($scalar = ...) =~ s///;
3113              
3114             # state
3115              
3116             # P.68 Persistent, Private Variables
3117             # in Chapter 4: Subroutines
3118             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3119              
3120             # P.160 Persistent Lexically Scoped Variables: state
3121             # in Chapter 4: Statements and Declarations
3122             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3123              
3124             # (and so on)
3125              
3126             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3127 85         186 my $e_string = e_string($1);
3128              
3129 85 50       2216 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
    50          
3130 0         0 $tr_variable = $e_string . e_string($1);
3131 0         0 $bind_operator = $2;
3132 0         0 $slash = 'm//';
3133 0         0 return '';
3134             }
3135             elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3136 0         0 $sub_variable = $e_string . e_string($1);
3137 0         0 $bind_operator = $2;
3138 0         0 $slash = 'm//';
3139 0         0 return '';
3140             }
3141             else {
3142 85         145 $slash = 'div';
3143 85         334 return $e_string;
3144             }
3145             }
3146              
3147             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
3148             elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3149 4         9 $slash = 'div';
3150 4         13 return q{Ekoi8u::PREMATCH()};
3151             }
3152              
3153             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
3154             elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3155 28         49 $slash = 'div';
3156 28         87 return q{Ekoi8u::MATCH()};
3157             }
3158              
3159             # $', ${'} --> $', ${'}
3160             elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3161 1         1 $slash = 'div';
3162 1         3 return $1;
3163             }
3164              
3165             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
3166             elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3167 3         7 $slash = 'div';
3168 3         9 return q{Ekoi8u::POSTMATCH()};
3169             }
3170              
3171             # scalar variable $scalar =~ tr///;
3172             # scalar variable $scalar =~ s///;
3173             # substr() =~ tr///;
3174             # substr() =~ s///;
3175             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3176 1604         3229 my $scalar = e_string($1);
3177              
3178 1604 100       6880 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
    100          
3179 1         11 $tr_variable = $scalar;
3180 1         3 $bind_operator = $1;
3181 1         2 $slash = 'm//';
3182 1         3 return '';
3183             }
3184             elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3185 61         112 $sub_variable = $scalar;
3186 61         146 $bind_operator = $1;
3187 61         90 $slash = 'm//';
3188 61         202 return '';
3189             }
3190             else {
3191 1542         1750 $slash = 'div';
3192 1542         4366 return $scalar;
3193             }
3194             }
3195              
3196             # end of statement
3197             elsif (/\G ( [,;] ) /oxgc) {
3198 4570         5240 $slash = 'm//';
3199              
3200             # clear tr/// variable
3201 4570         4323 $tr_variable = '';
3202              
3203             # clear s/// variable
3204 4570         3698 $sub_variable = '';
3205              
3206 4570         3643 $bind_operator = '';
3207              
3208 4570         16072 return $1;
3209             }
3210              
3211             # bareword
3212             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3213 0         0 return $1;
3214             }
3215              
3216             # $0 --> $0
3217             elsif (/\G ( \$ 0 ) /oxmsgc) {
3218 2         8 $slash = 'div';
3219 2         13 return $1;
3220             }
3221             elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3222 0         0 $slash = 'div';
3223 0         0 return $1;
3224             }
3225              
3226             # $$ --> $$
3227             elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3228 1         2 $slash = 'div';
3229 1         4 return $1;
3230             }
3231              
3232             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3233             # $1, $2, $3 --> $1, $2, $3 otherwise
3234             elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3235 4         5 $slash = 'div';
3236 4         7 return e_capture($1);
3237             }
3238             elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3239 0         0 $slash = 'div';
3240 0         0 return e_capture($1);
3241             }
3242              
3243             # $$foo[ ... ] --> $ $foo->[ ... ]
3244             elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3245 0         0 $slash = 'div';
3246 0         0 return e_capture($1.'->'.$2);
3247             }
3248              
3249             # $$foo{ ... } --> $ $foo->{ ... }
3250             elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3251 0         0 $slash = 'div';
3252 0         0 return e_capture($1.'->'.$2);
3253             }
3254              
3255             # $$foo
3256             elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3257 0         0 $slash = 'div';
3258 0         0 return e_capture($1);
3259             }
3260              
3261             # ${ foo }
3262             elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3263 0         0 $slash = 'div';
3264 0         0 return '${' . $1 . '}';
3265             }
3266              
3267             # ${ ... }
3268             elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3269 0         0 $slash = 'div';
3270 0         0 return e_capture($1);
3271             }
3272              
3273             # variable or function
3274             # $ @ % & * $ #
3275             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) {
3276 42         65 $slash = 'div';
3277 42         147 return $1;
3278             }
3279             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3280             # $ @ # \ ' " / ? ( ) [ ] < >
3281             elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3282 60         95 $slash = 'div';
3283 60         267 return $1;
3284             }
3285              
3286             # while ()
3287             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3288 0         0 return $1;
3289             }
3290              
3291             # while () --- glob
3292              
3293             # avoid "Error: Runtime exception" of perl version 5.005_03
3294              
3295             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3296 0         0 return 'while ($_ = Ekoi8u::glob("' . $1 . '"))';
3297             }
3298              
3299             # while (glob)
3300             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3301 0         0 return 'while ($_ = Ekoi8u::glob_)';
3302             }
3303              
3304             # while (glob(WILDCARD))
3305             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3306 0         0 return 'while ($_ = Ekoi8u::glob';
3307             }
3308              
3309             # doit if, doit unless, doit while, doit until, doit for, doit when
3310 241         528 elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
  241         1050  
3311              
3312             # subroutines of package Ekoi8u
3313 19         36 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  19         94  
3314 0         0 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3315 13         15 elsif (/\G \b KOI8U::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  13         37  
3316 0         0 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  0         0  
3317 114         127 elsif (/\G \b KOI8U::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval KOI8U::escape'; }
  114         330  
3318 2         4 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         6  
3319 0         0 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chop'; }
  0         0  
3320 2         4 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  2         5  
3321 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3322 0         0 elsif (/\G \b KOI8U::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::index'; }
  0         0  
3323 0         0 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::index'; }
  0         0  
3324 2         5 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  2         5  
3325 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3326 0         0 elsif (/\G \b KOI8U::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::rindex'; }
  0         0  
3327 0         0 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::rindex'; }
  0         0  
3328 1         3 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc'; }
  1         5  
3329 0         0 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst'; }
  0         0  
3330 1         3 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc'; }
  1         5  
3331 0         0 elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst'; }
  0         0  
3332 6         6 elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc'; }
  6         18  
3333              
3334             # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
3335 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3336 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3337 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3338 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3339 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3340 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3341 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  
3342              
3343 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3344 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3345 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3346 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3347 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3348 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3349 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3350              
3351             elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
3352 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3353 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3354 0         0 elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
  0         0  
3355 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  0         0  
3356              
3357 2         5 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  2         8  
3358 2         5 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         8  
3359 36         61 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr'; }
  36         134  
3360 2         6 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  2         7  
3361 8         15 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  8         32  
3362 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob'; }
  0         0  
3363 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc_'; }
  0         0  
3364 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst_'; }
  0         0  
3365 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc_'; }
  0         0  
3366 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst_'; }
  0         0  
3367 0         0 elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc_'; }
  0         0  
3368 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3369              
3370 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3371 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3372 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr_'; }
  0         0  
3373 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3374 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3375 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob_'; }
  0         0  
3376 0         0 elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
  0         0  
3377 8         20 elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
  8         36  
3378             # split
3379             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3380 87         143 $slash = 'm//';
3381              
3382 87         132 my $e = '';
3383 87         349 while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3384 85         342 $e .= $1;
3385             }
3386              
3387             # end of split
3388 87 100       7610 if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8u::split' . $e; }
  2 100       13  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3389              
3390             # split scalar value
3391 1         5 elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Ekoi8u::split' . $e . e_string($1); }
3392              
3393             # split literal space
3394 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {qq$1 $2}; }
3395 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3396 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3397 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3398 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3399 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3400 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {q$1 $2}; }
3401 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3402 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3403 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3404 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3405 0         0 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3406 10         45 elsif (/\G ' [ ] ' /oxgc) { return 'Ekoi8u::split' . $e . qq {' '}; }
3407 0         0 elsif (/\G " [ ] " /oxgc) { return 'Ekoi8u::split' . $e . qq {" "}; }
3408              
3409             # split qq//
3410             elsif (/\G \b (qq) \b /oxgc) {
3411 0 0       0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
  0         0  
3412             else {
3413 0         0 while (not /\G \z/oxgc) {
3414 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3415 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3416 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3417 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3418 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3419 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3420 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3421             }
3422 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3423             }
3424             }
3425              
3426             # split qr//
3427             elsif (/\G \b (qr) \b /oxgc) {
3428 12 50       484 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
  0         0  
3429             else {
3430 12         60 while (not /\G \z/oxgc) {
3431 12 50       3465 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    50          
    50          
    50          
3432 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3433 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3434 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3435 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3436 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3437 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3438 12         71 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3439             }
3440 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3441             }
3442             }
3443              
3444             # split q//
3445             elsif (/\G \b (q) \b /oxgc) {
3446 0 0       0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
  0         0  
3447             else {
3448 0         0 while (not /\G \z/oxgc) {
3449 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3450 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3451 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3452 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3453 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3454 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3455 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3456             }
3457 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3458             }
3459             }
3460              
3461             # split m//
3462             elsif (/\G \b (m) \b /oxgc) {
3463 18 50       503 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
  0         0  
3464             else {
3465 18         71 while (not /\G \z/oxgc) {
3466 18 50       3771 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    50          
    50          
    50          
3467 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3468 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3469 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3470 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3471 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3472 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3473 18         86 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3474             }
3475 0         0 die __FILE__, ": Search pattern not terminated\n";
3476             }
3477             }
3478              
3479             # split ''
3480             elsif (/\G (\') /oxgc) {
3481 0         0 my $q_string = '';
3482 0         0 while (not /\G \z/oxgc) {
3483 0 0       0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
3484 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3485 0         0 elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3486 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3487             }
3488 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3489             }
3490              
3491             # split ""
3492             elsif (/\G (\") /oxgc) {
3493 0         0 my $qq_string = '';
3494 0         0 while (not /\G \z/oxgc) {
3495 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
3496 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3497 0         0 elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3498 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3499             }
3500 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3501             }
3502              
3503             # split //
3504             elsif (/\G (\/) /oxgc) {
3505 44         81 my $regexp = '';
3506 44         141 while (not /\G \z/oxgc) {
3507 381 50       1569 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
  0 50       0  
    100          
    50          
3508 0         0 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3509 44         202 elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3510 337         628 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3511             }
3512 0         0 die __FILE__, ": Search pattern not terminated\n";
3513             }
3514             }
3515              
3516             # tr/// or y///
3517              
3518             # about [cdsrbB]* (/B modifier)
3519             #
3520             # P.559 appendix C
3521             # of ISBN 4-89052-384-7 Programming perl
3522             # (Japanese title is: Perl puroguramingu)
3523              
3524             elsif (/\G \b ( tr | y ) \b /oxgc) {
3525 3         7 my $ope = $1;
3526              
3527             # $1 $2 $3 $4 $5 $6
3528 3 50       48 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3529 0         0 my @tr = ($tr_variable,$2);
3530 0         0 return e_tr(@tr,'',$4,$6);
3531             }
3532             else {
3533 3         3 my $e = '';
3534 3         9 while (not /\G \z/oxgc) {
3535 3 50       269 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    50          
3536             elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3537 0         0 my @tr = ($tr_variable,$2);
3538 0         0 while (not /\G \z/oxgc) {
3539 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3540 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3541 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3542 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3543 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3544 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3545             }
3546 0         0 die __FILE__, ": Transliteration replacement not terminated\n";
3547             }
3548             elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3549 0         0 my @tr = ($tr_variable,$2);
3550 0         0 while (not /\G \z/oxgc) {
3551 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3552 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3553 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3554 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3555 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3556 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3557             }
3558 0         0 die __FILE__, ": Transliteration replacement not terminated\n";
3559             }
3560             elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3561 0         0 my @tr = ($tr_variable,$2);
3562 0         0 while (not /\G \z/oxgc) {
3563 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3564 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3565 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3566 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3567 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3568 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3569             }
3570 0         0 die __FILE__, ": Transliteration replacement not terminated\n";
3571             }
3572             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3573 0         0 my @tr = ($tr_variable,$2);
3574 0         0 while (not /\G \z/oxgc) {
3575 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3576 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3577 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3578 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3579 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3580 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3581             }
3582 0         0 die __FILE__, ": Transliteration replacement not terminated\n";
3583             }
3584             # $1 $2 $3 $4 $5 $6
3585             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3586 3         11 my @tr = ($tr_variable,$2);
3587 3         8 return e_tr(@tr,'',$4,$6);
3588             }
3589             }
3590 0         0 die __FILE__, ": Transliteration pattern not terminated\n";
3591             }
3592             }
3593              
3594             # qq//
3595             elsif (/\G \b (qq) \b /oxgc) {
3596 2130         3944 my $ope = $1;
3597              
3598             # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3599 2130 50       3410 if (/\G (\#) /oxgc) { # qq# #
3600 0         0 my $qq_string = '';
3601 0         0 while (not /\G \z/oxgc) {
3602 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
3603 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3604 0         0 elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3605 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3606             }
3607 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3608             }
3609              
3610             else {
3611 2130         2275 my $e = '';
3612 2130         4818 while (not /\G \z/oxgc) {
3613 2130 50       8533 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    100          
    50          
    50          
    0          
3614              
3615             # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3616             elsif (/\G (\() /oxgc) { # qq ( )
3617 0         0 my $qq_string = '';
3618 0         0 local $nest = 1;
3619 0         0 while (not /\G \z/oxgc) {
3620 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
    0          
3621 0         0 elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3622 0         0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3623             elsif (/\G (\)) /oxgc) {
3624 0 0       0 if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
  0         0  
3625 0         0 else { $qq_string .= $1; }
3626             }
3627 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3628             }
3629 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3630             }
3631              
3632             # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3633             elsif (/\G (\{) /oxgc) { # qq { }
3634 2100         1988 my $qq_string = '';
3635 2100         2678 local $nest = 1;
3636 2100         4255 while (not /\G \z/oxgc) {
3637 82631 100       281627 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  722 50       1427  
    100          
    100          
    50          
3638 0         0 elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3639 1103         1223 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  1103         2114  
3640             elsif (/\G (\}) /oxgc) {
3641 3203 100       4281 if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
  2100         4371  
3642 1103         2312 else { $qq_string .= $1; }
3643             }
3644 77603         150736 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3645             }
3646 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3647             }
3648              
3649             # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3650             elsif (/\G (\[) /oxgc) { # qq [ ]
3651 0         0 my $qq_string = '';
3652 0         0 local $nest = 1;
3653 0         0 while (not /\G \z/oxgc) {
3654 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
    0          
3655 0         0 elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3656 0         0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3657             elsif (/\G (\]) /oxgc) {
3658 0 0       0 if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
  0         0  
3659 0         0 else { $qq_string .= $1; }
3660             }
3661 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3662             }
3663 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3664             }
3665              
3666             # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3667             elsif (/\G (\<) /oxgc) { # qq < >
3668 30         39 my $qq_string = '';
3669 30         47 local $nest = 1;
3670 30         91 while (not /\G \z/oxgc) {
3671 1166 100       4127 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  22 50       50  
    50          
    100          
    50          
3672 0         0 elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3673 0         0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3674             elsif (/\G (\>) /oxgc) {
3675 30 50       66 if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
  30         75  
3676 0         0 else { $qq_string .= $1; }
3677             }
3678 1114         2125 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3679             }
3680 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3681             }
3682              
3683             # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3684             elsif (/\G (\S) /oxgc) { # qq * *
3685 0         0 my $delimiter = $1;
3686 0         0 my $qq_string = '';
3687 0         0 while (not /\G \z/oxgc) {
3688 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
3689 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3690 0         0 elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3691 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3692             }
3693 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3694             }
3695             }
3696 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3697             }
3698             }
3699              
3700             # qr//
3701             elsif (/\G \b (qr) \b /oxgc) {
3702 0         0 my $ope = $1;
3703 0 0       0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3704 0         0 return e_qr($ope,$1,$3,$2,$4);
3705             }
3706             else {
3707 0         0 my $e = '';
3708 0         0 while (not /\G \z/oxgc) {
3709 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3710 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3711 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3712 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3713 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3714 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3715 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3716 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3717             }
3718 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3719             }
3720             }
3721              
3722             # qw//
3723             elsif (/\G \b (qw) \b /oxgc) {
3724 16         39 my $ope = $1;
3725 16 50       74 if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3726 0         0 return e_qw($ope,$1,$3,$2);
3727             }
3728             else {
3729 16         31 my $e = '';
3730 16         55 while (not /\G \z/oxgc) {
3731 16 50       129 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3732              
3733 16         58 elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3734 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3735              
3736 0         0 elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3737 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3738              
3739 0         0 elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3740 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3741              
3742 0         0 elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3743 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3744              
3745 0         0 elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3746 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3747             }
3748 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3749             }
3750             }
3751              
3752             # qx//
3753             elsif (/\G \b (qx) \b /oxgc) {
3754 0         0 my $ope = $1;
3755 0 0       0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3756 0         0 return e_qq($ope,$1,$3,$2);
3757             }
3758             else {
3759 0         0 my $e = '';
3760 0         0 while (not /\G \z/oxgc) {
3761 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3762 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3763 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3764 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3765 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3766 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3767 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3768             }
3769 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3770             }
3771             }
3772              
3773             # q//
3774             elsif (/\G \b (q) \b /oxgc) {
3775 245         699 my $ope = $1;
3776              
3777             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3778              
3779             # avoid "Error: Runtime exception" of perl version 5.005_03
3780             # (and so on)
3781              
3782 245 50       813 if (/\G (\#) /oxgc) { # q# #
3783 0         0 my $q_string = '';
3784 0         0 while (not /\G \z/oxgc) {
3785 0 0       0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
3786 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3787 0         0 elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3788 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3789             }
3790 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3791             }
3792              
3793             else {
3794 245         465 my $e = '';
3795 245         944 while (not /\G \z/oxgc) {
3796 245 50       1897 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    100          
    50          
    100          
    50          
3797              
3798             # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3799             elsif (/\G (\() /oxgc) { # q ( )
3800 0         0 my $q_string = '';
3801 0         0 local $nest = 1;
3802 0         0 while (not /\G \z/oxgc) {
3803 0 0       0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3804 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
3805 0         0 elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3806 0         0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3807             elsif (/\G (\)) /oxgc) {
3808 0 0       0 if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
  0         0  
3809 0         0 else { $q_string .= $1; }
3810             }
3811 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3812             }
3813 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3814             }
3815              
3816             # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3817             elsif (/\G (\{) /oxgc) { # q { }
3818 239         405 my $q_string = '';
3819 239         470 local $nest = 1;
3820 239         897 while (not /\G \z/oxgc) {
3821 3624 50       17916 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 50       0  
    50          
    100          
    100          
    50          
3822 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
3823 0         0 elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3824 107         145 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  107         183  
3825             elsif (/\G (\}) /oxgc) {
3826 346 100       815 if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
  239         990  
3827 107         257 else { $q_string .= $1; }
3828             }
3829 3171         6372 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3830             }
3831 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3832             }
3833              
3834             # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3835             elsif (/\G (\[) /oxgc) { # q [ ]
3836 0         0 my $q_string = '';
3837 0         0 local $nest = 1;
3838 0         0 while (not /\G \z/oxgc) {
3839 0 0       0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3840 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
3841 0         0 elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3842 0         0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3843             elsif (/\G (\]) /oxgc) {
3844 0 0       0 if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
  0         0  
3845 0         0 else { $q_string .= $1; }
3846             }
3847 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3848             }
3849 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3850             }
3851              
3852             # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3853             elsif (/\G (\<) /oxgc) { # q < >
3854 5         11 my $q_string = '';
3855 5         10 local $nest = 1;
3856 5         74 while (not /\G \z/oxgc) {
3857 88 50       530 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 50       0  
    50          
    50          
    100          
    50          
3858 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
3859 0         0 elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3860 0         0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3861             elsif (/\G (\>) /oxgc) {
3862 5 50       19 if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
  5         18  
3863 0         0 else { $q_string .= $1; }
3864             }
3865 83         193 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3866             }
3867 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3868             }
3869              
3870             # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3871             elsif (/\G (\S) /oxgc) { # q * *
3872 1         3 my $delimiter = $1;
3873 1         2 my $q_string = '';
3874 1         4 while (not /\G \z/oxgc) {
3875 14 50       76 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 50       0  
    100          
    50          
3876 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3877 1         3 elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3878 13         21 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3879             }
3880 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3881             }
3882             }
3883 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3884             }
3885             }
3886              
3887             # m//
3888             elsif (/\G \b (m) \b /oxgc) {
3889 209         448 my $ope = $1;
3890 209 50       1876 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3891 0         0 return e_qr($ope,$1,$3,$2,$4);
3892             }
3893             else {
3894 209         281 my $e = '';
3895 209         608 while (not /\G \z/oxgc) {
3896 209 50       13378 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3897 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3898 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3899 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3900 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3901 0         0 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3902 10         39 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3903 0         0 elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3904 199         652 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3905             }
3906 0         0 die __FILE__, ": Search pattern not terminated\n";
3907             }
3908             }
3909              
3910             # s///
3911              
3912             # about [cegimosxpradlunbB]* (/cg modifier)
3913             #
3914             # P.67 Pattern-Matching Operators
3915             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3916              
3917             elsif (/\G \b (s) \b /oxgc) {
3918 97         266 my $ope = $1;
3919              
3920             # $1 $2 $3 $4 $5 $6
3921 97 100       2283 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3922 1         7 return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3923             }
3924             else {
3925 96         169 my $e = '';
3926 96         339 while (not /\G \z/oxgc) {
3927 96 50       12905 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3928             elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3929 0         0 my @s = ($1,$2,$3);
3930 0         0 while (not /\G \z/oxgc) {
3931 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3932             # $1 $2 $3 $4
3933 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3934 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3935 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3936 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3937 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3938 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3939 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3940 0         0 elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3941 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3942             }
3943 0         0 die __FILE__, ": Substitution replacement not terminated\n";
3944             }
3945             elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3946 0         0 my @s = ($1,$2,$3);
3947 0         0 while (not /\G \z/oxgc) {
3948 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3949             # $1 $2 $3 $4
3950 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3951 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3952 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3953 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3954 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3955 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3956 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3957 0         0 elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3958 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959             }
3960 0         0 die __FILE__, ": Substitution replacement not terminated\n";
3961             }
3962             elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3963 0         0 my @s = ($1,$2,$3);
3964 0         0 while (not /\G \z/oxgc) {
3965 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3966             # $1 $2 $3 $4
3967 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3968 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3969 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3970 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3971 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3972 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3973 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3974             }
3975 0         0 die __FILE__, ": Substitution replacement not terminated\n";
3976             }
3977             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3978 0         0 my @s = ($1,$2,$3);
3979 0         0 while (not /\G \z/oxgc) {
3980 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3981             # $1 $2 $3 $4
3982 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3983 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3984 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3985 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3986 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3987 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3988 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3989 0         0 elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3990 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3991             }
3992 0         0 die __FILE__, ": Substitution replacement not terminated\n";
3993             }
3994             # $1 $2 $3 $4 $5 $6
3995             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3996 21         72 return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3997             }
3998             # $1 $2 $3 $4 $5 $6
3999             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4000 0         0 return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
4001             }
4002             # $1 $2 $3 $4 $5 $6
4003             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4004 0         0 return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4005             }
4006             # $1 $2 $3 $4 $5 $6
4007             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4008 75         336 return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4009             }
4010             }
4011 0         0 die __FILE__, ": Substitution pattern not terminated\n";
4012             }
4013             }
4014              
4015             # require ignore module
4016 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
4017 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
4018 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4019              
4020             # use strict; --> use strict; no strict qw(refs);
4021 36         350 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4022 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4023 0         0 elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4024              
4025             # use 5.12.0; --> use 5.12.0; no strict qw(refs);
4026             elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4027 2 50 33     33 if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
      33        
4028 0         0 return "use $1; no strict qw(refs);";
4029             }
4030             else {
4031 2         15 return "use $1;";
4032             }
4033             }
4034             elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4035 0 0 0     0 if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
      0        
4036 0         0 return "use $1; no strict qw(refs);";
4037             }
4038             else {
4039 0         0 return "use $1;";
4040             }
4041             }
4042              
4043             # ignore use module
4044 2         21 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4045 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4046 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4047              
4048             # ignore no module
4049 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4050 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4051 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4052              
4053             # use else
4054 0         0 elsif (/\G \b use \b /oxmsgc) { return "use"; }
4055              
4056             # use else
4057 2         8 elsif (/\G \b no \b /oxmsgc) { return "no"; }
4058              
4059             # ''
4060             elsif (/\G (?
4061 841         1321 my $q_string = '';
4062 841         2295 while (not /\G \z/oxgc) {
4063 8196 100       28334 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  4 100       16  
    100          
    50          
4064 48         75 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4065 841         1948 elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4066 7303         14666 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4067             }
4068 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4069             }
4070              
4071             # ""
4072             elsif (/\G (\") /oxgc) {
4073 1763         2581 my $qq_string = '';
4074 1763         4597 while (not /\G \z/oxgc) {
4075 34211 100       110822 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  67 100       154  
    100          
    50          
4076 12         28 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4077 1763         4539 elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4078 32369         67927 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4079             }
4080 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4081             }
4082              
4083             # ``
4084             elsif (/\G (\`) /oxgc) {
4085 1         2 my $qx_string = '';
4086 1         4 while (not /\G \z/oxgc) {
4087 19 50       78 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
  0 50       0  
    100          
    50          
4088 0         0 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4089 1         2 elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4090 18         27 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4091             }
4092 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4093             }
4094              
4095             # // --- not divide operator (num / num), not defined-or
4096             elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4097 452         836 my $regexp = '';
4098 452         1459 while (not /\G \z/oxgc) {
4099 4490 50       17413 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
  0 50       0  
    100          
    50          
4100 0         0 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4101 452         1398 elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4102 4038         8524 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4103             }
4104 0         0 die __FILE__, ": Search pattern not terminated\n";
4105             }
4106              
4107             # ?? --- not conditional operator (condition ? then : else)
4108             elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4109 0         0 my $regexp = '';
4110 0         0 while (not /\G \z/oxgc) {
4111 0 0       0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
  0 0       0  
    0          
    0          
4112 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4113 0         0 elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4114 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4115             }
4116 0         0 die __FILE__, ": Search pattern not terminated\n";
4117             }
4118              
4119             # <<>> (a safer ARGV)
4120 0         0 elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
  0         0  
4121              
4122             # << (bit shift) --- not here document
4123 0         0 elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
  0         0  
4124              
4125             # <<'HEREDOC'
4126             elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4127 72         131 $slash = 'm//';
4128 72         152 my $here_quote = $1;
4129 72         137 my $delimiter = $2;
4130              
4131             # get here document
4132 72 50       167 if ($here_script eq '') {
4133 72         409 $here_script = CORE::substr $_, pos $_;
4134 72         466 $here_script =~ s/.*?\n//oxm;
4135             }
4136 72 50       687 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4137 72         259 push @heredoc, $1 . qq{\n$delimiter\n};
4138 72         145 push @heredoc_delimiter, $delimiter;
4139             }
4140             else {
4141 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4142             }
4143 72         320 return $here_quote;
4144             }
4145              
4146             # <<\HEREDOC
4147              
4148             # P.66 2.6.6. "Here" Documents
4149             # in Chapter 2: Bits and Pieces
4150             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4151              
4152             # P.73 "Here" Documents
4153             # in Chapter 2: Bits and Pieces
4154             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4155              
4156             elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4157 0         0 $slash = 'm//';
4158 0         0 my $here_quote = $1;
4159 0         0 my $delimiter = $2;
4160              
4161             # get here document
4162 0 0       0 if ($here_script eq '') {
4163 0         0 $here_script = CORE::substr $_, pos $_;
4164 0         0 $here_script =~ s/.*?\n//oxm;
4165             }
4166 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4167 0         0 push @heredoc, $1 . qq{\n$delimiter\n};
4168 0         0 push @heredoc_delimiter, $delimiter;
4169             }
4170             else {
4171 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4172             }
4173 0         0 return $here_quote;
4174             }
4175              
4176             # <<"HEREDOC"
4177             elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4178 36         67 $slash = 'm//';
4179 36         78 my $here_quote = $1;
4180 36         516 my $delimiter = $2;
4181              
4182             # get here document
4183 36 50       105 if ($here_script eq '') {
4184 36         274 $here_script = CORE::substr $_, pos $_;
4185 36         203 $here_script =~ s/.*?\n//oxm;
4186             }
4187 36 50       871 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4188 36         111 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4189 36         130 push @heredoc_delimiter, $delimiter;
4190             }
4191             else {
4192 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4193             }
4194 36         178 return $here_quote;
4195             }
4196              
4197             # <
4198             elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4199 42         77 $slash = 'm//';
4200 42         77 my $here_quote = $1;
4201 42         64 my $delimiter = $2;
4202              
4203             # get here document
4204 42 50       105 if ($here_script eq '') {
4205 42         325 $here_script = CORE::substr $_, pos $_;
4206 42         269 $here_script =~ s/.*?\n//oxm;
4207             }
4208 42 50       580 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4209 42         123 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4210 42         78 push @heredoc_delimiter, $delimiter;
4211             }
4212             else {
4213 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4214             }
4215 42         175 return $here_quote;
4216             }
4217              
4218             # <<`HEREDOC`
4219             elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4220 0         0 $slash = 'm//';
4221 0         0 my $here_quote = $1;
4222 0         0 my $delimiter = $2;
4223              
4224             # get here document
4225 0 0       0 if ($here_script eq '') {
4226 0         0 $here_script = CORE::substr $_, pos $_;
4227 0         0 $here_script =~ s/.*?\n//oxm;
4228             }
4229 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4230 0         0 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4231 0         0 push @heredoc_delimiter, $delimiter;
4232             }
4233             else {
4234 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4235             }
4236 0         0 return $here_quote;
4237             }
4238              
4239             # <<= <=> <= < operator
4240             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4241 11         56 return $1;
4242             }
4243              
4244             #
4245             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4246 0         0 return $1;
4247             }
4248              
4249             # --- glob
4250              
4251             # avoid "Error: Runtime exception" of perl version 5.005_03
4252              
4253             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4254 0         0 return 'Ekoi8u::glob("' . $1 . '")';
4255             }
4256              
4257             # __DATA__
4258 0         0 elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4259              
4260             # __END__
4261 200         1495 elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4262              
4263             # \cD Control-D
4264              
4265             # P.68 2.6.8. Other Literal Tokens
4266             # in Chapter 2: Bits and Pieces
4267             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4268              
4269             # P.76 Other Literal Tokens
4270             # in Chapter 2: Bits and Pieces
4271             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4272              
4273 0         0 elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4274              
4275             # \cZ Control-Z
4276 0         0 elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4277              
4278             # any operator before div
4279             elsif (/\G (
4280             -- | \+\+ |
4281             [\)\}\]]
4282              
4283 4824         6081 ) /oxgc) { $slash = 'div'; return $1; }
  4824         21050  
4284              
4285             # yada-yada or triple-dot operator
4286             elsif (/\G (
4287             \.\.\.
4288              
4289 7         11 ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
  7         23  
4290              
4291             # any operator before m//
4292              
4293             # //, //= (defined-or)
4294              
4295             # P.164 Logical Operators
4296             # in Chapter 10: More Control Structures
4297             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4298              
4299             # P.119 C-Style Logical (Short-Circuit) Operators
4300             # in Chapter 3: Unary and Binary Operators
4301             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4302              
4303             # (and so on)
4304              
4305             # ~~
4306              
4307             # P.221 The Smart Match Operator
4308             # in Chapter 15: Smart Matching and given-when
4309             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4310              
4311             # P.112 Smartmatch Operator
4312             # in Chapter 3: Unary and Binary Operators
4313             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4314              
4315             # (and so on)
4316              
4317             elsif (/\G ((?>
4318              
4319             !~~ | !~ | != | ! |
4320             %= | % |
4321             &&= | && | &= | &\.= | &\. | & |
4322             -= | -> | - |
4323             :(?>\s*)= |
4324             : |
4325             <<>> |
4326             <<= | <=> | <= | < |
4327             == | => | =~ | = |
4328             >>= | >> | >= | > |
4329             \*\*= | \*\* | \*= | \* |
4330             \+= | \+ |
4331             \.\. | \.= | \. |
4332             \/\/= | \/\/ |
4333             \/= | \/ |
4334             \? |
4335             \\ |
4336             \^= | \^\.= | \^\. | \^ |
4337             \b x= |
4338             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4339             ~~ | ~\. | ~ |
4340             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4341             \b(?: print )\b |
4342              
4343             [,;\(\{\[]
4344              
4345 8493         10295 )) /oxgc) { $slash = 'm//'; return $1; }
  8493         37517  
4346              
4347             # other any character
4348 14616         17073 elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
  14616         65389  
4349              
4350             # system error
4351             else {
4352 0         0 die __FILE__, ": Oops, this shouldn't happen!\n";
4353             }
4354             }
4355              
4356             # escape KOI8-U string
4357             sub e_string {
4358 1718     1718 0 3512 my($string) = @_;
4359 1718         1917 my $e_string = '';
4360              
4361 1718         2271 local $slash = 'm//';
4362              
4363             # P.1024 Appendix W.10 Multibyte Processing
4364             # of ISBN 1-56592-224-7 CJKV Information Processing
4365             # (and so on)
4366              
4367 1718         16941 my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4368              
4369             # without { ... }
4370 1718 100 66     8136 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4371 1701 50       3831 if ($string !~ /<
4372 1701         4472 return $string;
4373             }
4374             }
4375              
4376             E_STRING_LOOP:
4377 17         67 while ($string !~ /\G \z/oxgc) {
4378 190 50       16477 if (0) {
    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          
    100          
    50          
    100          
    50          
4379             }
4380              
4381             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Ekoi8u::PREMATCH()]}
4382 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4383 0         0 $e_string .= q{Ekoi8u::PREMATCH()};
4384 0         0 $slash = 'div';
4385             }
4386              
4387             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Ekoi8u::MATCH()]}
4388             elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4389 0         0 $e_string .= q{Ekoi8u::MATCH()};
4390 0         0 $slash = 'div';
4391             }
4392              
4393             # $', ${'} --> $', ${'}
4394             elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4395 0         0 $e_string .= $1;
4396 0         0 $slash = 'div';
4397             }
4398              
4399             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Ekoi8u::POSTMATCH()]}
4400             elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4401 0         0 $e_string .= q{Ekoi8u::POSTMATCH()};
4402 0         0 $slash = 'div';
4403             }
4404              
4405             # bareword
4406             elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4407 0         0 $e_string .= $1;
4408 0         0 $slash = 'div';
4409             }
4410              
4411             # $0 --> $0
4412             elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4413 0         0 $e_string .= $1;
4414 0         0 $slash = 'div';
4415             }
4416             elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4417 0         0 $e_string .= $1;
4418 0         0 $slash = 'div';
4419             }
4420              
4421             # $$ --> $$
4422             elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4423 0         0 $e_string .= $1;
4424 0         0 $slash = 'div';
4425             }
4426              
4427             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4428             # $1, $2, $3 --> $1, $2, $3 otherwise
4429             elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4430 0         0 $e_string .= e_capture($1);
4431 0         0 $slash = 'div';
4432             }
4433             elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4434 0         0 $e_string .= e_capture($1);
4435 0         0 $slash = 'div';
4436             }
4437              
4438             # $$foo[ ... ] --> $ $foo->[ ... ]
4439             elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4440 0         0 $e_string .= e_capture($1.'->'.$2);
4441 0         0 $slash = 'div';
4442             }
4443              
4444             # $$foo{ ... } --> $ $foo->{ ... }
4445             elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4446 0         0 $e_string .= e_capture($1.'->'.$2);
4447 0         0 $slash = 'div';
4448             }
4449              
4450             # $$foo
4451             elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4452 0         0 $e_string .= e_capture($1);
4453 0         0 $slash = 'div';
4454             }
4455              
4456             # ${ foo }
4457             elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4458 0         0 $e_string .= '${' . $1 . '}';
4459 0         0 $slash = 'div';
4460             }
4461              
4462             # ${ ... }
4463             elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4464 3         10 $e_string .= e_capture($1);
4465 3         18 $slash = 'div';
4466             }
4467              
4468             # variable or function
4469             # $ @ % & * $ #
4470             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) {
4471 7         19 $e_string .= $1;
4472 7         29 $slash = 'div';
4473             }
4474             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4475             # $ @ # \ ' " / ? ( ) [ ] < >
4476             elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4477 0         0 $e_string .= $1;
4478 0         0 $slash = 'div';
4479             }
4480              
4481             # subroutines of package Ekoi8u
4482 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4483 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4484 0         0 elsif ($string =~ /\G \b KOI8U::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4485 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4486 0         0 elsif ($string =~ /\G \b KOI8U::eval \b /oxgc) { $e_string .= 'eval KOI8U::escape'; $slash = 'm//'; }
  0         0  
4487 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4488 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Ekoi8u::chop'; $slash = 'm//'; }
  0         0  
4489 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4490 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4491 0         0 elsif ($string =~ /\G \b KOI8U::index \b /oxgc) { $e_string .= 'KOI8U::index'; $slash = 'm//'; }
  0         0  
4492 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Ekoi8u::index'; $slash = 'm//'; }
  0         0  
4493 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4494 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4495 0         0 elsif ($string =~ /\G \b KOI8U::rindex \b /oxgc) { $e_string .= 'KOI8U::rindex'; $slash = 'm//'; }
  0         0  
4496 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Ekoi8u::rindex'; $slash = 'm//'; }
  0         0  
4497 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::lc'; $slash = 'm//'; }
  0         0  
4498 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::lcfirst'; $slash = 'm//'; }
  0         0  
4499 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::uc'; $slash = 'm//'; }
  0         0  
4500 0         0 elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::ucfirst'; $slash = 'm//'; }
  0         0  
4501 0         0 elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::fc'; $slash = 'm//'; }
  0         0  
4502              
4503             # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
4504 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4505 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  
4506 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  
4507 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  
4508 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  
4509 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4510 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  
4511              
4512 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4513 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  
4514 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  
4515 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  
4516 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  
4517 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4518 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4519              
4520             elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
4521 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4522 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4523 0         0 elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
  0         0  
4524 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4525              
4526 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4527 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4528 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::chr'; $slash = 'm//'; }
  0         0  
4529 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4530 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4531 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8u::glob'; $slash = 'm//'; }
  0         0  
4532 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Ekoi8u::lc_'; $slash = 'm//'; }
  0         0  
4533 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Ekoi8u::lcfirst_'; $slash = 'm//'; }
  0         0  
4534 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Ekoi8u::uc_'; $slash = 'm//'; }
  0         0  
4535 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Ekoi8u::ucfirst_'; $slash = 'm//'; }
  0         0  
4536 0         0 elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Ekoi8u::fc_'; $slash = 'm//'; }
  0         0  
4537 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4538              
4539 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4540 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4541 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Ekoi8u::chr_'; $slash = 'm//'; }
  0         0  
4542 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4543 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4544 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Ekoi8u::glob_'; $slash = 'm//'; }
  0         0  
4545 0         0 elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
  0         0  
4546 0         0 elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
  0         0  
4547             # split
4548             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4549 0         0 $slash = 'm//';
4550              
4551 0         0 my $e = '';
4552 0         0 while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4553 0         0 $e .= $1;
4554             }
4555              
4556             # end of split
4557 0 0       0 if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8u::split' . $e; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
4558              
4559             # split scalar value
4560 0         0 elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . e_string($1); next E_STRING_LOOP; }
  0         0  
4561              
4562             # split literal space
4563 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4564 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4565 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4566 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4567 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4568 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  
4569 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4570 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4571 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4572 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4573 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4574 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  
4575 0         0 elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {' '}; next E_STRING_LOOP; }
  0         0  
4576 0         0 elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Ekoi8u::split' . $e . qq {" "}; next E_STRING_LOOP; }
  0         0  
4577              
4578             # split qq//
4579             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4580 0 0       0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
  0         0  
  0         0  
4581             else {
4582 0         0 while ($string !~ /\G \z/oxgc) {
4583 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4584 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  
4585 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  
4586 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  
4587 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  
4588 0         0 elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
  0         0  
4589 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 * *
  0         0  
4590             }
4591 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4592             }
4593             }
4594              
4595             # split qr//
4596             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4597 0 0       0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
  0         0  
  0         0  
4598             else {
4599 0         0 while ($string !~ /\G \z/oxgc) {
4600 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4601 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  
4602 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  
4603 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  
4604 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  
4605 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  
4606 0         0 elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
  0         0  
4607 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 * *
  0         0  
4608             }
4609 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4610             }
4611             }
4612              
4613             # split q//
4614             elsif ($string =~ /\G \b (q) \b /oxgc) {
4615 0 0       0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
  0         0  
  0         0  
4616             else {
4617 0         0 while ($string !~ /\G \z/oxgc) {
4618 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4619 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  
4620 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  
4621 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  
4622 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  
4623 0         0 elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
  0         0  
4624 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 * *
  0         0  
4625             }
4626 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4627             }
4628             }
4629              
4630             # split m//
4631             elsif ($string =~ /\G \b (m) \b /oxgc) {
4632 0 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 # #
  0         0  
  0         0  
4633             else {
4634 0         0 while ($string !~ /\G \z/oxgc) {
4635 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4636 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  
4637 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  
4638 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  
4639 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  
4640 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  
4641 0         0 elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
  0         0  
4642 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 * *
  0         0  
4643             }
4644 0         0 die __FILE__, ": Search pattern not terminated\n";
4645             }
4646             }
4647              
4648             # split ''
4649             elsif ($string =~ /\G (\') /oxgc) {
4650 0         0 my $q_string = '';
4651 0         0 while ($string !~ /\G \z/oxgc) {
4652 0 0       0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
4653 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4654 0         0 elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
  0         0  
4655 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4656             }
4657 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4658             }
4659              
4660             # split ""
4661             elsif ($string =~ /\G (\") /oxgc) {
4662 0         0 my $qq_string = '';
4663 0         0 while ($string !~ /\G \z/oxgc) {
4664 0 0       0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
4665 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4666 0         0 elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
  0         0  
4667 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4668             }
4669 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4670             }
4671              
4672             # split //
4673             elsif ($string =~ /\G (\/) /oxgc) {
4674 0         0 my $regexp = '';
4675 0         0 while ($string !~ /\G \z/oxgc) {
4676 0 0       0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0 0       0  
    0          
    0          
4677 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4678 0         0 elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
  0         0  
4679 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4680             }
4681 0         0 die __FILE__, ": Search pattern not terminated\n";
4682             }
4683             }
4684              
4685             # qq//
4686             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4687 0         0 my $ope = $1;
4688 0 0       0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4689 0         0 $e_string .= e_qq($ope,$1,$3,$2);
4690             }
4691             else {
4692 0         0 my $e = '';
4693 0         0 while ($string !~ /\G \z/oxgc) {
4694 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
4695 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4696 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4697 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4698 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
  0         0  
4699 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
  0         0  
4700             }
4701 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4702             }
4703             }
4704              
4705             # qx//
4706             elsif ($string =~ /\G \b (qx) \b /oxgc) {
4707 0         0 my $ope = $1;
4708 0 0       0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4709 0         0 $e_string .= e_qq($ope,$1,$3,$2);
4710             }
4711             else {
4712 0         0 my $e = '';
4713 0         0 while ($string !~ /\G \z/oxgc) {
4714 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4715 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4716 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4717 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4718 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4719 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
  0         0  
4720 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
  0         0  
4721             }
4722 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4723             }
4724             }
4725              
4726             # q//
4727             elsif ($string =~ /\G \b (q) \b /oxgc) {
4728 0         0 my $ope = $1;
4729 0 0       0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4730 0         0 $e_string .= e_q($ope,$1,$3,$2);
4731             }
4732             else {
4733 0         0 my $e = '';
4734 0         0 while ($string !~ /\G \z/oxgc) {
4735 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
4736 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4737 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4738 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4739 0         0 elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
  0         0  
4740 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 * *
  0         0  
4741             }
4742 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4743             }
4744             }
4745              
4746             # ''
4747 0         0 elsif ($string =~ /\G (?
4748              
4749             # ""
4750 0         0 elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4751              
4752             # ``
4753 0         0 elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4754              
4755             # <<>> (a safer ARGV)
4756 0         0 elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4757              
4758             # <<= <=> <= < operator
4759 0         0 elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4760              
4761             #
4762 0         0 elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4763              
4764             # --- glob
4765             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4766 0         0 $e_string .= 'Ekoi8u::glob("' . $1 . '")';
4767             }
4768              
4769             # << (bit shift) --- not here document
4770 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; $e_string .= $1; }
  0         0  
4771              
4772             # <<'HEREDOC'
4773             elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4774 0         0 $slash = 'm//';
4775 0         0 my $here_quote = $1;
4776 0         0 my $delimiter = $2;
4777              
4778             # get here document
4779 0 0       0 if ($here_script eq '') {
4780 0         0 $here_script = CORE::substr $_, pos $_;
4781 0         0 $here_script =~ s/.*?\n//oxm;
4782             }
4783 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4784 0         0 push @heredoc, $1 . qq{\n$delimiter\n};
4785 0         0 push @heredoc_delimiter, $delimiter;
4786             }
4787             else {
4788 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4789             }
4790 0         0 $e_string .= $here_quote;
4791             }
4792              
4793             # <<\HEREDOC
4794             elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4795 0         0 $slash = 'm//';
4796 0         0 my $here_quote = $1;
4797 0         0 my $delimiter = $2;
4798              
4799             # get here document
4800 0 0       0 if ($here_script eq '') {
4801 0         0 $here_script = CORE::substr $_, pos $_;
4802 0         0 $here_script =~ s/.*?\n//oxm;
4803             }
4804 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4805 0         0 push @heredoc, $1 . qq{\n$delimiter\n};
4806 0         0 push @heredoc_delimiter, $delimiter;
4807             }
4808             else {
4809 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4810             }
4811 0         0 $e_string .= $here_quote;
4812             }
4813              
4814             # <<"HEREDOC"
4815             elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4816 0         0 $slash = 'm//';
4817 0         0 my $here_quote = $1;
4818 0         0 my $delimiter = $2;
4819              
4820             # get here document
4821 0 0       0 if ($here_script eq '') {
4822 0         0 $here_script = CORE::substr $_, pos $_;
4823 0         0 $here_script =~ s/.*?\n//oxm;
4824             }
4825 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4826 0         0 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4827 0         0 push @heredoc_delimiter, $delimiter;
4828             }
4829             else {
4830 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4831             }
4832 0         0 $e_string .= $here_quote;
4833             }
4834              
4835             # <
4836             elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4837 0         0 $slash = 'm//';
4838 0         0 my $here_quote = $1;
4839 0         0 my $delimiter = $2;
4840              
4841             # get here document
4842 0 0       0 if ($here_script eq '') {
4843 0         0 $here_script = CORE::substr $_, pos $_;
4844 0         0 $here_script =~ s/.*?\n//oxm;
4845             }
4846 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4847 0         0 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4848 0         0 push @heredoc_delimiter, $delimiter;
4849             }
4850             else {
4851 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4852             }
4853 0         0 $e_string .= $here_quote;
4854             }
4855              
4856             # <<`HEREDOC`
4857             elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4858 0         0 $slash = 'm//';
4859 0         0 my $here_quote = $1;
4860 0         0 my $delimiter = $2;
4861              
4862             # get here document
4863 0 0       0 if ($here_script eq '') {
4864 0         0 $here_script = CORE::substr $_, pos $_;
4865 0         0 $here_script =~ s/.*?\n//oxm;
4866             }
4867 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4868 0         0 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4869 0         0 push @heredoc_delimiter, $delimiter;
4870             }
4871             else {
4872 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4873             }
4874 0         0 $e_string .= $here_quote;
4875             }
4876              
4877             # any operator before div
4878             elsif ($string =~ /\G (
4879             -- | \+\+ |
4880             [\)\}\]]
4881              
4882 18         36 ) /oxgc) { $slash = 'div'; $e_string .= $1; }
  18         80  
4883              
4884             # yada-yada or triple-dot operator
4885             elsif ($string =~ /\G (
4886             \.\.\.
4887              
4888 0         0 ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
  0         0  
4889              
4890             # any operator before m//
4891             elsif ($string =~ /\G ((?>
4892              
4893             !~~ | !~ | != | ! |
4894             %= | % |
4895             &&= | && | &= | &\.= | &\. | & |
4896             -= | -> | - |
4897             :(?>\s*)= |
4898             : |
4899             <<>> |
4900             <<= | <=> | <= | < |
4901             == | => | =~ | = |
4902             >>= | >> | >= | > |
4903             \*\*= | \*\* | \*= | \* |
4904             \+= | \+ |
4905             \.\. | \.= | \. |
4906             \/\/= | \/\/ |
4907             \/= | \/ |
4908             \? |
4909             \\ |
4910             \^= | \^\.= | \^\. | \^ |
4911             \b x= |
4912             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4913             ~~ | ~\. | ~ |
4914             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4915             \b(?: print )\b |
4916              
4917             [,;\(\{\[]
4918              
4919 31         47 )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
  31         158  
4920              
4921             # other any character
4922 131         458 elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
4923              
4924             # system error
4925             else {
4926 0         0 die __FILE__, ": Oops, this shouldn't happen!\n";
4927             }
4928             }
4929              
4930 17         83 return $e_string;
4931             }
4932              
4933             #
4934             # character class
4935             #
4936             sub character_class {
4937 1914     1914 0 2491 my($char,$modifier) = @_;
4938              
4939 1914 100       2775 if ($char eq '.') {
4940 52 100       112 if ($modifier =~ /s/) {
4941 17         42 return '${Ekoi8u::dot_s}';
4942             }
4943             else {
4944 35         91 return '${Ekoi8u::dot}';
4945             }
4946             }
4947             else {
4948 1862         2944 return Ekoi8u::classic_character_class($char);
4949             }
4950             }
4951              
4952             #
4953             # escape capture ($1, $2, $3, ...)
4954             #
4955             sub e_capture {
4956              
4957 212     212 0 1042 return join '', '${', $_[0], '}';
4958             }
4959              
4960             #
4961             # escape transliteration (tr/// or y///)
4962             #
4963             sub e_tr {
4964 3     3 0 8 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
4965 3         4 my $e_tr = '';
4966 3   50     4 $modifier ||= '';
4967              
4968 3         3 $slash = 'div';
4969              
4970             # quote character class 1
4971 3         5 $charclass = q_tr($charclass);
4972              
4973             # quote character class 2
4974 3         6 $charclass2 = q_tr($charclass2);
4975              
4976             # /b /B modifier
4977 3 50       10 if ($modifier =~ tr/bB//d) {
4978 0 0       0 if ($variable eq '') {
4979 0         0 $e_tr = qq{tr$charclass$e$charclass2$modifier};
4980             }
4981             else {
4982 0         0 $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
4983             }
4984             }
4985             else {
4986 3 100       6 if ($variable eq '') {
4987 2         6 $e_tr = qq{Ekoi8u::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
4988             }
4989             else {
4990 1         4 $e_tr = qq{Ekoi8u::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
4991             }
4992             }
4993              
4994             # clear tr/// variable
4995 3         6 $tr_variable = '';
4996 3         2 $bind_operator = '';
4997              
4998 3         14 return $e_tr;
4999             }
5000              
5001             #
5002             # quote for escape transliteration (tr/// or y///)
5003             #
5004             sub q_tr {
5005 6     6 0 6 my($charclass) = @_;
5006              
5007             # quote character class
5008 6 50       11 if ($charclass !~ /'/oxms) {
    0          
    0          
    0          
    0          
    0          
5009 6         8 return e_q('', "'", "'", $charclass); # --> q' '
5010             }
5011             elsif ($charclass !~ /\//oxms) {
5012 0         0 return e_q('q', '/', '/', $charclass); # --> q/ /
5013             }
5014             elsif ($charclass !~ /\#/oxms) {
5015 0         0 return e_q('q', '#', '#', $charclass); # --> q# #
5016             }
5017             elsif ($charclass !~ /[\<\>]/oxms) {
5018 0         0 return e_q('q', '<', '>', $charclass); # --> q< >
5019             }
5020             elsif ($charclass !~ /[\(\)]/oxms) {
5021 0         0 return e_q('q', '(', ')', $charclass); # --> q( )
5022             }
5023             elsif ($charclass !~ /[\{\}]/oxms) {
5024 0         0 return e_q('q', '{', '}', $charclass); # --> q{ }
5025             }
5026             else {
5027 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5028 0 0       0 if ($charclass !~ /\Q$char\E/xms) {
5029 0         0 return e_q('q', $char, $char, $charclass);
5030             }
5031             }
5032             }
5033              
5034 0         0 return e_q('q', '{', '}', $charclass);
5035             }
5036              
5037             #
5038             # escape q string (q//, '')
5039             #
5040             sub e_q {
5041 1092     1092 0 2070 my($ope,$delimiter,$end_delimiter,$string) = @_;
5042              
5043 1092         1290 $slash = 'div';
5044              
5045 1092         5779 return join '', $ope, $delimiter, $string, $end_delimiter;
5046             }
5047              
5048             #
5049             # escape qq string (qq//, "", qx//, ``)
5050             #
5051             sub e_qq {
5052 3975     3975 0 7038 my($ope,$delimiter,$end_delimiter,$string) = @_;
5053              
5054 3975         4354 $slash = 'div';
5055              
5056 3975         3837 my $left_e = 0;
5057 3975         3460 my $right_e = 0;
5058              
5059             # split regexp
5060 3975         154790 my @char = $string =~ /\G((?>
5061             [^\\\$] |
5062             \\x\{ (?>[0-9A-Fa-f]+) \} |
5063             \\o\{ (?>[0-7]+) \} |
5064             \\N\{ (?>[^0-9\}][^\}]*) \} |
5065             \\ $q_char |
5066             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5067             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5068             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5069             \$ (?>\s* [0-9]+) |
5070             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5071             \$ \$ (?![\w\{]) |
5072             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5073             $q_char
5074             ))/oxmsg;
5075              
5076 3975         15013 for (my $i=0; $i <= $#char; $i++) {
5077              
5078             # "\L\u" --> "\u\L"
5079 111695 50 33     458484 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 33        
    100          
    100          
    50          
5080 0         0 @char[$i,$i+1] = @char[$i+1,$i];
5081             }
5082              
5083             # "\U\l" --> "\l\U"
5084             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5085 0         0 @char[$i,$i+1] = @char[$i+1,$i];
5086             }
5087              
5088             # octal escape sequence
5089             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5090 1         4 $char[$i] = Ekoi8u::octchr($1);
5091             }
5092              
5093             # hexadecimal escape sequence
5094             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5095 1         4 $char[$i] = Ekoi8u::hexchr($1);
5096             }
5097              
5098             # \N{CHARNAME} --> N{CHARNAME}
5099             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5100 0         0 $char[$i] = $1;
5101             }
5102              
5103 111695 100       1249029 if (0) {
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5104             }
5105              
5106             # \F
5107             #
5108             # P.69 Table 2-6. Translation escapes
5109             # in Chapter 2: Bits and Pieces
5110             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5111             # (and so on)
5112              
5113             # \u \l \U \L \F \Q \E
5114 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5115 484 50       1342 if ($right_e < $left_e) {
5116 0         0 $char[$i] = '\\' . $char[$i];
5117             }
5118             }
5119             elsif ($char[$i] eq '\u') {
5120              
5121             # "STRING @{[ LIST EXPR ]} MORE STRING"
5122              
5123             # P.257 Other Tricks You Can Do with Hard References
5124             # in Chapter 8: References
5125             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5126              
5127             # P.353 Other Tricks You Can Do with Hard References
5128             # in Chapter 8: References
5129             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5130              
5131             # (and so on)
5132              
5133 0         0 $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5134 0         0 $left_e++;
5135             }
5136             elsif ($char[$i] eq '\l') {
5137 0         0 $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5138 0         0 $left_e++;
5139             }
5140             elsif ($char[$i] eq '\U') {
5141 0         0 $char[$i] = '@{[Ekoi8u::uc qq<';
5142 0         0 $left_e++;
5143             }
5144             elsif ($char[$i] eq '\L') {
5145 0         0 $char[$i] = '@{[Ekoi8u::lc qq<';
5146 0         0 $left_e++;
5147             }
5148             elsif ($char[$i] eq '\F') {
5149 24         22 $char[$i] = '@{[Ekoi8u::fc qq<';
5150 24         37 $left_e++;
5151             }
5152             elsif ($char[$i] eq '\Q') {
5153 0         0 $char[$i] = '@{[CORE::quotemeta qq<';
5154 0         0 $left_e++;
5155             }
5156             elsif ($char[$i] eq '\E') {
5157 24 50       32 if ($right_e < $left_e) {
5158 24         24 $char[$i] = '>]}';
5159 24         42 $right_e++;
5160             }
5161             else {
5162 0         0 $char[$i] = '';
5163             }
5164             }
5165             elsif ($char[$i] eq '\Q') {
5166 0         0 while (1) {
5167 0 0       0 if (++$i > $#char) {
5168 0         0 last;
5169             }
5170 0 0       0 if ($char[$i] eq '\E') {
5171 0         0 last;
5172             }
5173             }
5174             }
5175             elsif ($char[$i] eq '\E') {
5176             }
5177              
5178             # $0 --> $0
5179             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5180             }
5181             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5182             }
5183              
5184             # $$ --> $$
5185             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5186             }
5187              
5188             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5189             # $1, $2, $3 --> $1, $2, $3 otherwise
5190             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5191 205         459 $char[$i] = e_capture($1);
5192             }
5193             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5194 0         0 $char[$i] = e_capture($1);
5195             }
5196              
5197             # $$foo[ ... ] --> $ $foo->[ ... ]
5198             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5199 0         0 $char[$i] = e_capture($1.'->'.$2);
5200             }
5201              
5202             # $$foo{ ... } --> $ $foo->{ ... }
5203             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5204 0         0 $char[$i] = e_capture($1.'->'.$2);
5205             }
5206              
5207             # $$foo
5208             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5209 0         0 $char[$i] = e_capture($1);
5210             }
5211              
5212             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5213             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5214 44         114 $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5215             }
5216              
5217             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5218             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5219 45         138 $char[$i] = '@{[Ekoi8u::MATCH()]}';
5220             }
5221              
5222             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5223             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5224 33         90 $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5225             }
5226              
5227             # ${ foo } --> ${ foo }
5228             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5229             }
5230              
5231             # ${ ... }
5232             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5233 0         0 $char[$i] = e_capture($1);
5234             }
5235             }
5236              
5237             # return string
5238 3975 50       7159 if ($left_e > $right_e) {
5239 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5240             }
5241 3975         38655 return join '', $ope, $delimiter, @char, $end_delimiter;
5242             }
5243              
5244             #
5245             # escape qw string (qw//)
5246             #
5247             sub e_qw {
5248 16     16 0 101 my($ope,$delimiter,$end_delimiter,$string) = @_;
5249              
5250 16         29 $slash = 'div';
5251              
5252             # choice again delimiter
5253 16         239 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
  483         608  
5254 16 50       107 if (not $octet{$end_delimiter}) {
    0          
    0          
    0          
    0          
5255 16         131 return join '', $ope, $delimiter, $string, $end_delimiter;
5256             }
5257             elsif (not $octet{')'}) {
5258 0         0 return join '', $ope, '(', $string, ')';
5259             }
5260             elsif (not $octet{'}'}) {
5261 0         0 return join '', $ope, '{', $string, '}';
5262             }
5263             elsif (not $octet{']'}) {
5264 0         0 return join '', $ope, '[', $string, ']';
5265             }
5266             elsif (not $octet{'>'}) {
5267 0         0 return join '', $ope, '<', $string, '>';
5268             }
5269             else {
5270 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5271 0 0       0 if (not $octet{$char}) {
5272 0         0 return join '', $ope, $char, $string, $char;
5273             }
5274             }
5275             }
5276              
5277             # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5278 0         0 my @string = CORE::split(/\s+/, $string);
5279 0         0 for my $string (@string) {
5280 0         0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5281 0         0 for my $octet (@octet) {
5282 0 0       0 if ($octet =~ /\A (['\\]) \z/oxms) {
5283 0         0 $octet = '\\' . $1;
5284             }
5285             }
5286 0         0 $string = join '', @octet;
5287             }
5288 0         0 return join '', '(', (join ', ', map { "'$_'" } @string), ')';
  0         0  
5289             }
5290              
5291             #
5292             # escape here document (<<"HEREDOC", <
5293             #
5294             sub e_heredoc {
5295 78     78 0 186 my($string) = @_;
5296              
5297 78         100 $slash = 'm//';
5298              
5299 78         328 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5300              
5301 78         93 my $left_e = 0;
5302 78         80 my $right_e = 0;
5303              
5304             # split regexp
5305 78         7275 my @char = $string =~ /\G((?>
5306             [^\\\$] |
5307             \\x\{ (?>[0-9A-Fa-f]+) \} |
5308             \\o\{ (?>[0-7]+) \} |
5309             \\N\{ (?>[^0-9\}][^\}]*) \} |
5310             \\ $q_char |
5311             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5312             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5313             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5314             \$ (?>\s* [0-9]+) |
5315             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5316             \$ \$ (?![\w\{]) |
5317             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5318             $q_char
5319             ))/oxmsg;
5320              
5321 78         456 for (my $i=0; $i <= $#char; $i++) {
5322              
5323             # "\L\u" --> "\u\L"
5324 2856 50 33     10807 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 33        
    100          
    100          
    50          
5325 0         0 @char[$i,$i+1] = @char[$i+1,$i];
5326             }
5327              
5328             # "\U\l" --> "\l\U"
5329             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5330 0         0 @char[$i,$i+1] = @char[$i+1,$i];
5331             }
5332              
5333             # octal escape sequence
5334             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5335 1         3 $char[$i] = Ekoi8u::octchr($1);
5336             }
5337              
5338             # hexadecimal escape sequence
5339             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5340 1         4 $char[$i] = Ekoi8u::hexchr($1);
5341             }
5342              
5343             # \N{CHARNAME} --> N{CHARNAME}
5344             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5345 0         0 $char[$i] = $1;
5346             }
5347              
5348 2856 50       30315 if (0) {
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5349             }
5350              
5351             # \u \l \U \L \F \Q \E
5352 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5353 0 0       0 if ($right_e < $left_e) {
5354 0         0 $char[$i] = '\\' . $char[$i];
5355             }
5356             }
5357             elsif ($char[$i] eq '\u') {
5358 0         0 $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5359 0         0 $left_e++;
5360             }
5361             elsif ($char[$i] eq '\l') {
5362 0         0 $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5363 0         0 $left_e++;
5364             }
5365             elsif ($char[$i] eq '\U') {
5366 0         0 $char[$i] = '@{[Ekoi8u::uc qq<';
5367 0         0 $left_e++;
5368             }
5369             elsif ($char[$i] eq '\L') {
5370 0         0 $char[$i] = '@{[Ekoi8u::lc qq<';
5371 0         0 $left_e++;
5372             }
5373             elsif ($char[$i] eq '\F') {
5374 0         0 $char[$i] = '@{[Ekoi8u::fc qq<';
5375 0         0 $left_e++;
5376             }
5377             elsif ($char[$i] eq '\Q') {
5378 0         0 $char[$i] = '@{[CORE::quotemeta qq<';
5379 0         0 $left_e++;
5380             }
5381             elsif ($char[$i] eq '\E') {
5382 0 0       0 if ($right_e < $left_e) {
5383 0         0 $char[$i] = '>]}';
5384 0         0 $right_e++;
5385             }
5386             else {
5387 0         0 $char[$i] = '';
5388             }
5389             }
5390             elsif ($char[$i] eq '\Q') {
5391 0         0 while (1) {
5392 0 0       0 if (++$i > $#char) {
5393 0         0 last;
5394             }
5395 0 0       0 if ($char[$i] eq '\E') {
5396 0         0 last;
5397             }
5398             }
5399             }
5400             elsif ($char[$i] eq '\E') {
5401             }
5402              
5403             # $0 --> $0
5404             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5405             }
5406             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5407             }
5408              
5409             # $$ --> $$
5410             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5411             }
5412              
5413             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5414             # $1, $2, $3 --> $1, $2, $3 otherwise
5415             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5416 0         0 $char[$i] = e_capture($1);
5417             }
5418             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5419 0         0 $char[$i] = e_capture($1);
5420             }
5421              
5422             # $$foo[ ... ] --> $ $foo->[ ... ]
5423             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5424 0         0 $char[$i] = e_capture($1.'->'.$2);
5425             }
5426              
5427             # $$foo{ ... } --> $ $foo->{ ... }
5428             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5429 0         0 $char[$i] = e_capture($1.'->'.$2);
5430             }
5431              
5432             # $$foo
5433             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5434 0         0 $char[$i] = e_capture($1);
5435             }
5436              
5437             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5438             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5439 8         40 $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5440             }
5441              
5442             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5443             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5444 8         48 $char[$i] = '@{[Ekoi8u::MATCH()]}';
5445             }
5446              
5447             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5448             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5449 6         32 $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5450             }
5451              
5452             # ${ foo } --> ${ foo }
5453             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5454             }
5455              
5456             # ${ ... }
5457             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5458 0         0 $char[$i] = e_capture($1);
5459             }
5460             }
5461              
5462             # return string
5463 78 50       188 if ($left_e > $right_e) {
5464 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5465             }
5466 78         705 return join '', @char;
5467             }
5468              
5469             #
5470             # escape regexp (m//, qr//)
5471             #
5472             sub e_qr {
5473 651     651 0 1850 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5474 651   100     2398 $modifier ||= '';
5475              
5476 651         1061 $modifier =~ tr/p//d;
5477 651 50       1670 if ($modifier =~ /([adlu])/oxms) {
5478 0         0 my $line = 0;
5479 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5480 0 0       0 if ($filename ne __FILE__) {
5481 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5482 0         0 last;
5483             }
5484             }
5485 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
5486             }
5487              
5488 651         1029 $slash = 'div';
5489              
5490             # literal null string pattern
5491 651 100       2343 if ($string eq '') {
    100          
5492 8         9 $modifier =~ tr/bB//d;
5493 8         9 $modifier =~ tr/i//d;
5494 8         55 return join '', $ope, $delimiter, $end_delimiter, $modifier;
5495             }
5496              
5497             # /b /B modifier
5498             elsif ($modifier =~ tr/bB//d) {
5499              
5500             # choice again delimiter
5501 2 50       12 if ($delimiter =~ / [\@:] /oxms) {
5502 0         0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5503 0         0 my %octet = map {$_ => 1} @char;
  0         0  
5504 0 0       0 if (not $octet{')'}) {
    0          
    0          
    0          
5505 0         0 $delimiter = '(';
5506 0         0 $end_delimiter = ')';
5507             }
5508             elsif (not $octet{'}'}) {
5509 0         0 $delimiter = '{';
5510 0         0 $end_delimiter = '}';
5511             }
5512             elsif (not $octet{']'}) {
5513 0         0 $delimiter = '[';
5514 0         0 $end_delimiter = ']';
5515             }
5516             elsif (not $octet{'>'}) {
5517 0         0 $delimiter = '<';
5518 0         0 $end_delimiter = '>';
5519             }
5520             else {
5521 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5522 0 0       0 if (not $octet{$char}) {
5523 0         0 $delimiter = $char;
5524 0         0 $end_delimiter = $char;
5525 0         0 last;
5526             }
5527             }
5528             }
5529             }
5530              
5531 2 50 33     13 if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5532 0         0 return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5533             }
5534             else {
5535 2         9 return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5536             }
5537             }
5538              
5539 641 100       1425 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5540 641         2522 my $metachar = qr/[\@\\|[\]{^]/oxms;
5541              
5542             # split regexp
5543 641         70969 my @char = $string =~ /\G((?>
5544             [^\\\$\@\[\(] |
5545             \\x (?>[0-9A-Fa-f]{1,2}) |
5546             \\ (?>[0-7]{2,3}) |
5547             \\c [\x40-\x5F] |
5548             \\x\{ (?>[0-9A-Fa-f]+) \} |
5549             \\o\{ (?>[0-7]+) \} |
5550             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5551             \\ $q_char |
5552             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5553             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5554             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5555             [\$\@] $qq_variable |
5556             \$ (?>\s* [0-9]+) |
5557             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5558             \$ \$ (?![\w\{]) |
5559             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5560             \[\^ |
5561             \[\: (?>[a-z]+) :\] |
5562             \[\:\^ (?>[a-z]+) :\] |
5563             \(\? |
5564             $q_char
5565             ))/oxmsg;
5566              
5567             # choice again delimiter
5568 641 50       3831 if ($delimiter =~ / [\@:] /oxms) {
5569 0         0 my %octet = map {$_ => 1} @char;
  0         0  
5570 0 0       0 if (not $octet{')'}) {
    0          
    0          
    0          
5571 0         0 $delimiter = '(';
5572 0         0 $end_delimiter = ')';
5573             }
5574             elsif (not $octet{'}'}) {
5575 0         0 $delimiter = '{';
5576 0         0 $end_delimiter = '}';
5577             }
5578             elsif (not $octet{']'}) {
5579 0         0 $delimiter = '[';
5580 0         0 $end_delimiter = ']';
5581             }
5582             elsif (not $octet{'>'}) {
5583 0         0 $delimiter = '<';
5584 0         0 $end_delimiter = '>';
5585             }
5586             else {
5587 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5588 0 0       0 if (not $octet{$char}) {
5589 0         0 $delimiter = $char;
5590 0         0 $end_delimiter = $char;
5591 0         0 last;
5592             }
5593             }
5594             }
5595             }
5596              
5597 641         862 my $left_e = 0;
5598 641         732 my $right_e = 0;
5599 641         1813 for (my $i=0; $i <= $#char; $i++) {
5600              
5601             # "\L\u" --> "\u\L"
5602 1867 50 66     12215 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 66        
    100          
    100          
    100          
    100          
5603 0         0 @char[$i,$i+1] = @char[$i+1,$i];
5604             }
5605              
5606             # "\U\l" --> "\l\U"
5607             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5608 0         0 @char[$i,$i+1] = @char[$i+1,$i];
5609             }
5610              
5611             # octal escape sequence
5612             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5613 1         5 $char[$i] = Ekoi8u::octchr($1);
5614             }
5615              
5616             # hexadecimal escape sequence
5617             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5618 1         3 $char[$i] = Ekoi8u::hexchr($1);
5619             }
5620              
5621             # \b{...} --> b\{...}
5622             # \B{...} --> B\{...}
5623             # \N{CHARNAME} --> N\{CHARNAME}
5624             # \p{PROPERTY} --> p\{PROPERTY}
5625             # \P{PROPERTY} --> P\{PROPERTY}
5626             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5627 6         16 $char[$i] = $1 . '\\' . $2;
5628             }
5629              
5630             # \p, \P, \X --> p, P, X
5631             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5632 4         12 $char[$i] = $1;
5633             }
5634              
5635 1867 100 100     6214 if (0) {
    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          
5636             }
5637              
5638             # join separated multiple-octet
5639 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5640 6 50 33     97 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)) {
    50 33        
    50 33        
      33        
      66        
      33        
5641 0         0 $char[$i] .= join '', splice @char, $i+1, 3;
5642             }
5643             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)) {
5644 0         0 $char[$i] .= join '', splice @char, $i+1, 2;
5645             }
5646             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)) {
5647 0         0 $char[$i] .= join '', splice @char, $i+1, 1;
5648             }
5649             }
5650              
5651             # open character class [...]
5652             elsif ($char[$i] eq '[') {
5653 328         425 my $left = $i;
5654              
5655             # [] make die "Unmatched [] in regexp ...\n"
5656             # (and so on)
5657              
5658 328 100       923 if ($char[$i+1] eq ']') {
5659 3         7 $i++;
5660             }
5661              
5662 328         381 while (1) {
5663 1379 50       2027 if (++$i > $#char) {
5664 0         0 die __FILE__, ": Unmatched [] in regexp\n";
5665             }
5666 1379 100       2389 if ($char[$i] eq ']') {
5667 328         387 my $right = $i;
5668              
5669             # [...]
5670 328 100       2215 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5671 30         96 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);
  90         364  
5672             }
5673             else {
5674 298         1365 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
5675             }
5676              
5677 328         528 $i = $left;
5678 328         995 last;
5679             }
5680             }
5681             }
5682              
5683             # open character class [^...]
5684             elsif ($char[$i] eq '[^') {
5685 74         84 my $left = $i;
5686              
5687             # [^] make die "Unmatched [] in regexp ...\n"
5688             # (and so on)
5689              
5690 74 100       197 if ($char[$i+1] eq ']') {
5691 4         8 $i++;
5692             }
5693              
5694 74         65 while (1) {
5695 272 50       379 if (++$i > $#char) {
5696 0         0 die __FILE__, ": Unmatched [] in regexp\n";
5697             }
5698 272 100       472 if ($char[$i] eq ']') {
5699 74         73 my $right = $i;
5700              
5701             # [^...]
5702 74 100       442 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5703 30         68 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);
  90         108  
5704             }
5705             else {
5706 44         218 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5707             }
5708              
5709 74         115 $i = $left;
5710 74         218 last;
5711             }
5712             }
5713             }
5714              
5715             # rewrite character class or escape character
5716             elsif (my $char = character_class($char[$i],$modifier)) {
5717 139         551 $char[$i] = $char;
5718             }
5719              
5720             # /i modifier
5721             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
5722 20 50       23 if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
5723 20         26 $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
5724             }
5725             else {
5726 0         0 $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
5727             }
5728             }
5729              
5730             # \u \l \U \L \F \Q \E
5731             elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5732 1 50       8 if ($right_e < $left_e) {
5733 0         0 $char[$i] = '\\' . $char[$i];
5734             }
5735             }
5736             elsif ($char[$i] eq '\u') {
5737 0         0 $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5738 0         0 $left_e++;
5739             }
5740             elsif ($char[$i] eq '\l') {
5741 0         0 $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5742 0         0 $left_e++;
5743             }
5744             elsif ($char[$i] eq '\U') {
5745 1         2 $char[$i] = '@{[Ekoi8u::uc qq<';
5746 1         4 $left_e++;
5747             }
5748             elsif ($char[$i] eq '\L') {
5749 1         2 $char[$i] = '@{[Ekoi8u::lc qq<';
5750 1         4 $left_e++;
5751             }
5752             elsif ($char[$i] eq '\F') {
5753 18         21 $char[$i] = '@{[Ekoi8u::fc qq<';
5754 18         74 $left_e++;
5755             }
5756             elsif ($char[$i] eq '\Q') {
5757 1         2 $char[$i] = '@{[CORE::quotemeta qq<';
5758 1         4 $left_e++;
5759             }
5760             elsif ($char[$i] eq '\E') {
5761 21 50       29 if ($right_e < $left_e) {
5762 21         22 $char[$i] = '>]}';
5763 21         70 $right_e++;
5764             }
5765             else {
5766 0         0 $char[$i] = '';
5767             }
5768             }
5769             elsif ($char[$i] eq '\Q') {
5770 0         0 while (1) {
5771 0 0       0 if (++$i > $#char) {
5772 0         0 last;
5773             }
5774 0 0       0 if ($char[$i] eq '\E') {
5775 0         0 last;
5776             }
5777             }
5778             }
5779             elsif ($char[$i] eq '\E') {
5780             }
5781              
5782             # $0 --> $0
5783             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5784 0 0       0 if ($ignorecase) {
5785 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5786             }
5787             }
5788             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5789 0 0       0 if ($ignorecase) {
5790 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5791             }
5792             }
5793              
5794             # $$ --> $$
5795             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5796             }
5797              
5798             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5799             # $1, $2, $3 --> $1, $2, $3 otherwise
5800             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5801 0         0 $char[$i] = e_capture($1);
5802 0 0       0 if ($ignorecase) {
5803 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5804             }
5805             }
5806             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5807 0         0 $char[$i] = e_capture($1);
5808 0 0       0 if ($ignorecase) {
5809 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5810             }
5811             }
5812              
5813             # $$foo[ ... ] --> $ $foo->[ ... ]
5814             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5815 0         0 $char[$i] = e_capture($1.'->'.$2);
5816 0 0       0 if ($ignorecase) {
5817 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5818             }
5819             }
5820              
5821             # $$foo{ ... } --> $ $foo->{ ... }
5822             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5823 0         0 $char[$i] = e_capture($1.'->'.$2);
5824 0 0       0 if ($ignorecase) {
5825 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5826             }
5827             }
5828              
5829             # $$foo
5830             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5831 0         0 $char[$i] = e_capture($1);
5832 0 0       0 if ($ignorecase) {
5833 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5834             }
5835             }
5836              
5837             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5838             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5839 8 50       22 if ($ignorecase) {
5840 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
5841             }
5842             else {
5843 8         40 $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5844             }
5845             }
5846              
5847             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5848             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5849 8 50       22 if ($ignorecase) {
5850 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
5851             }
5852             else {
5853 8         47 $char[$i] = '@{[Ekoi8u::MATCH()]}';
5854             }
5855             }
5856              
5857             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5858             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5859 6 50       13 if ($ignorecase) {
5860 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
5861             }
5862             else {
5863 6         29 $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5864             }
5865             }
5866              
5867             # ${ foo }
5868             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
5869 0 0       0 if ($ignorecase) {
5870 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5871             }
5872             }
5873              
5874             # ${ ... }
5875             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5876 0         0 $char[$i] = e_capture($1);
5877 0 0       0 if ($ignorecase) {
5878 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5879             }
5880             }
5881              
5882             # $scalar or @array
5883             elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
5884 21         89 $char[$i] = e_string($char[$i]);
5885 21 100       70 if ($ignorecase) {
5886 11         56 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5887             }
5888             }
5889              
5890             # quote character before ? + * {
5891             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
5892 138 100 33     1193 if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
    50          
5893             }
5894             elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5895 0         0 my $char = $char[$i-1];
5896 0 0       0 if ($char[$i] eq '{') {
5897 0         0 die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
5898             }
5899             else {
5900 0         0 die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
5901             }
5902             }
5903             else {
5904 127         843 $char[$i-1] = '(?:' . $char[$i-1] . ')';
5905             }
5906             }
5907             }
5908              
5909             # make regexp string
5910 641         919 $modifier =~ tr/i//d;
5911 641 50       1634 if ($left_e > $right_e) {
5912 0 0 0     0 if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5913 0         0 return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
5914             }
5915             else {
5916 0         0 return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
5917             }
5918             }
5919 641 50 33     4108 if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5920 0         0 return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
5921             }
5922             else {
5923 641         5771 return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5924             }
5925             }
5926              
5927             #
5928             # double quote stuff
5929             #
5930             sub qq_stuff {
5931 180     180 0 214 my($delimiter,$end_delimiter,$stuff) = @_;
5932              
5933             # scalar variable or array variable
5934 180 100       515 if ($stuff =~ /\A [\$\@] /oxms) {
5935 100         385 return $stuff;
5936             }
5937              
5938             # quote by delimiter
5939 80         203 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
  80         268  
5940 80         211 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5941 80 50       149 next if $char eq $delimiter;
5942 80 50       125 next if $char eq $end_delimiter;
5943 80 50       150 if (not $octet{$char}) {
5944 80         494 return join '', 'qq', $char, $stuff, $char;
5945             }
5946             }
5947 0         0 return join '', 'qq', '<', $stuff, '>';
5948             }
5949              
5950             #
5951             # escape regexp (m'', qr'', and m''b, qr''b)
5952             #
5953             sub e_qr_q {
5954 10     10 0 37 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5955 10   50     43 $modifier ||= '';
5956              
5957 10         29 $modifier =~ tr/p//d;
5958 10 50       28 if ($modifier =~ /([adlu])/oxms) {
5959 0         0 my $line = 0;
5960 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5961 0 0       0 if ($filename ne __FILE__) {
5962 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5963 0         0 last;
5964             }
5965             }
5966 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
5967             }
5968              
5969 10         13 $slash = 'div';
5970              
5971             # literal null string pattern
5972 10 100       30 if ($string eq '') {
    50          
5973 8         9 $modifier =~ tr/bB//d;
5974 8         13 $modifier =~ tr/i//d;
5975 8         48 return join '', $ope, $delimiter, $end_delimiter, $modifier;
5976             }
5977              
5978             # with /b /B modifier
5979             elsif ($modifier =~ tr/bB//d) {
5980 0         0 return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
5981             }
5982              
5983             # without /b /B modifier
5984             else {
5985 2         9 return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
5986             }
5987             }
5988              
5989             #
5990             # escape regexp (m'', qr'')
5991             #
5992             sub e_qr_qt {
5993 2     2 0 6 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5994              
5995 2 50       9 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5996              
5997             # split regexp
5998 2         104 my @char = $string =~ /\G((?>
5999             [^\\\[\$\@\/] |
6000             [\x00-\xFF] |
6001             \[\^ |
6002             \[\: (?>[a-z]+) \:\] |
6003             \[\:\^ (?>[a-z]+) \:\] |
6004             [\$\@\/] |
6005             \\ (?:$q_char) |
6006             (?:$q_char)
6007             ))/oxmsg;
6008              
6009             # unescape character
6010 2         11 for (my $i=0; $i <= $#char; $i++) {
6011 2 50 33     19 if (0) {
    50 33        
    50 33        
    50          
    50          
    50          
6012             }
6013              
6014             # open character class [...]
6015 0         0 elsif ($char[$i] eq '[') {
6016 0         0 my $left = $i;
6017 0 0       0 if ($char[$i+1] eq ']') {
6018 0         0 $i++;
6019             }
6020 0         0 while (1) {
6021 0 0       0 if (++$i > $#char) {
6022 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6023             }
6024 0 0       0 if ($char[$i] eq ']') {
6025 0         0 my $right = $i;
6026              
6027             # [...]
6028 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6029              
6030 0         0 $i = $left;
6031 0         0 last;
6032             }
6033             }
6034             }
6035              
6036             # open character class [^...]
6037             elsif ($char[$i] eq '[^') {
6038 0         0 my $left = $i;
6039 0 0       0 if ($char[$i+1] eq ']') {
6040 0         0 $i++;
6041             }
6042 0         0 while (1) {
6043 0 0       0 if (++$i > $#char) {
6044 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6045             }
6046 0 0       0 if ($char[$i] eq ']') {
6047 0         0 my $right = $i;
6048              
6049             # [^...]
6050 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6051              
6052 0         0 $i = $left;
6053 0         0 last;
6054             }
6055             }
6056             }
6057              
6058             # escape $ @ / and \
6059             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6060 0         0 $char[$i] = '\\' . $char[$i];
6061             }
6062              
6063             # rewrite character class or escape character
6064             elsif (my $char = character_class($char[$i],$modifier)) {
6065 0         0 $char[$i] = $char;
6066             }
6067              
6068             # /i modifier
6069             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6070 0 0       0 if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6071 0         0 $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6072             }
6073             else {
6074 0         0 $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6075             }
6076             }
6077              
6078             # quote character before ? + * {
6079             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6080 0 0       0 if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6081             }
6082             else {
6083 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
6084             }
6085             }
6086             }
6087              
6088 2         6 $delimiter = '/';
6089 2         3 $end_delimiter = '/';
6090              
6091 2         3 $modifier =~ tr/i//d;
6092 2         14 return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6093             }
6094              
6095             #
6096             # escape regexp (m''b, qr''b)
6097             #
6098             sub e_qr_qb {
6099 0     0 0 0 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6100              
6101             # split regexp
6102 0         0 my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6103              
6104             # unescape character
6105 0         0 for (my $i=0; $i <= $#char; $i++) {
6106 0 0       0 if (0) {
    0          
6107             }
6108              
6109             # remain \\
6110 0         0 elsif ($char[$i] eq '\\\\') {
6111             }
6112              
6113             # escape $ @ / and \
6114             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6115 0         0 $char[$i] = '\\' . $char[$i];
6116             }
6117             }
6118              
6119 0         0 $delimiter = '/';
6120 0         0 $end_delimiter = '/';
6121 0         0 return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6122             }
6123              
6124             #
6125             # escape regexp (s/here//)
6126             #
6127             sub e_s1 {
6128 76     76 0 173 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6129 76   100     325 $modifier ||= '';
6130              
6131 76         107 $modifier =~ tr/p//d;
6132 76 50       234 if ($modifier =~ /([adlu])/oxms) {
6133 0         0 my $line = 0;
6134 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6135 0 0       0 if ($filename ne __FILE__) {
6136 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6137 0         0 last;
6138             }
6139             }
6140 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
6141             }
6142              
6143 76         129 $slash = 'div';
6144              
6145             # literal null string pattern
6146 76 100       362 if ($string eq '') {
    50          
6147 8         11 $modifier =~ tr/bB//d;
6148 8         9 $modifier =~ tr/i//d;
6149 8         68 return join '', $ope, $delimiter, $end_delimiter, $modifier;
6150             }
6151              
6152             # /b /B modifier
6153             elsif ($modifier =~ tr/bB//d) {
6154              
6155             # choice again delimiter
6156 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
6157 0         0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
6158 0         0 my %octet = map {$_ => 1} @char;
  0         0  
6159 0 0       0 if (not $octet{')'}) {
    0          
    0          
    0          
6160 0         0 $delimiter = '(';
6161 0         0 $end_delimiter = ')';
6162             }
6163             elsif (not $octet{'}'}) {
6164 0         0 $delimiter = '{';
6165 0         0 $end_delimiter = '}';
6166             }
6167             elsif (not $octet{']'}) {
6168 0         0 $delimiter = '[';
6169 0         0 $end_delimiter = ']';
6170             }
6171             elsif (not $octet{'>'}) {
6172 0         0 $delimiter = '<';
6173 0         0 $end_delimiter = '>';
6174             }
6175             else {
6176 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6177 0 0       0 if (not $octet{$char}) {
6178 0         0 $delimiter = $char;
6179 0         0 $end_delimiter = $char;
6180 0         0 last;
6181             }
6182             }
6183             }
6184             }
6185              
6186 0         0 my $prematch = '';
6187 0         0 return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6188             }
6189              
6190 68 100       203 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6191 68         347 my $metachar = qr/[\@\\|[\]{^]/oxms;
6192              
6193             # split regexp
6194 68         17767 my @char = $string =~ /\G((?>
6195             [^\\\$\@\[\(] |
6196             \\ (?>[1-9][0-9]*) |
6197             \\g (?>\s*) (?>[1-9][0-9]*) |
6198             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6199             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6200             \\x (?>[0-9A-Fa-f]{1,2}) |
6201             \\ (?>[0-7]{2,3}) |
6202             \\c [\x40-\x5F] |
6203             \\x\{ (?>[0-9A-Fa-f]+) \} |
6204             \\o\{ (?>[0-7]+) \} |
6205             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6206             \\ $q_char |
6207             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6208             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6209             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6210             [\$\@] $qq_variable |
6211             \$ (?>\s* [0-9]+) |
6212             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6213             \$ \$ (?![\w\{]) |
6214             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6215             \[\^ |
6216             \[\: (?>[a-z]+) :\] |
6217             \[\:\^ (?>[a-z]+) :\] |
6218             \(\? |
6219             $q_char
6220             ))/oxmsg;
6221              
6222             # choice again delimiter
6223 68 50       659 if ($delimiter =~ / [\@:] /oxms) {
6224 0         0 my %octet = map {$_ => 1} @char;
  0         0  
6225 0 0       0 if (not $octet{')'}) {
    0          
    0          
    0          
6226 0         0 $delimiter = '(';
6227 0         0 $end_delimiter = ')';
6228             }
6229             elsif (not $octet{'}'}) {
6230 0         0 $delimiter = '{';
6231 0         0 $end_delimiter = '}';
6232             }
6233             elsif (not $octet{']'}) {
6234 0         0 $delimiter = '[';
6235 0         0 $end_delimiter = ']';
6236             }
6237             elsif (not $octet{'>'}) {
6238 0         0 $delimiter = '<';
6239 0         0 $end_delimiter = '>';
6240             }
6241             else {
6242 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6243 0 0       0 if (not $octet{$char}) {
6244 0         0 $delimiter = $char;
6245 0         0 $end_delimiter = $char;
6246 0         0 last;
6247             }
6248             }
6249             }
6250             }
6251              
6252             # count '('
6253 68         153 my $parens = grep { $_ eq '(' } @char;
  253         439  
6254              
6255 68         100 my $left_e = 0;
6256 68         104 my $right_e = 0;
6257 68         249 for (my $i=0; $i <= $#char; $i++) {
6258              
6259             # "\L\u" --> "\u\L"
6260 195 50 33     1509 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 33        
    100          
    100          
    50          
    50          
6261 0         0 @char[$i,$i+1] = @char[$i+1,$i];
6262             }
6263              
6264             # "\U\l" --> "\l\U"
6265             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6266 0         0 @char[$i,$i+1] = @char[$i+1,$i];
6267             }
6268              
6269             # octal escape sequence
6270             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6271 1         3 $char[$i] = Ekoi8u::octchr($1);
6272             }
6273              
6274             # hexadecimal escape sequence
6275             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6276 1         4 $char[$i] = Ekoi8u::hexchr($1);
6277             }
6278              
6279             # \b{...} --> b\{...}
6280             # \B{...} --> B\{...}
6281             # \N{CHARNAME} --> N\{CHARNAME}
6282             # \p{PROPERTY} --> p\{PROPERTY}
6283             # \P{PROPERTY} --> P\{PROPERTY}
6284             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6285 0         0 $char[$i] = $1 . '\\' . $2;
6286             }
6287              
6288             # \p, \P, \X --> p, P, X
6289             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6290 0         0 $char[$i] = $1;
6291             }
6292              
6293 195 50 66     859 if (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          
6294             }
6295              
6296             # join separated multiple-octet
6297 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6298 0 0 0     0 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)) {
    0 0        
    0 0        
      0        
      0        
      0        
6299 0         0 $char[$i] .= join '', splice @char, $i+1, 3;
6300             }
6301             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)) {
6302 0         0 $char[$i] .= join '', splice @char, $i+1, 2;
6303             }
6304             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)) {
6305 0         0 $char[$i] .= join '', splice @char, $i+1, 1;
6306             }
6307             }
6308              
6309             # open character class [...]
6310             elsif ($char[$i] eq '[') {
6311 13         19 my $left = $i;
6312 13 50       51 if ($char[$i+1] eq ']') {
6313 0         0 $i++;
6314             }
6315 13         14 while (1) {
6316 58 50       86 if (++$i > $#char) {
6317 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6318             }
6319 58 100       109 if ($char[$i] eq ']') {
6320 13         18 my $right = $i;
6321              
6322             # [...]
6323 13 50       107 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6324 0         0 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);
  0         0  
6325             }
6326             else {
6327 13         114 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6328             }
6329              
6330 13         22 $i = $left;
6331 13         37 last;
6332             }
6333             }
6334             }
6335              
6336             # open character class [^...]
6337             elsif ($char[$i] eq '[^') {
6338 0         0 my $left = $i;
6339 0 0       0 if ($char[$i+1] eq ']') {
6340 0         0 $i++;
6341             }
6342 0         0 while (1) {
6343 0 0       0 if (++$i > $#char) {
6344 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6345             }
6346 0 0       0 if ($char[$i] eq ']') {
6347 0         0 my $right = $i;
6348              
6349             # [^...]
6350 0 0       0 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6351 0         0 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);
  0         0  
6352             }
6353             else {
6354 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6355             }
6356              
6357 0         0 $i = $left;
6358 0         0 last;
6359             }
6360             }
6361             }
6362              
6363             # rewrite character class or escape character
6364             elsif (my $char = character_class($char[$i],$modifier)) {
6365 7         19 $char[$i] = $char;
6366             }
6367              
6368             # /i modifier
6369             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6370 3 50       5 if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6371 3         5 $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6372             }
6373             else {
6374 0         0 $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6375             }
6376             }
6377              
6378             # \u \l \U \L \F \Q \E
6379             elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6380 0 0       0 if ($right_e < $left_e) {
6381 0         0 $char[$i] = '\\' . $char[$i];
6382             }
6383             }
6384             elsif ($char[$i] eq '\u') {
6385 0         0 $char[$i] = '@{[Ekoi8u::ucfirst qq<';
6386 0         0 $left_e++;
6387             }
6388             elsif ($char[$i] eq '\l') {
6389 0         0 $char[$i] = '@{[Ekoi8u::lcfirst qq<';
6390 0         0 $left_e++;
6391             }
6392             elsif ($char[$i] eq '\U') {
6393 0         0 $char[$i] = '@{[Ekoi8u::uc qq<';
6394 0         0 $left_e++;
6395             }
6396             elsif ($char[$i] eq '\L') {
6397 0         0 $char[$i] = '@{[Ekoi8u::lc qq<';
6398 0         0 $left_e++;
6399             }
6400             elsif ($char[$i] eq '\F') {
6401 0         0 $char[$i] = '@{[Ekoi8u::fc qq<';
6402 0         0 $left_e++;
6403             }
6404             elsif ($char[$i] eq '\Q') {
6405 0         0 $char[$i] = '@{[CORE::quotemeta qq<';
6406 0         0 $left_e++;
6407             }
6408             elsif ($char[$i] eq '\E') {
6409 0 0       0 if ($right_e < $left_e) {
6410 0         0 $char[$i] = '>]}';
6411 0         0 $right_e++;
6412             }
6413             else {
6414 0         0 $char[$i] = '';
6415             }
6416             }
6417             elsif ($char[$i] eq '\Q') {
6418 0         0 while (1) {
6419 0 0       0 if (++$i > $#char) {
6420 0         0 last;
6421             }
6422 0 0       0 if ($char[$i] eq '\E') {
6423 0         0 last;
6424             }
6425             }
6426             }
6427             elsif ($char[$i] eq '\E') {
6428             }
6429              
6430             # \0 --> \0
6431             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6432             }
6433              
6434             # \g{N}, \g{-N}
6435              
6436             # P.108 Using Simple Patterns
6437             # in Chapter 7: In the World of Regular Expressions
6438             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6439              
6440             # P.221 Capturing
6441             # in Chapter 5: Pattern Matching
6442             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6443              
6444             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6445             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6446             }
6447              
6448             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6449             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6450             }
6451              
6452             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6453             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6454             }
6455              
6456             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6457             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6458             }
6459              
6460             # $0 --> $0
6461             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6462 0 0       0 if ($ignorecase) {
6463 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6464             }
6465             }
6466             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6467 0 0       0 if ($ignorecase) {
6468 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6469             }
6470             }
6471              
6472             # $$ --> $$
6473             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6474             }
6475              
6476             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6477             # $1, $2, $3 --> $1, $2, $3 otherwise
6478             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6479 0         0 $char[$i] = e_capture($1);
6480 0 0       0 if ($ignorecase) {
6481 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6482             }
6483             }
6484             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6485 0         0 $char[$i] = e_capture($1);
6486 0 0       0 if ($ignorecase) {
6487 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6488             }
6489             }
6490              
6491             # $$foo[ ... ] --> $ $foo->[ ... ]
6492             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
6493 0         0 $char[$i] = e_capture($1.'->'.$2);
6494 0 0       0 if ($ignorecase) {
6495 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6496             }
6497             }
6498              
6499             # $$foo{ ... } --> $ $foo->{ ... }
6500             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
6501 0         0 $char[$i] = e_capture($1.'->'.$2);
6502 0 0       0 if ($ignorecase) {
6503 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6504             }
6505             }
6506              
6507             # $$foo
6508             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6509 0         0 $char[$i] = e_capture($1);
6510 0 0       0 if ($ignorecase) {
6511 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6512             }
6513             }
6514              
6515             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
6516             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6517 4 50       11 if ($ignorecase) {
6518 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
6519             }
6520             else {
6521 4         18 $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
6522             }
6523             }
6524              
6525             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
6526             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6527 4 50       15 if ($ignorecase) {
6528 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
6529             }
6530             else {
6531 4         27 $char[$i] = '@{[Ekoi8u::MATCH()]}';
6532             }
6533             }
6534              
6535             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
6536             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6537 3 50       9 if ($ignorecase) {
6538 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
6539             }
6540             else {
6541 3         18 $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
6542             }
6543             }
6544              
6545             # ${ foo }
6546             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
6547 0 0       0 if ($ignorecase) {
6548 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6549             }
6550             }
6551              
6552             # ${ ... }
6553             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6554 0         0 $char[$i] = e_capture($1);
6555 0 0       0 if ($ignorecase) {
6556 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6557             }
6558             }
6559              
6560             # $scalar or @array
6561             elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6562 4         13 $char[$i] = e_string($char[$i]);
6563 4 50       40 if ($ignorecase) {
6564 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6565             }
6566             }
6567              
6568             # quote character before ? + * {
6569             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6570 13 50       62 if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6571             }
6572             else {
6573 13         100 $char[$i-1] = '(?:' . $char[$i-1] . ')';
6574             }
6575             }
6576             }
6577              
6578             # make regexp string
6579 68         220 my $prematch = '';
6580 68         113 $modifier =~ tr/i//d;
6581 68 50       243 if ($left_e > $right_e) {
6582 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6583             }
6584 68         955 return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6585             }
6586              
6587             #
6588             # escape regexp (s'here'' or s'here''b)
6589             #
6590             sub e_s1_q {
6591 21     21 0 66 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6592 21   100     72 $modifier ||= '';
6593              
6594 21         28 $modifier =~ tr/p//d;
6595 21 50       42 if ($modifier =~ /([adlu])/oxms) {
6596 0         0 my $line = 0;
6597 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6598 0 0       0 if ($filename ne __FILE__) {
6599 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6600 0         0 last;
6601             }
6602             }
6603 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
6604             }
6605              
6606 21         28 $slash = 'div';
6607              
6608             # literal null string pattern
6609 21 100       57 if ($string eq '') {
    50          
6610 8         9 $modifier =~ tr/bB//d;
6611 8         8 $modifier =~ tr/i//d;
6612 8         54 return join '', $ope, $delimiter, $end_delimiter, $modifier;
6613             }
6614              
6615             # with /b /B modifier
6616             elsif ($modifier =~ tr/bB//d) {
6617 0         0 return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6618             }
6619              
6620             # without /b /B modifier
6621             else {
6622 13         31 return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6623             }
6624             }
6625              
6626             #
6627             # escape regexp (s'here'')
6628             #
6629             sub e_s1_qt {
6630 13     13 0 30 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6631              
6632 13 50       33 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6633              
6634             # split regexp
6635 13         308 my @char = $string =~ /\G((?>
6636             [^\\\[\$\@\/] |
6637             [\x00-\xFF] |
6638             \[\^ |
6639             \[\: (?>[a-z]+) \:\] |
6640             \[\:\^ (?>[a-z]+) \:\] |
6641             [\$\@\/] |
6642             \\ (?:$q_char) |
6643             (?:$q_char)
6644             ))/oxmsg;
6645              
6646             # unescape character
6647 13         49 for (my $i=0; $i <= $#char; $i++) {
6648 25 50 33     150 if (0) {
    50 33        
    50 66        
    100          
    50          
    50          
6649             }
6650              
6651             # open character class [...]
6652 0         0 elsif ($char[$i] eq '[') {
6653 0         0 my $left = $i;
6654 0 0       0 if ($char[$i+1] eq ']') {
6655 0         0 $i++;
6656             }
6657 0         0 while (1) {
6658 0 0       0 if (++$i > $#char) {
6659 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6660             }
6661 0 0       0 if ($char[$i] eq ']') {
6662 0         0 my $right = $i;
6663              
6664             # [...]
6665 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6666              
6667 0         0 $i = $left;
6668 0         0 last;
6669             }
6670             }
6671             }
6672              
6673             # open character class [^...]
6674             elsif ($char[$i] eq '[^') {
6675 0         0 my $left = $i;
6676 0 0       0 if ($char[$i+1] eq ']') {
6677 0         0 $i++;
6678             }
6679 0         0 while (1) {
6680 0 0       0 if (++$i > $#char) {
6681 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6682             }
6683 0 0       0 if ($char[$i] eq ']') {
6684 0         0 my $right = $i;
6685              
6686             # [^...]
6687 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6688              
6689 0         0 $i = $left;
6690 0         0 last;
6691             }
6692             }
6693             }
6694              
6695             # escape $ @ / and \
6696             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6697 0         0 $char[$i] = '\\' . $char[$i];
6698             }
6699              
6700             # rewrite character class or escape character
6701             elsif (my $char = character_class($char[$i],$modifier)) {
6702 6         19 $char[$i] = $char;
6703             }
6704              
6705             # /i modifier
6706             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6707 0 0       0 if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6708 0         0 $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6709             }
6710             else {
6711 0         0 $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6712             }
6713             }
6714              
6715             # quote character before ? + * {
6716             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6717 0 0       0 if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6718             }
6719             else {
6720 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
6721             }
6722             }
6723             }
6724              
6725 13         22 $modifier =~ tr/i//d;
6726 13         19 $delimiter = '/';
6727 13         15 $end_delimiter = '/';
6728 13         17 my $prematch = '';
6729 13         125 return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6730             }
6731              
6732             #
6733             # escape regexp (s'here''b)
6734             #
6735             sub e_s1_qb {
6736 0     0 0 0 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6737              
6738             # split regexp
6739 0         0 my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6740              
6741             # unescape character
6742 0         0 for (my $i=0; $i <= $#char; $i++) {
6743 0 0       0 if (0) {
    0          
6744             }
6745              
6746             # remain \\
6747 0         0 elsif ($char[$i] eq '\\\\') {
6748             }
6749              
6750             # escape $ @ / and \
6751             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6752 0         0 $char[$i] = '\\' . $char[$i];
6753             }
6754             }
6755              
6756 0         0 $delimiter = '/';
6757 0         0 $end_delimiter = '/';
6758 0         0 my $prematch = '';
6759 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6760             }
6761              
6762             #
6763             # escape regexp (s''here')
6764             #
6765             sub e_s2_q {
6766 16     16 0 30 my($ope,$delimiter,$end_delimiter,$string) = @_;
6767              
6768 16         17 $slash = 'div';
6769              
6770 16         127 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
6771 16         52 for (my $i=0; $i <= $#char; $i++) {
6772 9 100       37 if (0) {
    100          
6773             }
6774              
6775             # not escape \\
6776 0         0 elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
6777             }
6778              
6779             # escape $ @ / and \
6780             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6781 5         17 $char[$i] = '\\' . $char[$i];
6782             }
6783             }
6784              
6785 16         54 return join '', $ope, $delimiter, @char, $end_delimiter;
6786             }
6787              
6788             #
6789             # escape regexp (s/here/and here/modifier)
6790             #
6791             sub e_sub {
6792 97     97 0 524 my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
6793 97   100     414 $modifier ||= '';
6794              
6795 97         186 $modifier =~ tr/p//d;
6796 97 50       328 if ($modifier =~ /([adlu])/oxms) {
6797 0         0 my $line = 0;
6798 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6799 0 0       0 if ($filename ne __FILE__) {
6800 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6801 0         0 last;
6802             }
6803             }
6804 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
6805             }
6806              
6807 97 100       264 if ($variable eq '') {
6808 36         44 $variable = '$_';
6809 36         48 $bind_operator = ' =~ ';
6810             }
6811              
6812 97         158 $slash = 'div';
6813              
6814             # P.128 Start of match (or end of previous match): \G
6815             # P.130 Advanced Use of \G with Perl
6816             # in Chapter 3: Overview of Regular Expression Features and Flavors
6817             # P.312 Iterative Matching: Scalar Context, with /g
6818             # in Chapter 7: Perl
6819             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
6820              
6821             # P.181 Where You Left Off: The \G Assertion
6822             # in Chapter 5: Pattern Matching
6823             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6824              
6825             # P.220 Where You Left Off: The \G Assertion
6826             # in Chapter 5: Pattern Matching
6827             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6828              
6829 97         161 my $e_modifier = $modifier =~ tr/e//d;
6830 97         128 my $r_modifier = $modifier =~ tr/r//d;
6831              
6832 97         134 my $my = '';
6833 97 50       257 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
6834 0         0 $my = $variable;
6835 0         0 $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
6836 0         0 $variable =~ s/ = .+ \z//oxms;
6837             }
6838              
6839 97         240 (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
6840 97         160 $variable_basename =~ s/ \s+ \z//oxms;
6841              
6842             # quote replacement string
6843 97         118 my $e_replacement = '';
6844 97 100       250 if ($e_modifier >= 1) {
6845 17         34 $e_replacement = e_qq('', '', '', $replacement);
6846 17         27 $e_modifier--;
6847             }
6848             else {
6849 80 100       199 if ($delimiter2 eq "'") {
6850 16         40 $e_replacement = e_s2_q('qq', '/', '/', $replacement);
6851             }
6852             else {
6853 64         166 $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
6854             }
6855             }
6856              
6857 97         173 my $sub = '';
6858              
6859             # with /r
6860 97 100       242 if ($r_modifier) {
6861 8 100       20 if (0) {
6862             }
6863              
6864             # s///gr without multibyte anchoring
6865 0         0 elsif ($modifier =~ /g/oxms) {
6866 4 50       21 $sub = sprintf(
6867             # 1 2 3 4 5
6868             q,
6869              
6870             $variable, # 1
6871             ($delimiter1 eq "'") ? # 2
6872             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6873             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6874             $s_matched, # 3
6875             $e_replacement, # 4
6876             '$KOI8U::re_r=CORE::eval $KOI8U::re_r; ' x $e_modifier, # 5
6877             );
6878             }
6879              
6880             # s///r
6881             else {
6882              
6883 4         6 my $prematch = q{$`};
6884              
6885 4 50       16 $sub = sprintf(
6886             # 1 2 3 4 5 6 7
6887             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $KOI8U::re_r=%s; %s"%s$KOI8U::re_r$'" } : %s>,
6888              
6889             $variable, # 1
6890             ($delimiter1 eq "'") ? # 2
6891             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6892             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6893             $s_matched, # 3
6894             $e_replacement, # 4
6895             '$KOI8U::re_r=CORE::eval $KOI8U::re_r; ' x $e_modifier, # 5
6896             $prematch, # 6
6897             $variable, # 7
6898             );
6899             }
6900              
6901             # $var !~ s///r doesn't make sense
6902 8 50       29 if ($bind_operator =~ / !~ /oxms) {
6903 0         0 $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
6904             }
6905             }
6906              
6907             # without /r
6908             else {
6909 89 100       232 if (0) {
6910             }
6911              
6912             # s///g without multibyte anchoring
6913 0         0 elsif ($modifier =~ /g/oxms) {
6914 22 100       110 $sub = sprintf(
    100          
6915             # 1 2 3 4 5 6 7 8
6916             q,
6917              
6918             $variable, # 1
6919             ($delimiter1 eq "'") ? # 2
6920             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6921             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6922             $s_matched, # 3
6923             $e_replacement, # 4
6924             '$KOI8U::re_r=CORE::eval $KOI8U::re_r; ' x $e_modifier, # 5
6925             $variable, # 6
6926             $variable, # 7
6927             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
6928             );
6929             }
6930              
6931             # s///
6932             else {
6933              
6934 67         134 my $prematch = q{$`};
6935              
6936 67 100       456 $sub = sprintf(
    100          
6937              
6938             ($bind_operator =~ / =~ /oxms) ?
6939              
6940             # 1 2 3 4 5 6 7 8
6941             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $KOI8U::re_r=%s; %s%s="%s$KOI8U::re_r$'"; 1 } : undef> :
6942              
6943             # 1 2 3 4 5 6 7 8
6944             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $KOI8U::re_r=%s; %s%s="%s$KOI8U::re_r$'"; undef }>,
6945              
6946             $variable, # 1
6947             $bind_operator, # 2
6948             ($delimiter1 eq "'") ? # 3
6949             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6950             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6951             $s_matched, # 4
6952             $e_replacement, # 5
6953             '$KOI8U::re_r=CORE::eval $KOI8U::re_r; ' x $e_modifier, # 6
6954             $variable, # 7
6955             $prematch, # 8
6956             );
6957             }
6958             }
6959              
6960             # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
6961 97 50       286 if ($my ne '') {
6962 0         0 $sub = "($my, $sub)[1]";
6963             }
6964              
6965             # clear s/// variable
6966 97         136 $sub_variable = '';
6967 97         126 $bind_operator = '';
6968              
6969 97         784 return $sub;
6970             }
6971              
6972             #
6973             # escape regexp of split qr//
6974             #
6975             sub e_split {
6976 74     74 0 221 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6977 74   100     351 $modifier ||= '';
6978              
6979 74         113 $modifier =~ tr/p//d;
6980 74 50       327 if ($modifier =~ /([adlu])/oxms) {
6981 0         0 my $line = 0;
6982 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6983 0 0       0 if ($filename ne __FILE__) {
6984 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6985 0         0 last;
6986             }
6987             }
6988 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
6989             }
6990              
6991 74         107 $slash = 'div';
6992              
6993             # /b /B modifier
6994 74 50       159 if ($modifier =~ tr/bB//d) {
6995 0         0 return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
6996             }
6997              
6998 74 50       181 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6999 74         311 my $metachar = qr/[\@\\|[\]{^]/oxms;
7000              
7001             # split regexp
7002 74         9503 my @char = $string =~ /\G((?>
7003             [^\\\$\@\[\(] |
7004             \\x (?>[0-9A-Fa-f]{1,2}) |
7005             \\ (?>[0-7]{2,3}) |
7006             \\c [\x40-\x5F] |
7007             \\x\{ (?>[0-9A-Fa-f]+) \} |
7008             \\o\{ (?>[0-7]+) \} |
7009             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7010             \\ $q_char |
7011             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7012             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7013             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7014             [\$\@] $qq_variable |
7015             \$ (?>\s* [0-9]+) |
7016             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7017             \$ \$ (?![\w\{]) |
7018             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7019             \[\^ |
7020             \[\: (?>[a-z]+) :\] |
7021             \[\:\^ (?>[a-z]+) :\] |
7022             \(\? |
7023             $q_char
7024             ))/oxmsg;
7025              
7026 74         256 my $left_e = 0;
7027 74         86 my $right_e = 0;
7028 74         328 for (my $i=0; $i <= $#char; $i++) {
7029              
7030             # "\L\u" --> "\u\L"
7031 249 50 33     1489 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 33        
    100          
    100          
    50          
    50          
7032 0         0 @char[$i,$i+1] = @char[$i+1,$i];
7033             }
7034              
7035             # "\U\l" --> "\l\U"
7036             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7037 0         0 @char[$i,$i+1] = @char[$i+1,$i];
7038             }
7039              
7040             # octal escape sequence
7041             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7042 1         3 $char[$i] = Ekoi8u::octchr($1);
7043             }
7044              
7045             # hexadecimal escape sequence
7046             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7047 1         5 $char[$i] = Ekoi8u::hexchr($1);
7048             }
7049              
7050             # \b{...} --> b\{...}
7051             # \B{...} --> B\{...}
7052             # \N{CHARNAME} --> N\{CHARNAME}
7053             # \p{PROPERTY} --> p\{PROPERTY}
7054             # \P{PROPERTY} --> P\{PROPERTY}
7055             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7056 0         0 $char[$i] = $1 . '\\' . $2;
7057             }
7058              
7059             # \p, \P, \X --> p, P, X
7060             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7061 0         0 $char[$i] = $1;
7062             }
7063              
7064 249 50 100     836 if (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          
7065             }
7066              
7067             # join separated multiple-octet
7068 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7069 0 0 0     0 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)) {
    0 0        
    0 0        
      0        
      0        
      0        
7070 0         0 $char[$i] .= join '', splice @char, $i+1, 3;
7071             }
7072             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)) {
7073 0         0 $char[$i] .= join '', splice @char, $i+1, 2;
7074             }
7075             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)) {
7076 0         0 $char[$i] .= join '', splice @char, $i+1, 1;
7077             }
7078             }
7079              
7080             # open character class [...]
7081             elsif ($char[$i] eq '[') {
7082 3         4 my $left = $i;
7083 3 50       10 if ($char[$i+1] eq ']') {
7084 0         0 $i++;
7085             }
7086 3         4 while (1) {
7087 7 50       23 if (++$i > $#char) {
7088 0         0 die __FILE__, ": Unmatched [] in regexp\n";
7089             }
7090 7 100       15 if ($char[$i] eq ']') {
7091 3         4 my $right = $i;
7092              
7093             # [...]
7094 3 50       25 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7095 0         0 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);
  0         0  
7096             }
7097             else {
7098 3         17 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
7099             }
7100              
7101 3         5 $i = $left;
7102 3         9 last;
7103             }
7104             }
7105             }
7106              
7107             # open character class [^...]
7108             elsif ($char[$i] eq '[^') {
7109 0         0 my $left = $i;
7110 0 0       0 if ($char[$i+1] eq ']') {
7111 0         0 $i++;
7112             }
7113 0         0 while (1) {
7114 0 0       0 if (++$i > $#char) {
7115 0         0 die __FILE__, ": Unmatched [] in regexp\n";
7116             }
7117 0 0       0 if ($char[$i] eq ']') {
7118 0         0 my $right = $i;
7119              
7120             # [^...]
7121 0 0       0 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7122 0         0 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);
  0         0  
7123             }
7124             else {
7125 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7126             }
7127              
7128 0         0 $i = $left;
7129 0         0 last;
7130             }
7131             }
7132             }
7133              
7134             # rewrite character class or escape character
7135             elsif (my $char = character_class($char[$i],$modifier)) {
7136 1         3 $char[$i] = $char;
7137             }
7138              
7139             # P.794 29.2.161. split
7140             # in Chapter 29: Functions
7141             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7142              
7143             # P.951 split
7144             # in Chapter 27: Functions
7145             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7146              
7147             # said "The //m modifier is assumed when you split on the pattern /^/",
7148             # but perl5.008 is not so. Therefore, this software adds //m.
7149             # (and so on)
7150              
7151             # split(m/^/) --> split(m/^/m)
7152             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7153 7         31 $modifier .= 'm';
7154             }
7155              
7156             # /i modifier
7157             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
7158 0 0       0 if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
7159 0         0 $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
7160             }
7161             else {
7162 0         0 $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
7163             }
7164             }
7165              
7166             # \u \l \U \L \F \Q \E
7167             elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7168 0 0       0 if ($right_e < $left_e) {
7169 0         0 $char[$i] = '\\' . $char[$i];
7170             }
7171             }
7172             elsif ($char[$i] eq '\u') {
7173 0         0 $char[$i] = '@{[Ekoi8u::ucfirst qq<';
7174 0         0 $left_e++;
7175             }
7176             elsif ($char[$i] eq '\l') {
7177 0         0 $char[$i] = '@{[Ekoi8u::lcfirst qq<';
7178 0         0 $left_e++;
7179             }
7180             elsif ($char[$i] eq '\U') {
7181 0         0 $char[$i] = '@{[Ekoi8u::uc qq<';
7182 0         0 $left_e++;
7183             }
7184             elsif ($char[$i] eq '\L') {
7185 0         0 $char[$i] = '@{[Ekoi8u::lc qq<';
7186 0         0 $left_e++;
7187             }
7188             elsif ($char[$i] eq '\F') {
7189 0         0 $char[$i] = '@{[Ekoi8u::fc qq<';
7190 0         0 $left_e++;
7191             }
7192             elsif ($char[$i] eq '\Q') {
7193 0         0 $char[$i] = '@{[CORE::quotemeta qq<';
7194 0         0 $left_e++;
7195             }
7196             elsif ($char[$i] eq '\E') {
7197 0 0       0 if ($right_e < $left_e) {
7198 0         0 $char[$i] = '>]}';
7199 0         0 $right_e++;
7200             }
7201             else {
7202 0         0 $char[$i] = '';
7203             }
7204             }
7205             elsif ($char[$i] eq '\Q') {
7206 0         0 while (1) {
7207 0 0       0 if (++$i > $#char) {
7208 0         0 last;
7209             }
7210 0 0       0 if ($char[$i] eq '\E') {
7211 0         0 last;
7212             }
7213             }
7214             }
7215             elsif ($char[$i] eq '\E') {
7216             }
7217              
7218             # $0 --> $0
7219             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7220 0 0       0 if ($ignorecase) {
7221 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7222             }
7223             }
7224             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7225 0 0       0 if ($ignorecase) {
7226 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7227             }
7228             }
7229              
7230             # $$ --> $$
7231             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7232             }
7233              
7234             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7235             # $1, $2, $3 --> $1, $2, $3 otherwise
7236             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7237 0         0 $char[$i] = e_capture($1);
7238 0 0       0 if ($ignorecase) {
7239 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7240             }
7241             }
7242             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7243 0         0 $char[$i] = e_capture($1);
7244 0 0       0 if ($ignorecase) {
7245 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7246             }
7247             }
7248              
7249             # $$foo[ ... ] --> $ $foo->[ ... ]
7250             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7251 0         0 $char[$i] = e_capture($1.'->'.$2);
7252 0 0       0 if ($ignorecase) {
7253 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7254             }
7255             }
7256              
7257             # $$foo{ ... } --> $ $foo->{ ... }
7258             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
7259 0         0 $char[$i] = e_capture($1.'->'.$2);
7260 0 0       0 if ($ignorecase) {
7261 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7262             }
7263             }
7264              
7265             # $$foo
7266             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7267 0         0 $char[$i] = e_capture($1);
7268 0 0       0 if ($ignorecase) {
7269 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7270             }
7271             }
7272              
7273             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
7274             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7275 12 50       20 if ($ignorecase) {
7276 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
7277             }
7278             else {
7279 12         75 $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
7280             }
7281             }
7282              
7283             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
7284             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7285 12 50       21 if ($ignorecase) {
7286 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
7287             }
7288             else {
7289 12         91 $char[$i] = '@{[Ekoi8u::MATCH()]}';
7290             }
7291             }
7292              
7293             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
7294             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7295 9 50       18 if ($ignorecase) {
7296 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
7297             }
7298             else {
7299 9         67 $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
7300             }
7301             }
7302              
7303             # ${ foo }
7304             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
7305 0 0       0 if ($ignorecase) {
7306 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $1 . ')]}';
7307             }
7308             }
7309              
7310             # ${ ... }
7311             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7312 0         0 $char[$i] = e_capture($1);
7313 0 0       0 if ($ignorecase) {
7314 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7315             }
7316             }
7317              
7318             # $scalar or @array
7319             elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7320 3         6 $char[$i] = e_string($char[$i]);
7321 3 50       24 if ($ignorecase) {
7322 0         0 $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7323             }
7324             }
7325              
7326             # quote character before ? + * {
7327             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7328 1 50       9 if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7329             }
7330             else {
7331 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
7332             }
7333             }
7334             }
7335              
7336             # make regexp string
7337 74         106 $modifier =~ tr/i//d;
7338 74 50       182 if ($left_e > $right_e) {
7339 0         0 return join '', 'Ekoi8u::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7340             }
7341 74         754 return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7342             }
7343              
7344             #
7345             # escape regexp of split qr''
7346             #
7347             sub e_split_q {
7348 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7349 0   0       $modifier ||= '';
7350              
7351 0           $modifier =~ tr/p//d;
7352 0 0         if ($modifier =~ /([adlu])/oxms) {
7353 0           my $line = 0;
7354 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7355 0 0         if ($filename ne __FILE__) {
7356 0           $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7357 0           last;
7358             }
7359             }
7360 0           die qq{Unsupported modifier "$1" used at line $line.\n};
7361             }
7362              
7363 0           $slash = 'div';
7364              
7365             # /b /B modifier
7366 0 0         if ($modifier =~ tr/bB//d) {
7367 0           return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7368             }
7369              
7370 0 0         my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7371              
7372             # split regexp
7373 0           my @char = $string =~ /\G((?>
7374             [^\\\[] |
7375             [\x00-\xFF] |
7376             \[\^ |
7377             \[\: (?>[a-z]+) \:\] |
7378             \[\:\^ (?>[a-z]+) \:\] |
7379             \\ (?:$q_char) |
7380             (?:$q_char)
7381             ))/oxmsg;
7382              
7383             # unescape character
7384 0           for (my $i=0; $i <= $#char; $i++) {
7385 0 0 0       if (0) {
    0 0        
    0 0        
    0 0        
    0          
    0          
7386             }
7387              
7388             # open character class [...]
7389 0           elsif ($char[$i] eq '[') {
7390 0           my $left = $i;
7391 0 0         if ($char[$i+1] eq ']') {
7392 0           $i++;
7393             }
7394 0           while (1) {
7395 0 0         if (++$i > $#char) {
7396 0           die __FILE__, ": Unmatched [] in regexp\n";
7397             }
7398 0 0         if ($char[$i] eq ']') {
7399 0           my $right = $i;
7400              
7401             # [...]
7402 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
7403              
7404 0           $i = $left;
7405 0           last;
7406             }
7407             }
7408             }
7409              
7410             # open character class [^...]
7411             elsif ($char[$i] eq '[^') {
7412 0           my $left = $i;
7413 0 0         if ($char[$i+1] eq ']') {
7414 0           $i++;
7415             }
7416 0           while (1) {
7417 0 0         if (++$i > $#char) {
7418 0           die __FILE__, ": Unmatched [] in regexp\n";
7419             }
7420 0 0         if ($char[$i] eq ']') {
7421 0           my $right = $i;
7422              
7423             # [^...]
7424 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7425              
7426 0           $i = $left;
7427 0           last;
7428             }
7429             }
7430             }
7431              
7432             # rewrite character class or escape character
7433             elsif (my $char = character_class($char[$i],$modifier)) {
7434 0           $char[$i] = $char;
7435             }
7436              
7437             # split(m/^/) --> split(m/^/m)
7438             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7439 0           $modifier .= 'm';
7440             }
7441              
7442             # /i modifier
7443             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
7444 0 0         if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
7445 0           $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
7446             }
7447             else {
7448 0           $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
7449             }
7450             }
7451              
7452             # quote character before ? + * {
7453             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7454 0 0         if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7455             }
7456             else {
7457 0           $char[$i-1] = '(?:' . $char[$i-1] . ')';
7458             }
7459             }
7460             }
7461              
7462 0           $modifier =~ tr/i//d;
7463 0           return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7464             }
7465              
7466             #
7467             # instead of Carp::carp
7468             #
7469             sub carp {
7470 0     0 0   my($package,$filename,$line) = caller(1);
7471 0           print STDERR "@_ at $filename line $line.\n";
7472             }
7473              
7474             #
7475             # instead of Carp::croak
7476             #
7477             sub croak {
7478 0     0 0   my($package,$filename,$line) = caller(1);
7479 0           print STDERR "@_ at $filename line $line.\n";
7480 0           die "\n";
7481             }
7482              
7483             #
7484             # instead of Carp::cluck
7485             #
7486             sub cluck {
7487 0     0 0   my $i = 0;
7488 0           my @cluck = ();
7489 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7490 0           push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7491 0           $i++;
7492             }
7493 0           print STDERR CORE::reverse @cluck;
7494 0           print STDERR "\n";
7495 0           carp @_;
7496             }
7497              
7498             #
7499             # instead of Carp::confess
7500             #
7501             sub confess {
7502 0     0 0   my $i = 0;
7503 0           my @confess = ();
7504 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7505 0           push @confess, "[$i] $filename($line) $package::$subroutine\n";
7506 0           $i++;
7507             }
7508 0           print STDERR CORE::reverse @confess;
7509 0           print STDERR "\n";
7510 0           croak @_;
7511             }
7512              
7513             1;
7514              
7515             __END__