File Coverage

blib/lib/Ekoi8u.pm
Criterion Covered Total %
statement 905 2814 32.1
branch 890 2412 36.9
condition 98 355 27.6
subroutine 54 113 47.7
pod 7 74 9.4
total 1954 5768 33.8


line stmt bran cond sub pod time code
1             package Ekoi8u;
2 206     206   7083 use strict;
  206         353  
  206         26283  
3 206 50   206   3869 BEGIN { $INC{'warnings.pm'} = '' if $] < 5.006 } use warnings;
  206     206   870  
  206         350  
  206         6625  
4             ######################################################################
5             #
6             # Ekoi8u - Run-time routines for KOI8U.pm
7             #
8             # http://search.cpan.org/dist/Char-KOI8U/
9             #
10             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
11             ######################################################################
12              
13 206     206   3872 use 5.00503; # Galapagos Consensus 1998 for primetools
  206         704  
14             # use 5.008001; # Lancaster Consensus 2013 for toolchains
15              
16             # 12.3. Delaying use Until Runtime
17             # in Chapter 12. Packages, Libraries, and Modules
18             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
19             # (and so on)
20              
21             # Version numbers should be boring
22             # http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
23             # For the impatient, the disinterested or those who just want to follow
24             # a recipe, my advice for all modules is this:
25             # our $VERSION = "0.001"; # or "0.001_001" for a dev release
26             # $VERSION = eval $VERSION; # No!! because '1.10' makes '1.1'
27              
28 206     206   1080 use vars qw($VERSION);
  206         460  
  206         31188  
29             $VERSION = '1.22';
30             $VERSION = $VERSION;
31              
32             BEGIN {
33 206 50   206   1195 if ($^X =~ / jperl /oxmsi) {
34 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
35             }
36 206         329 if (CORE::ord('A') == 193) {
37             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
38             }
39 206         28496 if (CORE::ord('A') != 0x41) {
40             die __FILE__, ": is not US-ASCII script (must be US-ASCII script).\n";
41             }
42             }
43              
44             BEGIN {
45              
46             # instead of utf8.pm
47 206     206   14136 CORE::eval q{
  206     206   1215  
  206     82   424  
  206         40039  
  0         0  
  0         0  
  0         0  
  0         0  
48             no warnings qw(redefine);
49             *utf8::upgrade = sub { CORE::length $_[0] };
50             *utf8::downgrade = sub { 1 };
51             *utf8::encode = sub { };
52             *utf8::decode = sub { 1 };
53             *utf8::is_utf8 = sub { };
54             *utf8::valid = sub { 1 };
55             };
56 206 50       79716 if ($@) {
57 0         0 *utf8::upgrade = sub { CORE::length $_[0] };
  0         0  
58 0         0 *utf8::downgrade = sub { 1 };
  0         0  
59 0         0 *utf8::encode = sub { };
60 0         0 *utf8::decode = sub { 1 };
  0         0  
61 0         0 *utf8::is_utf8 = sub { };
62 0         0 *utf8::valid = sub { 1 };
  0         0  
63             }
64             }
65              
66             # instead of Symbol.pm
67 0         0 BEGIN {
68             sub gensym () {
69 0 0   0 0 0 if ($] < 5.006) {
70 0         0 return \do { local *_ };
  0         0  
71             }
72             else {
73 0         0 return undef;
74             }
75             }
76              
77             sub qualify ($$) {
78 0     0 0 0 my($name) = @_;
79              
80 0 0       0 if (ref $name) {
    0          
    0          
    0          
    0          
    0          
    0          
81 0         0 return $name;
82             }
83             elsif (Ekoi8u::index($name,'::') >= 0) {
84 0         0 return $name;
85             }
86             elsif (Ekoi8u::index($name,"'") >= 0) {
87 0         0 return $name;
88             }
89              
90             # special character, "^xyz"
91             elsif ($name =~ /\A \^ [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+ \z/x) {
92              
93             # RGS 2001-11-05 : translate leading ^X to control-char
94 0         0 $name =~ s{\A \^ ([ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]) }{'qq(\c'.$1.')'}xee;
  0         0  
95 0         0 return 'main::' . $name;
96             }
97              
98             # Global names
99             elsif ($name =~ /\A (?: ARGV | ARGVOUT | ENV | INC | SIG | STDERR | STDIN | STDOUT ) \z/x) {
100 0         0 return 'main::' . $name;
101             }
102              
103             # or other
104             elsif ($name =~ /\A [^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz] \z/x) {
105 0         0 return 'main::' . $name;
106             }
107              
108             elsif (defined $_[1]) {
109 0         0 return $_[1] . '::' . $name;
110             }
111             else {
112 0         0 return (caller)[0] . '::' . $name;
113             }
114             }
115              
116             sub qualify_to_ref ($;$) {
117 0 0   0 0 0 if (defined $_[1]) {
118 206     206   1649 no strict qw(refs);
  206         358  
  206         13804  
119 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
120             }
121             else {
122 206     206   1248 no strict qw(refs);
  206     0   389  
  206         48620  
123 0         0 return \*{ qualify $_[0], (caller)[0] };
  0         0  
124             }
125             }
126             }
127              
128             # P.714 29.2.39. flock
129             # in Chapter 29: Functions
130             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
131              
132             # P.863 flock
133             # in Chapter 27: Functions
134             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
135              
136             sub LOCK_SH() {1}
137             sub LOCK_EX() {2}
138             sub LOCK_UN() {8}
139             sub LOCK_NB() {4}
140              
141             # instead of Carp.pm
142             sub carp;
143             sub croak;
144             sub cluck;
145             sub confess;
146              
147             # 6.18. Matching Multiple-Byte Characters
148             # in Chapter 6. Pattern Matching
149             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
150             # (and so on)
151              
152             # regexp of character
153             my $your_char = q{[\x00-\xFF]};
154 206     206   1715 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  206         455  
  206         13816  
155 206     206   1484 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  206         563  
  206         400533  
156              
157             #
158             # KOI8-U character range per length
159             #
160             my %range_tr = ();
161              
162             #
163             # KOI8-U case conversion
164             #
165             my %lc = ();
166             @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)} =
167             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
168             my %uc = ();
169             @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)} =
170             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);
171             my %fc = ();
172             @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)} =
173             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);
174              
175             if (0) {
176             }
177              
178             elsif (__PACKAGE__ =~ / \b Ekoi8u \z/oxms) {
179             %range_tr = (
180             1 => [ [0x00..0xFF],
181             ],
182             );
183              
184             %lc = (%lc,
185             "\xB3" => "\xA3", # CYRILLIC LETTER IO
186             "\xB4" => "\xA4", # CYRILLIC LETTER UKRAINIAN IE
187             "\xB6" => "\xA6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
188             "\xB7" => "\xA7", # CYRILLIC LETTER YI (UKRAINIAN)
189             "\xBD" => "\xAD", # CYRILLIC LETTER GHE WITH UPTURN
190             "\xE0" => "\xC0", # CYRILLIC LETTER YU
191             "\xE1" => "\xC1", # CYRILLIC LETTER A
192             "\xE2" => "\xC2", # CYRILLIC LETTER BE
193             "\xE3" => "\xC3", # CYRILLIC LETTER TSE
194             "\xE4" => "\xC4", # CYRILLIC LETTER DE
195             "\xE5" => "\xC5", # CYRILLIC LETTER IE
196             "\xE6" => "\xC6", # CYRILLIC LETTER EF
197             "\xE7" => "\xC7", # CYRILLIC LETTER GHE
198             "\xE8" => "\xC8", # CYRILLIC LETTER KHA
199             "\xE9" => "\xC9", # CYRILLIC LETTER I
200             "\xEA" => "\xCA", # CYRILLIC LETTER SHORT I
201             "\xEB" => "\xCB", # CYRILLIC LETTER KA
202             "\xEC" => "\xCC", # CYRILLIC LETTER EL
203             "\xED" => "\xCD", # CYRILLIC LETTER EM
204             "\xEE" => "\xCE", # CYRILLIC LETTER EN
205             "\xEF" => "\xCF", # CYRILLIC LETTER O
206             "\xF0" => "\xD0", # CYRILLIC LETTER PE
207             "\xF1" => "\xD1", # CYRILLIC LETTER YA
208             "\xF2" => "\xD2", # CYRILLIC LETTER ER
209             "\xF3" => "\xD3", # CYRILLIC LETTER ES
210             "\xF4" => "\xD4", # CYRILLIC LETTER TE
211             "\xF5" => "\xD5", # CYRILLIC LETTER U
212             "\xF6" => "\xD6", # CYRILLIC LETTER ZHE
213             "\xF7" => "\xD7", # CYRILLIC LETTER VE
214             "\xF8" => "\xD8", # CYRILLIC LETTER SOFT SIGN
215             "\xF9" => "\xD9", # CYRILLIC LETTER YERU
216             "\xFA" => "\xDA", # CYRILLIC LETTER ZE
217             "\xFB" => "\xDB", # CYRILLIC LETTER SHA
218             "\xFC" => "\xDC", # CYRILLIC LETTER E
219             "\xFD" => "\xDD", # CYRILLIC LETTER SHCHA
220             "\xFE" => "\xDE", # CYRILLIC LETTER CHE
221             "\xFF" => "\xDF", # CYRILLIC LETTER HARD SIGN
222             );
223              
224             %uc = (%uc,
225             "\xA3" => "\xB3", # CYRILLIC LETTER IO
226             "\xA4" => "\xB4", # CYRILLIC LETTER UKRAINIAN IE
227             "\xA6" => "\xB6", # CYRILLIC LETTER BYELORUSSIAN-UKRAINIAN I
228             "\xA7" => "\xB7", # CYRILLIC LETTER YI (UKRAINIAN)
229             "\xAD" => "\xBD", # CYRILLIC LETTER GHE WITH UPTURN
230             "\xC0" => "\xE0", # CYRILLIC LETTER YU
231             "\xC1" => "\xE1", # CYRILLIC LETTER A
232             "\xC2" => "\xE2", # CYRILLIC LETTER BE
233             "\xC3" => "\xE3", # CYRILLIC LETTER TSE
234             "\xC4" => "\xE4", # CYRILLIC LETTER DE
235             "\xC5" => "\xE5", # CYRILLIC LETTER IE
236             "\xC6" => "\xE6", # CYRILLIC LETTER EF
237             "\xC7" => "\xE7", # CYRILLIC LETTER GHE
238             "\xC8" => "\xE8", # CYRILLIC LETTER KHA
239             "\xC9" => "\xE9", # CYRILLIC LETTER I
240             "\xCA" => "\xEA", # CYRILLIC LETTER SHORT I
241             "\xCB" => "\xEB", # CYRILLIC LETTER KA
242             "\xCC" => "\xEC", # CYRILLIC LETTER EL
243             "\xCD" => "\xED", # CYRILLIC LETTER EM
244             "\xCE" => "\xEE", # CYRILLIC LETTER EN
245             "\xCF" => "\xEF", # CYRILLIC LETTER O
246             "\xD0" => "\xF0", # CYRILLIC LETTER PE
247             "\xD1" => "\xF1", # CYRILLIC LETTER YA
248             "\xD2" => "\xF2", # CYRILLIC LETTER ER
249             "\xD3" => "\xF3", # CYRILLIC LETTER ES
250             "\xD4" => "\xF4", # CYRILLIC LETTER TE
251             "\xD5" => "\xF5", # CYRILLIC LETTER U
252             "\xD6" => "\xF6", # CYRILLIC LETTER ZHE
253             "\xD7" => "\xF7", # CYRILLIC LETTER VE
254             "\xD8" => "\xF8", # CYRILLIC LETTER SOFT SIGN
255             "\xD9" => "\xF9", # CYRILLIC LETTER YERU
256             "\xDA" => "\xFA", # CYRILLIC LETTER ZE
257             "\xDB" => "\xFB", # CYRILLIC LETTER SHA
258             "\xDC" => "\xFC", # CYRILLIC LETTER E
259             "\xDD" => "\xFD", # CYRILLIC LETTER SHCHA
260             "\xDE" => "\xFE", # CYRILLIC LETTER CHE
261             "\xDF" => "\xFF", # CYRILLIC LETTER HARD SIGN
262             );
263              
264             %fc = (%fc,
265             "\xB3" => "\xA3", # CYRILLIC CAPITAL LETTER IO --> CYRILLIC SMALL LETTER IO
266             "\xB4" => "\xA4", # CYRILLIC CAPITAL LETTER UKRAINIAN IE --> CYRILLIC SMALL LETTER UKRAINIAN IE
267             "\xB6" => "\xA6", # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I --> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
268             "\xB7" => "\xA7", # CYRILLIC CAPITAL LETTER YI --> CYRILLIC SMALL LETTER YI
269             "\xBD" => "\xAD", # CYRILLIC CAPITAL LETTER GHE WITH UPTURN --> CYRILLIC SMALL LETTER GHE WITH UPTURN
270             "\xE0" => "\xC0", # CYRILLIC CAPITAL LETTER YU --> CYRILLIC SMALL LETTER YU
271             "\xE1" => "\xC1", # CYRILLIC CAPITAL LETTER A --> CYRILLIC SMALL LETTER A
272             "\xE2" => "\xC2", # CYRILLIC CAPITAL LETTER BE --> CYRILLIC SMALL LETTER BE
273             "\xE3" => "\xC3", # CYRILLIC CAPITAL LETTER TSE --> CYRILLIC SMALL LETTER TSE
274             "\xE4" => "\xC4", # CYRILLIC CAPITAL LETTER DE --> CYRILLIC SMALL LETTER DE
275             "\xE5" => "\xC5", # CYRILLIC CAPITAL LETTER IE --> CYRILLIC SMALL LETTER IE
276             "\xE6" => "\xC6", # CYRILLIC CAPITAL LETTER EF --> CYRILLIC SMALL LETTER EF
277             "\xE7" => "\xC7", # CYRILLIC CAPITAL LETTER GHE --> CYRILLIC SMALL LETTER GHE
278             "\xE8" => "\xC8", # CYRILLIC CAPITAL LETTER HA --> CYRILLIC SMALL LETTER HA
279             "\xE9" => "\xC9", # CYRILLIC CAPITAL LETTER I --> CYRILLIC SMALL LETTER I
280             "\xEA" => "\xCA", # CYRILLIC CAPITAL LETTER SHORT I --> CYRILLIC SMALL LETTER SHORT I
281             "\xEB" => "\xCB", # CYRILLIC CAPITAL LETTER KA --> CYRILLIC SMALL LETTER KA
282             "\xEC" => "\xCC", # CYRILLIC CAPITAL LETTER EL --> CYRILLIC SMALL LETTER EL
283             "\xED" => "\xCD", # CYRILLIC CAPITAL LETTER EM --> CYRILLIC SMALL LETTER EM
284             "\xEE" => "\xCE", # CYRILLIC CAPITAL LETTER EN --> CYRILLIC SMALL LETTER EN
285             "\xEF" => "\xCF", # CYRILLIC CAPITAL LETTER O --> CYRILLIC SMALL LETTER O
286             "\xF0" => "\xD0", # CYRILLIC CAPITAL LETTER PE --> CYRILLIC SMALL LETTER PE
287             "\xF1" => "\xD1", # CYRILLIC CAPITAL LETTER YA --> CYRILLIC SMALL LETTER YA
288             "\xF2" => "\xD2", # CYRILLIC CAPITAL LETTER ER --> CYRILLIC SMALL LETTER ER
289             "\xF3" => "\xD3", # CYRILLIC CAPITAL LETTER ES --> CYRILLIC SMALL LETTER ES
290             "\xF4" => "\xD4", # CYRILLIC CAPITAL LETTER TE --> CYRILLIC SMALL LETTER TE
291             "\xF5" => "\xD5", # CYRILLIC CAPITAL LETTER U --> CYRILLIC SMALL LETTER U
292             "\xF6" => "\xD6", # CYRILLIC CAPITAL LETTER ZHE --> CYRILLIC SMALL LETTER ZHE
293             "\xF7" => "\xD7", # CYRILLIC CAPITAL LETTER VE --> CYRILLIC SMALL LETTER VE
294             "\xF8" => "\xD8", # CYRILLIC CAPITAL LETTER SOFT SIGN --> CYRILLIC SMALL LETTER SOFT SIGN
295             "\xF9" => "\xD9", # CYRILLIC CAPITAL LETTER YERU --> CYRILLIC SMALL LETTER YERU
296             "\xFA" => "\xDA", # CYRILLIC CAPITAL LETTER ZE --> CYRILLIC SMALL LETTER ZE
297             "\xFB" => "\xDB", # CYRILLIC CAPITAL LETTER SHA --> CYRILLIC SMALL LETTER SHA
298             "\xFC" => "\xDC", # CYRILLIC CAPITAL LETTER E --> CYRILLIC SMALL LETTER E
299             "\xFD" => "\xDD", # CYRILLIC CAPITAL LETTER SHCHA --> CYRILLIC SMALL LETTER SHCHA
300             "\xFE" => "\xDE", # CYRILLIC CAPITAL LETTER CHE --> CYRILLIC SMALL LETTER CHE
301             "\xFF" => "\xDF", # CYRILLIC CAPITAL LETTER HARD SIGN --> CYRILLIC SMALL LETTER HARD SIGN
302             );
303             }
304              
305             else {
306             croak "Don't know my package name '@{[__PACKAGE__]}'";
307             }
308              
309             #
310             # @ARGV wildcard globbing
311             #
312             sub import {
313              
314 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
315 0         0 my @argv = ();
316 0         0 for (@ARGV) {
317              
318             # has space
319 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
320 0 0       0 if (my @glob = Ekoi8u::glob(qq{"$_"})) {
321 0         0 push @argv, @glob;
322             }
323             else {
324 0         0 push @argv, $_;
325             }
326             }
327              
328             # has wildcard metachar
329             elsif (/\A (?:$q_char)*? [*?] /oxms) {
330 0 0       0 if (my @glob = Ekoi8u::glob($_)) {
331 0         0 push @argv, @glob;
332             }
333             else {
334 0         0 push @argv, $_;
335             }
336             }
337              
338             # no wildcard globbing
339             else {
340 0         0 push @argv, $_;
341             }
342             }
343 0         0 @ARGV = @argv;
344             }
345              
346 0         0 *Char::ord = \&KOI8U::ord;
347 0         0 *Char::ord_ = \&KOI8U::ord_;
348 0         0 *Char::reverse = \&KOI8U::reverse;
349 0         0 *Char::getc = \&KOI8U::getc;
350 0         0 *Char::length = \&KOI8U::length;
351 0         0 *Char::substr = \&KOI8U::substr;
352 0         0 *Char::index = \&KOI8U::index;
353 0         0 *Char::rindex = \&KOI8U::rindex;
354 0         0 *Char::eval = \&KOI8U::eval;
355 0         0 *Char::escape = \&KOI8U::escape;
356 0         0 *Char::escape_token = \&KOI8U::escape_token;
357 0         0 *Char::escape_script = \&KOI8U::escape_script;
358             }
359              
360             # P.230 Care with Prototypes
361             # in Chapter 6: Subroutines
362             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
363             #
364             # If you aren't careful, you can get yourself into trouble with prototypes.
365             # But if you are careful, you can do a lot of neat things with them. This is
366             # all very powerful, of course, and should only be used in moderation to make
367             # the world a better place.
368              
369             # P.332 Care with Prototypes
370             # in Chapter 7: Subroutines
371             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
372             #
373             # If you aren't careful, you can get yourself into trouble with prototypes.
374             # But if you are careful, you can do a lot of neat things with them. This is
375             # all very powerful, of course, and should only be used in moderation to make
376             # the world a better place.
377              
378             #
379             # Prototypes of subroutines
380             #
381       0     sub unimport {}
382             sub Ekoi8u::split(;$$$);
383             sub Ekoi8u::tr($$$$;$);
384             sub Ekoi8u::chop(@);
385             sub Ekoi8u::index($$;$);
386             sub Ekoi8u::rindex($$;$);
387             sub Ekoi8u::lcfirst(@);
388             sub Ekoi8u::lcfirst_();
389             sub Ekoi8u::lc(@);
390             sub Ekoi8u::lc_();
391             sub Ekoi8u::ucfirst(@);
392             sub Ekoi8u::ucfirst_();
393             sub Ekoi8u::uc(@);
394             sub Ekoi8u::uc_();
395             sub Ekoi8u::fc(@);
396             sub Ekoi8u::fc_();
397             sub Ekoi8u::ignorecase;
398             sub Ekoi8u::classic_character_class;
399             sub Ekoi8u::capture;
400             sub Ekoi8u::chr(;$);
401             sub Ekoi8u::chr_();
402             sub Ekoi8u::glob($);
403             sub Ekoi8u::glob_();
404              
405             sub KOI8U::ord(;$);
406             sub KOI8U::ord_();
407             sub KOI8U::reverse(@);
408             sub KOI8U::getc(;*@);
409             sub KOI8U::length(;$);
410             sub KOI8U::substr($$;$$);
411             sub KOI8U::index($$;$);
412             sub KOI8U::rindex($$;$);
413             sub KOI8U::escape(;$);
414              
415             #
416             # Regexp work
417             #
418 206         19201 use vars qw(
419             $re_a
420             $re_t
421             $re_n
422             $re_r
423 206     206   1596 );
  206         425  
424              
425             #
426             # Character class
427             #
428 206         2092868 use vars qw(
429             $dot
430             $dot_s
431             $eD
432             $eS
433             $eW
434             $eH
435             $eV
436             $eR
437             $eN
438             $not_alnum
439             $not_alpha
440             $not_ascii
441             $not_blank
442             $not_cntrl
443             $not_digit
444             $not_graph
445             $not_lower
446             $not_lower_i
447             $not_print
448             $not_punct
449             $not_space
450             $not_upper
451             $not_upper_i
452             $not_word
453             $not_xdigit
454             $eb
455             $eB
456 206     206   1307 );
  206         410  
457              
458             ${Ekoi8u::dot} = qr{(?>[^\x0A])};
459             ${Ekoi8u::dot_s} = qr{(?>[\x00-\xFF])};
460             ${Ekoi8u::eD} = qr{(?>[^0-9])};
461              
462             # Vertical tabs are now whitespace
463             # \s in a regex now matches a vertical tab in all circumstances.
464             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
465             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
466             # ${Ekoi8u::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
467             ${Ekoi8u::eS} = qr{(?>[^\s])};
468              
469             ${Ekoi8u::eW} = qr{(?>[^0-9A-Z_a-z])};
470             ${Ekoi8u::eH} = qr{(?>[^\x09\x20])};
471             ${Ekoi8u::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
472             ${Ekoi8u::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
473             ${Ekoi8u::eN} = qr{(?>[^\x0A])};
474             ${Ekoi8u::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
475             ${Ekoi8u::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
476             ${Ekoi8u::not_ascii} = qr{(?>[^\x00-\x7F])};
477             ${Ekoi8u::not_blank} = qr{(?>[^\x09\x20])};
478             ${Ekoi8u::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
479             ${Ekoi8u::not_digit} = qr{(?>[^\x30-\x39])};
480             ${Ekoi8u::not_graph} = qr{(?>[^\x21-\x7F])};
481             ${Ekoi8u::not_lower} = qr{(?>[^\x61-\x7A])};
482             ${Ekoi8u::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
483             # ${Ekoi8u::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
484             ${Ekoi8u::not_print} = qr{(?>[^\x20-\x7F])};
485             ${Ekoi8u::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
486             ${Ekoi8u::not_space} = qr{(?>[^\s\x0B])};
487             ${Ekoi8u::not_upper} = qr{(?>[^\x41-\x5A])};
488             ${Ekoi8u::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
489             # ${Ekoi8u::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
490             ${Ekoi8u::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
491             ${Ekoi8u::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
492             ${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))};
493             ${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]))};
494              
495             # avoid: Name "Ekoi8u::foo" used only once: possible typo at here.
496             ${Ekoi8u::dot} = ${Ekoi8u::dot};
497             ${Ekoi8u::dot_s} = ${Ekoi8u::dot_s};
498             ${Ekoi8u::eD} = ${Ekoi8u::eD};
499             ${Ekoi8u::eS} = ${Ekoi8u::eS};
500             ${Ekoi8u::eW} = ${Ekoi8u::eW};
501             ${Ekoi8u::eH} = ${Ekoi8u::eH};
502             ${Ekoi8u::eV} = ${Ekoi8u::eV};
503             ${Ekoi8u::eR} = ${Ekoi8u::eR};
504             ${Ekoi8u::eN} = ${Ekoi8u::eN};
505             ${Ekoi8u::not_alnum} = ${Ekoi8u::not_alnum};
506             ${Ekoi8u::not_alpha} = ${Ekoi8u::not_alpha};
507             ${Ekoi8u::not_ascii} = ${Ekoi8u::not_ascii};
508             ${Ekoi8u::not_blank} = ${Ekoi8u::not_blank};
509             ${Ekoi8u::not_cntrl} = ${Ekoi8u::not_cntrl};
510             ${Ekoi8u::not_digit} = ${Ekoi8u::not_digit};
511             ${Ekoi8u::not_graph} = ${Ekoi8u::not_graph};
512             ${Ekoi8u::not_lower} = ${Ekoi8u::not_lower};
513             ${Ekoi8u::not_lower_i} = ${Ekoi8u::not_lower_i};
514             ${Ekoi8u::not_print} = ${Ekoi8u::not_print};
515             ${Ekoi8u::not_punct} = ${Ekoi8u::not_punct};
516             ${Ekoi8u::not_space} = ${Ekoi8u::not_space};
517             ${Ekoi8u::not_upper} = ${Ekoi8u::not_upper};
518             ${Ekoi8u::not_upper_i} = ${Ekoi8u::not_upper_i};
519             ${Ekoi8u::not_word} = ${Ekoi8u::not_word};
520             ${Ekoi8u::not_xdigit} = ${Ekoi8u::not_xdigit};
521             ${Ekoi8u::eb} = ${Ekoi8u::eb};
522             ${Ekoi8u::eB} = ${Ekoi8u::eB};
523              
524             #
525             # KOI8-U split
526             #
527             sub Ekoi8u::split(;$$$) {
528              
529             # P.794 29.2.161. split
530             # in Chapter 29: Functions
531             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
532              
533             # P.951 split
534             # in Chapter 27: Functions
535             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
536              
537 0     0 0 0 my $pattern = $_[0];
538 0         0 my $string = $_[1];
539 0         0 my $limit = $_[2];
540              
541             # if $pattern is also omitted or is the literal space, " "
542 0 0       0 if (not defined $pattern) {
543 0         0 $pattern = ' ';
544             }
545              
546             # if $string is omitted, the function splits the $_ string
547 0 0       0 if (not defined $string) {
548 0 0       0 if (defined $_) {
549 0         0 $string = $_;
550             }
551             else {
552 0         0 $string = '';
553             }
554             }
555              
556 0         0 my @split = ();
557              
558             # when string is empty
559 0 0       0 if ($string eq '') {
    0          
560              
561             # resulting list value in list context
562 0 0       0 if (wantarray) {
563 0         0 return @split;
564             }
565              
566             # count of substrings in scalar context
567             else {
568 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
569 0         0 @_ = @split;
570 0         0 return scalar @_;
571             }
572             }
573              
574             # split's first argument is more consistently interpreted
575             #
576             # After some changes earlier in v5.17, split's behavior has been simplified:
577             # if the PATTERN argument evaluates to a string containing one space, it is
578             # treated the way that a literal string containing one space once was.
579             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
580              
581             # if $pattern is also omitted or is the literal space, " ", the function splits
582             # on whitespace, /\s+/, after skipping any leading whitespace
583             # (and so on)
584              
585             elsif ($pattern eq ' ') {
586 0 0       0 if (not defined $limit) {
587 0         0 return CORE::split(' ', $string);
588             }
589             else {
590 0         0 return CORE::split(' ', $string, $limit);
591             }
592             }
593              
594             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
595 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
596              
597             # a pattern capable of matching either the null string or something longer than the
598             # null string will split the value of $string into separate characters wherever it
599             # matches the null string between characters
600             # (and so on)
601              
602 0 0       0 if ('' =~ / \A $pattern \z /xms) {
603 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
604 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
605              
606             # P.1024 Appendix W.10 Multibyte Processing
607             # of ISBN 1-56592-224-7 CJKV Information Processing
608             # (and so on)
609              
610             # the //m modifier is assumed when you split on the pattern /^/
611             # (and so on)
612              
613 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
614             # V
615 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
616              
617             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
618             # is included in the resulting list, interspersed with the fields that are ordinarily returned
619             # (and so on)
620              
621 0         0 local $@;
622 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
623 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
624 0         0 push @split, CORE::eval('$' . $digit);
625             }
626             }
627             }
628              
629             else {
630 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
631              
632 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
633             # V
634 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
635 0         0 local $@;
636 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
637 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
638 0         0 push @split, CORE::eval('$' . $digit);
639             }
640             }
641             }
642             }
643              
644             elsif ($limit > 0) {
645 0 0       0 if ('' =~ / \A $pattern \z /xms) {
646 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
647 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
648              
649 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
650             # V
651 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
652 0         0 local $@;
653 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
654 0         0 push @split, CORE::eval('$' . $digit);
655             }
656             }
657             }
658             }
659             else {
660 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
661 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
662              
663 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
664             # V
665 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
666 0         0 local $@;
667 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
668 0         0 push @split, CORE::eval('$' . $digit);
669             }
670             }
671             }
672             }
673             }
674              
675 0 0       0 if (CORE::length($string) > 0) {
676 0         0 push @split, $string;
677             }
678              
679             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
680 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
681 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
682 0         0 pop @split;
683             }
684             }
685              
686             # resulting list value in list context
687 0 0       0 if (wantarray) {
688 0         0 return @split;
689             }
690              
691             # count of substrings in scalar context
692             else {
693 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
694 0         0 @_ = @split;
695 0         0 return scalar @_;
696             }
697             }
698              
699             #
700             # get last subexpression offsets
701             #
702             sub _last_subexpression_offsets {
703 0     0   0 my $pattern = $_[0];
704              
705             # remove comment
706 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
707              
708 0         0 my $modifier = '';
709 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
710 0         0 $modifier = $1;
711 0         0 $modifier =~ s/-[A-Za-z]*//;
712             }
713              
714             # with /x modifier
715 0         0 my @char = ();
716 0 0       0 if ($modifier =~ /x/oxms) {
717 0         0 @char = $pattern =~ /\G((?>
718             [^\\\#\[\(] |
719             \\ $q_char |
720             \# (?>[^\n]*) $ |
721             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
722             \(\? |
723             $q_char
724             ))/oxmsg;
725             }
726              
727             # without /x modifier
728             else {
729 0         0 @char = $pattern =~ /\G((?>
730             [^\\\[\(] |
731             \\ $q_char |
732             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
733             \(\? |
734             $q_char
735             ))/oxmsg;
736             }
737              
738 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
739             }
740              
741             #
742             # KOI8-U transliteration (tr///)
743             #
744             sub Ekoi8u::tr($$$$;$) {
745              
746 0     0 0 0 my $bind_operator = $_[1];
747 0         0 my $searchlist = $_[2];
748 0         0 my $replacementlist = $_[3];
749 0   0     0 my $modifier = $_[4] || '';
750              
751 0 0       0 if ($modifier =~ /r/oxms) {
752 0 0       0 if ($bind_operator =~ / !~ /oxms) {
753 0         0 croak "Using !~ with tr///r doesn't make sense";
754             }
755             }
756              
757 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
758 0         0 my @searchlist = _charlist_tr($searchlist);
759 0         0 my @replacementlist = _charlist_tr($replacementlist);
760              
761 0         0 my %tr = ();
762 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
763 0 0       0 if (not exists $tr{$searchlist[$i]}) {
764 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
765 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
766             }
767             elsif ($modifier =~ /d/oxms) {
768 0         0 $tr{$searchlist[$i]} = '';
769             }
770             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
771 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
772             }
773             else {
774 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
775             }
776             }
777             }
778              
779 0         0 my $tr = 0;
780 0         0 my $replaced = '';
781 0 0       0 if ($modifier =~ /c/oxms) {
782 0         0 while (defined(my $char = shift @char)) {
783 0 0       0 if (not exists $tr{$char}) {
784 0 0       0 if (defined $replacementlist[-1]) {
785 0         0 $replaced .= $replacementlist[-1];
786             }
787 0         0 $tr++;
788 0 0       0 if ($modifier =~ /s/oxms) {
789 0   0     0 while (@char and (not exists $tr{$char[0]})) {
790 0         0 shift @char;
791 0         0 $tr++;
792             }
793             }
794             }
795             else {
796 0         0 $replaced .= $char;
797             }
798             }
799             }
800             else {
801 0         0 while (defined(my $char = shift @char)) {
802 0 0       0 if (exists $tr{$char}) {
803 0         0 $replaced .= $tr{$char};
804 0         0 $tr++;
805 0 0       0 if ($modifier =~ /s/oxms) {
806 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
807 0         0 shift @char;
808 0         0 $tr++;
809             }
810             }
811             }
812             else {
813 0         0 $replaced .= $char;
814             }
815             }
816             }
817              
818 0 0       0 if ($modifier =~ /r/oxms) {
819 0         0 return $replaced;
820             }
821             else {
822 0         0 $_[0] = $replaced;
823 0 0       0 if ($bind_operator =~ / !~ /oxms) {
824 0         0 return not $tr;
825             }
826             else {
827 0         0 return $tr;
828             }
829             }
830             }
831              
832             #
833             # KOI8-U chop
834             #
835             sub Ekoi8u::chop(@) {
836              
837 0     0 0 0 my $chop;
838 0 0       0 if (@_ == 0) {
839 0         0 my @char = /\G (?>$q_char) /oxmsg;
840 0         0 $chop = pop @char;
841 0         0 $_ = join '', @char;
842             }
843             else {
844 0         0 for (@_) {
845 0         0 my @char = /\G (?>$q_char) /oxmsg;
846 0         0 $chop = pop @char;
847 0         0 $_ = join '', @char;
848             }
849             }
850 0         0 return $chop;
851             }
852              
853             #
854             # KOI8-U index by octet
855             #
856             sub Ekoi8u::index($$;$) {
857              
858 0     0 1 0 my($str,$substr,$position) = @_;
859 0   0     0 $position ||= 0;
860 0         0 my $pos = 0;
861              
862 0         0 while ($pos < CORE::length($str)) {
863 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
864 0 0       0 if ($pos >= $position) {
865 0         0 return $pos;
866             }
867             }
868 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
869 0         0 $pos += CORE::length($1);
870             }
871             else {
872 0         0 $pos += 1;
873             }
874             }
875 0         0 return -1;
876             }
877              
878             #
879             # KOI8-U reverse index
880             #
881             sub Ekoi8u::rindex($$;$) {
882              
883 0     0 0 0 my($str,$substr,$position) = @_;
884 0   0     0 $position ||= CORE::length($str) - 1;
885 0         0 my $pos = 0;
886 0         0 my $rindex = -1;
887              
888 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
889 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
890 0         0 $rindex = $pos;
891             }
892 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
893 0         0 $pos += CORE::length($1);
894             }
895             else {
896 0         0 $pos += 1;
897             }
898             }
899 0         0 return $rindex;
900             }
901              
902             #
903             # KOI8-U lower case first with parameter
904             #
905             sub Ekoi8u::lcfirst(@) {
906 0 0   0 0 0 if (@_) {
907 0         0 my $s = shift @_;
908 0 0 0     0 if (@_ and wantarray) {
909 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
910             }
911             else {
912 0         0 return Ekoi8u::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
913             }
914             }
915             else {
916 0         0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
917             }
918             }
919              
920             #
921             # KOI8-U lower case first without parameter
922             #
923             sub Ekoi8u::lcfirst_() {
924 0     0 0 0 return Ekoi8u::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
925             }
926              
927             #
928             # KOI8-U lower case with parameter
929             #
930             sub Ekoi8u::lc(@) {
931 0 0   0 0 0 if (@_) {
932 0         0 my $s = shift @_;
933 0 0 0     0 if (@_ and wantarray) {
934 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
935             }
936             else {
937 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
938             }
939             }
940             else {
941 0         0 return Ekoi8u::lc_();
942             }
943             }
944              
945             #
946             # KOI8-U lower case without parameter
947             #
948             sub Ekoi8u::lc_() {
949 0     0 0 0 my $s = $_;
950 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
951             }
952              
953             #
954             # KOI8-U upper case first with parameter
955             #
956             sub Ekoi8u::ucfirst(@) {
957 0 0   0 0 0 if (@_) {
958 0         0 my $s = shift @_;
959 0 0 0     0 if (@_ and wantarray) {
960 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
961             }
962             else {
963 0         0 return Ekoi8u::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
964             }
965             }
966             else {
967 0         0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
968             }
969             }
970              
971             #
972             # KOI8-U upper case first without parameter
973             #
974             sub Ekoi8u::ucfirst_() {
975 0     0 0 0 return Ekoi8u::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
976             }
977              
978             #
979             # KOI8-U upper case with parameter
980             #
981             sub Ekoi8u::uc(@) {
982 0 50   174 0 0 if (@_) {
983 174         267 my $s = shift @_;
984 174 50 33     213 if (@_ and wantarray) {
985 174 0       325 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
986             }
987             else {
988 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         500  
989             }
990             }
991             else {
992 174         584 return Ekoi8u::uc_();
993             }
994             }
995              
996             #
997             # KOI8-U upper case without parameter
998             #
999             sub Ekoi8u::uc_() {
1000 0     0 0 0 my $s = $_;
1001 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1002             }
1003              
1004             #
1005             # KOI8-U fold case with parameter
1006             #
1007             sub Ekoi8u::fc(@) {
1008 0 50   197 0 0 if (@_) {
1009 197         319 my $s = shift @_;
1010 197 50 33     253 if (@_ and wantarray) {
1011 197 0       328 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1012             }
1013             else {
1014 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         468  
1015             }
1016             }
1017             else {
1018 197         1097 return Ekoi8u::fc_();
1019             }
1020             }
1021              
1022             #
1023             # KOI8-U fold case without parameter
1024             #
1025             sub Ekoi8u::fc_() {
1026 0     0 0 0 my $s = $_;
1027 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1028             }
1029              
1030             #
1031             # KOI8-U regexp capture
1032             #
1033             {
1034             sub Ekoi8u::capture {
1035 0     0 1 0 return $_[0];
1036             }
1037             }
1038              
1039             #
1040             # KOI8-U regexp ignore case modifier
1041             #
1042             sub Ekoi8u::ignorecase {
1043              
1044 0     0 0 0 my @string = @_;
1045 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1046              
1047             # ignore case of $scalar or @array
1048 0         0 for my $string (@string) {
1049              
1050             # split regexp
1051 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1052              
1053             # unescape character
1054 0         0 for (my $i=0; $i <= $#char; $i++) {
1055 0 0       0 next if not defined $char[$i];
1056              
1057             # open character class [...]
1058 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1059 0         0 my $left = $i;
1060              
1061             # [] make die "unmatched [] in regexp ...\n"
1062              
1063 0 0       0 if ($char[$i+1] eq ']') {
1064 0         0 $i++;
1065             }
1066              
1067 0         0 while (1) {
1068 0 0       0 if (++$i > $#char) {
1069 0         0 croak "Unmatched [] in regexp";
1070             }
1071 0 0       0 if ($char[$i] eq ']') {
1072 0         0 my $right = $i;
1073 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1074              
1075             # escape character
1076 0         0 for my $char (@charlist) {
1077 0 0       0 if (0) {
1078             }
1079              
1080 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1081 0         0 $char = '\\' . $char;
1082             }
1083             }
1084              
1085             # [...]
1086 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1087              
1088 0         0 $i = $left;
1089 0         0 last;
1090             }
1091             }
1092             }
1093              
1094             # open character class [^...]
1095             elsif ($char[$i] eq '[^') {
1096 0         0 my $left = $i;
1097              
1098             # [^] make die "unmatched [] in regexp ...\n"
1099              
1100 0 0       0 if ($char[$i+1] eq ']') {
1101 0         0 $i++;
1102             }
1103              
1104 0         0 while (1) {
1105 0 0       0 if (++$i > $#char) {
1106 0         0 croak "Unmatched [] in regexp";
1107             }
1108 0 0       0 if ($char[$i] eq ']') {
1109 0         0 my $right = $i;
1110 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1111              
1112             # escape character
1113 0         0 for my $char (@charlist) {
1114 0 0       0 if (0) {
1115             }
1116              
1117 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1118 0         0 $char = '\\' . $char;
1119             }
1120             }
1121              
1122             # [^...]
1123 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1124              
1125 0         0 $i = $left;
1126 0         0 last;
1127             }
1128             }
1129             }
1130              
1131             # rewrite classic character class or escape character
1132             elsif (my $char = classic_character_class($char[$i])) {
1133 0         0 $char[$i] = $char;
1134             }
1135              
1136             # with /i modifier
1137             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1138 0         0 my $uc = Ekoi8u::uc($char[$i]);
1139 0         0 my $fc = Ekoi8u::fc($char[$i]);
1140 0 0       0 if ($uc ne $fc) {
1141 0 0       0 if (CORE::length($fc) == 1) {
1142 0         0 $char[$i] = '[' . $uc . $fc . ']';
1143             }
1144             else {
1145 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1146             }
1147             }
1148             }
1149             }
1150              
1151             # characterize
1152 0         0 for (my $i=0; $i <= $#char; $i++) {
1153 0 0       0 next if not defined $char[$i];
1154              
1155 0 0       0 if (0) {
1156             }
1157              
1158             # quote character before ? + * {
1159 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1160 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1161 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1162             }
1163             }
1164             }
1165              
1166 0         0 $string = join '', @char;
1167             }
1168              
1169             # make regexp string
1170 0         0 return @string;
1171             }
1172              
1173             #
1174             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1175             #
1176             sub Ekoi8u::classic_character_class {
1177 0     1867 0 0 my($char) = @_;
1178              
1179             return {
1180             '\D' => '${Ekoi8u::eD}',
1181             '\S' => '${Ekoi8u::eS}',
1182             '\W' => '${Ekoi8u::eW}',
1183             '\d' => '[0-9]',
1184              
1185             # Before Perl 5.6, \s only matched the five whitespace characters
1186             # tab, newline, form-feed, carriage return, and the space character
1187             # itself, which, taken together, is the character class [\t\n\f\r ].
1188              
1189             # Vertical tabs are now whitespace
1190             # \s in a regex now matches a vertical tab in all circumstances.
1191             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1192             # \t \n \v \f \r space
1193             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1194             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1195             '\s' => '\s',
1196              
1197             '\w' => '[0-9A-Z_a-z]',
1198             '\C' => '[\x00-\xFF]',
1199             '\X' => 'X',
1200              
1201             # \h \v \H \V
1202              
1203             # P.114 Character Class Shortcuts
1204             # in Chapter 7: In the World of Regular Expressions
1205             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1206              
1207             # P.357 13.2.3 Whitespace
1208             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1209             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1210             #
1211             # 0x00009 CHARACTER TABULATION h s
1212             # 0x0000a LINE FEED (LF) vs
1213             # 0x0000b LINE TABULATION v
1214             # 0x0000c FORM FEED (FF) vs
1215             # 0x0000d CARRIAGE RETURN (CR) vs
1216             # 0x00020 SPACE h s
1217              
1218             # P.196 Table 5-9. Alphanumeric regex metasymbols
1219             # in Chapter 5. Pattern Matching
1220             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1221              
1222             # (and so on)
1223              
1224             '\H' => '${Ekoi8u::eH}',
1225             '\V' => '${Ekoi8u::eV}',
1226             '\h' => '[\x09\x20]',
1227             '\v' => '[\x0A\x0B\x0C\x0D]',
1228             '\R' => '${Ekoi8u::eR}',
1229              
1230             # \N
1231             #
1232             # http://perldoc.perl.org/perlre.html
1233             # Character Classes and other Special Escapes
1234             # Any character but \n (experimental). Not affected by /s modifier
1235              
1236             '\N' => '${Ekoi8u::eN}',
1237              
1238             # \b \B
1239              
1240             # P.180 Boundaries: The \b and \B Assertions
1241             # in Chapter 5: Pattern Matching
1242             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1243              
1244             # P.219 Boundaries: The \b and \B Assertions
1245             # in Chapter 5: Pattern Matching
1246             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1247              
1248             # \b really means (?:(?<=\w)(?!\w)|(?
1249             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1250             '\b' => '${Ekoi8u::eb}',
1251              
1252             # \B really means (?:(?<=\w)(?=\w)|(?
1253             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1254             '\B' => '${Ekoi8u::eB}',
1255              
1256 1867   100     2620 }->{$char} || '';
1257             }
1258              
1259             #
1260             # prepare KOI8-U characters per length
1261             #
1262              
1263             # 1 octet characters
1264             my @chars1 = ();
1265             sub chars1 {
1266 1867 0   0 0 67572 if (@chars1) {
1267 0         0 return @chars1;
1268             }
1269 0 0       0 if (exists $range_tr{1}) {
1270 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1271 0         0 while (my @range = splice(@ranges,0,1)) {
1272 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1273 0         0 push @chars1, pack 'C', $oct0;
1274             }
1275             }
1276             }
1277 0         0 return @chars1;
1278             }
1279              
1280             # 2 octets characters
1281             my @chars2 = ();
1282             sub chars2 {
1283 0 0   0 0 0 if (@chars2) {
1284 0         0 return @chars2;
1285             }
1286 0 0       0 if (exists $range_tr{2}) {
1287 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1288 0         0 while (my @range = splice(@ranges,0,2)) {
1289 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1290 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1291 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1292             }
1293             }
1294             }
1295             }
1296 0         0 return @chars2;
1297             }
1298              
1299             # 3 octets characters
1300             my @chars3 = ();
1301             sub chars3 {
1302 0 0   0 0 0 if (@chars3) {
1303 0         0 return @chars3;
1304             }
1305 0 0       0 if (exists $range_tr{3}) {
1306 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1307 0         0 while (my @range = splice(@ranges,0,3)) {
1308 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1309 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1310 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1311 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1312             }
1313             }
1314             }
1315             }
1316             }
1317 0         0 return @chars3;
1318             }
1319              
1320             # 4 octets characters
1321             my @chars4 = ();
1322             sub chars4 {
1323 0 0   0 0 0 if (@chars4) {
1324 0         0 return @chars4;
1325             }
1326 0 0       0 if (exists $range_tr{4}) {
1327 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1328 0         0 while (my @range = splice(@ranges,0,4)) {
1329 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1330 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1331 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1332 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1333 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1334             }
1335             }
1336             }
1337             }
1338             }
1339             }
1340 0         0 return @chars4;
1341             }
1342              
1343             #
1344             # KOI8-U open character list for tr
1345             #
1346             sub _charlist_tr {
1347              
1348 0     0   0 local $_ = shift @_;
1349              
1350             # unescape character
1351 0         0 my @char = ();
1352 0         0 while (not /\G \z/oxmsgc) {
1353 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1354 0         0 push @char, '\-';
1355             }
1356             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1357 0         0 push @char, CORE::chr(oct $1);
1358             }
1359             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1360 0         0 push @char, CORE::chr(hex $1);
1361             }
1362             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1363 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1364             }
1365             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1366             push @char, {
1367             '\0' => "\0",
1368             '\n' => "\n",
1369             '\r' => "\r",
1370             '\t' => "\t",
1371             '\f' => "\f",
1372             '\b' => "\x08", # \b means backspace in character class
1373             '\a' => "\a",
1374             '\e' => "\e",
1375 0         0 }->{$1};
1376             }
1377             elsif (/\G \\ ($q_char) /oxmsgc) {
1378 0         0 push @char, $1;
1379             }
1380             elsif (/\G ($q_char) /oxmsgc) {
1381 0         0 push @char, $1;
1382             }
1383             }
1384              
1385             # join separated multiple-octet
1386 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1387              
1388             # unescape '-'
1389 0         0 my @i = ();
1390 0         0 for my $i (0 .. $#char) {
1391 0 0       0 if ($char[$i] eq '\-') {
    0          
1392 0         0 $char[$i] = '-';
1393             }
1394             elsif ($char[$i] eq '-') {
1395 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1396 0         0 push @i, $i;
1397             }
1398             }
1399             }
1400              
1401             # open character list (reverse for splice)
1402 0         0 for my $i (CORE::reverse @i) {
1403 0         0 my @range = ();
1404              
1405             # range error
1406 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1407 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1408             }
1409              
1410             # range of multiple-octet code
1411 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1412 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1413 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1414             }
1415             elsif (CORE::length($char[$i+1]) == 2) {
1416 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1417 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1418             }
1419             elsif (CORE::length($char[$i+1]) == 3) {
1420 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1421 0         0 push @range, chars2();
1422 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1423             }
1424             elsif (CORE::length($char[$i+1]) == 4) {
1425 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1426 0         0 push @range, chars2();
1427 0         0 push @range, chars3();
1428 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1429             }
1430             else {
1431 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1432             }
1433             }
1434             elsif (CORE::length($char[$i-1]) == 2) {
1435 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1436 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1437             }
1438             elsif (CORE::length($char[$i+1]) == 3) {
1439 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1440 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1441             }
1442             elsif (CORE::length($char[$i+1]) == 4) {
1443 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1444 0         0 push @range, chars3();
1445 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1446             }
1447             else {
1448 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1449             }
1450             }
1451             elsif (CORE::length($char[$i-1]) == 3) {
1452 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1453 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1454             }
1455             elsif (CORE::length($char[$i+1]) == 4) {
1456 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1457 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1458             }
1459             else {
1460 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1461             }
1462             }
1463             elsif (CORE::length($char[$i-1]) == 4) {
1464 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1465 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1466             }
1467             else {
1468 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1469             }
1470             }
1471             else {
1472 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1473             }
1474              
1475 0         0 splice @char, $i-1, 3, @range;
1476             }
1477              
1478 0         0 return @char;
1479             }
1480              
1481             #
1482             # KOI8-U open character class
1483             #
1484             sub _cc {
1485 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1486 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1487             }
1488             elsif (scalar(@_) == 1) {
1489 0         0 return sprintf('\x%02X',$_[0]);
1490             }
1491             elsif (scalar(@_) == 2) {
1492 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1493 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1494             }
1495             elsif ($_[0] == $_[1]) {
1496 0         0 return sprintf('\x%02X',$_[0]);
1497             }
1498             elsif (($_[0]+1) == $_[1]) {
1499 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1500             }
1501             else {
1502 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1503             }
1504             }
1505             else {
1506 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1507             }
1508             }
1509              
1510             #
1511             # KOI8-U octet range
1512             #
1513             sub _octets {
1514 0     182   0 my $length = shift @_;
1515              
1516 182 50       296 if ($length == 1) {
1517 182         353 my($a1) = unpack 'C', $_[0];
1518 182         443 my($z1) = unpack 'C', $_[1];
1519              
1520 182 50       290 if ($a1 > $z1) {
1521 182         379 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1522             }
1523              
1524 0 50       0 if ($a1 == $z1) {
    50          
1525 182         435 return sprintf('\x%02X',$a1);
1526             }
1527             elsif (($a1+1) == $z1) {
1528 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1529             }
1530             else {
1531 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1532             }
1533             }
1534             else {
1535 182         1177 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1536             }
1537             }
1538              
1539             #
1540             # KOI8-U range regexp
1541             #
1542             sub _range_regexp {
1543 0     182   0 my($length,$first,$last) = @_;
1544              
1545 182         355 my @range_regexp = ();
1546 182 50       260 if (not exists $range_tr{$length}) {
1547 182         419 return @range_regexp;
1548             }
1549              
1550 0         0 my @ranges = @{ $range_tr{$length} };
  182         265  
1551 182         369 while (my @range = splice(@ranges,0,$length)) {
1552 182         582 my $min = '';
1553 182         277 my $max = '';
1554 182         254 for (my $i=0; $i < $length; $i++) {
1555 182         421 $min .= pack 'C', $range[$i][0];
1556 182         575 $max .= pack 'C', $range[$i][-1];
1557             }
1558              
1559             # min___max
1560             # FIRST_____________LAST
1561             # (nothing)
1562              
1563 182 50 33     409 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1564             }
1565              
1566             # **********
1567             # min_________max
1568             # FIRST_____________LAST
1569             # **********
1570              
1571             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1572 182         1617 push @range_regexp, _octets($length,$first,$max,$min,$max);
1573             }
1574              
1575             # **********************
1576             # min________________max
1577             # FIRST_____________LAST
1578             # **********************
1579              
1580             elsif (($min eq $first) and ($max eq $last)) {
1581 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1582             }
1583              
1584             # *********
1585             # min___max
1586             # FIRST_____________LAST
1587             # *********
1588              
1589             elsif (($first le $min) and ($max le $last)) {
1590 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1591             }
1592              
1593             # **********************
1594             # min__________________________max
1595             # FIRST_____________LAST
1596             # **********************
1597              
1598             elsif (($min le $first) and ($last le $max)) {
1599 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1600             }
1601              
1602             # *********
1603             # min________max
1604             # FIRST_____________LAST
1605             # *********
1606              
1607             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1608 182         415 push @range_regexp, _octets($length,$min,$last,$min,$max);
1609             }
1610              
1611             # min___max
1612             # FIRST_____________LAST
1613             # (nothing)
1614              
1615             elsif ($last lt $min) {
1616             }
1617              
1618             else {
1619 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1620             }
1621             }
1622              
1623 0         0 return @range_regexp;
1624             }
1625              
1626             #
1627             # KOI8-U open character list for qr and not qr
1628             #
1629             sub _charlist {
1630              
1631 182     358   403 my $modifier = pop @_;
1632 358         701 my @char = @_;
1633              
1634 358 100       717 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1635              
1636             # unescape character
1637 358         810 for (my $i=0; $i <= $#char; $i++) {
1638              
1639             # escape - to ...
1640 358 100 100     1526 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1641 1125 100 100     7823 if ((0 < $i) and ($i < $#char)) {
1642 206         720 $char[$i] = '...';
1643             }
1644             }
1645              
1646             # octal escape sequence
1647             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1648 182         378 $char[$i] = octchr($1);
1649             }
1650              
1651             # hexadecimal escape sequence
1652             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1653 0         0 $char[$i] = hexchr($1);
1654             }
1655              
1656             # \b{...} --> b\{...}
1657             # \B{...} --> B\{...}
1658             # \N{CHARNAME} --> N\{CHARNAME}
1659             # \p{PROPERTY} --> p\{PROPERTY}
1660             # \P{PROPERTY} --> P\{PROPERTY}
1661             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1662 0         0 $char[$i] = $1 . '\\' . $2;
1663             }
1664              
1665             # \p, \P, \X --> p, P, X
1666             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1667 0         0 $char[$i] = $1;
1668             }
1669              
1670             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1671 0         0 $char[$i] = CORE::chr oct $1;
1672             }
1673             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1674 0         0 $char[$i] = CORE::chr hex $1;
1675             }
1676             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1677 22         104 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1678             }
1679             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1680             $char[$i] = {
1681             '\0' => "\0",
1682             '\n' => "\n",
1683             '\r' => "\r",
1684             '\t' => "\t",
1685             '\f' => "\f",
1686             '\b' => "\x08", # \b means backspace in character class
1687             '\a' => "\a",
1688             '\e' => "\e",
1689             '\d' => '[0-9]',
1690              
1691             # Vertical tabs are now whitespace
1692             # \s in a regex now matches a vertical tab in all circumstances.
1693             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1694             # \t \n \v \f \r space
1695             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1696             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1697             '\s' => '\s',
1698              
1699             '\w' => '[0-9A-Z_a-z]',
1700             '\D' => '${Ekoi8u::eD}',
1701             '\S' => '${Ekoi8u::eS}',
1702             '\W' => '${Ekoi8u::eW}',
1703              
1704             '\H' => '${Ekoi8u::eH}',
1705             '\V' => '${Ekoi8u::eV}',
1706             '\h' => '[\x09\x20]',
1707             '\v' => '[\x0A\x0B\x0C\x0D]',
1708             '\R' => '${Ekoi8u::eR}',
1709              
1710 0         0 }->{$1};
1711             }
1712              
1713             # POSIX-style character classes
1714             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1715             $char[$i] = {
1716              
1717             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1718             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1719             '[:^lower:]' => '${Ekoi8u::not_lower_i}',
1720             '[:^upper:]' => '${Ekoi8u::not_upper_i}',
1721              
1722 25         389 }->{$1};
1723             }
1724             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1725             $char[$i] = {
1726              
1727             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1728             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1729             '[:ascii:]' => '[\x00-\x7F]',
1730             '[:blank:]' => '[\x09\x20]',
1731             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1732             '[:digit:]' => '[\x30-\x39]',
1733             '[:graph:]' => '[\x21-\x7F]',
1734             '[:lower:]' => '[\x61-\x7A]',
1735             '[:print:]' => '[\x20-\x7F]',
1736             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1737              
1738             # P.174 POSIX-Style Character Classes
1739             # in Chapter 5: Pattern Matching
1740             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1741              
1742             # P.311 11.2.4 Character Classes and other Special Escapes
1743             # in Chapter 11: perlre: Perl regular expressions
1744             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1745              
1746             # P.210 POSIX-Style Character Classes
1747             # in Chapter 5: Pattern Matching
1748             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1749              
1750             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1751              
1752             '[:upper:]' => '[\x41-\x5A]',
1753             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1754             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1755             '[:^alnum:]' => '${Ekoi8u::not_alnum}',
1756             '[:^alpha:]' => '${Ekoi8u::not_alpha}',
1757             '[:^ascii:]' => '${Ekoi8u::not_ascii}',
1758             '[:^blank:]' => '${Ekoi8u::not_blank}',
1759             '[:^cntrl:]' => '${Ekoi8u::not_cntrl}',
1760             '[:^digit:]' => '${Ekoi8u::not_digit}',
1761             '[:^graph:]' => '${Ekoi8u::not_graph}',
1762             '[:^lower:]' => '${Ekoi8u::not_lower}',
1763             '[:^print:]' => '${Ekoi8u::not_print}',
1764             '[:^punct:]' => '${Ekoi8u::not_punct}',
1765             '[:^space:]' => '${Ekoi8u::not_space}',
1766             '[:^upper:]' => '${Ekoi8u::not_upper}',
1767             '[:^word:]' => '${Ekoi8u::not_word}',
1768             '[:^xdigit:]' => '${Ekoi8u::not_xdigit}',
1769              
1770 8         59 }->{$1};
1771             }
1772             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1773 70         1187 $char[$i] = $1;
1774             }
1775             }
1776              
1777             # open character list
1778 7         35 my @singleoctet = ();
1779 358         625 my @multipleoctet = ();
1780 358         457 for (my $i=0; $i <= $#char; ) {
1781              
1782             # escaped -
1783 358 100 100     773 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1784 943         3903 $i += 1;
1785 182         241 next;
1786             }
1787              
1788             # make range regexp
1789             elsif ($char[$i] eq '...') {
1790              
1791             # range error
1792 182 50       324 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1793 182         632 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1794             }
1795             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1796 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1797 182         425 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1798             }
1799             }
1800              
1801             # make range regexp per length
1802 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1803 182         492 my @regexp = ();
1804              
1805             # is first and last
1806 182 50 33     286 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1807 182         607 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1808             }
1809              
1810             # is first
1811             elsif ($length == CORE::length($char[$i-1])) {
1812 182         463 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1813             }
1814              
1815             # is inside in first and last
1816             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1817 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1818             }
1819              
1820             # is last
1821             elsif ($length == CORE::length($char[$i+1])) {
1822 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1823             }
1824              
1825             else {
1826 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1827             }
1828              
1829 0 50       0 if ($length == 1) {
1830 182         338 push @singleoctet, @regexp;
1831             }
1832             else {
1833 182         413 push @multipleoctet, @regexp;
1834             }
1835             }
1836              
1837 0         0 $i += 2;
1838             }
1839              
1840             # with /i modifier
1841             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1842 182 100       364 if ($modifier =~ /i/oxms) {
1843 493         721 my $uc = Ekoi8u::uc($char[$i]);
1844 24         47 my $fc = Ekoi8u::fc($char[$i]);
1845 24 100       46 if ($uc ne $fc) {
1846 24 50       43 if (CORE::length($fc) == 1) {
1847 12         19 push @singleoctet, $uc, $fc;
1848             }
1849             else {
1850 12         20 push @singleoctet, $uc;
1851 0         0 push @multipleoctet, $fc;
1852             }
1853             }
1854             else {
1855 0         0 push @singleoctet, $char[$i];
1856             }
1857             }
1858             else {
1859 12         32 push @singleoctet, $char[$i];
1860             }
1861 469         646 $i += 1;
1862             }
1863              
1864             # single character of single octet code
1865             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1866 493         755 push @singleoctet, "\t", "\x20";
1867 0         0 $i += 1;
1868             }
1869             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1870 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1871 0         0 $i += 1;
1872             }
1873             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1874 0         0 push @singleoctet, $char[$i];
1875 2         6 $i += 1;
1876             }
1877              
1878             # single character of multiple-octet code
1879             else {
1880 2         6 push @multipleoctet, $char[$i];
1881 84         145 $i += 1;
1882             }
1883             }
1884              
1885             # quote metachar
1886 84         161 for (@singleoctet) {
1887 358 50       788 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1888 689         2956 $_ = '-';
1889             }
1890             elsif (/\A \n \z/oxms) {
1891 0         0 $_ = '\n';
1892             }
1893             elsif (/\A \r \z/oxms) {
1894 8         23 $_ = '\r';
1895             }
1896             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1897 8         18 $_ = sprintf('\x%02X', CORE::ord $1);
1898             }
1899             elsif (/\A [\x00-\xFF] \z/oxms) {
1900 60         266 $_ = quotemeta $_;
1901             }
1902             }
1903              
1904             # return character list
1905 429         638 return \@singleoctet, \@multipleoctet;
1906             }
1907              
1908             #
1909             # KOI8-U octal escape sequence
1910             #
1911             sub octchr {
1912 358     5 0 1240 my($octdigit) = @_;
1913              
1914 5         14 my @binary = ();
1915 5         9 for my $octal (split(//,$octdigit)) {
1916             push @binary, {
1917             '0' => '000',
1918             '1' => '001',
1919             '2' => '010',
1920             '3' => '011',
1921             '4' => '100',
1922             '5' => '101',
1923             '6' => '110',
1924             '7' => '111',
1925 5         27 }->{$octal};
1926             }
1927 50         175 my $binary = join '', @binary;
1928              
1929             my $octchr = {
1930             # 1234567
1931             1 => pack('B*', "0000000$binary"),
1932             2 => pack('B*', "000000$binary"),
1933             3 => pack('B*', "00000$binary"),
1934             4 => pack('B*', "0000$binary"),
1935             5 => pack('B*', "000$binary"),
1936             6 => pack('B*', "00$binary"),
1937             7 => pack('B*', "0$binary"),
1938             0 => pack('B*', "$binary"),
1939              
1940 5         14 }->{CORE::length($binary) % 8};
1941              
1942 5         60 return $octchr;
1943             }
1944              
1945             #
1946             # KOI8-U hexadecimal escape sequence
1947             #
1948             sub hexchr {
1949 5     5 0 19 my($hexdigit) = @_;
1950              
1951             my $hexchr = {
1952             1 => pack('H*', "0$hexdigit"),
1953             0 => pack('H*', "$hexdigit"),
1954              
1955 5         15 }->{CORE::length($_[0]) % 2};
1956              
1957 5         48 return $hexchr;
1958             }
1959              
1960             #
1961             # KOI8-U open character list for qr
1962             #
1963             sub charlist_qr {
1964              
1965 5     314 0 19 my $modifier = pop @_;
1966 314         694 my @char = @_;
1967              
1968 314         727 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1969 314         917 my @singleoctet = @$singleoctet;
1970 314         622 my @multipleoctet = @$multipleoctet;
1971              
1972             # return character list
1973 314 100       462 if (scalar(@singleoctet) >= 1) {
1974              
1975             # with /i modifier
1976 314 100       730 if ($modifier =~ m/i/oxms) {
1977 236         454 my %singleoctet_ignorecase = ();
1978 22         26 for (@singleoctet) {
1979 22   100     40 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1980 46         195 for my $ord (hex($1) .. hex($2)) {
1981 46         124 my $char = CORE::chr($ord);
1982 66         93 my $uc = Ekoi8u::uc($char);
1983 66         93 my $fc = Ekoi8u::fc($char);
1984 66 100       100 if ($uc eq $fc) {
1985 66         107 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1986             }
1987             else {
1988 12 50       72 if (CORE::length($fc) == 1) {
1989 54         71 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1990 54         119 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1991             }
1992             else {
1993 54         185 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1994 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1995             }
1996             }
1997             }
1998             }
1999 0 50       0 if ($_ ne '') {
2000 46         86 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2001             }
2002             }
2003 0         0 my $i = 0;
2004 22         29 my @singleoctet_ignorecase = ();
2005 22         31 for my $ord (0 .. 255) {
2006 22 100       29 if (exists $singleoctet_ignorecase{$ord}) {
2007 5632         6065 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         85  
2008             }
2009             else {
2010 96         202 $i++;
2011             }
2012             }
2013 5536         5361 @singleoctet = ();
2014 22         33 for my $range (@singleoctet_ignorecase) {
2015 22 100       56 if (ref $range) {
2016 3648 100       5478 if (scalar(@{$range}) == 1) {
  56 50       54  
2017 56         78 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         44  
2018             }
2019 36         118 elsif (scalar(@{$range}) == 2) {
2020 20         30 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2021             }
2022             else {
2023 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         23  
  20         21  
2024             }
2025             }
2026             }
2027             }
2028              
2029 20         71 my $not_anchor = '';
2030              
2031 236         514 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2032             }
2033 236 100       710 if (scalar(@multipleoctet) >= 2) {
2034 314         640 return '(?:' . join('|', @multipleoctet) . ')';
2035             }
2036             else {
2037 6         31 return $multipleoctet[0];
2038             }
2039             }
2040              
2041             #
2042             # KOI8-U open character list for not qr
2043             #
2044             sub charlist_not_qr {
2045              
2046 308     44 0 1269 my $modifier = pop @_;
2047 44         106 my @char = @_;
2048              
2049 44         122 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2050 44         153 my @singleoctet = @$singleoctet;
2051 44         98 my @multipleoctet = @$multipleoctet;
2052              
2053             # with /i modifier
2054 44 100       68 if ($modifier =~ m/i/oxms) {
2055 44         102 my %singleoctet_ignorecase = ();
2056 10         14 for (@singleoctet) {
2057 10   66     11 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2058 10         44 for my $ord (hex($1) .. hex($2)) {
2059 10         32 my $char = CORE::chr($ord);
2060 30         68 my $uc = Ekoi8u::uc($char);
2061 30         47 my $fc = Ekoi8u::fc($char);
2062 30 50       44 if ($uc eq $fc) {
2063 30         43 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2064             }
2065             else {
2066 0 50       0 if (CORE::length($fc) == 1) {
2067 30         42 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2068 30         62 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2069             }
2070             else {
2071 30         91 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2072 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2073             }
2074             }
2075             }
2076             }
2077 0 50       0 if ($_ ne '') {
2078 10         36 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2079             }
2080             }
2081 0         0 my $i = 0;
2082 10         12 my @singleoctet_ignorecase = ();
2083 10         13 for my $ord (0 .. 255) {
2084 10 100       15 if (exists $singleoctet_ignorecase{$ord}) {
2085 2560         3391 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         49  
2086             }
2087             else {
2088 60         93 $i++;
2089             }
2090             }
2091 2500         2456 @singleoctet = ();
2092 10         14 for my $range (@singleoctet_ignorecase) {
2093 10 100       48 if (ref $range) {
2094 960 50       1473 if (scalar(@{$range}) == 1) {
  20 50       18  
2095 20         31 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2096             }
2097 0         0 elsif (scalar(@{$range}) == 2) {
2098 20         28 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2099             }
2100             else {
2101 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         23  
  20         23  
2102             }
2103             }
2104             }
2105             }
2106              
2107             # return character list
2108 20 50       76 if (scalar(@multipleoctet) >= 1) {
2109 44 0       92 if (scalar(@singleoctet) >= 1) {
2110              
2111             # any character other than multiple-octet and single octet character class
2112 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2113             }
2114             else {
2115              
2116             # any character other than multiple-octet character class
2117 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2118             }
2119             }
2120             else {
2121 0 50       0 if (scalar(@singleoctet) >= 1) {
2122              
2123             # any character other than single octet character class
2124 44         102 return '(?:[^' . join('', @singleoctet) . '])';
2125             }
2126             else {
2127              
2128             # any character
2129 44         258 return "(?:$your_char)";
2130             }
2131             }
2132             }
2133              
2134             #
2135             # open file in read mode
2136             #
2137             sub _open_r {
2138 0     412   0 my(undef,$file) = @_;
2139 206     206   2518 use Fcntl qw(O_RDONLY);
  206         6971  
  206         27378  
2140 412         1143 return CORE::sysopen($_[0], $file, &O_RDONLY);
2141             }
2142              
2143             #
2144             # open file in append mode
2145             #
2146             sub _open_a {
2147 412     206   16641 my(undef,$file) = @_;
2148 206     206   1425 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  206         385  
  206         751578  
2149 206         707 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2150             }
2151              
2152             #
2153             # safe system
2154             #
2155             sub _systemx {
2156              
2157             # P.707 29.2.33. exec
2158             # in Chapter 29: Functions
2159             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2160             #
2161             # Be aware that in older releases of Perl, exec (and system) did not flush
2162             # your output buffer, so you needed to enable command buffering by setting $|
2163             # on one or more filehandles to avoid lost output in the case of exec, or
2164             # misordererd output in the case of system. This situation was largely remedied
2165             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2166              
2167             # P.855 exec
2168             # in Chapter 27: Functions
2169             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2170             #
2171             # In very old release of Perl (before v5.6), exec (and system) did not flush
2172             # your output buffer, so you needed to enable command buffering by setting $|
2173             # on one or more filehandles to avoid lost output with exec or misordered
2174             # output with system.
2175              
2176 206     206   38337 $| = 1;
2177              
2178             # P.565 23.1.2. Cleaning Up Your Environment
2179             # in Chapter 23: Security
2180             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2181              
2182             # P.656 Cleaning Up Your Environment
2183             # in Chapter 20: Security
2184             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2185              
2186             # local $ENV{'PATH'} = '.';
2187 206         909 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2188              
2189             # P.707 29.2.33. exec
2190             # in Chapter 29: Functions
2191             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2192             #
2193             # As we mentioned earlier, exec treats a discrete list of arguments as an
2194             # indication that it should bypass shell processing. However, there is one
2195             # place where you might still get tripped up. The exec call (and system, too)
2196             # will not distinguish between a single scalar argument and an array containing
2197             # only one element.
2198             #
2199             # @args = ("echo surprise"); # just one element in list
2200             # exec @args # still subject to shell escapes
2201             # or die "exec: $!"; # because @args == 1
2202             #
2203             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2204             # first argument as the pathname, which forces the rest of the arguments to be
2205             # interpreted as a list, even if there is only one of them:
2206             #
2207             # exec { $args[0] } @args # safe even with one-argument list
2208             # or die "can't exec @args: $!";
2209              
2210             # P.855 exec
2211             # in Chapter 27: Functions
2212             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2213             #
2214             # As we mentioned earlier, exec treats a discrete list of arguments as a
2215             # directive to bypass shell processing. However, there is one place where
2216             # you might still get tripped up. The exec call (and system, too) cannot
2217             # distinguish between a single scalar argument and an array containing
2218             # only one element.
2219             #
2220             # @args = ("echo surprise"); # just one element in list
2221             # exec @args # still subject to shell escapes
2222             # || die "exec: $!"; # because @args == 1
2223             #
2224             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2225             # argument as the pathname, which forces the rest of the arguments to be
2226             # interpreted as a list, even if there is only one of them:
2227             #
2228             # exec { $args[0] } @args # safe even with one-argument list
2229             # || die "can't exec @args: $!";
2230              
2231 206         2151 return CORE::system { $_[0] } @_; # safe even with one-argument list
  206         467  
2232             }
2233              
2234             #
2235             # KOI8-U order to character (with parameter)
2236             #
2237             sub Ekoi8u::chr(;$) {
2238              
2239 206 0   0 0 18828490 my $c = @_ ? $_[0] : $_;
2240              
2241 0 0       0 if ($c == 0x00) {
2242 0         0 return "\x00";
2243             }
2244             else {
2245 0         0 my @chr = ();
2246 0         0 while ($c > 0) {
2247 0         0 unshift @chr, ($c % 0x100);
2248 0         0 $c = int($c / 0x100);
2249             }
2250 0         0 return pack 'C*', @chr;
2251             }
2252             }
2253              
2254             #
2255             # KOI8-U order to character (without parameter)
2256             #
2257             sub Ekoi8u::chr_() {
2258              
2259 0     0 0 0 my $c = $_;
2260              
2261 0 0       0 if ($c == 0x00) {
2262 0         0 return "\x00";
2263             }
2264             else {
2265 0         0 my @chr = ();
2266 0         0 while ($c > 0) {
2267 0         0 unshift @chr, ($c % 0x100);
2268 0         0 $c = int($c / 0x100);
2269             }
2270 0         0 return pack 'C*', @chr;
2271             }
2272             }
2273              
2274             #
2275             # KOI8-U path globbing (with parameter)
2276             #
2277             sub Ekoi8u::glob($) {
2278              
2279 0 0   0 0 0 if (wantarray) {
2280 0         0 my @glob = _DOS_like_glob(@_);
2281 0         0 for my $glob (@glob) {
2282 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2283             }
2284 0         0 return @glob;
2285             }
2286             else {
2287 0         0 my $glob = _DOS_like_glob(@_);
2288 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2289 0         0 return $glob;
2290             }
2291             }
2292              
2293             #
2294             # KOI8-U path globbing (without parameter)
2295             #
2296             sub Ekoi8u::glob_() {
2297              
2298 0 0   0 0 0 if (wantarray) {
2299 0         0 my @glob = _DOS_like_glob();
2300 0         0 for my $glob (@glob) {
2301 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2302             }
2303 0         0 return @glob;
2304             }
2305             else {
2306 0         0 my $glob = _DOS_like_glob();
2307 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2308 0         0 return $glob;
2309             }
2310             }
2311              
2312             #
2313             # KOI8-U path globbing via File::DosGlob 1.10
2314             #
2315             # Often I confuse "_dosglob" and "_doglob".
2316             # So, I renamed "_dosglob" to "_DOS_like_glob".
2317             #
2318             my %iter;
2319             my %entries;
2320             sub _DOS_like_glob {
2321              
2322             # context (keyed by second cxix argument provided by core)
2323 0     0   0 my($expr,$cxix) = @_;
2324              
2325             # glob without args defaults to $_
2326 0 0       0 $expr = $_ if not defined $expr;
2327              
2328             # represents the current user's home directory
2329             #
2330             # 7.3. Expanding Tildes in Filenames
2331             # in Chapter 7. File Access
2332             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2333             #
2334             # and File::HomeDir, File::HomeDir::Windows module
2335              
2336             # DOS-like system
2337 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2338 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2339             { my_home_MSWin32() }oxmse;
2340             }
2341              
2342             # UNIX-like system
2343 0 0 0     0 else {
  0         0  
2344             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2345             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2346             }
2347 0 0       0  
2348 0 0       0 # assume global context if not provided one
2349             $cxix = '_G_' if not defined $cxix;
2350             $iter{$cxix} = 0 if not exists $iter{$cxix};
2351 0 0       0  
2352 0         0 # if we're just beginning, do it all first
2353             if ($iter{$cxix} == 0) {
2354             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2355             }
2356 0 0       0  
2357 0         0 # chuck it all out, quick or slow
2358 0         0 if (wantarray) {
  0         0  
2359             delete $iter{$cxix};
2360             return @{delete $entries{$cxix}};
2361 0 0       0 }
  0         0  
2362 0         0 else {
  0         0  
2363             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2364             return shift @{$entries{$cxix}};
2365             }
2366 0         0 else {
2367 0         0 # return undef for EOL
2368 0         0 delete $iter{$cxix};
2369             delete $entries{$cxix};
2370             return undef;
2371             }
2372             }
2373             }
2374              
2375             #
2376             # KOI8-U path globbing subroutine
2377             #
2378 0     0   0 sub _do_glob {
2379 0         0  
2380 0         0 my($cond,@expr) = @_;
2381             my @glob = ();
2382             my $fix_drive_relative_paths = 0;
2383 0         0  
2384 0 0       0 OUTER:
2385 0 0       0 for my $expr (@expr) {
2386             next OUTER if not defined $expr;
2387 0         0 next OUTER if $expr eq '';
2388 0         0  
2389 0         0 my @matched = ();
2390 0         0 my @globdir = ();
2391 0         0 my $head = '.';
2392             my $pathsep = '/';
2393             my $tail;
2394 0 0       0  
2395 0         0 # if argument is within quotes strip em and do no globbing
2396 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2397 0 0       0 $expr = $1;
2398 0         0 if ($cond eq 'd') {
2399             if (-d $expr) {
2400             push @glob, $expr;
2401             }
2402 0 0       0 }
2403 0         0 else {
2404             if (-e $expr) {
2405             push @glob, $expr;
2406 0         0 }
2407             }
2408             next OUTER;
2409             }
2410              
2411 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2412 0 0       0 # to h:./*.pm to expand correctly
2413 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2414             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2415             $fix_drive_relative_paths = 1;
2416             }
2417 0 0       0 }
2418 0 0       0  
2419 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2420 0         0 if ($tail eq '') {
2421             push @glob, $expr;
2422 0 0       0 next OUTER;
2423 0 0       0 }
2424 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2425 0         0 if (@globdir = _do_glob('d', $head)) {
2426             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2427             next OUTER;
2428 0 0 0     0 }
2429 0         0 }
2430             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2431 0         0 $head .= $pathsep;
2432             }
2433             $expr = $tail;
2434             }
2435 0 0       0  
2436 0 0       0 # If file component has no wildcards, we can avoid opendir
2437 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2438             if ($head eq '.') {
2439 0 0 0     0 $head = '';
2440 0         0 }
2441             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2442 0         0 $head .= $pathsep;
2443 0 0       0 }
2444 0 0       0 $head .= $expr;
2445 0         0 if ($cond eq 'd') {
2446             if (-d $head) {
2447             push @glob, $head;
2448             }
2449 0 0       0 }
2450 0         0 else {
2451             if (-e $head) {
2452             push @glob, $head;
2453 0         0 }
2454             }
2455 0 0       0 next OUTER;
2456 0         0 }
2457 0         0 opendir(*DIR, $head) or next OUTER;
2458             my @leaf = readdir DIR;
2459 0 0       0 closedir DIR;
2460 0         0  
2461             if ($head eq '.') {
2462 0 0 0     0 $head = '';
2463 0         0 }
2464             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2465             $head .= $pathsep;
2466 0         0 }
2467 0         0  
2468 0         0 my $pattern = '';
2469             while ($expr =~ / \G ($q_char) /oxgc) {
2470             my $char = $1;
2471              
2472             # 6.9. Matching Shell Globs as Regular Expressions
2473             # in Chapter 6. Pattern Matching
2474             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2475 0 0       0 # (and so on)
    0          
    0          
2476 0         0  
2477             if ($char eq '*') {
2478             $pattern .= "(?:$your_char)*",
2479 0         0 }
2480             elsif ($char eq '?') {
2481             $pattern .= "(?:$your_char)?", # DOS style
2482             # $pattern .= "(?:$your_char)", # UNIX style
2483 0         0 }
2484             elsif ((my $fc = Ekoi8u::fc($char)) ne $char) {
2485             $pattern .= $fc;
2486 0         0 }
2487             else {
2488             $pattern .= quotemeta $char;
2489 0     0   0 }
  0         0  
2490             }
2491             my $matchsub = sub { Ekoi8u::fc($_[0]) =~ /\A $pattern \z/xms };
2492              
2493             # if ($@) {
2494             # print STDERR "$0: $@\n";
2495             # next OUTER;
2496             # }
2497 0         0  
2498 0 0 0     0 INNER:
2499 0         0 for my $leaf (@leaf) {
2500             if ($leaf eq '.' or $leaf eq '..') {
2501 0 0 0     0 next INNER;
2502 0         0 }
2503             if ($cond eq 'd' and not -d "$head$leaf") {
2504             next INNER;
2505 0 0       0 }
2506 0         0  
2507 0         0 if (&$matchsub($leaf)) {
2508             push @matched, "$head$leaf";
2509             next INNER;
2510             }
2511              
2512             # [DOS compatibility special case]
2513 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2514              
2515             if (Ekoi8u::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2516             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2517 0 0       0 Ekoi8u::index($pattern,'\\.') != -1 # pattern has a dot.
2518 0         0 ) {
2519 0         0 if (&$matchsub("$leaf.")) {
2520             push @matched, "$head$leaf";
2521             next INNER;
2522             }
2523 0 0       0 }
2524 0         0 }
2525             if (@matched) {
2526             push @glob, @matched;
2527 0 0       0 }
2528 0         0 }
2529 0         0 if ($fix_drive_relative_paths) {
2530             for my $glob (@glob) {
2531             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2532 0         0 }
2533             }
2534             return @glob;
2535             }
2536              
2537             #
2538             # KOI8-U parse line
2539             #
2540 0     0   0 sub _parse_line {
2541              
2542 0         0 my($line) = @_;
2543 0         0  
2544 0         0 $line .= ' ';
2545             my @piece = ();
2546             while ($line =~ /
2547             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2548             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2549 0 0       0 /oxmsg
2550             ) {
2551 0         0 push @piece, defined($1) ? $1 : $2;
2552             }
2553             return @piece;
2554             }
2555              
2556             #
2557             # KOI8-U parse path
2558             #
2559 0     0   0 sub _parse_path {
2560              
2561 0         0 my($path,$pathsep) = @_;
2562 0         0  
2563 0         0 $path .= '/';
2564             my @subpath = ();
2565             while ($path =~ /
2566             ((?: [^\/\\] )+?) [\/\\]
2567 0         0 /oxmsg
2568             ) {
2569             push @subpath, $1;
2570 0         0 }
2571 0         0  
2572 0         0 my $tail = pop @subpath;
2573             my $head = join $pathsep, @subpath;
2574             return $head, $tail;
2575             }
2576              
2577             #
2578             # via File::HomeDir::Windows 1.00
2579             #
2580             sub my_home_MSWin32 {
2581              
2582             # A lot of unix people and unix-derived tools rely on
2583 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2584 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2585             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2586             return $ENV{'HOME'};
2587             }
2588              
2589 0         0 # Do we have a user profile?
2590             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2591             return $ENV{'USERPROFILE'};
2592             }
2593              
2594 0         0 # Some Windows use something like $ENV{'HOME'}
2595             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2596             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2597 0         0 }
2598              
2599             return undef;
2600             }
2601              
2602             #
2603             # via File::HomeDir::Unix 1.00
2604 0     0 0 0 #
2605             sub my_home {
2606 0 0 0     0 my $home;
    0 0        
2607 0         0  
2608             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2609             $home = $ENV{'HOME'};
2610             }
2611              
2612             # This is from the original code, but I'm guessing
2613 0         0 # it means "login directory" and exists on some Unixes.
2614             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2615             $home = $ENV{'LOGDIR'};
2616             }
2617              
2618             ### More-desperate methods
2619              
2620 0         0 # Light desperation on any (Unixish) platform
2621             else {
2622             $home = CORE::eval q{ (getpwuid($<))[7] };
2623             }
2624              
2625 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2626 0         0 # For example, "nobody"-like users might use /nonexistant
2627             if (defined $home and ! -d($home)) {
2628 0         0 $home = undef;
2629             }
2630             return $home;
2631             }
2632              
2633             #
2634             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2635 0     0 0 0 #
2636             sub Ekoi8u::PREMATCH {
2637             return $`;
2638             }
2639              
2640             #
2641             # ${^MATCH}, $MATCH, $& the string that matched
2642 0     0 0 0 #
2643             sub Ekoi8u::MATCH {
2644             return $&;
2645             }
2646              
2647             #
2648             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2649 0     0 0 0 #
2650             sub Ekoi8u::POSTMATCH {
2651             return $';
2652             }
2653              
2654             #
2655             # KOI8-U character to order (with parameter)
2656             #
2657 0 0   0 1 0 sub KOI8U::ord(;$) {
2658              
2659 0 0       0 local $_ = shift if @_;
2660 0         0  
2661 0         0 if (/\A ($q_char) /oxms) {
2662 0         0 my @ord = unpack 'C*', $1;
2663 0         0 my $ord = 0;
2664             while (my $o = shift @ord) {
2665 0         0 $ord = $ord * 0x100 + $o;
2666             }
2667             return $ord;
2668 0         0 }
2669             else {
2670             return CORE::ord $_;
2671             }
2672             }
2673              
2674             #
2675             # KOI8-U character to order (without parameter)
2676             #
2677 0 0   0 0 0 sub KOI8U::ord_() {
2678 0         0  
2679 0         0 if (/\A ($q_char) /oxms) {
2680 0         0 my @ord = unpack 'C*', $1;
2681 0         0 my $ord = 0;
2682             while (my $o = shift @ord) {
2683 0         0 $ord = $ord * 0x100 + $o;
2684             }
2685             return $ord;
2686 0         0 }
2687             else {
2688             return CORE::ord $_;
2689             }
2690             }
2691              
2692             #
2693             # KOI8-U reverse
2694             #
2695 0 0   0 0 0 sub KOI8U::reverse(@) {
2696 0         0  
2697             if (wantarray) {
2698             return CORE::reverse @_;
2699             }
2700             else {
2701              
2702             # One of us once cornered Larry in an elevator and asked him what
2703             # problem he was solving with this, but he looked as far off into
2704             # the distance as he could in an elevator and said, "It seemed like
2705 0         0 # a good idea at the time."
2706              
2707             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2708             }
2709             }
2710              
2711             #
2712             # KOI8-U getc (with parameter, without parameter)
2713             #
2714 0     0 0 0 sub KOI8U::getc(;*@) {
2715 0 0       0  
2716 0 0 0     0 my($package) = caller;
2717             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2718 0         0 croak 'Too many arguments for KOI8U::getc' if @_ and not wantarray;
  0         0  
2719 0         0  
2720 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2721 0         0 my $getc = '';
2722 0 0       0 for my $length ($length[0] .. $length[-1]) {
2723 0 0       0 $getc .= CORE::getc($fh);
2724 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2725             if ($getc =~ /\A ${Ekoi8u::dot_s} \z/oxms) {
2726             return wantarray ? ($getc,@_) : $getc;
2727             }
2728 0 0       0 }
2729             }
2730             return wantarray ? ($getc,@_) : $getc;
2731             }
2732              
2733             #
2734             # KOI8-U length by character
2735             #
2736 0 0   0 1 0 sub KOI8U::length(;$) {
2737              
2738 0         0 local $_ = shift if @_;
2739 0         0  
2740             local @_ = /\G ($q_char) /oxmsg;
2741             return scalar @_;
2742             }
2743              
2744             #
2745             # KOI8-U substr by character
2746             #
2747             BEGIN {
2748              
2749             # P.232 The lvalue Attribute
2750             # in Chapter 6: Subroutines
2751             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2752              
2753             # P.336 The lvalue Attribute
2754             # in Chapter 7: Subroutines
2755             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2756              
2757             # P.144 8.4 Lvalue subroutines
2758             # in Chapter 8: perlsub: Perl subroutines
2759 206 50 0 206 1 166052 # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
  0 0   0   0  
  0 0   0   0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
2760              
2761             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2762             # vv----------------------*******
2763             sub KOI8U::substr($$;$$) %s {
2764              
2765             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2766              
2767             # If the substring is beyond either end of the string, substr() returns the undefined
2768             # value and produces a warning. When used as an lvalue, specifying a substring that
2769             # is entirely outside the string raises an exception.
2770             # http://perldoc.perl.org/functions/substr.html
2771              
2772             # A return with no argument returns the scalar value undef in scalar context,
2773             # an empty list () in list context, and (naturally) nothing at all in void
2774             # context.
2775              
2776             my $offset = $_[1];
2777             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2778             return;
2779             }
2780              
2781             # substr($string,$offset,$length,$replacement)
2782             if (@_ == 4) {
2783             my(undef,undef,$length,$replacement) = @_;
2784             my $substr = join '', splice(@char, $offset, $length, $replacement);
2785             $_[0] = join '', @char;
2786              
2787             # return $substr; this doesn't work, don't say "return"
2788             $substr;
2789             }
2790              
2791             # substr($string,$offset,$length)
2792             elsif (@_ == 3) {
2793             my(undef,undef,$length) = @_;
2794             my $octet_offset = 0;
2795             my $octet_length = 0;
2796             if ($offset == 0) {
2797             $octet_offset = 0;
2798             }
2799             elsif ($offset > 0) {
2800             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2801             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2802             }
2803             else {
2804             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2805             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2806             }
2807             if ($length == 0) {
2808             $octet_length = 0;
2809             }
2810             elsif ($length > 0) {
2811             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2812             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2813             }
2814             else {
2815             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2816             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2817             }
2818             CORE::substr($_[0], $octet_offset, $octet_length);
2819             }
2820              
2821             # substr($string,$offset)
2822             else {
2823             my $octet_offset = 0;
2824             if ($offset == 0) {
2825             $octet_offset = 0;
2826             }
2827             elsif ($offset > 0) {
2828             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2829             }
2830             else {
2831             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2832             }
2833             CORE::substr($_[0], $octet_offset);
2834             }
2835             }
2836             END
2837             }
2838              
2839             #
2840             # KOI8-U index by character
2841             #
2842 0     0 1 0 sub KOI8U::index($$;$) {
2843 0 0       0  
2844 0         0 my $index;
2845             if (@_ == 3) {
2846             $index = Ekoi8u::index($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2847 0         0 }
2848             else {
2849             $index = Ekoi8u::index($_[0], $_[1]);
2850 0 0       0 }
2851 0         0  
2852             if ($index == -1) {
2853             return -1;
2854 0         0 }
2855             else {
2856             return KOI8U::length(CORE::substr $_[0], 0, $index);
2857             }
2858             }
2859              
2860             #
2861             # KOI8-U rindex by character
2862             #
2863 0     0 1 0 sub KOI8U::rindex($$;$) {
2864 0 0       0  
2865 0         0 my $rindex;
2866             if (@_ == 3) {
2867             $rindex = Ekoi8u::rindex($_[0], $_[1], CORE::length(KOI8U::substr($_[0], 0, $_[2])));
2868 0         0 }
2869             else {
2870             $rindex = Ekoi8u::rindex($_[0], $_[1]);
2871 0 0       0 }
2872 0         0  
2873             if ($rindex == -1) {
2874             return -1;
2875 0         0 }
2876             else {
2877             return KOI8U::length(CORE::substr $_[0], 0, $rindex);
2878             }
2879             }
2880              
2881 206     206   1667 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  206         556  
  206         19203  
2882             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2883             use vars qw($slash); $slash = 'm//';
2884              
2885             # ord() to ord() or KOI8U::ord()
2886             my $function_ord = 'ord';
2887              
2888             # ord to ord or KOI8U::ord_
2889             my $function_ord_ = 'ord';
2890              
2891             # reverse to reverse or KOI8U::reverse
2892             my $function_reverse = 'reverse';
2893              
2894             # getc to getc or KOI8U::getc
2895             my $function_getc = 'getc';
2896              
2897             # P.1023 Appendix W.9 Multibyte Anchoring
2898             # of ISBN 1-56592-224-7 CJKV Information Processing
2899              
2900 206     206   1479 my $anchor = '';
  206     0   387  
  206         8554069  
2901              
2902             use vars qw($nest);
2903              
2904             # regexp of nested parens in qqXX
2905              
2906             # P.340 Matching Nested Constructs with Embedded Code
2907             # in Chapter 7: Perl
2908             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2909              
2910             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2911             [^\\()] |
2912             \( (?{$nest++}) |
2913             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2914             \\ [^c] |
2915             \\c[\x40-\x5F] |
2916             [\x00-\xFF]
2917             }xms;
2918              
2919             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2920             [^\\{}] |
2921             \{ (?{$nest++}) |
2922             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2923             \\ [^c] |
2924             \\c[\x40-\x5F] |
2925             [\x00-\xFF]
2926             }xms;
2927              
2928             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2929             [^\\\[\]] |
2930             \[ (?{$nest++}) |
2931             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2932             \\ [^c] |
2933             \\c[\x40-\x5F] |
2934             [\x00-\xFF]
2935             }xms;
2936              
2937             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2938             [^\\<>] |
2939             \< (?{$nest++}) |
2940             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2941             \\ [^c] |
2942             \\c[\x40-\x5F] |
2943             [\x00-\xFF]
2944             }xms;
2945              
2946             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2947             (?: ::)? (?:
2948             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2949             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2950             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2951             ))
2952             }xms;
2953              
2954             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2955             (?: ::)? (?:
2956             (?>[0-9]+) |
2957             [^a-zA-Z_0-9\[\]] |
2958             ^[A-Z] |
2959             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2960             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2961             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2962             ))
2963             }xms;
2964              
2965             my $qq_substr = qr{(?> Char::substr | KOI8U::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2966             }xms;
2967              
2968             # regexp of nested parens in qXX
2969             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2970             [^()] |
2971             \( (?{$nest++}) |
2972             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2973             [\x00-\xFF]
2974             }xms;
2975              
2976             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2977             [^\{\}] |
2978             \{ (?{$nest++}) |
2979             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2980             [\x00-\xFF]
2981             }xms;
2982              
2983             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2984             [^\[\]] |
2985             \[ (?{$nest++}) |
2986             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2987             [\x00-\xFF]
2988             }xms;
2989              
2990             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2991             [^<>] |
2992             \< (?{$nest++}) |
2993             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2994             [\x00-\xFF]
2995             }xms;
2996              
2997             my $matched = '';
2998             my $s_matched = '';
2999              
3000             my $tr_variable = ''; # variable of tr///
3001             my $sub_variable = ''; # variable of s///
3002             my $bind_operator = ''; # =~ or !~
3003              
3004             my @heredoc = (); # here document
3005             my @heredoc_delimiter = ();
3006             my $here_script = ''; # here script
3007              
3008             #
3009             # escape KOI8-U script
3010 0 50   206 0 0 #
3011             sub KOI8U::escape(;$) {
3012             local($_) = $_[0] if @_;
3013              
3014             # P.359 The Study Function
3015             # in Chapter 7: Perl
3016 206         696 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3017              
3018             study $_; # Yes, I studied study yesterday.
3019              
3020             # while all script
3021              
3022             # 6.14. Matching from Where the Last Pattern Left Off
3023             # in Chapter 6. Pattern Matching
3024             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3025             # (and so on)
3026              
3027             # one member of Tag-team
3028             #
3029             # P.128 Start of match (or end of previous match): \G
3030             # P.130 Advanced Use of \G with Perl
3031             # in Chapter 3: Overview of Regular Expression Features and Flavors
3032             # P.255 Use leading anchors
3033             # P.256 Expose ^ and \G at the front expressions
3034             # in Chapter 6: Crafting an Efficient Expression
3035             # P.315 "Tag-team" matching with /gc
3036             # in Chapter 7: Perl
3037 206         545 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3038 206         348  
3039 206         2272 my $e_script = '';
3040             while (not /\G \z/oxgc) { # member
3041             $e_script .= KOI8U::escape_token();
3042 74842         111835 }
3043              
3044             return $e_script;
3045             }
3046              
3047             #
3048             # escape KOI8-U token of script
3049             #
3050             sub KOI8U::escape_token {
3051              
3052 206     74842 0 2884 # \n output here document
3053              
3054             my $ignore_modules = join('|', qw(
3055             utf8
3056             bytes
3057             charnames
3058             I18N::Japanese
3059             I18N::Collate
3060             I18N::JExt
3061             File::DosGlob
3062             Wild
3063             Wildcard
3064             Japanese
3065             ));
3066              
3067             # another member of Tag-team
3068             #
3069             # P.315 "Tag-team" matching with /gc
3070             # in Chapter 7: Perl
3071 74842 100 100     97867 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
    100 66        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
3072 74842         2897209  
3073 12535 100       14635 if (/\G ( \n ) /oxgc) { # another member (and so on)
3074 12535         20477 my $heredoc = '';
3075             if (scalar(@heredoc_delimiter) >= 1) {
3076 174         395 $slash = 'm//';
3077 174         330  
3078             $heredoc = join '', @heredoc;
3079             @heredoc = ();
3080 174         321  
3081 174         288 # skip here document
3082             for my $heredoc_delimiter (@heredoc_delimiter) {
3083 174         1333 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3084             }
3085 174         310 @heredoc_delimiter = ();
3086              
3087 174         236 $here_script = '';
3088             }
3089             return "\n" . $heredoc;
3090             }
3091 12535         36429  
3092             # ignore space, comment
3093             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3094              
3095             # if (, elsif (, unless (, while (, until (, given (, and when (
3096              
3097             # given, when
3098              
3099             # P.225 The given Statement
3100             # in Chapter 15: Smart Matching and given-when
3101             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3102              
3103             # P.133 The given Statement
3104             # in Chapter 4: Statements and Declarations
3105             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3106 17992         53420  
3107 1401         2103 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3108             $slash = 'm//';
3109             return $1;
3110             }
3111              
3112             # scalar variable ($scalar = ...) =~ tr///;
3113             # scalar variable ($scalar = ...) =~ s///;
3114              
3115             # state
3116              
3117             # P.68 Persistent, Private Variables
3118             # in Chapter 4: Subroutines
3119             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3120              
3121             # P.160 Persistent Lexically Scoped Variables: state
3122             # in Chapter 4: Statements and Declarations
3123             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3124              
3125             # (and so on)
3126 1401         4634  
3127             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3128 86 50       199 my $e_string = e_string($1);
    50          
3129 86         1946  
3130 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3131 0         0 $tr_variable = $e_string . e_string($1);
3132 0         0 $bind_operator = $2;
3133             $slash = 'm//';
3134             return '';
3135 0         0 }
3136 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3137 0         0 $sub_variable = $e_string . e_string($1);
3138 0         0 $bind_operator = $2;
3139             $slash = 'm//';
3140             return '';
3141 0         0 }
3142 86         172 else {
3143             $slash = 'div';
3144             return $e_string;
3145             }
3146             }
3147              
3148 86         289 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
3149 4         8 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3150             $slash = 'div';
3151             return q{Ekoi8u::PREMATCH()};
3152             }
3153              
3154 4         12 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
3155 28         54 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3156             $slash = 'div';
3157             return q{Ekoi8u::MATCH()};
3158             }
3159              
3160 28         91 # $', ${'} --> $', ${'}
3161 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3162             $slash = 'div';
3163             return $1;
3164             }
3165              
3166 1         3 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
3167 3         6 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3168             $slash = 'div';
3169             return q{Ekoi8u::POSTMATCH()};
3170             }
3171              
3172             # scalar variable $scalar =~ tr///;
3173             # scalar variable $scalar =~ s///;
3174             # substr() =~ tr///;
3175 3         9 # substr() =~ s///;
3176             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3177 1673 100       3689 my $scalar = e_string($1);
    100          
3178 1673         6147  
3179 1         3 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3180 1         1 $tr_variable = $scalar;
3181 1         2 $bind_operator = $1;
3182             $slash = 'm//';
3183             return '';
3184 1         4 }
3185 61         139 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3186 61         124 $sub_variable = $scalar;
3187 61         98 $bind_operator = $1;
3188             $slash = 'm//';
3189             return '';
3190 61         186 }
3191 1611         2242 else {
3192             $slash = 'div';
3193             return $scalar;
3194             }
3195             }
3196              
3197 1611         4213 # end of statement
3198             elsif (/\G ( [,;] ) /oxgc) {
3199             $slash = 'm//';
3200 5008         11638  
3201             # clear tr/// variable
3202             $tr_variable = '';
3203 5008         5762  
3204             # clear s/// variable
3205 5008         5422 $sub_variable = '';
3206              
3207 5008         5483 $bind_operator = '';
3208              
3209             return $1;
3210             }
3211              
3212 5008         19537 # bareword
3213             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3214             return $1;
3215             }
3216              
3217 0         0 # $0 --> $0
3218 2         5 elsif (/\G ( \$ 0 ) /oxmsgc) {
3219             $slash = 'div';
3220             return $1;
3221 2         7 }
3222 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3223             $slash = 'div';
3224             return $1;
3225             }
3226              
3227 0         0 # $$ --> $$
3228 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3229             $slash = 'div';
3230             return $1;
3231             }
3232              
3233             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3234 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
3235 4         8 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3236             $slash = 'div';
3237             return e_capture($1);
3238 4         9 }
3239 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3240             $slash = 'div';
3241             return e_capture($1);
3242             }
3243              
3244 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3245 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3246             $slash = 'div';
3247             return e_capture($1.'->'.$2);
3248             }
3249              
3250 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3251 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3252             $slash = 'div';
3253             return e_capture($1.'->'.$2);
3254             }
3255              
3256 0         0 # $$foo
3257 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3258             $slash = 'div';
3259             return e_capture($1);
3260             }
3261              
3262 0         0 # ${ foo }
3263 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3264             $slash = 'div';
3265             return '${' . $1 . '}';
3266             }
3267              
3268 0         0 # ${ ... }
3269 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3270             $slash = 'div';
3271             return e_capture($1);
3272             }
3273              
3274             # variable or function
3275 0         0 # $ @ % & * $ #
3276 42         68 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) {
3277             $slash = 'div';
3278             return $1;
3279             }
3280             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3281 42         145 # $ @ # \ ' " / ? ( ) [ ] < >
3282 62         106 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3283             $slash = 'div';
3284             return $1;
3285             }
3286              
3287 62         199 # while ()
3288             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3289             return $1;
3290             }
3291              
3292             # while () --- glob
3293              
3294             # avoid "Error: Runtime exception" of perl version 5.005_03
3295 0         0  
3296             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3297             return 'while ($_ = Ekoi8u::glob("' . $1 . '"))';
3298             }
3299              
3300 0         0 # while (glob)
3301             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3302             return 'while ($_ = Ekoi8u::glob_)';
3303             }
3304              
3305 0         0 # while (glob(WILDCARD))
3306             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3307             return 'while ($_ = Ekoi8u::glob';
3308             }
3309 0         0  
  248         576  
3310             # doit if, doit unless, doit while, doit until, doit for, doit when
3311             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3312 248         847  
  19         36  
3313 19         73 # subroutines of package Ekoi8u
  0         0  
3314 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         16  
3315 13         36 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3316 0         0 elsif (/\G \b KOI8U::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         177  
3317 114         336 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         5  
3318 2         6 elsif (/\G \b KOI8U::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval KOI8U::escape'; }
  0         0  
3319 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         3  
3320 2         5 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chop'; }
  0         0  
3321 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3322 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3323 0         0 elsif (/\G \b KOI8U::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::index'; }
  2         3  
3324 2         5 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::index'; }
  0         0  
3325 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3326 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3327 0         0 elsif (/\G \b KOI8U::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8U::rindex'; }
  1         2  
3328 1         4 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::rindex'; }
  0         0  
3329 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc'; }
  1         3  
3330 1         4 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst'; }
  0         0  
3331 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc'; }
  6         12  
3332             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst'; }
3333             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc'; }
3334 6         16  
  0         0  
3335 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3336 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3337 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3338 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3339 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3340 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3341             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3342 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  
3343 0         0  
  0         0  
3344 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3345 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3346 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3347 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3348 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3349             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3350             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3351 0         0  
  0         0  
3352 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3353 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3354 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3355             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3356 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         3  
3357 2         7  
  2         3  
3358 2         7 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         64  
3359 36         95 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         4  
3360 2         7 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr'; }
  8         18  
3361 8         23 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3362 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3363 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob'; }
  0         0  
3364 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lc_'; }
  0         0  
3365 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::lcfirst_'; }
  0         0  
3366 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::uc_'; }
  0         0  
3367 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::ucfirst_'; }
  0         0  
3368             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::fc_'; }
3369 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3370 0         0  
  0         0  
3371 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3372 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3373 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::chr_'; }
  0         0  
3374 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3375 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3376 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8u::glob_'; }
  8         17  
3377             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3378             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3379 8         26 # split
3380             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3381 87         176 $slash = 'm//';
3382 87         129  
3383 87         288 my $e = '';
3384             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3385             $e .= $1;
3386             }
3387 85 100       426  
  87 100       5785  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3388             # end of split
3389             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8u::split' . $e; }
3390 2         11  
3391             # split scalar value
3392             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Ekoi8u::split' . $e . e_string($1); }
3393 1         4  
3394 0         0 # split literal space
3395 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {qq$1 $2}; }
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*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3400 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq{$1qq$2 $3}; }
3401 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Ekoi8u::split' . $e . qq {q$1 $2}; }
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*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3406 10         40 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8u::split' . $e . qq {$1q$2 $3}; }
3407             elsif (/\G ' [ ] ' /oxgc) { return 'Ekoi8u::split' . $e . qq {' '}; }
3408             elsif (/\G " [ ] " /oxgc) { return 'Ekoi8u::split' . $e . qq {" "}; }
3409              
3410 0 0       0 # split qq//
  0         0  
3411             elsif (/\G \b (qq) \b /oxgc) {
3412 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3413 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3414 0         0 while (not /\G \z/oxgc) {
3415 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3416 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3417 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3418 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3419 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3420             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3421 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3422             }
3423             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3424             }
3425             }
3426              
3427 0 50       0 # split qr//
  12         454  
3428             elsif (/\G \b (qr) \b /oxgc) {
3429 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3430 12 50       59 else {
  12 50       3224  
    50          
    50          
    50          
    50          
    50          
    50          
3431 0         0 while (not /\G \z/oxgc) {
3432 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3433 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3434 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3435 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3436 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3437 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3438             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3439 12         78 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3440             }
3441             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3442             }
3443             }
3444              
3445 0 0       0 # split q//
  0         0  
3446             elsif (/\G \b (q) \b /oxgc) {
3447 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3448 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3449 0         0 while (not /\G \z/oxgc) {
3450 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3451 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3452 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3453 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3454 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3455             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3456 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3457             }
3458             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3459             }
3460             }
3461              
3462 0 50       0 # split m//
  18         453  
3463             elsif (/\G \b (m) \b /oxgc) {
3464 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3465 18 50       76 else {
  18 50       3753  
    50          
    50          
    50          
    50          
    50          
    50          
3466 0         0 while (not /\G \z/oxgc) {
3467 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3468 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3469 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3470 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3471 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3472 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3473             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3474 18         100 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3475             }
3476             die __FILE__, ": Search pattern not terminated\n";
3477             }
3478             }
3479              
3480 0         0 # split ''
3481 0         0 elsif (/\G (\') /oxgc) {
3482 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3483 0         0 while (not /\G \z/oxgc) {
3484 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3485 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3486             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3487 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3488             }
3489             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3490             }
3491              
3492 0         0 # split ""
3493 0         0 elsif (/\G (\") /oxgc) {
3494 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3495 0         0 while (not /\G \z/oxgc) {
3496 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3497 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3498             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3499 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3500             }
3501             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3502             }
3503              
3504 0         0 # split //
3505 44         119 elsif (/\G (\/) /oxgc) {
3506 44 50       166 my $regexp = '';
  381 50       1477  
    100          
    50          
3507 0         0 while (not /\G \z/oxgc) {
3508 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3509 44         194 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3510             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3511 337         728 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3512             }
3513             die __FILE__, ": Search pattern not terminated\n";
3514             }
3515             }
3516              
3517             # tr/// or y///
3518              
3519             # about [cdsrbB]* (/B modifier)
3520             #
3521             # P.559 appendix C
3522             # of ISBN 4-89052-384-7 Programming perl
3523             # (Japanese title is: Perl puroguramingu)
3524 0         0  
3525             elsif (/\G \b ( tr | y ) \b /oxgc) {
3526             my $ope = $1;
3527 3 50       7  
3528 3         37 # $1 $2 $3 $4 $5 $6
3529 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3530             my @tr = ($tr_variable,$2);
3531             return e_tr(@tr,'',$4,$6);
3532 0         0 }
3533 3         6 else {
3534 3 50       16 my $e = '';
  3 50       222  
    50          
    50          
    50          
    50          
3535             while (not /\G \z/oxgc) {
3536 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3537 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3538 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3539 0         0 while (not /\G \z/oxgc) {
3540 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3541 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3542 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3543 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3544             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3545 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3546             }
3547             die __FILE__, ": Transliteration replacement not terminated\n";
3548 0         0 }
3549 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3550 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3551 0         0 while (not /\G \z/oxgc) {
3552 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3553 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3554 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3555 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3556             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3557 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3558             }
3559             die __FILE__, ": Transliteration replacement not terminated\n";
3560 0         0 }
3561 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3562 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3563 0         0 while (not /\G \z/oxgc) {
3564 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3565 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3566 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3567 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3568             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3569 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3570             }
3571             die __FILE__, ": Transliteration replacement not terminated\n";
3572 0         0 }
3573 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3574 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3575 0         0 while (not /\G \z/oxgc) {
3576 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3577 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3578 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3579 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3580             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3581 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3582             }
3583             die __FILE__, ": Transliteration replacement not terminated\n";
3584             }
3585 0         0 # $1 $2 $3 $4 $5 $6
3586 3         11 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3587             my @tr = ($tr_variable,$2);
3588             return e_tr(@tr,'',$4,$6);
3589 3         7 }
3590             }
3591             die __FILE__, ": Transliteration pattern not terminated\n";
3592             }
3593             }
3594              
3595 0         0 # qq//
3596             elsif (/\G \b (qq) \b /oxgc) {
3597             my $ope = $1;
3598 2180 50       5040  
3599 2180         4094 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3600 0         0 if (/\G (\#) /oxgc) { # qq# #
3601 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3602 0         0 while (not /\G \z/oxgc) {
3603 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3604 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3605             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3606 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3607             }
3608             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3609             }
3610 0         0  
3611 2180         2830 else {
3612 2180 50       4892 my $e = '';
  2180 50       8261  
    100          
    50          
    50          
    0          
3613             while (not /\G \z/oxgc) {
3614             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3615              
3616 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3617 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3618 0         0 my $qq_string = '';
3619 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3620 0         0 while (not /\G \z/oxgc) {
3621 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3622             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3623 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3624 0         0 elsif (/\G (\)) /oxgc) {
3625             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3626 0         0 else { $qq_string .= $1; }
3627             }
3628 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3629             }
3630             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3631             }
3632              
3633 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3634 2150         3106 elsif (/\G (\{) /oxgc) { # qq { }
3635 2150         3928 my $qq_string = '';
3636 2150 100       4117 local $nest = 1;
  83993 50       269086  
    100          
    100          
    50          
3637 722         1732 while (not /\G \z/oxgc) {
3638 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         2096  
3639             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3640 1153 100       1899 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         5868  
3641 2150         4178 elsif (/\G (\}) /oxgc) {
3642             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3643 1153         2743 else { $qq_string .= $1; }
3644             }
3645 78815         165925 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3646             }
3647             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3648             }
3649              
3650 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3651 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3652 0         0 my $qq_string = '';
3653 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3654 0         0 while (not /\G \z/oxgc) {
3655 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3656             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3657 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3658 0         0 elsif (/\G (\]) /oxgc) {
3659             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3660 0         0 else { $qq_string .= $1; }
3661             }
3662 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3663             }
3664             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3665             }
3666              
3667 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3668 30         58 elsif (/\G (\<) /oxgc) { # qq < >
3669 30         65 my $qq_string = '';
3670 30 100       92 local $nest = 1;
  1166 50       4950  
    50          
    100          
    50          
3671 22         55 while (not /\G \z/oxgc) {
3672 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3673             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3674 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         73  
3675 30         120 elsif (/\G (\>) /oxgc) {
3676             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3677 0         0 else { $qq_string .= $1; }
3678             }
3679 1114         18376 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3680             }
3681             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3682             }
3683              
3684 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3685 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3686 0         0 my $delimiter = $1;
3687 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3688 0         0 while (not /\G \z/oxgc) {
3689 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3690 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3691             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3692 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3693             }
3694             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3695 0         0 }
3696             }
3697             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3698             }
3699             }
3700              
3701 0         0 # qr//
3702 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3703 0         0 my $ope = $1;
3704             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3705             return e_qr($ope,$1,$3,$2,$4);
3706 0         0 }
3707 0         0 else {
3708 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3709 0         0 while (not /\G \z/oxgc) {
3710 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3711 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3712 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3713 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3714 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3715 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3716             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3717 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3718             }
3719             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3720             }
3721             }
3722              
3723 0         0 # qw//
3724 16 50       47 elsif (/\G \b (qw) \b /oxgc) {
3725 16         83 my $ope = $1;
3726             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3727             return e_qw($ope,$1,$3,$2);
3728 0         0 }
3729 16         55 else {
3730 16 50       80 my $e = '';
  16 50       110  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3731             while (not /\G \z/oxgc) {
3732 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3733 16         83  
3734             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3735 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3736 0         0  
3737             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3738 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3739 0         0  
3740             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3741 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3742 0         0  
3743             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3744 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3745 0         0  
3746             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3747 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3748             }
3749             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3750             }
3751             }
3752              
3753 0         0 # qx//
3754 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3755 0         0 my $ope = $1;
3756             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3757             return e_qq($ope,$1,$3,$2);
3758 0         0 }
3759 0         0 else {
3760 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3761 0         0 while (not /\G \z/oxgc) {
3762 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3763 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3764 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3765 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3766 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3767             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3768 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3769             }
3770             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3771             }
3772             }
3773              
3774 0         0 # q//
3775             elsif (/\G \b (q) \b /oxgc) {
3776             my $ope = $1;
3777              
3778             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3779              
3780             # avoid "Error: Runtime exception" of perl version 5.005_03
3781 410 50       1035 # (and so on)
3782 410         1063  
3783 0         0 if (/\G (\#) /oxgc) { # q# #
3784 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3785 0         0 while (not /\G \z/oxgc) {
3786 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3787 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3788             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3789 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3790             }
3791             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3792             }
3793 0         0  
3794 410         719 else {
3795 410 50       1127 my $e = '';
  410 50       1997  
    100          
    50          
    100          
    50          
3796             while (not /\G \z/oxgc) {
3797             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3798              
3799 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3800 0         0 elsif (/\G (\() /oxgc) { # q ( )
3801 0         0 my $q_string = '';
3802 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3803 0         0 while (not /\G \z/oxgc) {
3804 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3805 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3806             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3807 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3808 0         0 elsif (/\G (\)) /oxgc) {
3809             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3810 0         0 else { $q_string .= $1; }
3811             }
3812 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3813             }
3814             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3815             }
3816              
3817 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3818 404         16680 elsif (/\G (\{) /oxgc) { # q { }
3819 404         716 my $q_string = '';
3820 404 50       1001 local $nest = 1;
  6757 50       24139  
    50          
    100          
    100          
    50          
3821 0         0 while (not /\G \z/oxgc) {
3822 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3823 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         153  
3824             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3825 107 100       188 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         931  
3826 404         1002 elsif (/\G (\}) /oxgc) {
3827             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3828 107         222 else { $q_string .= $1; }
3829             }
3830 6139         11230 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3831             }
3832             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3833             }
3834              
3835 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3836 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3837 0         0 my $q_string = '';
3838 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3839 0         0 while (not /\G \z/oxgc) {
3840 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3841 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3842             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3843 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3844 0         0 elsif (/\G (\]) /oxgc) {
3845             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3846 0         0 else { $q_string .= $1; }
3847             }
3848 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3849             }
3850             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3851             }
3852              
3853 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3854 5         12 elsif (/\G (\<) /oxgc) { # q < >
3855 5         13 my $q_string = '';
3856 5 50       22 local $nest = 1;
  88 50       484  
    50          
    50          
    100          
    50          
3857 0         0 while (not /\G \z/oxgc) {
3858 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3859 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3860             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3861 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         16  
3862 5         35 elsif (/\G (\>) /oxgc) {
3863             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3864 0         0 else { $q_string .= $1; }
3865             }
3866 83         162 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3867             }
3868             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3869             }
3870              
3871 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3872 1         3 elsif (/\G (\S) /oxgc) { # q * *
3873 1         2 my $delimiter = $1;
3874 1 50       4 my $q_string = '';
  14 50       63  
    100          
    50          
3875 0         0 while (not /\G \z/oxgc) {
3876 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3877 1         3 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3878             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3879 13         25 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3880             }
3881             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3882 0         0 }
3883             }
3884             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3885             }
3886             }
3887              
3888 0         0 # m//
3889 209 50       540 elsif (/\G \b (m) \b /oxgc) {
3890 209         1329 my $ope = $1;
3891             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3892             return e_qr($ope,$1,$3,$2,$4);
3893 0         0 }
3894 209         358 else {
3895 209 50       539 my $e = '';
  209 50       12227  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3896 0         0 while (not /\G \z/oxgc) {
3897 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3898 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3899 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3900 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3901 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3902 10         31 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3903 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3904             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3905 199         642 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3906             }
3907             die __FILE__, ": Search pattern not terminated\n";
3908             }
3909             }
3910              
3911             # s///
3912              
3913             # about [cegimosxpradlunbB]* (/cg modifier)
3914             #
3915             # P.67 Pattern-Matching Operators
3916             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3917 0         0  
3918             elsif (/\G \b (s) \b /oxgc) {
3919             my $ope = $1;
3920 97 100       289  
3921 97         1865 # $1 $2 $3 $4 $5 $6
3922             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3923             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3924 1         5 }
3925 96         187 else {
3926 96 50       328 my $e = '';
  96 50       13568  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3927             while (not /\G \z/oxgc) {
3928 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3929 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3930 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3931             while (not /\G \z/oxgc) {
3932 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3933 0         0 # $1 $2 $3 $4
3934 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3935 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3936 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3937 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([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             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3942 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3943             }
3944             die __FILE__, ": Substitution replacement not terminated\n";
3945 0         0 }
3946 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3947 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3948             while (not /\G \z/oxgc) {
3949 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3950 0         0 # $1 $2 $3 $4
3951 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3952 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3953 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3954 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([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             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3960             }
3961             die __FILE__, ": Substitution replacement not terminated\n";
3962 0         0 }
3963 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3964 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3965             while (not /\G \z/oxgc) {
3966 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3967 0         0 # $1 $2 $3 $4
3968 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3969 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3970 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3971 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([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             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3974 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3975             }
3976             die __FILE__, ": Substitution replacement not terminated\n";
3977 0         0 }
3978 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3979 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3980             while (not /\G \z/oxgc) {
3981 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3982 0         0 # $1 $2 $3 $4
3983 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3984 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3985 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3986 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([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             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3991 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3992             }
3993             die __FILE__, ": Substitution replacement not terminated\n";
3994             }
3995 0         0 # $1 $2 $3 $4 $5 $6
3996             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3997             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3998             }
3999 21         70 # $1 $2 $3 $4 $5 $6
4000             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4001             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
4002             }
4003 0         0 # $1 $2 $3 $4 $5 $6
4004             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4005             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4006             }
4007 0         0 # $1 $2 $3 $4 $5 $6
4008             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4009             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4010 75         344 }
4011             }
4012             die __FILE__, ": Substitution pattern not terminated\n";
4013             }
4014             }
4015 0         0  
4016 0         0 # require ignore module
4017 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
4018             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
4019             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4020 0         0  
4021 37         322 # use strict; --> use strict; no strict qw(refs);
4022 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4023             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4024             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4025              
4026 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
4027 2         28 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4028             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4029             return "use $1; no strict qw(refs);";
4030 0         0 }
4031             else {
4032             return "use $1;";
4033             }
4034 2 0 0     12 }
      0        
4035 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4036             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4037             return "use $1; no strict qw(refs);";
4038 0         0 }
4039             else {
4040             return "use $1;";
4041             }
4042             }
4043 0         0  
4044 2         15 # ignore use module
4045 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4046             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4047             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4048 0         0  
4049 0         0 # ignore no module
4050 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4051             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4052             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4053 0         0  
4054             # use else
4055             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4056 0         0  
4057             # use else
4058             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4059              
4060 2         9 # ''
4061 848         1808 elsif (/\G (?
4062 848 100       2205 my $q_string = '';
  8241 100       25423  
    100          
    50          
4063 4         8 while (not /\G \z/oxgc) {
4064 48         83 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4065 848         2046 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4066             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4067 7341         13882 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4068             }
4069             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4070             }
4071              
4072 0         0 # ""
4073 1808         3394 elsif (/\G (\") /oxgc) {
4074 1808 100       4345 my $qq_string = '';
  35024 100       110873  
    100          
    50          
4075 67         169 while (not /\G \z/oxgc) {
4076 12         23 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4077 1808         4065 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4078             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4079 33137         74762 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4080             }
4081             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4082             }
4083              
4084 0         0 # ``
4085 1         6 elsif (/\G (\`) /oxgc) {
4086 1 50       4 my $qx_string = '';
  19 50       70  
    100          
    50          
4087 0         0 while (not /\G \z/oxgc) {
4088 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4089 1         4 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4090             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4091 18         33 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4092             }
4093             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4094             }
4095              
4096 0         0 # // --- not divide operator (num / num), not defined-or
4097 453         1088 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4098 453 50       5274 my $regexp = '';
  4496 50       14180  
    100          
    50          
4099 0         0 while (not /\G \z/oxgc) {
4100 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4101 453         1168 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4102             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4103 4043         8383 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4104             }
4105             die __FILE__, ": Search pattern not terminated\n";
4106             }
4107              
4108 0         0 # ?? --- not conditional operator (condition ? then : else)
4109 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4110 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4111 0         0 while (not /\G \z/oxgc) {
4112 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4113 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4114             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4115 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4116             }
4117             die __FILE__, ": Search pattern not terminated\n";
4118             }
4119 0         0  
  0         0  
4120             # <<>> (a safer ARGV)
4121             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4122 0         0  
  0         0  
4123             # << (bit shift) --- not here document
4124             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4125              
4126 0         0 # <<~'HEREDOC'
4127 6         15 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4128 6         12 $slash = 'm//';
4129             my $here_quote = $1;
4130             my $delimiter = $2;
4131 6 50       8  
4132 6         14 # get here document
4133 6         20 if ($here_script eq '') {
4134             $here_script = CORE::substr $_, pos $_;
4135 6 50       29 $here_script =~ s/.*?\n//oxm;
4136 6         64 }
4137 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4138 6         6 my $heredoc = $1;
4139 6         50 my $indent = $2;
4140 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4141             push @heredoc, $heredoc . qq{\n$delimiter\n};
4142             push @heredoc_delimiter, qq{\\s*$delimiter};
4143 6         12 }
4144             else {
4145 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4146             }
4147             return qq{<<'$delimiter'};
4148             }
4149              
4150             # <<~\HEREDOC
4151              
4152             # P.66 2.6.6. "Here" Documents
4153             # in Chapter 2: Bits and Pieces
4154             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4155              
4156             # P.73 "Here" Documents
4157             # in Chapter 2: Bits and Pieces
4158             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4159 6         24  
4160 3         6 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4161 3         6 $slash = 'm//';
4162             my $here_quote = $1;
4163             my $delimiter = $2;
4164 3 50       5  
4165 3         8 # get here document
4166 3         31 if ($here_script eq '') {
4167             $here_script = CORE::substr $_, pos $_;
4168 3 50       19 $here_script =~ s/.*?\n//oxm;
4169 3         44 }
4170 3         21 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4171 3         5 my $heredoc = $1;
4172 3         37 my $indent = $2;
4173 3         12 $heredoc =~ s{^$indent}{}msg; # no /ox
4174             push @heredoc, $heredoc . qq{\n$delimiter\n};
4175             push @heredoc_delimiter, qq{\\s*$delimiter};
4176 3         7 }
4177             else {
4178 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4179             }
4180             return qq{<<\\$delimiter};
4181             }
4182              
4183 3         15 # <<~"HEREDOC"
4184 6         12 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4185 6         10 $slash = 'm//';
4186             my $here_quote = $1;
4187             my $delimiter = $2;
4188 6 50       9  
4189 6         19 # get here document
4190 6         20 if ($here_script eq '') {
4191             $here_script = CORE::substr $_, pos $_;
4192 6 50       28 $here_script =~ s/.*?\n//oxm;
4193 6         64 }
4194 6         15 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4195 6         6 my $heredoc = $1;
4196 6         46 my $indent = $2;
4197 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4198             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4199             push @heredoc_delimiter, qq{\\s*$delimiter};
4200 6         13 }
4201             else {
4202 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4203             }
4204             return qq{<<"$delimiter"};
4205             }
4206              
4207 6         23 # <<~HEREDOC
4208 3         6 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4209 3         7 $slash = 'm//';
4210             my $here_quote = $1;
4211             my $delimiter = $2;
4212 3 50       5  
4213 3         6 # get here document
4214 3         28 if ($here_script eq '') {
4215             $here_script = CORE::substr $_, pos $_;
4216 3 50       18 $here_script =~ s/.*?\n//oxm;
4217 3         40 }
4218 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4219 3         4 my $heredoc = $1;
4220 3         35 my $indent = $2;
4221 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
4222             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4223             push @heredoc_delimiter, qq{\\s*$delimiter};
4224 3         7 }
4225             else {
4226 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4227             }
4228             return qq{<<$delimiter};
4229             }
4230              
4231 3         12 # <<~`HEREDOC`
4232 6         14 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4233 6         11 $slash = 'm//';
4234             my $here_quote = $1;
4235             my $delimiter = $2;
4236 6 50       21  
4237 6         16 # get here document
4238 6         40 if ($here_script eq '') {
4239             $here_script = CORE::substr $_, pos $_;
4240 6 50       34 $here_script =~ s/.*?\n//oxm;
4241 6         489 }
4242 6         16 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4243 6         8 my $heredoc = $1;
4244 6         55 my $indent = $2;
4245 6         19 $heredoc =~ s{^$indent}{}msg; # no /ox
4246             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4247             push @heredoc_delimiter, qq{\\s*$delimiter};
4248 6         14 }
4249             else {
4250 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4251             }
4252             return qq{<<`$delimiter`};
4253             }
4254              
4255 6         93 # <<'HEREDOC'
4256 72         140 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4257 72         146 $slash = 'm//';
4258             my $here_quote = $1;
4259             my $delimiter = $2;
4260 72 50       103  
4261 72         133 # get here document
4262 72         387 if ($here_script eq '') {
4263             $here_script = CORE::substr $_, pos $_;
4264 72 50       384 $here_script =~ s/.*?\n//oxm;
4265 72         536 }
4266 72         224 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4267             push @heredoc, $1 . qq{\n$delimiter\n};
4268             push @heredoc_delimiter, $delimiter;
4269 72         109 }
4270             else {
4271 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4272             }
4273             return $here_quote;
4274             }
4275              
4276             # <<\HEREDOC
4277              
4278             # P.66 2.6.6. "Here" Documents
4279             # in Chapter 2: Bits and Pieces
4280             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4281              
4282             # P.73 "Here" Documents
4283             # in Chapter 2: Bits and Pieces
4284             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4285 72         279  
4286 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4287 0         0 $slash = 'm//';
4288             my $here_quote = $1;
4289             my $delimiter = $2;
4290 0 0       0  
4291 0         0 # get here document
4292 0         0 if ($here_script eq '') {
4293             $here_script = CORE::substr $_, pos $_;
4294 0 0       0 $here_script =~ s/.*?\n//oxm;
4295 0         0 }
4296 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4297             push @heredoc, $1 . qq{\n$delimiter\n};
4298             push @heredoc_delimiter, $delimiter;
4299 0         0 }
4300             else {
4301 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4302             }
4303             return $here_quote;
4304             }
4305              
4306 0         0 # <<"HEREDOC"
4307 36         83 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4308 36         81 $slash = 'm//';
4309             my $here_quote = $1;
4310             my $delimiter = $2;
4311 36 50       466  
4312 36         100 # get here document
4313 36         205 if ($here_script eq '') {
4314             $here_script = CORE::substr $_, pos $_;
4315 36 50       200 $here_script =~ s/.*?\n//oxm;
4316 36         794 }
4317 36         114 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4318             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4319             push @heredoc_delimiter, $delimiter;
4320 36         146 }
4321             else {
4322 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4323             }
4324             return $here_quote;
4325             }
4326              
4327 36         139 # <
4328 42         109 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4329 42         86 $slash = 'm//';
4330             my $here_quote = $1;
4331             my $delimiter = $2;
4332 42 50       77  
4333 42         103 # get here document
4334 42         341 if ($here_script eq '') {
4335             $here_script = CORE::substr $_, pos $_;
4336 42 50       330 $here_script =~ s/.*?\n//oxm;
4337 42         562 }
4338 42         202 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4339             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4340             push @heredoc_delimiter, $delimiter;
4341 42         114 }
4342             else {
4343 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4344             }
4345             return $here_quote;
4346             }
4347              
4348 42         179 # <<`HEREDOC`
4349 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4350 0         0 $slash = 'm//';
4351             my $here_quote = $1;
4352             my $delimiter = $2;
4353 0 0       0  
4354 0         0 # get here document
4355 0         0 if ($here_script eq '') {
4356             $here_script = CORE::substr $_, pos $_;
4357 0 0       0 $here_script =~ s/.*?\n//oxm;
4358 0         0 }
4359 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4360             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4361             push @heredoc_delimiter, $delimiter;
4362 0         0 }
4363             else {
4364 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4365             }
4366             return $here_quote;
4367             }
4368              
4369 0         0 # <<= <=> <= < operator
4370             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4371             return $1;
4372             }
4373              
4374 12         56 #
4375             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4376             return $1;
4377             }
4378              
4379             # --- glob
4380              
4381             # avoid "Error: Runtime exception" of perl version 5.005_03
4382 0         0  
4383             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4384             return 'Ekoi8u::glob("' . $1 . '")';
4385             }
4386 0         0  
4387             # __DATA__
4388             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4389 0         0  
4390             # __END__
4391             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4392              
4393             # \cD Control-D
4394              
4395             # P.68 2.6.8. Other Literal Tokens
4396             # in Chapter 2: Bits and Pieces
4397             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4398              
4399             # P.76 Other Literal Tokens
4400             # in Chapter 2: Bits and Pieces
4401 204         1696 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4402              
4403             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4404 0         0  
4405             # \cZ Control-Z
4406             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4407              
4408             # any operator before div
4409             elsif (/\G (
4410             -- | \+\+ |
4411 0         0 [\)\}\]]
  5083         10144  
4412              
4413             ) /oxgc) { $slash = 'div'; return $1; }
4414              
4415             # yada-yada or triple-dot operator
4416             elsif (/\G (
4417 5083         21557 \.\.\.
  7         10  
4418              
4419             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4420              
4421             # any operator before m//
4422              
4423             # //, //= (defined-or)
4424              
4425             # P.164 Logical Operators
4426             # in Chapter 10: More Control Structures
4427             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4428              
4429             # P.119 C-Style Logical (Short-Circuit) Operators
4430             # in Chapter 3: Unary and Binary Operators
4431             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4432              
4433             # (and so on)
4434              
4435             # ~~
4436              
4437             # P.221 The Smart Match Operator
4438             # in Chapter 15: Smart Matching and given-when
4439             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4440              
4441             # P.112 Smartmatch Operator
4442             # in Chapter 3: Unary and Binary Operators
4443             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4444              
4445             # (and so on)
4446              
4447             elsif (/\G ((?>
4448              
4449             !~~ | !~ | != | ! |
4450             %= | % |
4451             &&= | && | &= | &\.= | &\. | & |
4452             -= | -> | - |
4453             :(?>\s*)= |
4454             : |
4455             <<>> |
4456             <<= | <=> | <= | < |
4457             == | => | =~ | = |
4458             >>= | >> | >= | > |
4459             \*\*= | \*\* | \*= | \* |
4460             \+= | \+ |
4461             \.\. | \.= | \. |
4462             \/\/= | \/\/ |
4463             \/= | \/ |
4464             \? |
4465             \\ |
4466             \^= | \^\.= | \^\. | \^ |
4467             \b x= |
4468             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4469             ~~ | ~\. | ~ |
4470             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4471             \b(?: print )\b |
4472              
4473 7         37 [,;\(\{\[]
  8858         16679  
4474              
4475             )) /oxgc) { $slash = 'm//'; return $1; }
4476 8858         43380  
  15041         26551  
4477             # other any character
4478             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4479              
4480 15041         65088 # system error
4481             else {
4482             die __FILE__, ": Oops, this shouldn't happen!\n";
4483             }
4484             }
4485              
4486 0     1788 0 0 # escape KOI8-U string
4487 1788         4486 sub e_string {
4488             my($string) = @_;
4489 1788         2478 my $e_string = '';
4490              
4491             local $slash = 'm//';
4492              
4493             # P.1024 Appendix W.10 Multibyte Processing
4494             # of ISBN 1-56592-224-7 CJKV Information Processing
4495 1788         2521 # (and so on)
4496              
4497             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4498 1788 100 66     15010  
4499 1788 50       7626 # without { ... }
4500 1769         3745 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4501             if ($string !~ /<
4502             return $string;
4503             }
4504             }
4505 1769         4137  
4506 19 50       82 E_STRING_LOOP:
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
4507             while ($string !~ /\G \z/oxgc) {
4508             if (0) {
4509             }
4510 223         3793  
4511 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Ekoi8u::PREMATCH()]}
4512 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4513             $e_string .= q{Ekoi8u::PREMATCH()};
4514             $slash = 'div';
4515             }
4516              
4517 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Ekoi8u::MATCH()]}
4518 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4519             $e_string .= q{Ekoi8u::MATCH()};
4520             $slash = 'div';
4521             }
4522              
4523 0         0 # $', ${'} --> $', ${'}
4524 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4525             $e_string .= $1;
4526             $slash = 'div';
4527             }
4528              
4529 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Ekoi8u::POSTMATCH()]}
4530 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4531             $e_string .= q{Ekoi8u::POSTMATCH()};
4532             $slash = 'div';
4533             }
4534              
4535 0         0 # bareword
4536 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4537             $e_string .= $1;
4538             $slash = 'div';
4539             }
4540              
4541 0         0 # $0 --> $0
4542 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4543             $e_string .= $1;
4544             $slash = 'div';
4545 0         0 }
4546 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4547             $e_string .= $1;
4548             $slash = 'div';
4549             }
4550              
4551 0         0 # $$ --> $$
4552 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4553             $e_string .= $1;
4554             $slash = 'div';
4555             }
4556              
4557             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4558 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4559 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4560             $e_string .= e_capture($1);
4561             $slash = 'div';
4562 0         0 }
4563 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4564             $e_string .= e_capture($1);
4565             $slash = 'div';
4566             }
4567              
4568 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4569 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4570             $e_string .= e_capture($1.'->'.$2);
4571             $slash = 'div';
4572             }
4573              
4574 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4575 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4576             $e_string .= e_capture($1.'->'.$2);
4577             $slash = 'div';
4578             }
4579              
4580 0         0 # $$foo
4581 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4582             $e_string .= e_capture($1);
4583             $slash = 'div';
4584             }
4585              
4586 0         0 # ${ foo }
4587 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4588             $e_string .= '${' . $1 . '}';
4589             $slash = 'div';
4590             }
4591              
4592 0         0 # ${ ... }
4593 3         10 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4594             $e_string .= e_capture($1);
4595             $slash = 'div';
4596             }
4597              
4598             # variable or function
4599 3         13 # $ @ % & * $ #
4600 7         19 elsif ($string =~ /\G ( (?: [\$\@\%\&\*] | \$\# | -> | \b sub \b) (?>\s*) (?: split | chop | index | rindex | lc | uc | fc | chr | ord | reverse | getc | tr | y | q | qq | qx | qw | m | s | qr | glob | lstat | opendir | stat | unlink | chdir ) ) \b /oxmsgc) {
4601             $e_string .= $1;
4602             $slash = 'div';
4603             }
4604             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4605 7         24 # $ @ # \ ' " / ? ( ) [ ] < >
4606 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4607             $e_string .= $1;
4608             $slash = 'div';
4609             }
4610              
4611 0         0 # qq//
4612 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4613 0         0 my $ope = $1;
4614             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4615             $e_string .= e_qq($ope,$1,$3,$2);
4616 0         0 }
4617 0         0 else {
4618 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4619 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4620 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4621 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4622 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4623 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4624             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4625 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4626             }
4627             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4628             }
4629             }
4630              
4631 0         0 # qx//
4632 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4633 0         0 my $ope = $1;
4634             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4635             $e_string .= e_qq($ope,$1,$3,$2);
4636 0         0 }
4637 0         0 else {
4638 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4639 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4640 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4641 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4642 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4643 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4644 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4645             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4646 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4647             }
4648             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4649             }
4650             }
4651              
4652 0         0 # q//
4653 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4654 0         0 my $ope = $1;
4655             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4656             $e_string .= e_q($ope,$1,$3,$2);
4657 0         0 }
4658 0         0 else {
4659 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4660 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4661 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4662 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4663 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4664 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4665             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4666 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 * *
4667             }
4668             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4669             }
4670             }
4671 0         0  
4672             # ''
4673             elsif ($string =~ /\G (?
4674 0         0  
4675             # ""
4676             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4677 0         0  
4678             # ``
4679             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4680 0         0  
4681             # other any character
4682             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
4683              
4684 213         466 # system error
4685             else {
4686             die __FILE__, ": Oops, this shouldn't happen!\n";
4687             }
4688 0         0 }
4689              
4690             return $e_string;
4691             }
4692              
4693             #
4694             # character class
4695 19     1919 0 75 #
4696             sub character_class {
4697 1919 100       3307 my($char,$modifier) = @_;
4698 1919 100       2897  
4699 52         99 if ($char eq '.') {
4700             if ($modifier =~ /s/) {
4701             return '${Ekoi8u::dot_s}';
4702 17         65 }
4703             else {
4704             return '${Ekoi8u::dot}';
4705             }
4706 35         78 }
4707             else {
4708             return Ekoi8u::classic_character_class($char);
4709             }
4710             }
4711              
4712             #
4713             # escape capture ($1, $2, $3, ...)
4714             #
4715 1867     212 0 3190 sub e_capture {
4716              
4717             return join '', '${', $_[0], '}';
4718             }
4719              
4720             #
4721             # escape transliteration (tr/// or y///)
4722 212     3 0 748 #
4723 3         16 sub e_tr {
4724 3   50     7 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
4725             my $e_tr = '';
4726 3         5 $modifier ||= '';
4727              
4728             $slash = 'div';
4729 3         4  
4730             # quote character class 1
4731             $charclass = q_tr($charclass);
4732 3         7  
4733             # quote character class 2
4734             $charclass2 = q_tr($charclass2);
4735 3 50       5  
4736 3 0       9 # /b /B modifier
4737 0         0 if ($modifier =~ tr/bB//d) {
4738             if ($variable eq '') {
4739             $e_tr = qq{tr$charclass$e$charclass2$modifier};
4740 0         0 }
4741             else {
4742             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
4743             }
4744 0 100       0 }
4745 3         12 else {
4746             if ($variable eq '') {
4747             $e_tr = qq{Ekoi8u::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
4748 2         6 }
4749             else {
4750             $e_tr = qq{Ekoi8u::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
4751             }
4752             }
4753 1         4  
4754 3         5 # clear tr/// variable
4755             $tr_variable = '';
4756 3         4 $bind_operator = '';
4757              
4758             return $e_tr;
4759             }
4760              
4761             #
4762             # quote for escape transliteration (tr/// or y///)
4763 3     6 0 15 #
4764             sub q_tr {
4765             my($charclass) = @_;
4766 6 50       10  
    0          
    0          
    0          
    0          
    0          
4767 6         12 # quote character class
4768             if ($charclass !~ /'/oxms) {
4769             return e_q('', "'", "'", $charclass); # --> q' '
4770 6         9 }
4771             elsif ($charclass !~ /\//oxms) {
4772             return e_q('q', '/', '/', $charclass); # --> q/ /
4773 0         0 }
4774             elsif ($charclass !~ /\#/oxms) {
4775             return e_q('q', '#', '#', $charclass); # --> q# #
4776 0         0 }
4777             elsif ($charclass !~ /[\<\>]/oxms) {
4778             return e_q('q', '<', '>', $charclass); # --> q< >
4779 0         0 }
4780             elsif ($charclass !~ /[\(\)]/oxms) {
4781             return e_q('q', '(', ')', $charclass); # --> q( )
4782 0         0 }
4783             elsif ($charclass !~ /[\{\}]/oxms) {
4784             return e_q('q', '{', '}', $charclass); # --> q{ }
4785 0         0 }
4786 0 0       0 else {
4787 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
4788             if ($charclass !~ /\Q$char\E/xms) {
4789             return e_q('q', $char, $char, $charclass);
4790             }
4791             }
4792 0         0 }
4793              
4794             return e_q('q', '{', '}', $charclass);
4795             }
4796              
4797             #
4798             # escape q string (q//, '')
4799 0     1264 0 0 #
4800             sub e_q {
4801 1264         2874 my($ope,$delimiter,$end_delimiter,$string) = @_;
4802              
4803 1264         2751 $slash = 'div';
4804              
4805             return join '', $ope, $delimiter, $string, $end_delimiter;
4806             }
4807              
4808             #
4809             # escape qq string (qq//, "", qx//, ``)
4810 1264     4070 0 5979 #
4811             sub e_qq {
4812 4070         8784 my($ope,$delimiter,$end_delimiter,$string) = @_;
4813              
4814 4070         5174 $slash = 'div';
4815 4070         4991  
4816             my $left_e = 0;
4817             my $right_e = 0;
4818 4070         4586  
4819             # split regexp
4820             my @char = $string =~ /\G((?>
4821             [^\\\$] |
4822             \\x\{ (?>[0-9A-Fa-f]+) \} |
4823             \\o\{ (?>[0-7]+) \} |
4824             \\N\{ (?>[^0-9\}][^\}]*) \} |
4825             \\ $q_char |
4826             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
4827             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
4828             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
4829             \$ (?>\s* [0-9]+) |
4830             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
4831             \$ \$ (?![\w\{]) |
4832             \$ (?>\s*) \$ (?>\s*) $qq_variable |
4833             $q_char
4834 4070         134949 ))/oxmsg;
4835              
4836             for (my $i=0; $i <= $#char; $i++) {
4837 4070 50 33     28588  
    50 33        
    100          
    100          
    50          
4838 113656         368308 # "\L\u" --> "\u\L"
4839             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
4840             @char[$i,$i+1] = @char[$i+1,$i];
4841             }
4842              
4843 0         0 # "\U\l" --> "\l\U"
4844             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
4845             @char[$i,$i+1] = @char[$i+1,$i];
4846             }
4847              
4848 0         0 # octal escape sequence
4849             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
4850             $char[$i] = Ekoi8u::octchr($1);
4851             }
4852              
4853 1         4 # hexadecimal escape sequence
4854             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
4855             $char[$i] = Ekoi8u::hexchr($1);
4856             }
4857              
4858 1         3 # \N{CHARNAME} --> N{CHARNAME}
4859             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
4860             $char[$i] = $1;
4861 0 100       0 }
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
4862              
4863             if (0) {
4864             }
4865              
4866             # \F
4867             #
4868             # P.69 Table 2-6. Translation escapes
4869             # in Chapter 2: Bits and Pieces
4870             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4871             # (and so on)
4872 113656         917588  
4873 0 50       0 # \u \l \U \L \F \Q \E
4874 484         990 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
4875             if ($right_e < $left_e) {
4876             $char[$i] = '\\' . $char[$i];
4877             }
4878             }
4879             elsif ($char[$i] eq '\u') {
4880              
4881             # "STRING @{[ LIST EXPR ]} MORE STRING"
4882              
4883             # P.257 Other Tricks You Can Do with Hard References
4884             # in Chapter 8: References
4885             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4886              
4887             # P.353 Other Tricks You Can Do with Hard References
4888             # in Chapter 8: References
4889             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4890              
4891 0         0 # (and so on)
4892 0         0  
4893             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
4894             $left_e++;
4895 0         0 }
4896 0         0 elsif ($char[$i] eq '\l') {
4897             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
4898             $left_e++;
4899 0         0 }
4900 0         0 elsif ($char[$i] eq '\U') {
4901             $char[$i] = '@{[Ekoi8u::uc qq<';
4902             $left_e++;
4903 0         0 }
4904 0         0 elsif ($char[$i] eq '\L') {
4905             $char[$i] = '@{[Ekoi8u::lc qq<';
4906             $left_e++;
4907 0         0 }
4908 24         36 elsif ($char[$i] eq '\F') {
4909             $char[$i] = '@{[Ekoi8u::fc qq<';
4910             $left_e++;
4911 24         41 }
4912 0         0 elsif ($char[$i] eq '\Q') {
4913             $char[$i] = '@{[CORE::quotemeta qq<';
4914             $left_e++;
4915 0 50       0 }
4916 24         34 elsif ($char[$i] eq '\E') {
4917 24         31 if ($right_e < $left_e) {
4918             $char[$i] = '>]}';
4919             $right_e++;
4920 24         42 }
4921             else {
4922             $char[$i] = '';
4923             }
4924 0         0 }
4925 0 0       0 elsif ($char[$i] eq '\Q') {
4926 0         0 while (1) {
4927             if (++$i > $#char) {
4928 0 0       0 last;
4929 0         0 }
4930             if ($char[$i] eq '\E') {
4931             last;
4932             }
4933             }
4934             }
4935             elsif ($char[$i] eq '\E') {
4936             }
4937              
4938             # $0 --> $0
4939             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
4940             }
4941             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
4942             }
4943              
4944             # $$ --> $$
4945             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
4946             }
4947              
4948             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4949 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4950             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
4951             $char[$i] = e_capture($1);
4952 205         407 }
4953             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
4954             $char[$i] = e_capture($1);
4955             }
4956              
4957 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4958             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
4959             $char[$i] = e_capture($1.'->'.$2);
4960             }
4961              
4962 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4963             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
4964             $char[$i] = e_capture($1.'->'.$2);
4965             }
4966              
4967 0         0 # $$foo
4968             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
4969             $char[$i] = e_capture($1);
4970             }
4971              
4972 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
4973             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
4974             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
4975             }
4976              
4977 44         111 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
4978             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
4979             $char[$i] = '@{[Ekoi8u::MATCH()]}';
4980             }
4981              
4982 45         110 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
4983             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
4984             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
4985             }
4986              
4987             # ${ foo } --> ${ foo }
4988             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
4989             }
4990              
4991 33         89 # ${ ... }
4992             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
4993             $char[$i] = e_capture($1);
4994             }
4995             }
4996 0 50       0  
4997 4070         9032 # return string
4998             if ($left_e > $right_e) {
4999 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5000             }
5001             return join '', $ope, $delimiter, @char, $end_delimiter;
5002             }
5003              
5004             #
5005             # escape qw string (qw//)
5006 4070     16 0 35291 #
5007             sub e_qw {
5008 16         222 my($ope,$delimiter,$end_delimiter,$string) = @_;
5009              
5010             $slash = 'div';
5011 16         43  
  16         253  
5012 483 50       1921 # choice again delimiter
    0          
    0          
    0          
    0          
5013 16         105 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5014             if (not $octet{$end_delimiter}) {
5015             return join '', $ope, $delimiter, $string, $end_delimiter;
5016 16         140 }
5017             elsif (not $octet{')'}) {
5018             return join '', $ope, '(', $string, ')';
5019 0         0 }
5020             elsif (not $octet{'}'}) {
5021             return join '', $ope, '{', $string, '}';
5022 0         0 }
5023             elsif (not $octet{']'}) {
5024             return join '', $ope, '[', $string, ']';
5025 0         0 }
5026             elsif (not $octet{'>'}) {
5027             return join '', $ope, '<', $string, '>';
5028 0         0 }
5029 0 0       0 else {
5030 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5031             if (not $octet{$char}) {
5032             return join '', $ope, $char, $string, $char;
5033             }
5034             }
5035             }
5036 0         0  
5037 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5038 0         0 my @string = CORE::split(/\s+/, $string);
5039 0         0 for my $string (@string) {
5040 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5041 0         0 for my $octet (@octet) {
5042             if ($octet =~ /\A (['\\]) \z/oxms) {
5043             $octet = '\\' . $1;
5044 0         0 }
5045             }
5046 0         0 $string = join '', @octet;
  0         0  
5047             }
5048             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5049             }
5050              
5051             #
5052             # escape here document (<<"HEREDOC", <
5053 0     93 0 0 #
5054             sub e_heredoc {
5055 93         320 my($string) = @_;
5056              
5057 93         161 $slash = 'm//';
5058              
5059 93         449 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5060 93         144  
5061             my $left_e = 0;
5062             my $right_e = 0;
5063 93         115  
5064             # split regexp
5065             my @char = $string =~ /\G((?>
5066             [^\\\$] |
5067             \\x\{ (?>[0-9A-Fa-f]+) \} |
5068             \\o\{ (?>[0-7]+) \} |
5069             \\N\{ (?>[^0-9\}][^\}]*) \} |
5070             \\ $q_char |
5071             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5072             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5073             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5074             \$ (?>\s* [0-9]+) |
5075             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5076             \$ \$ (?![\w\{]) |
5077             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5078             $q_char
5079 93         8965 ))/oxmsg;
5080              
5081             for (my $i=0; $i <= $#char; $i++) {
5082 93 50 33     435  
    50 33        
    100          
    100          
    50          
5083 3151         10144 # "\L\u" --> "\u\L"
5084             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5085             @char[$i,$i+1] = @char[$i+1,$i];
5086             }
5087              
5088 0         0 # "\U\l" --> "\l\U"
5089             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5090             @char[$i,$i+1] = @char[$i+1,$i];
5091             }
5092              
5093 0         0 # octal escape sequence
5094             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5095             $char[$i] = Ekoi8u::octchr($1);
5096             }
5097              
5098 1         2 # hexadecimal escape sequence
5099             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5100             $char[$i] = Ekoi8u::hexchr($1);
5101             }
5102              
5103 1         3 # \N{CHARNAME} --> N{CHARNAME}
5104             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5105             $char[$i] = $1;
5106 0 50       0 }
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5107              
5108             if (0) {
5109             }
5110 3151         26841  
5111 0 0       0 # \u \l \U \L \F \Q \E
5112 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5113             if ($right_e < $left_e) {
5114             $char[$i] = '\\' . $char[$i];
5115             }
5116 0         0 }
5117 0         0 elsif ($char[$i] eq '\u') {
5118             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5119             $left_e++;
5120 0         0 }
5121 0         0 elsif ($char[$i] eq '\l') {
5122             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5123             $left_e++;
5124 0         0 }
5125 0         0 elsif ($char[$i] eq '\U') {
5126             $char[$i] = '@{[Ekoi8u::uc qq<';
5127             $left_e++;
5128 0         0 }
5129 0         0 elsif ($char[$i] eq '\L') {
5130             $char[$i] = '@{[Ekoi8u::lc qq<';
5131             $left_e++;
5132 0         0 }
5133 0         0 elsif ($char[$i] eq '\F') {
5134             $char[$i] = '@{[Ekoi8u::fc qq<';
5135             $left_e++;
5136 0         0 }
5137 0         0 elsif ($char[$i] eq '\Q') {
5138             $char[$i] = '@{[CORE::quotemeta qq<';
5139             $left_e++;
5140 0 0       0 }
5141 0         0 elsif ($char[$i] eq '\E') {
5142 0         0 if ($right_e < $left_e) {
5143             $char[$i] = '>]}';
5144             $right_e++;
5145 0         0 }
5146             else {
5147             $char[$i] = '';
5148             }
5149 0         0 }
5150 0 0       0 elsif ($char[$i] eq '\Q') {
5151 0         0 while (1) {
5152             if (++$i > $#char) {
5153 0 0       0 last;
5154 0         0 }
5155             if ($char[$i] eq '\E') {
5156             last;
5157             }
5158             }
5159             }
5160             elsif ($char[$i] eq '\E') {
5161             }
5162              
5163             # $0 --> $0
5164             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5165             }
5166             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5167             }
5168              
5169             # $$ --> $$
5170             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5171             }
5172              
5173             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5174 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5175             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5176             $char[$i] = e_capture($1);
5177 0         0 }
5178             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5179             $char[$i] = e_capture($1);
5180             }
5181              
5182 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5183             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5184             $char[$i] = e_capture($1.'->'.$2);
5185             }
5186              
5187 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5188             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5189             $char[$i] = e_capture($1.'->'.$2);
5190             }
5191              
5192 0         0 # $$foo
5193             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5194             $char[$i] = e_capture($1);
5195             }
5196              
5197 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5198             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5199             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5200             }
5201              
5202 8         45 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5203             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5204             $char[$i] = '@{[Ekoi8u::MATCH()]}';
5205             }
5206              
5207 8         59 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5208             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5209             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5210             }
5211              
5212             # ${ foo } --> ${ foo }
5213             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5214             }
5215              
5216 6         36 # ${ ... }
5217             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5218             $char[$i] = e_capture($1);
5219             }
5220             }
5221 0 50       0  
5222 93         196 # return string
5223             if ($left_e > $right_e) {
5224 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5225             }
5226             return join '', @char;
5227             }
5228              
5229             #
5230             # escape regexp (m//, qr//)
5231 93     652 0 905 #
5232 652   100     2649 sub e_qr {
5233             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5234 652         2588 $modifier ||= '';
5235 652 50       1084  
5236 652         1570 $modifier =~ tr/p//d;
5237 0         0 if ($modifier =~ /([adlu])/oxms) {
5238 0 0       0 my $line = 0;
5239 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5240 0         0 if ($filename ne __FILE__) {
5241             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5242             last;
5243 0         0 }
5244             }
5245             die qq{Unsupported modifier "$1" used at line $line.\n};
5246 0         0 }
5247              
5248             $slash = 'div';
5249 652 100       1066  
    100          
5250 652         2021 # literal null string pattern
5251 8         11 if ($string eq '') {
5252 8         8 $modifier =~ tr/bB//d;
5253             $modifier =~ tr/i//d;
5254             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5255             }
5256              
5257             # /b /B modifier
5258             elsif ($modifier =~ tr/bB//d) {
5259 8 50       37  
5260 2         6 # choice again delimiter
5261 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5262 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5263 0         0 my %octet = map {$_ => 1} @char;
5264 0         0 if (not $octet{')'}) {
5265             $delimiter = '(';
5266             $end_delimiter = ')';
5267 0         0 }
5268 0         0 elsif (not $octet{'}'}) {
5269             $delimiter = '{';
5270             $end_delimiter = '}';
5271 0         0 }
5272 0         0 elsif (not $octet{']'}) {
5273             $delimiter = '[';
5274             $end_delimiter = ']';
5275 0         0 }
5276 0         0 elsif (not $octet{'>'}) {
5277             $delimiter = '<';
5278             $end_delimiter = '>';
5279 0         0 }
5280 0 0       0 else {
5281 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5282 0         0 if (not $octet{$char}) {
5283 0         0 $delimiter = $char;
5284             $end_delimiter = $char;
5285             last;
5286             }
5287             }
5288             }
5289 0 50 33     0 }
5290 2         12  
5291             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5292             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5293 0         0 }
5294             else {
5295             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5296             }
5297 2 100       12 }
5298 642         1478  
5299             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5300             my $metachar = qr/[\@\\|[\]{^]/oxms;
5301 642         2335  
5302             # split regexp
5303             my @char = $string =~ /\G((?>
5304             [^\\\$\@\[\(] |
5305             \\x (?>[0-9A-Fa-f]{1,2}) |
5306             \\ (?>[0-7]{2,3}) |
5307             \\c [\x40-\x5F] |
5308             \\x\{ (?>[0-9A-Fa-f]+) \} |
5309             \\o\{ (?>[0-7]+) \} |
5310             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5311             \\ $q_char |
5312             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5313             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5314             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5315             [\$\@] $qq_variable |
5316             \$ (?>\s* [0-9]+) |
5317             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5318             \$ \$ (?![\w\{]) |
5319             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5320             \[\^ |
5321             \[\: (?>[a-z]+) :\] |
5322             \[\:\^ (?>[a-z]+) :\] |
5323             \(\? |
5324             $q_char
5325             ))/oxmsg;
5326 642 50       64753  
5327 642         3642 # choice again delimiter
  0         0  
5328 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5329 0         0 my %octet = map {$_ => 1} @char;
5330 0         0 if (not $octet{')'}) {
5331             $delimiter = '(';
5332             $end_delimiter = ')';
5333 0         0 }
5334 0         0 elsif (not $octet{'}'}) {
5335             $delimiter = '{';
5336             $end_delimiter = '}';
5337 0         0 }
5338 0         0 elsif (not $octet{']'}) {
5339             $delimiter = '[';
5340             $end_delimiter = ']';
5341 0         0 }
5342 0         0 elsif (not $octet{'>'}) {
5343             $delimiter = '<';
5344             $end_delimiter = '>';
5345 0         0 }
5346 0 0       0 else {
5347 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5348 0         0 if (not $octet{$char}) {
5349 0         0 $delimiter = $char;
5350             $end_delimiter = $char;
5351             last;
5352             }
5353             }
5354             }
5355 0         0 }
5356 642         1002  
5357 642         923 my $left_e = 0;
5358             my $right_e = 0;
5359             for (my $i=0; $i <= $#char; $i++) {
5360 642 50 66     1549  
    50 66        
    100          
    100          
    100          
    100          
5361 1872         17177 # "\L\u" --> "\u\L"
5362             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5363             @char[$i,$i+1] = @char[$i+1,$i];
5364             }
5365              
5366 0         0 # "\U\l" --> "\l\U"
5367             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5368             @char[$i,$i+1] = @char[$i+1,$i];
5369             }
5370              
5371 0         0 # octal escape sequence
5372             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5373             $char[$i] = Ekoi8u::octchr($1);
5374             }
5375              
5376 1         4 # hexadecimal escape sequence
5377             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5378             $char[$i] = Ekoi8u::hexchr($1);
5379             }
5380              
5381             # \b{...} --> b\{...}
5382             # \B{...} --> B\{...}
5383             # \N{CHARNAME} --> N\{CHARNAME}
5384             # \p{PROPERTY} --> p\{PROPERTY}
5385 1         4 # \P{PROPERTY} --> P\{PROPERTY}
5386             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5387             $char[$i] = $1 . '\\' . $2;
5388             }
5389              
5390 6         66 # \p, \P, \X --> p, P, X
5391             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5392             $char[$i] = $1;
5393 4 100 100     15 }
    100 100        
    100 100        
    100          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
5394              
5395             if (0) {
5396             }
5397 1872         6133  
5398 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5399 6         122 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5400             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)) {
5401             $char[$i] .= join '', splice @char, $i+1, 3;
5402 0         0 }
5403             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)) {
5404             $char[$i] .= join '', splice @char, $i+1, 2;
5405 0         0 }
5406             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)) {
5407             $char[$i] .= join '', splice @char, $i+1, 1;
5408             }
5409             }
5410              
5411 0         0 # open character class [...]
5412             elsif ($char[$i] eq '[') {
5413             my $left = $i;
5414              
5415             # [] make die "Unmatched [] in regexp ...\n"
5416 328 100       401 # (and so on)
5417 328         753  
5418             if ($char[$i+1] eq ']') {
5419             $i++;
5420 3         6 }
5421 328 50       432  
5422 1379         1929 while (1) {
5423             if (++$i > $#char) {
5424 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5425 1379         2059 }
5426             if ($char[$i] eq ']') {
5427             my $right = $i;
5428 328 100       386  
5429 328         1613 # [...]
  30         62  
5430             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5431             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);
5432 90         148 }
5433             else {
5434             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
5435 298         1136 }
5436 328         564  
5437             $i = $left;
5438             last;
5439             }
5440             }
5441             }
5442              
5443 328         790 # open character class [^...]
5444             elsif ($char[$i] eq '[^') {
5445             my $left = $i;
5446              
5447             # [^] make die "Unmatched [] in regexp ...\n"
5448 74 100       174 # (and so on)
5449 74         227  
5450             if ($char[$i+1] eq ']') {
5451             $i++;
5452 4         44 }
5453 74 50       90  
5454 272         435 while (1) {
5455             if (++$i > $#char) {
5456 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5457 272         626 }
5458             if ($char[$i] eq ']') {
5459             my $right = $i;
5460 74 100       114  
5461 74         450 # [^...]
  30         67  
5462             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5463             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);
5464 90         139 }
5465             else {
5466             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5467 44         199 }
5468 74         140  
5469             $i = $left;
5470             last;
5471             }
5472             }
5473             }
5474              
5475 74         177 # rewrite character class or escape character
5476             elsif (my $char = character_class($char[$i],$modifier)) {
5477             $char[$i] = $char;
5478             }
5479              
5480 139 50       351 # /i modifier
5481 20         34 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
5482             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
5483             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
5484 20         30 }
5485             else {
5486             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
5487             }
5488             }
5489              
5490 0 50       0 # \u \l \U \L \F \Q \E
5491 1         4 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5492             if ($right_e < $left_e) {
5493             $char[$i] = '\\' . $char[$i];
5494             }
5495 0         0 }
5496 0         0 elsif ($char[$i] eq '\u') {
5497             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
5498             $left_e++;
5499 0         0 }
5500 0         0 elsif ($char[$i] eq '\l') {
5501             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
5502             $left_e++;
5503 0         0 }
5504 1         2 elsif ($char[$i] eq '\U') {
5505             $char[$i] = '@{[Ekoi8u::uc qq<';
5506             $left_e++;
5507 1         4 }
5508 1         2 elsif ($char[$i] eq '\L') {
5509             $char[$i] = '@{[Ekoi8u::lc qq<';
5510             $left_e++;
5511 1         4 }
5512 18         71 elsif ($char[$i] eq '\F') {
5513             $char[$i] = '@{[Ekoi8u::fc qq<';
5514             $left_e++;
5515 18         36 }
5516 1         4 elsif ($char[$i] eq '\Q') {
5517             $char[$i] = '@{[CORE::quotemeta qq<';
5518             $left_e++;
5519 1 50       3 }
5520 21         39 elsif ($char[$i] eq '\E') {
5521 21         25 if ($right_e < $left_e) {
5522             $char[$i] = '>]}';
5523             $right_e++;
5524 21         45 }
5525             else {
5526             $char[$i] = '';
5527             }
5528 0         0 }
5529 0 0       0 elsif ($char[$i] eq '\Q') {
5530 0         0 while (1) {
5531             if (++$i > $#char) {
5532 0 0       0 last;
5533 0         0 }
5534             if ($char[$i] eq '\E') {
5535             last;
5536             }
5537             }
5538             }
5539             elsif ($char[$i] eq '\E') {
5540             }
5541              
5542 0 0       0 # $0 --> $0
5543 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5544             if ($ignorecase) {
5545             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5546             }
5547 0 0       0 }
5548 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5549             if ($ignorecase) {
5550             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5551             }
5552             }
5553              
5554             # $$ --> $$
5555             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5556             }
5557              
5558             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5559 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5560 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5561 0         0 $char[$i] = e_capture($1);
5562             if ($ignorecase) {
5563             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5564             }
5565 0         0 }
5566 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5567 0         0 $char[$i] = e_capture($1);
5568             if ($ignorecase) {
5569             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5570             }
5571             }
5572              
5573 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5574 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5575 0         0 $char[$i] = e_capture($1.'->'.$2);
5576             if ($ignorecase) {
5577             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5578             }
5579             }
5580              
5581 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5582 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5583 0         0 $char[$i] = e_capture($1.'->'.$2);
5584             if ($ignorecase) {
5585             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5586             }
5587             }
5588              
5589 0         0 # $$foo
5590 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5591 0         0 $char[$i] = e_capture($1);
5592             if ($ignorecase) {
5593             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5594             }
5595             }
5596              
5597 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
5598 8         21 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5599             if ($ignorecase) {
5600             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
5601 0         0 }
5602             else {
5603             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
5604             }
5605             }
5606              
5607 8 50       24 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
5608 8         20 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5609             if ($ignorecase) {
5610             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
5611 0         0 }
5612             else {
5613             $char[$i] = '@{[Ekoi8u::MATCH()]}';
5614             }
5615             }
5616              
5617 8 50       22 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
5618 6         16 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5619             if ($ignorecase) {
5620             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
5621 0         0 }
5622             else {
5623             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
5624             }
5625             }
5626              
5627 6 0       18 # ${ foo }
5628 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
5629             if ($ignorecase) {
5630             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5631             }
5632             }
5633              
5634 0         0 # ${ ... }
5635 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5636 0         0 $char[$i] = e_capture($1);
5637             if ($ignorecase) {
5638             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5639             }
5640             }
5641              
5642 0         0 # $scalar or @array
5643 21 100       54 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
5644 21         54 $char[$i] = e_string($char[$i]);
5645             if ($ignorecase) {
5646             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
5647             }
5648             }
5649              
5650 11 100 33     35 # quote character before ? + * {
    50          
5651             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
5652             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
5653 138         966 }
5654 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5655 0         0 my $char = $char[$i-1];
5656             if ($char[$i] eq '{') {
5657             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
5658 0         0 }
5659             else {
5660             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
5661             }
5662 0         0 }
5663             else {
5664             $char[$i-1] = '(?:' . $char[$i-1] . ')';
5665             }
5666             }
5667             }
5668 127         486  
5669 642 50       1316 # make regexp string
5670 642 0 0     1431 $modifier =~ tr/i//d;
5671 0         0 if ($left_e > $right_e) {
5672             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5673             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
5674 0         0 }
5675             else {
5676             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
5677 0 50 33     0 }
5678 642         3582 }
5679             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5680             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
5681 0         0 }
5682             else {
5683             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5684             }
5685             }
5686              
5687             #
5688             # double quote stuff
5689 642     180 0 5239 #
5690             sub qq_stuff {
5691             my($delimiter,$end_delimiter,$stuff) = @_;
5692 180 100       270  
5693 180         334 # scalar variable or array variable
5694             if ($stuff =~ /\A [\$\@] /oxms) {
5695             return $stuff;
5696             }
5697 100         305  
  80         173  
5698 80         217 # quote by delimiter
5699 80 50       206 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
5700 80 50       121 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5701 80 50       121 next if $char eq $delimiter;
5702 80         128 next if $char eq $end_delimiter;
5703             if (not $octet{$char}) {
5704             return join '', 'qq', $char, $stuff, $char;
5705 80         344 }
5706             }
5707             return join '', 'qq', '<', $stuff, '>';
5708             }
5709              
5710             #
5711             # escape regexp (m'', qr'', and m''b, qr''b)
5712 0     10 0 0 #
5713 10   50     48 sub e_qr_q {
5714             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5715 10         43 $modifier ||= '';
5716 10 50       14  
5717 10         21 $modifier =~ tr/p//d;
5718 0         0 if ($modifier =~ /([adlu])/oxms) {
5719 0 0       0 my $line = 0;
5720 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5721 0         0 if ($filename ne __FILE__) {
5722             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5723             last;
5724 0         0 }
5725             }
5726             die qq{Unsupported modifier "$1" used at line $line.\n};
5727 0         0 }
5728              
5729             $slash = 'div';
5730 10 100       17  
    50          
5731 10         24 # literal null string pattern
5732 8         9 if ($string eq '') {
5733 8         11 $modifier =~ tr/bB//d;
5734             $modifier =~ tr/i//d;
5735             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5736             }
5737              
5738 8         35 # with /b /B modifier
5739             elsif ($modifier =~ tr/bB//d) {
5740             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
5741             }
5742              
5743 0         0 # without /b /B modifier
5744             else {
5745             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
5746             }
5747             }
5748              
5749             #
5750             # escape regexp (m'', qr'')
5751 2     2 0 8 #
5752             sub e_qr_qt {
5753 2 50       7 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5754              
5755             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5756 2         7  
5757             # split regexp
5758             my @char = $string =~ /\G((?>
5759             [^\\\[\$\@\/] |
5760             [\x00-\xFF] |
5761             \[\^ |
5762             \[\: (?>[a-z]+) \:\] |
5763             \[\:\^ (?>[a-z]+) \:\] |
5764             [\$\@\/] |
5765             \\ (?:$q_char) |
5766             (?:$q_char)
5767             ))/oxmsg;
5768 2         64  
5769 2 50 33     13 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
5770             for (my $i=0; $i <= $#char; $i++) {
5771             if (0) {
5772             }
5773 2         18  
5774 0         0 # open character class [...]
5775 0 0       0 elsif ($char[$i] eq '[') {
5776 0         0 my $left = $i;
5777             if ($char[$i+1] eq ']') {
5778 0         0 $i++;
5779 0 0       0 }
5780 0         0 while (1) {
5781             if (++$i > $#char) {
5782 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
5783 0         0 }
5784             if ($char[$i] eq ']') {
5785             my $right = $i;
5786 0         0  
5787             # [...]
5788 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
5789 0         0  
5790             $i = $left;
5791             last;
5792             }
5793             }
5794             }
5795              
5796 0         0 # open character class [^...]
5797 0 0       0 elsif ($char[$i] eq '[^') {
5798 0         0 my $left = $i;
5799             if ($char[$i+1] eq ']') {
5800 0         0 $i++;
5801 0 0       0 }
5802 0         0 while (1) {
5803             if (++$i > $#char) {
5804 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
5805 0         0 }
5806             if ($char[$i] eq ']') {
5807             my $right = $i;
5808 0         0  
5809             # [^...]
5810 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5811 0         0  
5812             $i = $left;
5813             last;
5814             }
5815             }
5816             }
5817              
5818 0         0 # escape $ @ / and \
5819             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
5820             $char[$i] = '\\' . $char[$i];
5821             }
5822              
5823 0         0 # rewrite character class or escape character
5824             elsif (my $char = character_class($char[$i],$modifier)) {
5825             $char[$i] = $char;
5826             }
5827              
5828 0 0       0 # /i modifier
5829 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
5830             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
5831             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
5832 0         0 }
5833             else {
5834             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
5835             }
5836             }
5837              
5838 0 0       0 # quote character before ? + * {
5839             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
5840             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
5841 0         0 }
5842             else {
5843             $char[$i-1] = '(?:' . $char[$i-1] . ')';
5844             }
5845             }
5846 0         0 }
5847 2         5  
5848             $delimiter = '/';
5849 2         5 $end_delimiter = '/';
5850 2         4  
5851             $modifier =~ tr/i//d;
5852             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5853             }
5854              
5855             #
5856             # escape regexp (m''b, qr''b)
5857 2     0 0 16 #
5858             sub e_qr_qb {
5859             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5860 0         0  
5861             # split regexp
5862             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
5863 0         0  
5864 0 0       0 # unescape character
    0          
5865             for (my $i=0; $i <= $#char; $i++) {
5866             if (0) {
5867             }
5868 0         0  
5869             # remain \\
5870             elsif ($char[$i] eq '\\\\') {
5871             }
5872              
5873 0         0 # escape $ @ / and \
5874             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
5875             $char[$i] = '\\' . $char[$i];
5876             }
5877 0         0 }
5878 0         0  
5879 0         0 $delimiter = '/';
5880             $end_delimiter = '/';
5881             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5882             }
5883              
5884             #
5885             # escape regexp (s/here//)
5886 0     76 0 0 #
5887 76   100     229 sub e_s1 {
5888             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5889 76         418 $modifier ||= '';
5890 76 50       125  
5891 76         233 $modifier =~ tr/p//d;
5892 0         0 if ($modifier =~ /([adlu])/oxms) {
5893 0 0       0 my $line = 0;
5894 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5895 0         0 if ($filename ne __FILE__) {
5896             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5897             last;
5898 0         0 }
5899             }
5900             die qq{Unsupported modifier "$1" used at line $line.\n};
5901 0         0 }
5902              
5903             $slash = 'div';
5904 76 100       138  
    50          
5905 76         259 # literal null string pattern
5906 8         9 if ($string eq '') {
5907 8         10 $modifier =~ tr/bB//d;
5908             $modifier =~ tr/i//d;
5909             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5910             }
5911              
5912             # /b /B modifier
5913             elsif ($modifier =~ tr/bB//d) {
5914 8 0       47  
5915 0         0 # choice again delimiter
5916 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5917 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5918 0         0 my %octet = map {$_ => 1} @char;
5919 0         0 if (not $octet{')'}) {
5920             $delimiter = '(';
5921             $end_delimiter = ')';
5922 0         0 }
5923 0         0 elsif (not $octet{'}'}) {
5924             $delimiter = '{';
5925             $end_delimiter = '}';
5926 0         0 }
5927 0         0 elsif (not $octet{']'}) {
5928             $delimiter = '[';
5929             $end_delimiter = ']';
5930 0         0 }
5931 0         0 elsif (not $octet{'>'}) {
5932             $delimiter = '<';
5933             $end_delimiter = '>';
5934 0         0 }
5935 0 0       0 else {
5936 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5937 0         0 if (not $octet{$char}) {
5938 0         0 $delimiter = $char;
5939             $end_delimiter = $char;
5940             last;
5941             }
5942             }
5943             }
5944 0         0 }
5945 0         0  
5946             my $prematch = '';
5947             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5948 0 100       0 }
5949 68         195  
5950             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5951             my $metachar = qr/[\@\\|[\]{^]/oxms;
5952 68         354  
5953             # split regexp
5954             my @char = $string =~ /\G((?>
5955             [^\\\$\@\[\(] |
5956             \\ (?>[1-9][0-9]*) |
5957             \\g (?>\s*) (?>[1-9][0-9]*) |
5958             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
5959             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
5960             \\x (?>[0-9A-Fa-f]{1,2}) |
5961             \\ (?>[0-7]{2,3}) |
5962             \\c [\x40-\x5F] |
5963             \\x\{ (?>[0-9A-Fa-f]+) \} |
5964             \\o\{ (?>[0-7]+) \} |
5965             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5966             \\ $q_char |
5967             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5968             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5969             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5970             [\$\@] $qq_variable |
5971             \$ (?>\s* [0-9]+) |
5972             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5973             \$ \$ (?![\w\{]) |
5974             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5975             \[\^ |
5976             \[\: (?>[a-z]+) :\] |
5977             \[\:\^ (?>[a-z]+) :\] |
5978             \(\? |
5979             $q_char
5980             ))/oxmsg;
5981 68 50       18026  
5982 68         499 # choice again delimiter
  0         0  
5983 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5984 0         0 my %octet = map {$_ => 1} @char;
5985 0         0 if (not $octet{')'}) {
5986             $delimiter = '(';
5987             $end_delimiter = ')';
5988 0         0 }
5989 0         0 elsif (not $octet{'}'}) {
5990             $delimiter = '{';
5991             $end_delimiter = '}';
5992 0         0 }
5993 0         0 elsif (not $octet{']'}) {
5994             $delimiter = '[';
5995             $end_delimiter = ']';
5996 0         0 }
5997 0         0 elsif (not $octet{'>'}) {
5998             $delimiter = '<';
5999             $end_delimiter = '>';
6000 0         0 }
6001 0 0       0 else {
6002 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6003 0         0 if (not $octet{$char}) {
6004 0         0 $delimiter = $char;
6005             $end_delimiter = $char;
6006             last;
6007             }
6008             }
6009             }
6010             }
6011 0         0  
  68         150  
6012             # count '('
6013 253         507 my $parens = grep { $_ eq '(' } @char;
6014 68         107  
6015 68         120 my $left_e = 0;
6016             my $right_e = 0;
6017             for (my $i=0; $i <= $#char; $i++) {
6018 68 50 33     746  
    50 33        
    100          
    100          
    50          
    50          
6019 195         1197 # "\L\u" --> "\u\L"
6020             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6021             @char[$i,$i+1] = @char[$i+1,$i];
6022             }
6023              
6024 0         0 # "\U\l" --> "\l\U"
6025             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6026             @char[$i,$i+1] = @char[$i+1,$i];
6027             }
6028              
6029 0         0 # octal escape sequence
6030             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6031             $char[$i] = Ekoi8u::octchr($1);
6032             }
6033              
6034 1         4 # hexadecimal escape sequence
6035             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6036             $char[$i] = Ekoi8u::hexchr($1);
6037             }
6038              
6039             # \b{...} --> b\{...}
6040             # \B{...} --> B\{...}
6041             # \N{CHARNAME} --> N\{CHARNAME}
6042             # \p{PROPERTY} --> p\{PROPERTY}
6043 1         2 # \P{PROPERTY} --> P\{PROPERTY}
6044             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6045             $char[$i] = $1 . '\\' . $2;
6046             }
6047              
6048 0         0 # \p, \P, \X --> p, P, X
6049             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6050             $char[$i] = $1;
6051 0 50 66     0 }
    100 66        
    50 100        
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
6052              
6053             if (0) {
6054             }
6055 195         966  
6056 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6057 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6058             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)) {
6059             $char[$i] .= join '', splice @char, $i+1, 3;
6060 0         0 }
6061             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)) {
6062             $char[$i] .= join '', splice @char, $i+1, 2;
6063 0         0 }
6064             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)) {
6065             $char[$i] .= join '', splice @char, $i+1, 1;
6066             }
6067             }
6068              
6069 0         0 # open character class [...]
6070 13 50       23 elsif ($char[$i] eq '[') {
6071 13         51 my $left = $i;
6072             if ($char[$i+1] eq ']') {
6073 0         0 $i++;
6074 13 50       20 }
6075 58         87 while (1) {
6076             if (++$i > $#char) {
6077 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6078 58         120 }
6079             if ($char[$i] eq ']') {
6080             my $right = $i;
6081 13 50       22  
6082 13         160 # [...]
  0         0  
6083             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6084             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);
6085 0         0 }
6086             else {
6087             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6088 13         60 }
6089 13         32  
6090             $i = $left;
6091             last;
6092             }
6093             }
6094             }
6095              
6096 13         35 # open character class [^...]
6097 0 0       0 elsif ($char[$i] eq '[^') {
6098 0         0 my $left = $i;
6099             if ($char[$i+1] eq ']') {
6100 0         0 $i++;
6101 0 0       0 }
6102 0         0 while (1) {
6103             if (++$i > $#char) {
6104 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6105 0         0 }
6106             if ($char[$i] eq ']') {
6107             my $right = $i;
6108 0 0       0  
6109 0         0 # [^...]
  0         0  
6110             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6111             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);
6112 0         0 }
6113             else {
6114             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6115 0         0 }
6116 0         0  
6117             $i = $left;
6118             last;
6119             }
6120             }
6121             }
6122              
6123 0         0 # rewrite character class or escape character
6124             elsif (my $char = character_class($char[$i],$modifier)) {
6125             $char[$i] = $char;
6126             }
6127              
6128 7 50       17 # /i modifier
6129 3         6 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6130             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6131             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6132 3         15 }
6133             else {
6134             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6135             }
6136             }
6137              
6138 0 0       0 # \u \l \U \L \F \Q \E
6139 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6140             if ($right_e < $left_e) {
6141             $char[$i] = '\\' . $char[$i];
6142             }
6143 0         0 }
6144 0         0 elsif ($char[$i] eq '\u') {
6145             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
6146             $left_e++;
6147 0         0 }
6148 0         0 elsif ($char[$i] eq '\l') {
6149             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
6150             $left_e++;
6151 0         0 }
6152 0         0 elsif ($char[$i] eq '\U') {
6153             $char[$i] = '@{[Ekoi8u::uc qq<';
6154             $left_e++;
6155 0         0 }
6156 0         0 elsif ($char[$i] eq '\L') {
6157             $char[$i] = '@{[Ekoi8u::lc qq<';
6158             $left_e++;
6159 0         0 }
6160 0         0 elsif ($char[$i] eq '\F') {
6161             $char[$i] = '@{[Ekoi8u::fc qq<';
6162             $left_e++;
6163 0         0 }
6164 0         0 elsif ($char[$i] eq '\Q') {
6165             $char[$i] = '@{[CORE::quotemeta qq<';
6166             $left_e++;
6167 0 0       0 }
6168 0         0 elsif ($char[$i] eq '\E') {
6169 0         0 if ($right_e < $left_e) {
6170             $char[$i] = '>]}';
6171             $right_e++;
6172 0         0 }
6173             else {
6174             $char[$i] = '';
6175             }
6176 0         0 }
6177 0 0       0 elsif ($char[$i] eq '\Q') {
6178 0         0 while (1) {
6179             if (++$i > $#char) {
6180 0 0       0 last;
6181 0         0 }
6182             if ($char[$i] eq '\E') {
6183             last;
6184             }
6185             }
6186             }
6187             elsif ($char[$i] eq '\E') {
6188             }
6189              
6190             # \0 --> \0
6191             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6192             }
6193              
6194             # \g{N}, \g{-N}
6195              
6196             # P.108 Using Simple Patterns
6197             # in Chapter 7: In the World of Regular Expressions
6198             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6199              
6200             # P.221 Capturing
6201             # in Chapter 5: Pattern Matching
6202             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6203              
6204             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6205             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6206             }
6207              
6208             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6209             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6210             }
6211              
6212             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6213             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6214             }
6215              
6216             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6217             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6218             }
6219              
6220 0 0       0 # $0 --> $0
6221 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6222             if ($ignorecase) {
6223             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6224             }
6225 0 0       0 }
6226 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6227             if ($ignorecase) {
6228             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6229             }
6230             }
6231              
6232             # $$ --> $$
6233             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6234             }
6235              
6236             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6237 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6238 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6239 0         0 $char[$i] = e_capture($1);
6240             if ($ignorecase) {
6241             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6242             }
6243 0         0 }
6244 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6245 0         0 $char[$i] = e_capture($1);
6246             if ($ignorecase) {
6247             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6248             }
6249             }
6250              
6251 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6252 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
6253 0         0 $char[$i] = e_capture($1.'->'.$2);
6254             if ($ignorecase) {
6255             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6256             }
6257             }
6258              
6259 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6260 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
6261 0         0 $char[$i] = e_capture($1.'->'.$2);
6262             if ($ignorecase) {
6263             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6264             }
6265             }
6266              
6267 0         0 # $$foo
6268 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6269 0         0 $char[$i] = e_capture($1);
6270             if ($ignorecase) {
6271             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6272             }
6273             }
6274              
6275 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
6276 4         15 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6277             if ($ignorecase) {
6278             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
6279 0         0 }
6280             else {
6281             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
6282             }
6283             }
6284              
6285 4 50       14 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
6286 4         15 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6287             if ($ignorecase) {
6288             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
6289 0         0 }
6290             else {
6291             $char[$i] = '@{[Ekoi8u::MATCH()]}';
6292             }
6293             }
6294              
6295 4 50       13 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
6296 3         10 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6297             if ($ignorecase) {
6298             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
6299 0         0 }
6300             else {
6301             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
6302             }
6303             }
6304              
6305 3 0       11 # ${ foo }
6306 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
6307             if ($ignorecase) {
6308             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6309             }
6310             }
6311              
6312 0         0 # ${ ... }
6313 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6314 0         0 $char[$i] = e_capture($1);
6315             if ($ignorecase) {
6316             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6317             }
6318             }
6319              
6320 0         0 # $scalar or @array
6321 4 50       16 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6322 4         25 $char[$i] = e_string($char[$i]);
6323             if ($ignorecase) {
6324             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6325             }
6326             }
6327              
6328 0 50       0 # quote character before ? + * {
6329             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6330             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6331 13         71 }
6332             else {
6333             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6334             }
6335             }
6336             }
6337 13         74  
6338 68         157 # make regexp string
6339 68 50       111 my $prematch = '';
6340 68         220 $modifier =~ tr/i//d;
6341             if ($left_e > $right_e) {
6342 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6343             }
6344             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6345             }
6346              
6347             #
6348             # escape regexp (s'here'' or s'here''b)
6349 68     21 0 919 #
6350 21   100     148 sub e_s1_q {
6351             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6352 21         75 $modifier ||= '';
6353 21 50       28  
6354 21         47 $modifier =~ tr/p//d;
6355 0         0 if ($modifier =~ /([adlu])/oxms) {
6356 0 0       0 my $line = 0;
6357 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6358 0         0 if ($filename ne __FILE__) {
6359             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6360             last;
6361 0         0 }
6362             }
6363             die qq{Unsupported modifier "$1" used at line $line.\n};
6364 0         0 }
6365              
6366             $slash = 'div';
6367 21 100       36  
    50          
6368 21         62 # literal null string pattern
6369 8         23 if ($string eq '') {
6370 8         16 $modifier =~ tr/bB//d;
6371             $modifier =~ tr/i//d;
6372             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6373             }
6374              
6375 8         49 # with /b /B modifier
6376             elsif ($modifier =~ tr/bB//d) {
6377             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6378             }
6379              
6380 0         0 # without /b /B modifier
6381             else {
6382             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6383             }
6384             }
6385              
6386             #
6387             # escape regexp (s'here'')
6388 13     13 0 35 #
6389             sub e_s1_qt {
6390 13 50       33 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6391              
6392             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6393 13         32  
6394             # split regexp
6395             my @char = $string =~ /\G((?>
6396             [^\\\[\$\@\/] |
6397             [\x00-\xFF] |
6398             \[\^ |
6399             \[\: (?>[a-z]+) \:\] |
6400             \[\:\^ (?>[a-z]+) \:\] |
6401             [\$\@\/] |
6402             \\ (?:$q_char) |
6403             (?:$q_char)
6404             ))/oxmsg;
6405 13         239  
6406 13 50 33     51 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6407             for (my $i=0; $i <= $#char; $i++) {
6408             if (0) {
6409             }
6410 25         152  
6411 0         0 # open character class [...]
6412 0 0       0 elsif ($char[$i] eq '[') {
6413 0         0 my $left = $i;
6414             if ($char[$i+1] eq ']') {
6415 0         0 $i++;
6416 0 0       0 }
6417 0         0 while (1) {
6418             if (++$i > $#char) {
6419 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6420 0         0 }
6421             if ($char[$i] eq ']') {
6422             my $right = $i;
6423 0         0  
6424             # [...]
6425 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6426 0         0  
6427             $i = $left;
6428             last;
6429             }
6430             }
6431             }
6432              
6433 0         0 # open character class [^...]
6434 0 0       0 elsif ($char[$i] eq '[^') {
6435 0         0 my $left = $i;
6436             if ($char[$i+1] eq ']') {
6437 0         0 $i++;
6438 0 0       0 }
6439 0         0 while (1) {
6440             if (++$i > $#char) {
6441 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6442 0         0 }
6443             if ($char[$i] eq ']') {
6444             my $right = $i;
6445 0         0  
6446             # [^...]
6447 0         0 splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6448 0         0  
6449             $i = $left;
6450             last;
6451             }
6452             }
6453             }
6454              
6455 0         0 # escape $ @ / and \
6456             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6457             $char[$i] = '\\' . $char[$i];
6458             }
6459              
6460 0         0 # rewrite character class or escape character
6461             elsif (my $char = character_class($char[$i],$modifier)) {
6462             $char[$i] = $char;
6463             }
6464              
6465 6 0       14 # /i modifier
6466 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6467             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6468             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6469 0         0 }
6470             else {
6471             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6472             }
6473             }
6474              
6475 0 0       0 # quote character before ? + * {
6476             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6477             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6478 0         0 }
6479             else {
6480             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6481             }
6482             }
6483 0         0 }
6484 13         22  
6485 13         25 $modifier =~ tr/i//d;
6486 13         17 $delimiter = '/';
6487 13         19 $end_delimiter = '/';
6488             my $prematch = '';
6489             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6490             }
6491              
6492             #
6493             # escape regexp (s'here''b)
6494 13     0 0 112 #
6495             sub e_s1_qb {
6496             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6497 0         0  
6498             # split regexp
6499             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6500 0         0  
6501 0 0       0 # unescape character
    0          
6502             for (my $i=0; $i <= $#char; $i++) {
6503             if (0) {
6504             }
6505 0         0  
6506             # remain \\
6507             elsif ($char[$i] eq '\\\\') {
6508             }
6509              
6510 0         0 # escape $ @ / and \
6511             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6512             $char[$i] = '\\' . $char[$i];
6513             }
6514 0         0 }
6515 0         0  
6516 0         0 $delimiter = '/';
6517 0         0 $end_delimiter = '/';
6518             my $prematch = '';
6519             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6520             }
6521              
6522             #
6523             # escape regexp (s''here')
6524 0     16 0 0 #
6525             sub e_s2_q {
6526 16         36 my($ope,$delimiter,$end_delimiter,$string) = @_;
6527              
6528 16         19 $slash = 'div';
6529 16         105  
6530 16 100       46 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
6531             for (my $i=0; $i <= $#char; $i++) {
6532             if (0) {
6533             }
6534 9         34  
6535             # not escape \\
6536             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
6537             }
6538              
6539 0         0 # escape $ @ / and \
6540             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6541             $char[$i] = '\\' . $char[$i];
6542             }
6543 5         14 }
6544              
6545             return join '', $ope, $delimiter, @char, $end_delimiter;
6546             }
6547              
6548             #
6549             # escape regexp (s/here/and here/modifier)
6550 16     97 0 47 #
6551 97   100     801 sub e_sub {
6552             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
6553 97         487 $modifier ||= '';
6554 97 50       212  
6555 97         267 $modifier =~ tr/p//d;
6556 0         0 if ($modifier =~ /([adlu])/oxms) {
6557 0 0       0 my $line = 0;
6558 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6559 0         0 if ($filename ne __FILE__) {
6560             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6561             last;
6562 0         0 }
6563             }
6564             die qq{Unsupported modifier "$1" used at line $line.\n};
6565 0 100       0 }
6566 97         291  
6567 36         48 if ($variable eq '') {
6568             $variable = '$_';
6569             $bind_operator = ' =~ ';
6570 36         59 }
6571              
6572             $slash = 'div';
6573              
6574             # P.128 Start of match (or end of previous match): \G
6575             # P.130 Advanced Use of \G with Perl
6576             # in Chapter 3: Overview of Regular Expression Features and Flavors
6577             # P.312 Iterative Matching: Scalar Context, with /g
6578             # in Chapter 7: Perl
6579             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
6580              
6581             # P.181 Where You Left Off: The \G Assertion
6582             # in Chapter 5: Pattern Matching
6583             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6584              
6585             # P.220 Where You Left Off: The \G Assertion
6586             # in Chapter 5: Pattern Matching
6587 97         158 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6588 97         141  
6589             my $e_modifier = $modifier =~ tr/e//d;
6590 97         144 my $r_modifier = $modifier =~ tr/r//d;
6591 97 50       166  
6592 97         371 my $my = '';
6593 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
6594 0         0 $my = $variable;
6595             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
6596             $variable =~ s/ = .+ \z//oxms;
6597 0         0 }
6598 97         255  
6599             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
6600             $variable_basename =~ s/ \s+ \z//oxms;
6601 97         236  
6602 97 100       146 # quote replacement string
6603 97         249 my $e_replacement = '';
6604 17         39 if ($e_modifier >= 1) {
6605             $e_replacement = e_qq('', '', '', $replacement);
6606             $e_modifier--;
6607 17 100       27 }
6608 80         215 else {
6609             if ($delimiter2 eq "'") {
6610             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
6611 16         40 }
6612             else {
6613             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
6614             }
6615 64         215 }
6616              
6617             my $sub = '';
6618 97 100       170  
6619 97 100       222 # with /r
6620             if ($r_modifier) {
6621             if (0) {
6622             }
6623 8         19  
6624 0 50       0 # s///gr without multibyte anchoring
6625             elsif ($modifier =~ /g/oxms) {
6626             $sub = sprintf(
6627             # 1 2 3 4 5
6628             q,
6629              
6630             $variable, # 1
6631             ($delimiter1 eq "'") ? # 2
6632             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6633             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6634             $s_matched, # 3
6635             $e_replacement, # 4
6636             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
6637             );
6638             }
6639              
6640             # s///r
6641 4         14 else {
6642              
6643 4 50       5 my $prematch = q{$`};
6644              
6645             $sub = sprintf(
6646             # 1 2 3 4 5 6 7
6647             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s"%s$Ekoi8u::re_r$'" } : %s>,
6648              
6649             $variable, # 1
6650             ($delimiter1 eq "'") ? # 2
6651             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6652             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6653             $s_matched, # 3
6654             $e_replacement, # 4
6655             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
6656             $prematch, # 6
6657             $variable, # 7
6658             );
6659             }
6660 4 50       13  
6661 8         24 # $var !~ s///r doesn't make sense
6662             if ($bind_operator =~ / !~ /oxms) {
6663             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
6664             }
6665             }
6666              
6667 0 100       0 # without /r
6668             else {
6669             if (0) {
6670             }
6671 89         244  
6672 0 100       0 # s///g without multibyte anchoring
    100          
6673             elsif ($modifier =~ /g/oxms) {
6674             $sub = sprintf(
6675             # 1 2 3 4 5 6 7 8
6676             q,
6677              
6678             $variable, # 1
6679             ($delimiter1 eq "'") ? # 2
6680             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6681             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6682             $s_matched, # 3
6683             $e_replacement, # 4
6684             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 5
6685             $variable, # 6
6686             $variable, # 7
6687             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
6688             );
6689             }
6690              
6691             # s///
6692 22         99 else {
6693              
6694 67 100       110 my $prematch = q{$`};
    100          
6695              
6696             $sub = sprintf(
6697              
6698             ($bind_operator =~ / =~ /oxms) ?
6699              
6700             # 1 2 3 4 5 6 7 8
6701             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s%s="%s$Ekoi8u::re_r$'"; 1 } : undef> :
6702              
6703             # 1 2 3 4 5 6 7 8
6704             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Ekoi8u::re_r=%s; %s%s="%s$Ekoi8u::re_r$'"; undef }>,
6705              
6706             $variable, # 1
6707             $bind_operator, # 2
6708             ($delimiter1 eq "'") ? # 3
6709             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6710             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6711             $s_matched, # 4
6712             $e_replacement, # 5
6713             '$Ekoi8u::re_r=CORE::eval $Ekoi8u::re_r; ' x $e_modifier, # 6
6714             $variable, # 7
6715             $prematch, # 8
6716             );
6717             }
6718             }
6719 67 50       396  
6720 97         323 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
6721             if ($my ne '') {
6722             $sub = "($my, $sub)[1]";
6723             }
6724 0         0  
6725 97         163 # clear s/// variable
6726             $sub_variable = '';
6727 97         148 $bind_operator = '';
6728              
6729             return $sub;
6730             }
6731              
6732             #
6733             # escape regexp of split qr//
6734 97     74 0 733 #
6735 74   100     346 sub e_split {
6736             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6737 74         339 $modifier ||= '';
6738 74 50       137  
6739 74         293 $modifier =~ tr/p//d;
6740 0         0 if ($modifier =~ /([adlu])/oxms) {
6741 0 0       0 my $line = 0;
6742 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6743 0         0 if ($filename ne __FILE__) {
6744             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6745             last;
6746 0         0 }
6747             }
6748             die qq{Unsupported modifier "$1" used at line $line.\n};
6749 0         0 }
6750              
6751             $slash = 'div';
6752 74 50       125  
6753 74         151 # /b /B modifier
6754             if ($modifier =~ tr/bB//d) {
6755             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
6756 0 50       0 }
6757 74         161  
6758             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6759             my $metachar = qr/[\@\\|[\]{^]/oxms;
6760 74         316  
6761             # split regexp
6762             my @char = $string =~ /\G((?>
6763             [^\\\$\@\[\(] |
6764             \\x (?>[0-9A-Fa-f]{1,2}) |
6765             \\ (?>[0-7]{2,3}) |
6766             \\c [\x40-\x5F] |
6767             \\x\{ (?>[0-9A-Fa-f]+) \} |
6768             \\o\{ (?>[0-7]+) \} |
6769             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6770             \\ $q_char |
6771             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6772             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6773             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6774             [\$\@] $qq_variable |
6775             \$ (?>\s* [0-9]+) |
6776             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6777             \$ \$ (?![\w\{]) |
6778             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6779             \[\^ |
6780             \[\: (?>[a-z]+) :\] |
6781             \[\:\^ (?>[a-z]+) :\] |
6782             \(\? |
6783             $q_char
6784 74         9001 ))/oxmsg;
6785 74         245  
6786 74         187 my $left_e = 0;
6787             my $right_e = 0;
6788             for (my $i=0; $i <= $#char; $i++) {
6789 74 50 33     271  
    50 33        
    100          
    100          
    50          
    50          
6790 249         1708 # "\L\u" --> "\u\L"
6791             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6792             @char[$i,$i+1] = @char[$i+1,$i];
6793             }
6794              
6795 0         0 # "\U\l" --> "\l\U"
6796             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6797             @char[$i,$i+1] = @char[$i+1,$i];
6798             }
6799              
6800 0         0 # octal escape sequence
6801             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6802             $char[$i] = Ekoi8u::octchr($1);
6803             }
6804              
6805 1         3 # hexadecimal escape sequence
6806             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6807             $char[$i] = Ekoi8u::hexchr($1);
6808             }
6809              
6810             # \b{...} --> b\{...}
6811             # \B{...} --> B\{...}
6812             # \N{CHARNAME} --> N\{CHARNAME}
6813             # \p{PROPERTY} --> p\{PROPERTY}
6814 1         3 # \P{PROPERTY} --> P\{PROPERTY}
6815             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6816             $char[$i] = $1 . '\\' . $2;
6817             }
6818              
6819 0         0 # \p, \P, \X --> p, P, X
6820             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6821             $char[$i] = $1;
6822 0 50 100     0 }
    100 33        
    50 33        
    100 100        
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
6823              
6824             if (0) {
6825             }
6826 249         857  
6827 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6828 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6829             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)) {
6830             $char[$i] .= join '', splice @char, $i+1, 3;
6831 0         0 }
6832             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)) {
6833             $char[$i] .= join '', splice @char, $i+1, 2;
6834 0         0 }
6835             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)) {
6836             $char[$i] .= join '', splice @char, $i+1, 1;
6837             }
6838             }
6839              
6840 0         0 # open character class [...]
6841 3 50       6 elsif ($char[$i] eq '[') {
6842 3         10 my $left = $i;
6843             if ($char[$i+1] eq ']') {
6844 0         0 $i++;
6845 3 50       4 }
6846 7         13 while (1) {
6847             if (++$i > $#char) {
6848 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6849 7         15 }
6850             if ($char[$i] eq ']') {
6851             my $right = $i;
6852 3 50       4  
6853 3         19 # [...]
  0         0  
6854             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6855             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);
6856 0         0 }
6857             else {
6858             splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
6859 3         19 }
6860 3         5  
6861             $i = $left;
6862             last;
6863             }
6864             }
6865             }
6866              
6867 3         8 # open character class [^...]
6868 0 0       0 elsif ($char[$i] eq '[^') {
6869 0         0 my $left = $i;
6870             if ($char[$i+1] eq ']') {
6871 0         0 $i++;
6872 0 0       0 }
6873 0         0 while (1) {
6874             if (++$i > $#char) {
6875 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6876 0         0 }
6877             if ($char[$i] eq ']') {
6878             my $right = $i;
6879 0 0       0  
6880 0         0 # [^...]
  0         0  
6881             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6882             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);
6883 0         0 }
6884             else {
6885             splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6886 0         0 }
6887 0         0  
6888             $i = $left;
6889             last;
6890             }
6891             }
6892             }
6893              
6894 0         0 # rewrite character class or escape character
6895             elsif (my $char = character_class($char[$i],$modifier)) {
6896             $char[$i] = $char;
6897             }
6898              
6899             # P.794 29.2.161. split
6900             # in Chapter 29: Functions
6901             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6902              
6903             # P.951 split
6904             # in Chapter 27: Functions
6905             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6906              
6907             # said "The //m modifier is assumed when you split on the pattern /^/",
6908             # but perl5.008 is not so. Therefore, this software adds //m.
6909             # (and so on)
6910              
6911 1         2 # split(m/^/) --> split(m/^/m)
6912             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
6913             $modifier .= 'm';
6914             }
6915              
6916 7 0       20 # /i modifier
6917 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
6918             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
6919             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
6920 0         0 }
6921             else {
6922             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
6923             }
6924             }
6925              
6926 0 0       0 # \u \l \U \L \F \Q \E
6927 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
6928             if ($right_e < $left_e) {
6929             $char[$i] = '\\' . $char[$i];
6930             }
6931 0         0 }
6932 0         0 elsif ($char[$i] eq '\u') {
6933             $char[$i] = '@{[Ekoi8u::ucfirst qq<';
6934             $left_e++;
6935 0         0 }
6936 0         0 elsif ($char[$i] eq '\l') {
6937             $char[$i] = '@{[Ekoi8u::lcfirst qq<';
6938             $left_e++;
6939 0         0 }
6940 0         0 elsif ($char[$i] eq '\U') {
6941             $char[$i] = '@{[Ekoi8u::uc qq<';
6942             $left_e++;
6943 0         0 }
6944 0         0 elsif ($char[$i] eq '\L') {
6945             $char[$i] = '@{[Ekoi8u::lc qq<';
6946             $left_e++;
6947 0         0 }
6948 0         0 elsif ($char[$i] eq '\F') {
6949             $char[$i] = '@{[Ekoi8u::fc qq<';
6950             $left_e++;
6951 0         0 }
6952 0         0 elsif ($char[$i] eq '\Q') {
6953             $char[$i] = '@{[CORE::quotemeta qq<';
6954             $left_e++;
6955 0 0       0 }
6956 0         0 elsif ($char[$i] eq '\E') {
6957 0         0 if ($right_e < $left_e) {
6958             $char[$i] = '>]}';
6959             $right_e++;
6960 0         0 }
6961             else {
6962             $char[$i] = '';
6963             }
6964 0         0 }
6965 0 0       0 elsif ($char[$i] eq '\Q') {
6966 0         0 while (1) {
6967             if (++$i > $#char) {
6968 0 0       0 last;
6969 0         0 }
6970             if ($char[$i] eq '\E') {
6971             last;
6972             }
6973             }
6974             }
6975             elsif ($char[$i] eq '\E') {
6976             }
6977              
6978 0 0       0 # $0 --> $0
6979 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6980             if ($ignorecase) {
6981             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6982             }
6983 0 0       0 }
6984 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6985             if ($ignorecase) {
6986             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
6987             }
6988             }
6989              
6990             # $$ --> $$
6991             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6992             }
6993              
6994             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6995 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6996 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6997 0         0 $char[$i] = e_capture($1);
6998             if ($ignorecase) {
6999             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7000             }
7001 0         0 }
7002 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7003 0         0 $char[$i] = e_capture($1);
7004             if ($ignorecase) {
7005             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7006             }
7007             }
7008              
7009 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7010 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7011 0         0 $char[$i] = e_capture($1.'->'.$2);
7012             if ($ignorecase) {
7013             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7014             }
7015             }
7016              
7017 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7018 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
7019 0         0 $char[$i] = e_capture($1.'->'.$2);
7020             if ($ignorecase) {
7021             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7022             }
7023             }
7024              
7025 0         0 # $$foo
7026 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7027 0         0 $char[$i] = e_capture($1);
7028             if ($ignorecase) {
7029             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7030             }
7031             }
7032              
7033 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8u::PREMATCH()
7034 12         33 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7035             if ($ignorecase) {
7036             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::PREMATCH())]}';
7037 0         0 }
7038             else {
7039             $char[$i] = '@{[Ekoi8u::PREMATCH()]}';
7040             }
7041             }
7042              
7043 12 50       54 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8u::MATCH()
7044 12         32 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7045             if ($ignorecase) {
7046             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::MATCH())]}';
7047 0         0 }
7048             else {
7049             $char[$i] = '@{[Ekoi8u::MATCH()]}';
7050             }
7051             }
7052              
7053 12 50       50 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8u::POSTMATCH()
7054 9         35 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7055             if ($ignorecase) {
7056             $char[$i] = '@{[Ekoi8u::ignorecase(Ekoi8u::POSTMATCH())]}';
7057 0         0 }
7058             else {
7059             $char[$i] = '@{[Ekoi8u::POSTMATCH()]}';
7060             }
7061             }
7062              
7063 9 0       41 # ${ foo }
7064 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
7065             if ($ignorecase) {
7066             $char[$i] = '@{[Ekoi8u::ignorecase(' . $1 . ')]}';
7067             }
7068             }
7069              
7070 0         0 # ${ ... }
7071 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7072 0         0 $char[$i] = e_capture($1);
7073             if ($ignorecase) {
7074             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7075             }
7076             }
7077              
7078 0         0 # $scalar or @array
7079 3 50       8 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7080 3         12 $char[$i] = e_string($char[$i]);
7081             if ($ignorecase) {
7082             $char[$i] = '@{[Ekoi8u::ignorecase(' . $char[$i] . ')]}';
7083             }
7084             }
7085              
7086 0 50       0 # quote character before ? + * {
7087             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7088             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7089 1         8 }
7090             else {
7091             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7092             }
7093             }
7094             }
7095 0         0  
7096 74 50       139 # make regexp string
7097 74         165 $modifier =~ tr/i//d;
7098             if ($left_e > $right_e) {
7099 0         0 return join '', 'Ekoi8u::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7100             }
7101             return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7102             }
7103              
7104             #
7105             # escape regexp of split qr''
7106 74     0 0 730 #
7107 0   0       sub e_split_q {
7108             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7109 0           $modifier ||= '';
7110 0 0          
7111 0           $modifier =~ tr/p//d;
7112 0           if ($modifier =~ /([adlu])/oxms) {
7113 0 0         my $line = 0;
7114 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7115 0           if ($filename ne __FILE__) {
7116             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7117             last;
7118 0           }
7119             }
7120             die qq{Unsupported modifier "$1" used at line $line.\n};
7121 0           }
7122              
7123             $slash = 'div';
7124 0 0          
7125 0           # /b /B modifier
7126             if ($modifier =~ tr/bB//d) {
7127             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7128 0 0         }
7129              
7130             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7131 0            
7132             # split regexp
7133             my @char = $string =~ /\G((?>
7134             [^\\\[] |
7135             [\x00-\xFF] |
7136             \[\^ |
7137             \[\: (?>[a-z]+) \:\] |
7138             \[\:\^ (?>[a-z]+) \:\] |
7139             \\ (?:$q_char) |
7140             (?:$q_char)
7141             ))/oxmsg;
7142 0            
7143 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7144             for (my $i=0; $i <= $#char; $i++) {
7145             if (0) {
7146             }
7147 0            
7148 0           # open character class [...]
7149 0 0         elsif ($char[$i] eq '[') {
7150 0           my $left = $i;
7151             if ($char[$i+1] eq ']') {
7152 0           $i++;
7153 0 0         }
7154 0           while (1) {
7155             if (++$i > $#char) {
7156 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7157 0           }
7158             if ($char[$i] eq ']') {
7159             my $right = $i;
7160 0            
7161             # [...]
7162 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_qr(@char[$left+1..$right-1], $modifier);
7163 0            
7164             $i = $left;
7165             last;
7166             }
7167             }
7168             }
7169              
7170 0           # open character class [^...]
7171 0 0         elsif ($char[$i] eq '[^') {
7172 0           my $left = $i;
7173             if ($char[$i+1] eq ']') {
7174 0           $i++;
7175 0 0         }
7176 0           while (1) {
7177             if (++$i > $#char) {
7178 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7179 0           }
7180             if ($char[$i] eq ']') {
7181             my $right = $i;
7182 0            
7183             # [^...]
7184 0           splice @char, $left, $right-$left+1, Ekoi8u::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7185 0            
7186             $i = $left;
7187             last;
7188             }
7189             }
7190             }
7191              
7192 0           # rewrite character class or escape character
7193             elsif (my $char = character_class($char[$i],$modifier)) {
7194             $char[$i] = $char;
7195             }
7196              
7197 0           # split(m/^/) --> split(m/^/m)
7198             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7199             $modifier .= 'm';
7200             }
7201              
7202 0 0         # /i modifier
7203 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8u::uc($char[$i]) ne Ekoi8u::fc($char[$i]))) {
7204             if (CORE::length(Ekoi8u::fc($char[$i])) == 1) {
7205             $char[$i] = '[' . Ekoi8u::uc($char[$i]) . Ekoi8u::fc($char[$i]) . ']';
7206 0           }
7207             else {
7208             $char[$i] = '(?:' . Ekoi8u::uc($char[$i]) . '|' . Ekoi8u::fc($char[$i]) . ')';
7209             }
7210             }
7211              
7212 0 0         # quote character before ? + * {
7213             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7214             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7215 0           }
7216             else {
7217             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7218             }
7219             }
7220 0           }
7221 0            
7222             $modifier =~ tr/i//d;
7223             return join '', 'Ekoi8u::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7224             }
7225              
7226             #
7227             # instead of Carp::carp
7228 0     0 0   #
7229 0           sub carp {
7230             my($package,$filename,$line) = caller(1);
7231             print STDERR "@_ at $filename line $line.\n";
7232             }
7233              
7234             #
7235             # instead of Carp::croak
7236 0     0 0   #
7237 0           sub croak {
7238 0           my($package,$filename,$line) = caller(1);
7239             print STDERR "@_ at $filename line $line.\n";
7240             die "\n";
7241             }
7242              
7243             #
7244             # instead of Carp::cluck
7245 0     0 0   #
7246 0           sub cluck {
7247 0           my $i = 0;
7248 0           my @cluck = ();
7249 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7250             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7251 0           $i++;
7252 0           }
7253 0           print STDERR CORE::reverse @cluck;
7254             print STDERR "\n";
7255             print STDERR @_;
7256             }
7257              
7258             #
7259             # instead of Carp::confess
7260 0     0 0   #
7261 0           sub confess {
7262 0           my $i = 0;
7263 0           my @confess = ();
7264 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7265             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7266 0           $i++;
7267 0           }
7268 0           print STDERR CORE::reverse @confess;
7269 0           print STDERR "\n";
7270             print STDERR @_;
7271             die "\n";
7272             }
7273              
7274             1;
7275              
7276             __END__