File Coverage

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


line stmt bran cond sub pod time code
1             package Ekoi8r;
2 204     204   1169 use strict;
  204         357  
  204         6657  
3             ######################################################################
4             #
5             # Ekoi8r - Run-time routines for KOI8R.pm
6             #
7             # http://search.cpan.org/dist/Char-KOI8R/
8             #
9             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
10             ######################################################################
11              
12 204     204   3016 use 5.00503; # Galapagos Consensus 1998 for primetools
  204         789  
13             # use 5.008001; # Lancaster Consensus 2013 for toolchains
14              
15             # 12.3. Delaying use Until Runtime
16             # in Chapter 12. Packages, Libraries, and Modules
17             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
18             # (and so on)
19              
20             # Version numbers should be boring
21             # http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
22             # For the impatient, the disinterested or those who just want to follow
23             # a recipe, my advice for all modules is this:
24             # our $VERSION = "0.001"; # or "0.001_001" for a dev release
25             # $VERSION = eval $VERSION; # No!! because '1.10' makes '1.1'
26              
27 204     204   1493 use vars qw($VERSION);
  204         459  
  204         28945  
28             $VERSION = '1.15';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 204 50   204   2565 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 204         413 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 204         28391 if (CORE::ord('A') != 0x41) {
39             die __FILE__, ": is not US-ASCII script (must be US-ASCII script).\n";
40             }
41             }
42              
43             BEGIN {
44              
45             # instead of utf8.pm
46 204     204   34438 CORE::eval q{
  204     204   1573  
  204     74   446  
  204         25881  
  0         0  
  0         0  
  0         0  
  0         0  
47             no warnings qw(redefine);
48             *utf8::upgrade = sub { CORE::length $_[0] };
49             *utf8::downgrade = sub { 1 };
50             *utf8::encode = sub { };
51             *utf8::decode = sub { 1 };
52             *utf8::is_utf8 = sub { };
53             *utf8::valid = sub { 1 };
54             };
55 204 50       77977 if ($@) {
56 0         0 *utf8::upgrade = sub { CORE::length $_[0] };
  0         0  
57 0         0 *utf8::downgrade = sub { 1 };
  0         0  
58 0         0 *utf8::encode = sub { };
59 0         0 *utf8::decode = sub { 1 };
  0         0  
60 0         0 *utf8::is_utf8 = sub { };
61 0         0 *utf8::valid = sub { 1 };
  0         0  
62             }
63             }
64              
65             # instead of Symbol.pm
66 0         0 BEGIN {
67             sub gensym () {
68 0 0   0 0 0 if ($] < 5.006) {
69 0         0 return \do { local *_ };
  0         0  
70             }
71             else {
72 0         0 return undef;
73             }
74             }
75              
76             sub qualify ($$) {
77 0     0 0 0 my($name) = @_;
78              
79 0 0       0 if (ref $name) {
    0          
    0          
    0          
    0          
    0          
    0          
80 0         0 return $name;
81             }
82             elsif (Ekoi8r::index($name,'::') >= 0) {
83 0         0 return $name;
84             }
85             elsif (Ekoi8r::index($name,"'") >= 0) {
86 0         0 return $name;
87             }
88              
89             # special character, "^xyz"
90             elsif ($name =~ /\A \^ [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+ \z/x) {
91              
92             # RGS 2001-11-05 : translate leading ^X to control-char
93 0         0 $name =~ s{\A \^ ([ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]) }{'qq(\c'.$1.')'}xee;
  0         0  
94 0         0 return 'main::' . $name;
95             }
96              
97             # Global names
98             elsif ($name =~ /\A (?: ARGV | ARGVOUT | ENV | INC | SIG | STDERR | STDIN | STDOUT ) \z/x) {
99 0         0 return 'main::' . $name;
100             }
101              
102             # or other
103             elsif ($name =~ /\A [^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz] \z/x) {
104 0         0 return 'main::' . $name;
105             }
106              
107             elsif (defined $_[1]) {
108 0         0 return $_[1] . '::' . $name;
109             }
110             else {
111 0         0 return (caller)[0] . '::' . $name;
112             }
113             }
114              
115             sub qualify_to_ref ($;$) {
116 0 0   0 0 0 if (defined $_[1]) {
117 204     204   2671 no strict qw(refs);
  204         531  
  204         28501  
118 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
119             }
120             else {
121 204     204   1659 no strict qw(refs);
  204     0   366  
  204         37568  
122 0         0 return \*{ qualify $_[0], (caller)[0] };
  0         0  
123             }
124             }
125             }
126              
127             # P.714 29.2.39. flock
128             # in Chapter 29: Functions
129             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
130              
131             # P.863 flock
132             # in Chapter 27: Functions
133             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
134              
135             sub LOCK_SH() {1}
136             sub LOCK_EX() {2}
137             sub LOCK_UN() {8}
138             sub LOCK_NB() {4}
139              
140             # instead of Carp.pm
141             sub carp;
142             sub croak;
143             sub cluck;
144             sub confess;
145              
146             # 6.18. Matching Multiple-Byte Characters
147             # in Chapter 6. Pattern Matching
148             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
149             # (and so on)
150              
151             # regexp of character
152             my $your_char = q{[\x00-\xFF]};
153 204     204   1638 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  204         350  
  204         14528  
154 204     204   1438 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  204         374  
  204         387901  
155              
156             #
157             # KOI8-R character range per length
158             #
159             my %range_tr = ();
160              
161             #
162             # KOI8-R case conversion
163             #
164             my %lc = ();
165             @lc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
166             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
167             my %uc = ();
168             @uc{qw(a b c d e f g h i j k l m n o p q r s t u v w x y z)} =
169             qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
170             my %fc = ();
171             @fc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
172             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
173              
174             if (0) {
175             }
176              
177             elsif (__PACKAGE__ =~ / \b Ekoi8r \z/oxms) {
178             %range_tr = (
179             1 => [ [0x00..0xFF],
180             ],
181             );
182              
183             %lc = (%lc,
184             "\xB3" => "\xA3", # CYRILLIC LETTER IO
185             "\xE0" => "\xC0", # CYRILLIC LETTER IU
186             "\xE1" => "\xC1", # CYRILLIC LETTER A
187             "\xE2" => "\xC2", # CYRILLIC LETTER BE
188             "\xE3" => "\xC3", # CYRILLIC LETTER TSE
189             "\xE4" => "\xC4", # CYRILLIC LETTER DE
190             "\xE5" => "\xC5", # CYRILLIC LETTER IE
191             "\xE6" => "\xC6", # CYRILLIC LETTER EF
192             "\xE7" => "\xC7", # CYRILLIC LETTER GE
193             "\xE8" => "\xC8", # CYRILLIC LETTER KHA
194             "\xE9" => "\xC9", # CYRILLIC LETTER II
195             "\xEA" => "\xCA", # CYRILLIC LETTER SHORT II
196             "\xEB" => "\xCB", # CYRILLIC LETTER KA
197             "\xEC" => "\xCC", # CYRILLIC LETTER EL
198             "\xED" => "\xCD", # CYRILLIC LETTER EM
199             "\xEE" => "\xCE", # CYRILLIC LETTER EN
200             "\xEF" => "\xCF", # CYRILLIC LETTER O
201             "\xF0" => "\xD0", # CYRILLIC LETTER PE
202             "\xF1" => "\xD1", # CYRILLIC LETTER IA
203             "\xF2" => "\xD2", # CYRILLIC LETTER ER
204             "\xF3" => "\xD3", # CYRILLIC LETTER ES
205             "\xF4" => "\xD4", # CYRILLIC LETTER TE
206             "\xF5" => "\xD5", # CYRILLIC LETTER U
207             "\xF6" => "\xD6", # CYRILLIC LETTER ZHE
208             "\xF7" => "\xD7", # CYRILLIC LETTER VE
209             "\xF8" => "\xD8", # CYRILLIC LETTER SOFT SIGN
210             "\xF9" => "\xD9", # CYRILLIC LETTER YERI
211             "\xFA" => "\xDA", # CYRILLIC LETTER ZE
212             "\xFB" => "\xDB", # CYRILLIC LETTER SHA
213             "\xFC" => "\xDC", # CYRILLIC LETTER REVERSED E
214             "\xFD" => "\xDD", # CYRILLIC LETTER SHCHA
215             "\xFE" => "\xDE", # CYRILLIC LETTER CHE
216             "\xFF" => "\xDF", # CYRILLIC LETTER HARD SIGN
217             );
218              
219             %uc = (%uc,
220             "\xA3" => "\xB3", # CYRILLIC LETTER IO
221             "\xC0" => "\xE0", # CYRILLIC LETTER IU
222             "\xC1" => "\xE1", # CYRILLIC LETTER A
223             "\xC2" => "\xE2", # CYRILLIC LETTER BE
224             "\xC3" => "\xE3", # CYRILLIC LETTER TSE
225             "\xC4" => "\xE4", # CYRILLIC LETTER DE
226             "\xC5" => "\xE5", # CYRILLIC LETTER IE
227             "\xC6" => "\xE6", # CYRILLIC LETTER EF
228             "\xC7" => "\xE7", # CYRILLIC LETTER GE
229             "\xC8" => "\xE8", # CYRILLIC LETTER KHA
230             "\xC9" => "\xE9", # CYRILLIC LETTER II
231             "\xCA" => "\xEA", # CYRILLIC LETTER SHORT II
232             "\xCB" => "\xEB", # CYRILLIC LETTER KA
233             "\xCC" => "\xEC", # CYRILLIC LETTER EL
234             "\xCD" => "\xED", # CYRILLIC LETTER EM
235             "\xCE" => "\xEE", # CYRILLIC LETTER EN
236             "\xCF" => "\xEF", # CYRILLIC LETTER O
237             "\xD0" => "\xF0", # CYRILLIC LETTER PE
238             "\xD1" => "\xF1", # CYRILLIC LETTER IA
239             "\xD2" => "\xF2", # CYRILLIC LETTER ER
240             "\xD3" => "\xF3", # CYRILLIC LETTER ES
241             "\xD4" => "\xF4", # CYRILLIC LETTER TE
242             "\xD5" => "\xF5", # CYRILLIC LETTER U
243             "\xD6" => "\xF6", # CYRILLIC LETTER ZHE
244             "\xD7" => "\xF7", # CYRILLIC LETTER VE
245             "\xD8" => "\xF8", # CYRILLIC LETTER SOFT SIGN
246             "\xD9" => "\xF9", # CYRILLIC LETTER YERI
247             "\xDA" => "\xFA", # CYRILLIC LETTER ZE
248             "\xDB" => "\xFB", # CYRILLIC LETTER SHA
249             "\xDC" => "\xFC", # CYRILLIC LETTER REVERSED E
250             "\xDD" => "\xFD", # CYRILLIC LETTER SHCHA
251             "\xDE" => "\xFE", # CYRILLIC LETTER CHE
252             "\xDF" => "\xFF", # CYRILLIC LETTER HARD SIGN
253             );
254              
255             %fc = (%fc,
256             "\xB3" => "\xA3", # CYRILLIC CAPITAL LETTER IO --> CYRILLIC SMALL LETTER IO
257             "\xE0" => "\xC0", # CYRILLIC CAPITAL LETTER YU --> CYRILLIC SMALL LETTER YU
258             "\xE1" => "\xC1", # CYRILLIC CAPITAL LETTER A --> CYRILLIC SMALL LETTER A
259             "\xE2" => "\xC2", # CYRILLIC CAPITAL LETTER BE --> CYRILLIC SMALL LETTER BE
260             "\xE3" => "\xC3", # CYRILLIC CAPITAL LETTER TSE --> CYRILLIC SMALL LETTER TSE
261             "\xE4" => "\xC4", # CYRILLIC CAPITAL LETTER DE --> CYRILLIC SMALL LETTER DE
262             "\xE5" => "\xC5", # CYRILLIC CAPITAL LETTER IE --> CYRILLIC SMALL LETTER IE
263             "\xE6" => "\xC6", # CYRILLIC CAPITAL LETTER EF --> CYRILLIC SMALL LETTER EF
264             "\xE7" => "\xC7", # CYRILLIC CAPITAL LETTER GHE --> CYRILLIC SMALL LETTER GHE
265             "\xE8" => "\xC8", # CYRILLIC CAPITAL LETTER HA --> CYRILLIC SMALL LETTER HA
266             "\xE9" => "\xC9", # CYRILLIC CAPITAL LETTER I --> CYRILLIC SMALL LETTER I
267             "\xEA" => "\xCA", # CYRILLIC CAPITAL LETTER SHORT I --> CYRILLIC SMALL LETTER SHORT I
268             "\xEB" => "\xCB", # CYRILLIC CAPITAL LETTER KA --> CYRILLIC SMALL LETTER KA
269             "\xEC" => "\xCC", # CYRILLIC CAPITAL LETTER EL --> CYRILLIC SMALL LETTER EL
270             "\xED" => "\xCD", # CYRILLIC CAPITAL LETTER EM --> CYRILLIC SMALL LETTER EM
271             "\xEE" => "\xCE", # CYRILLIC CAPITAL LETTER EN --> CYRILLIC SMALL LETTER EN
272             "\xEF" => "\xCF", # CYRILLIC CAPITAL LETTER O --> CYRILLIC SMALL LETTER O
273             "\xF0" => "\xD0", # CYRILLIC CAPITAL LETTER PE --> CYRILLIC SMALL LETTER PE
274             "\xF1" => "\xD1", # CYRILLIC CAPITAL LETTER YA --> CYRILLIC SMALL LETTER YA
275             "\xF2" => "\xD2", # CYRILLIC CAPITAL LETTER ER --> CYRILLIC SMALL LETTER ER
276             "\xF3" => "\xD3", # CYRILLIC CAPITAL LETTER ES --> CYRILLIC SMALL LETTER ES
277             "\xF4" => "\xD4", # CYRILLIC CAPITAL LETTER TE --> CYRILLIC SMALL LETTER TE
278             "\xF5" => "\xD5", # CYRILLIC CAPITAL LETTER U --> CYRILLIC SMALL LETTER U
279             "\xF6" => "\xD6", # CYRILLIC CAPITAL LETTER ZHE --> CYRILLIC SMALL LETTER ZHE
280             "\xF7" => "\xD7", # CYRILLIC CAPITAL LETTER VE --> CYRILLIC SMALL LETTER VE
281             "\xF8" => "\xD8", # CYRILLIC CAPITAL LETTER SOFT SIGN --> CYRILLIC SMALL LETTER SOFT SIGN
282             "\xF9" => "\xD9", # CYRILLIC CAPITAL LETTER YERU --> CYRILLIC SMALL LETTER YERU
283             "\xFA" => "\xDA", # CYRILLIC CAPITAL LETTER ZE --> CYRILLIC SMALL LETTER ZE
284             "\xFB" => "\xDB", # CYRILLIC CAPITAL LETTER SHA --> CYRILLIC SMALL LETTER SHA
285             "\xFC" => "\xDC", # CYRILLIC CAPITAL LETTER E --> CYRILLIC SMALL LETTER E
286             "\xFD" => "\xDD", # CYRILLIC CAPITAL LETTER SHCHA --> CYRILLIC SMALL LETTER SHCHA
287             "\xFE" => "\xDE", # CYRILLIC CAPITAL LETTER CHE --> CYRILLIC SMALL LETTER CHE
288             "\xFF" => "\xDF", # CYRILLIC CAPITAL LETTER HARD SIGN --> CYRILLIC SMALL LETTER HARD SIGN
289             );
290             }
291              
292             else {
293             croak "Don't know my package name '@{[__PACKAGE__]}'";
294             }
295              
296             #
297             # @ARGV wildcard globbing
298             #
299             sub import {
300              
301 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
302 0         0 my @argv = ();
303 0         0 for (@ARGV) {
304              
305             # has space
306 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
307 0 0       0 if (my @glob = Ekoi8r::glob(qq{"$_"})) {
308 0         0 push @argv, @glob;
309             }
310             else {
311 0         0 push @argv, $_;
312             }
313             }
314              
315             # has wildcard metachar
316             elsif (/\A (?:$q_char)*? [*?] /oxms) {
317 0 0       0 if (my @glob = Ekoi8r::glob($_)) {
318 0         0 push @argv, @glob;
319             }
320             else {
321 0         0 push @argv, $_;
322             }
323             }
324              
325             # no wildcard globbing
326             else {
327 0         0 push @argv, $_;
328             }
329             }
330 0         0 @ARGV = @argv;
331             }
332              
333 0         0 *Char::ord = \&KOI8R::ord;
334 0         0 *Char::ord_ = \&KOI8R::ord_;
335 0         0 *Char::reverse = \&KOI8R::reverse;
336 0         0 *Char::getc = \&KOI8R::getc;
337 0         0 *Char::length = \&KOI8R::length;
338 0         0 *Char::substr = \&KOI8R::substr;
339 0         0 *Char::index = \&KOI8R::index;
340 0         0 *Char::rindex = \&KOI8R::rindex;
341 0         0 *Char::eval = \&KOI8R::eval;
342 0         0 *Char::escape = \&KOI8R::escape;
343 0         0 *Char::escape_token = \&KOI8R::escape_token;
344 0         0 *Char::escape_script = \&KOI8R::escape_script;
345             }
346              
347             # P.230 Care with Prototypes
348             # in Chapter 6: Subroutines
349             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
350             #
351             # If you aren't careful, you can get yourself into trouble with prototypes.
352             # But if you are careful, you can do a lot of neat things with them. This is
353             # all very powerful, of course, and should only be used in moderation to make
354             # the world a better place.
355              
356             # P.332 Care with Prototypes
357             # in Chapter 7: Subroutines
358             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
359             #
360             # If you aren't careful, you can get yourself into trouble with prototypes.
361             # But if you are careful, you can do a lot of neat things with them. This is
362             # all very powerful, of course, and should only be used in moderation to make
363             # the world a better place.
364              
365             #
366             # Prototypes of subroutines
367             #
368       0     sub unimport {}
369             sub Ekoi8r::split(;$$$);
370             sub Ekoi8r::tr($$$$;$);
371             sub Ekoi8r::chop(@);
372             sub Ekoi8r::index($$;$);
373             sub Ekoi8r::rindex($$;$);
374             sub Ekoi8r::lcfirst(@);
375             sub Ekoi8r::lcfirst_();
376             sub Ekoi8r::lc(@);
377             sub Ekoi8r::lc_();
378             sub Ekoi8r::ucfirst(@);
379             sub Ekoi8r::ucfirst_();
380             sub Ekoi8r::uc(@);
381             sub Ekoi8r::uc_();
382             sub Ekoi8r::fc(@);
383             sub Ekoi8r::fc_();
384             sub Ekoi8r::ignorecase;
385             sub Ekoi8r::classic_character_class;
386             sub Ekoi8r::capture;
387             sub Ekoi8r::chr(;$);
388             sub Ekoi8r::chr_();
389             sub Ekoi8r::glob($);
390             sub Ekoi8r::glob_();
391              
392             sub KOI8R::ord(;$);
393             sub KOI8R::ord_();
394             sub KOI8R::reverse(@);
395             sub KOI8R::getc(;*@);
396             sub KOI8R::length(;$);
397             sub KOI8R::substr($$;$$);
398             sub KOI8R::index($$;$);
399             sub KOI8R::rindex($$;$);
400             sub KOI8R::escape(;$);
401              
402             #
403             # Regexp work
404             #
405 204         21753 use vars qw(
406             $re_a
407             $re_t
408             $re_n
409             $re_r
410 204     204   1933 );
  204         480  
411              
412             #
413             # Character class
414             #
415 204         2151498 use vars qw(
416             $dot
417             $dot_s
418             $eD
419             $eS
420             $eW
421             $eH
422             $eV
423             $eR
424             $eN
425             $not_alnum
426             $not_alpha
427             $not_ascii
428             $not_blank
429             $not_cntrl
430             $not_digit
431             $not_graph
432             $not_lower
433             $not_lower_i
434             $not_print
435             $not_punct
436             $not_space
437             $not_upper
438             $not_upper_i
439             $not_word
440             $not_xdigit
441             $eb
442             $eB
443 204     204   1624 );
  204         394  
444              
445             ${Ekoi8r::dot} = qr{(?>[^\x0A])};
446             ${Ekoi8r::dot_s} = qr{(?>[\x00-\xFF])};
447             ${Ekoi8r::eD} = qr{(?>[^0-9])};
448              
449             # Vertical tabs are now whitespace
450             # \s in a regex now matches a vertical tab in all circumstances.
451             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
452             # ${Ekoi8r::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
453             # ${Ekoi8r::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
454             ${Ekoi8r::eS} = qr{(?>[^\s])};
455              
456             ${Ekoi8r::eW} = qr{(?>[^0-9A-Z_a-z])};
457             ${Ekoi8r::eH} = qr{(?>[^\x09\x20])};
458             ${Ekoi8r::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
459             ${Ekoi8r::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
460             ${Ekoi8r::eN} = qr{(?>[^\x0A])};
461             ${Ekoi8r::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
462             ${Ekoi8r::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
463             ${Ekoi8r::not_ascii} = qr{(?>[^\x00-\x7F])};
464             ${Ekoi8r::not_blank} = qr{(?>[^\x09\x20])};
465             ${Ekoi8r::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
466             ${Ekoi8r::not_digit} = qr{(?>[^\x30-\x39])};
467             ${Ekoi8r::not_graph} = qr{(?>[^\x21-\x7F])};
468             ${Ekoi8r::not_lower} = qr{(?>[^\x61-\x7A])};
469             ${Ekoi8r::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
470             # ${Ekoi8r::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
471             ${Ekoi8r::not_print} = qr{(?>[^\x20-\x7F])};
472             ${Ekoi8r::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
473             ${Ekoi8r::not_space} = qr{(?>[^\s\x0B])};
474             ${Ekoi8r::not_upper} = qr{(?>[^\x41-\x5A])};
475             ${Ekoi8r::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
476             # ${Ekoi8r::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
477             ${Ekoi8r::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
478             ${Ekoi8r::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
479             ${Ekoi8r::eb} = qr{(?:\A(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[0-9A-Z_a-z])|(?<=[0-9A-Z_a-z])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]|\z))};
480             ${Ekoi8r::eB} = qr{(?:(?<=[0-9A-Z_a-z])(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]))};
481              
482             # avoid: Name "Ekoi8r::foo" used only once: possible typo at here.
483             ${Ekoi8r::dot} = ${Ekoi8r::dot};
484             ${Ekoi8r::dot_s} = ${Ekoi8r::dot_s};
485             ${Ekoi8r::eD} = ${Ekoi8r::eD};
486             ${Ekoi8r::eS} = ${Ekoi8r::eS};
487             ${Ekoi8r::eW} = ${Ekoi8r::eW};
488             ${Ekoi8r::eH} = ${Ekoi8r::eH};
489             ${Ekoi8r::eV} = ${Ekoi8r::eV};
490             ${Ekoi8r::eR} = ${Ekoi8r::eR};
491             ${Ekoi8r::eN} = ${Ekoi8r::eN};
492             ${Ekoi8r::not_alnum} = ${Ekoi8r::not_alnum};
493             ${Ekoi8r::not_alpha} = ${Ekoi8r::not_alpha};
494             ${Ekoi8r::not_ascii} = ${Ekoi8r::not_ascii};
495             ${Ekoi8r::not_blank} = ${Ekoi8r::not_blank};
496             ${Ekoi8r::not_cntrl} = ${Ekoi8r::not_cntrl};
497             ${Ekoi8r::not_digit} = ${Ekoi8r::not_digit};
498             ${Ekoi8r::not_graph} = ${Ekoi8r::not_graph};
499             ${Ekoi8r::not_lower} = ${Ekoi8r::not_lower};
500             ${Ekoi8r::not_lower_i} = ${Ekoi8r::not_lower_i};
501             ${Ekoi8r::not_print} = ${Ekoi8r::not_print};
502             ${Ekoi8r::not_punct} = ${Ekoi8r::not_punct};
503             ${Ekoi8r::not_space} = ${Ekoi8r::not_space};
504             ${Ekoi8r::not_upper} = ${Ekoi8r::not_upper};
505             ${Ekoi8r::not_upper_i} = ${Ekoi8r::not_upper_i};
506             ${Ekoi8r::not_word} = ${Ekoi8r::not_word};
507             ${Ekoi8r::not_xdigit} = ${Ekoi8r::not_xdigit};
508             ${Ekoi8r::eb} = ${Ekoi8r::eb};
509             ${Ekoi8r::eB} = ${Ekoi8r::eB};
510              
511             #
512             # KOI8-R split
513             #
514             sub Ekoi8r::split(;$$$) {
515              
516             # P.794 29.2.161. split
517             # in Chapter 29: Functions
518             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
519              
520             # P.951 split
521             # in Chapter 27: Functions
522             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
523              
524 0     0 0 0 my $pattern = $_[0];
525 0         0 my $string = $_[1];
526 0         0 my $limit = $_[2];
527              
528             # if $pattern is also omitted or is the literal space, " "
529 0 0       0 if (not defined $pattern) {
530 0         0 $pattern = ' ';
531             }
532              
533             # if $string is omitted, the function splits the $_ string
534 0 0       0 if (not defined $string) {
535 0 0       0 if (defined $_) {
536 0         0 $string = $_;
537             }
538             else {
539 0         0 $string = '';
540             }
541             }
542              
543 0         0 my @split = ();
544              
545             # when string is empty
546 0 0       0 if ($string eq '') {
    0          
547              
548             # resulting list value in list context
549 0 0       0 if (wantarray) {
550 0         0 return @split;
551             }
552              
553             # count of substrings in scalar context
554             else {
555 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
556 0         0 @_ = @split;
557 0         0 return scalar @_;
558             }
559             }
560              
561             # split's first argument is more consistently interpreted
562             #
563             # After some changes earlier in v5.17, split's behavior has been simplified:
564             # if the PATTERN argument evaluates to a string containing one space, it is
565             # treated the way that a literal string containing one space once was.
566             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
567              
568             # if $pattern is also omitted or is the literal space, " ", the function splits
569             # on whitespace, /\s+/, after skipping any leading whitespace
570             # (and so on)
571              
572             elsif ($pattern eq ' ') {
573 0 0       0 if (not defined $limit) {
574 0         0 return CORE::split(' ', $string);
575             }
576             else {
577 0         0 return CORE::split(' ', $string, $limit);
578             }
579             }
580              
581             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
582 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
583              
584             # a pattern capable of matching either the null string or something longer than the
585             # null string will split the value of $string into separate characters wherever it
586             # matches the null string between characters
587             # (and so on)
588              
589 0 0       0 if ('' =~ / \A $pattern \z /xms) {
590 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
591 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
592              
593             # P.1024 Appendix W.10 Multibyte Processing
594             # of ISBN 1-56592-224-7 CJKV Information Processing
595             # (and so on)
596              
597             # the //m modifier is assumed when you split on the pattern /^/
598             # (and so on)
599              
600             # V
601 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
602              
603             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
604             # is included in the resulting list, interspersed with the fields that are ordinarily returned
605             # (and so on)
606              
607 0         0 local $@;
608 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
609 0         0 push @split, CORE::eval('$' . $digit);
610             }
611             }
612             }
613              
614             else {
615 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
616              
617             # V
618 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
619 0         0 local $@;
620 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
621 0         0 push @split, CORE::eval('$' . $digit);
622             }
623             }
624             }
625             }
626              
627             elsif ($limit > 0) {
628 0 0       0 if ('' =~ / \A $pattern \z /xms) {
629 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
630 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
631              
632             # V
633 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
634 0         0 local $@;
635 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
636 0         0 push @split, CORE::eval('$' . $digit);
637             }
638             }
639             }
640             }
641             else {
642 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
643 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
644              
645             # V
646 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
647 0         0 local $@;
648 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
649 0         0 push @split, CORE::eval('$' . $digit);
650             }
651             }
652             }
653             }
654             }
655              
656 0 0       0 if (CORE::length($string) > 0) {
657 0         0 push @split, $string;
658             }
659              
660             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
661 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
662 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
663 0         0 pop @split;
664             }
665             }
666              
667             # resulting list value in list context
668 0 0       0 if (wantarray) {
669 0         0 return @split;
670             }
671              
672             # count of substrings in scalar context
673             else {
674 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
675 0         0 @_ = @split;
676 0         0 return scalar @_;
677             }
678             }
679              
680             #
681             # get last subexpression offsets
682             #
683             sub _last_subexpression_offsets {
684 0     0   0 my $pattern = $_[0];
685              
686             # remove comment
687 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
688              
689 0         0 my $modifier = '';
690 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
691 0         0 $modifier = $1;
692 0         0 $modifier =~ s/-[A-Za-z]*//;
693             }
694              
695             # with /x modifier
696 0         0 my @char = ();
697 0 0       0 if ($modifier =~ /x/oxms) {
698 0         0 @char = $pattern =~ /\G((?>
699             [^\\\#\[\(] |
700             \\ $q_char |
701             \# (?>[^\n]*) $ |
702             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
703             \(\? |
704             $q_char
705             ))/oxmsg;
706             }
707              
708             # without /x modifier
709             else {
710 0         0 @char = $pattern =~ /\G((?>
711             [^\\\[\(] |
712             \\ $q_char |
713             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
714             \(\? |
715             $q_char
716             ))/oxmsg;
717             }
718              
719 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
720             }
721              
722             #
723             # KOI8-R transliteration (tr///)
724             #
725             sub Ekoi8r::tr($$$$;$) {
726              
727 0     0 0 0 my $bind_operator = $_[1];
728 0         0 my $searchlist = $_[2];
729 0         0 my $replacementlist = $_[3];
730 0   0     0 my $modifier = $_[4] || '';
731              
732 0 0       0 if ($modifier =~ /r/oxms) {
733 0 0       0 if ($bind_operator =~ / !~ /oxms) {
734 0         0 croak "Using !~ with tr///r doesn't make sense";
735             }
736             }
737              
738 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
739 0         0 my @searchlist = _charlist_tr($searchlist);
740 0         0 my @replacementlist = _charlist_tr($replacementlist);
741              
742 0         0 my %tr = ();
743 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
744 0 0       0 if (not exists $tr{$searchlist[$i]}) {
745 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
746 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
747             }
748             elsif ($modifier =~ /d/oxms) {
749 0         0 $tr{$searchlist[$i]} = '';
750             }
751             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
752 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
753             }
754             else {
755 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
756             }
757             }
758             }
759              
760 0         0 my $tr = 0;
761 0         0 my $replaced = '';
762 0 0       0 if ($modifier =~ /c/oxms) {
763 0         0 while (defined(my $char = shift @char)) {
764 0 0       0 if (not exists $tr{$char}) {
765 0 0       0 if (defined $replacementlist[0]) {
766 0         0 $replaced .= $replacementlist[0];
767             }
768 0         0 $tr++;
769 0 0       0 if ($modifier =~ /s/oxms) {
770 0   0     0 while (@char and (not exists $tr{$char[0]})) {
771 0         0 shift @char;
772 0         0 $tr++;
773             }
774             }
775             }
776             else {
777 0         0 $replaced .= $char;
778             }
779             }
780             }
781             else {
782 0         0 while (defined(my $char = shift @char)) {
783 0 0       0 if (exists $tr{$char}) {
784 0         0 $replaced .= $tr{$char};
785 0         0 $tr++;
786 0 0       0 if ($modifier =~ /s/oxms) {
787 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
788 0         0 shift @char;
789 0         0 $tr++;
790             }
791             }
792             }
793             else {
794 0         0 $replaced .= $char;
795             }
796             }
797             }
798              
799 0 0       0 if ($modifier =~ /r/oxms) {
800 0         0 return $replaced;
801             }
802             else {
803 0         0 $_[0] = $replaced;
804 0 0       0 if ($bind_operator =~ / !~ /oxms) {
805 0         0 return not $tr;
806             }
807             else {
808 0         0 return $tr;
809             }
810             }
811             }
812              
813             #
814             # KOI8-R chop
815             #
816             sub Ekoi8r::chop(@) {
817              
818 0     0 0 0 my $chop;
819 0 0       0 if (@_ == 0) {
820 0         0 my @char = /\G (?>$q_char) /oxmsg;
821 0         0 $chop = pop @char;
822 0         0 $_ = join '', @char;
823             }
824             else {
825 0         0 for (@_) {
826 0         0 my @char = /\G (?>$q_char) /oxmsg;
827 0         0 $chop = pop @char;
828 0         0 $_ = join '', @char;
829             }
830             }
831 0         0 return $chop;
832             }
833              
834             #
835             # KOI8-R index by octet
836             #
837             sub Ekoi8r::index($$;$) {
838              
839 0     0 1 0 my($str,$substr,$position) = @_;
840 0   0     0 $position ||= 0;
841 0         0 my $pos = 0;
842              
843 0         0 while ($pos < CORE::length($str)) {
844 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
845 0 0       0 if ($pos >= $position) {
846 0         0 return $pos;
847             }
848             }
849 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
850 0         0 $pos += CORE::length($1);
851             }
852             else {
853 0         0 $pos += 1;
854             }
855             }
856 0         0 return -1;
857             }
858              
859             #
860             # KOI8-R reverse index
861             #
862             sub Ekoi8r::rindex($$;$) {
863              
864 0     0 0 0 my($str,$substr,$position) = @_;
865 0   0     0 $position ||= CORE::length($str) - 1;
866 0         0 my $pos = 0;
867 0         0 my $rindex = -1;
868              
869 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
870 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
871 0         0 $rindex = $pos;
872             }
873 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
874 0         0 $pos += CORE::length($1);
875             }
876             else {
877 0         0 $pos += 1;
878             }
879             }
880 0         0 return $rindex;
881             }
882              
883             #
884             # KOI8-R lower case first with parameter
885             #
886             sub Ekoi8r::lcfirst(@) {
887 0 0   0 0 0 if (@_) {
888 0         0 my $s = shift @_;
889 0 0 0     0 if (@_ and wantarray) {
890 0         0 return Ekoi8r::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
891             }
892             else {
893 0         0 return Ekoi8r::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
894             }
895             }
896             else {
897 0         0 return Ekoi8r::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
898             }
899             }
900              
901             #
902             # KOI8-R lower case first without parameter
903             #
904             sub Ekoi8r::lcfirst_() {
905 0     0 0 0 return Ekoi8r::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
906             }
907              
908             #
909             # KOI8-R lower case with parameter
910             #
911             sub Ekoi8r::lc(@) {
912 0 0   0 0 0 if (@_) {
913 0         0 my $s = shift @_;
914 0 0 0     0 if (@_ and wantarray) {
915 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
916             }
917             else {
918 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
919             }
920             }
921             else {
922 0         0 return Ekoi8r::lc_();
923             }
924             }
925              
926             #
927             # KOI8-R lower case without parameter
928             #
929             sub Ekoi8r::lc_() {
930 0     0 0 0 my $s = $_;
931 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
932             }
933              
934             #
935             # KOI8-R upper case first with parameter
936             #
937             sub Ekoi8r::ucfirst(@) {
938 0 0   0 0 0 if (@_) {
939 0         0 my $s = shift @_;
940 0 0 0     0 if (@_ and wantarray) {
941 0         0 return Ekoi8r::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
942             }
943             else {
944 0         0 return Ekoi8r::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
945             }
946             }
947             else {
948 0         0 return Ekoi8r::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
949             }
950             }
951              
952             #
953             # KOI8-R upper case first without parameter
954             #
955             sub Ekoi8r::ucfirst_() {
956 0     0 0 0 return Ekoi8r::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
957             }
958              
959             #
960             # KOI8-R upper case with parameter
961             #
962             sub Ekoi8r::uc(@) {
963 0 50   174 0 0 if (@_) {
964 174         248 my $s = shift @_;
965 174 50 33     206 if (@_ and wantarray) {
966 174 0       360 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
967             }
968             else {
969 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         576  
970             }
971             }
972             else {
973 174         635 return Ekoi8r::uc_();
974             }
975             }
976              
977             #
978             # KOI8-R upper case without parameter
979             #
980             sub Ekoi8r::uc_() {
981 0     0 0 0 my $s = $_;
982 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
983             }
984              
985             #
986             # KOI8-R fold case with parameter
987             #
988             sub Ekoi8r::fc(@) {
989 0 50   197 0 0 if (@_) {
990 197         284 my $s = shift @_;
991 197 50 33     222 if (@_ and wantarray) {
992 197 0       323 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
993             }
994             else {
995 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         611  
996             }
997             }
998             else {
999 197         1022 return Ekoi8r::fc_();
1000             }
1001             }
1002              
1003             #
1004             # KOI8-R fold case without parameter
1005             #
1006             sub Ekoi8r::fc_() {
1007 0     0 0 0 my $s = $_;
1008 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1009             }
1010              
1011             #
1012             # KOI8-R regexp capture
1013             #
1014             {
1015             sub Ekoi8r::capture {
1016 0     0 1 0 return $_[0];
1017             }
1018             }
1019              
1020             #
1021             # KOI8-R regexp ignore case modifier
1022             #
1023             sub Ekoi8r::ignorecase {
1024              
1025 0     0 0 0 my @string = @_;
1026 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1027              
1028             # ignore case of $scalar or @array
1029 0         0 for my $string (@string) {
1030              
1031             # split regexp
1032 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1033              
1034             # unescape character
1035 0         0 for (my $i=0; $i <= $#char; $i++) {
1036 0 0       0 next if not defined $char[$i];
1037              
1038             # open character class [...]
1039 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1040 0         0 my $left = $i;
1041              
1042             # [] make die "unmatched [] in regexp ...\n"
1043              
1044 0 0       0 if ($char[$i+1] eq ']') {
1045 0         0 $i++;
1046             }
1047              
1048 0         0 while (1) {
1049 0 0       0 if (++$i > $#char) {
1050 0         0 croak "Unmatched [] in regexp";
1051             }
1052 0 0       0 if ($char[$i] eq ']') {
1053 0         0 my $right = $i;
1054 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1055              
1056             # escape character
1057 0         0 for my $char (@charlist) {
1058 0 0       0 if (0) {
1059             }
1060              
1061 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1062 0         0 $char = '\\' . $char;
1063             }
1064             }
1065              
1066             # [...]
1067 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1068              
1069 0         0 $i = $left;
1070 0         0 last;
1071             }
1072             }
1073             }
1074              
1075             # open character class [^...]
1076             elsif ($char[$i] eq '[^') {
1077 0         0 my $left = $i;
1078              
1079             # [^] make die "unmatched [] in regexp ...\n"
1080              
1081 0 0       0 if ($char[$i+1] eq ']') {
1082 0         0 $i++;
1083             }
1084              
1085 0         0 while (1) {
1086 0 0       0 if (++$i > $#char) {
1087 0         0 croak "Unmatched [] in regexp";
1088             }
1089 0 0       0 if ($char[$i] eq ']') {
1090 0         0 my $right = $i;
1091 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1092              
1093             # escape character
1094 0         0 for my $char (@charlist) {
1095 0 0       0 if (0) {
1096             }
1097              
1098 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1099 0         0 $char = '\\' . $char;
1100             }
1101             }
1102              
1103             # [^...]
1104 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1105              
1106 0         0 $i = $left;
1107 0         0 last;
1108             }
1109             }
1110             }
1111              
1112             # rewrite classic character class or escape character
1113             elsif (my $char = classic_character_class($char[$i])) {
1114 0         0 $char[$i] = $char;
1115             }
1116              
1117             # with /i modifier
1118             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1119 0         0 my $uc = Ekoi8r::uc($char[$i]);
1120 0         0 my $fc = Ekoi8r::fc($char[$i]);
1121 0 0       0 if ($uc ne $fc) {
1122 0 0       0 if (CORE::length($fc) == 1) {
1123 0         0 $char[$i] = '[' . $uc . $fc . ']';
1124             }
1125             else {
1126 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1127             }
1128             }
1129             }
1130             }
1131              
1132             # characterize
1133 0         0 for (my $i=0; $i <= $#char; $i++) {
1134 0 0       0 next if not defined $char[$i];
1135              
1136 0 0       0 if (0) {
1137             }
1138              
1139             # quote character before ? + * {
1140 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1141 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1142 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1143             }
1144             }
1145             }
1146              
1147 0         0 $string = join '', @char;
1148             }
1149              
1150             # make regexp string
1151 0         0 return @string;
1152             }
1153              
1154             #
1155             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1156             #
1157             sub Ekoi8r::classic_character_class {
1158 0     1867 0 0 my($char) = @_;
1159              
1160             return {
1161             '\D' => '${Ekoi8r::eD}',
1162             '\S' => '${Ekoi8r::eS}',
1163             '\W' => '${Ekoi8r::eW}',
1164             '\d' => '[0-9]',
1165              
1166             # Before Perl 5.6, \s only matched the five whitespace characters
1167             # tab, newline, form-feed, carriage return, and the space character
1168             # itself, which, taken together, is the character class [\t\n\f\r ].
1169              
1170             # Vertical tabs are now whitespace
1171             # \s in a regex now matches a vertical tab in all circumstances.
1172             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1173             # \t \n \v \f \r space
1174             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1175             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1176             '\s' => '\s',
1177              
1178             '\w' => '[0-9A-Z_a-z]',
1179             '\C' => '[\x00-\xFF]',
1180             '\X' => 'X',
1181              
1182             # \h \v \H \V
1183              
1184             # P.114 Character Class Shortcuts
1185             # in Chapter 7: In the World of Regular Expressions
1186             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1187              
1188             # P.357 13.2.3 Whitespace
1189             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1190             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1191             #
1192             # 0x00009 CHARACTER TABULATION h s
1193             # 0x0000a LINE FEED (LF) vs
1194             # 0x0000b LINE TABULATION v
1195             # 0x0000c FORM FEED (FF) vs
1196             # 0x0000d CARRIAGE RETURN (CR) vs
1197             # 0x00020 SPACE h s
1198              
1199             # P.196 Table 5-9. Alphanumeric regex metasymbols
1200             # in Chapter 5. Pattern Matching
1201             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1202              
1203             # (and so on)
1204              
1205             '\H' => '${Ekoi8r::eH}',
1206             '\V' => '${Ekoi8r::eV}',
1207             '\h' => '[\x09\x20]',
1208             '\v' => '[\x0A\x0B\x0C\x0D]',
1209             '\R' => '${Ekoi8r::eR}',
1210              
1211             # \N
1212             #
1213             # http://perldoc.perl.org/perlre.html
1214             # Character Classes and other Special Escapes
1215             # Any character but \n (experimental). Not affected by /s modifier
1216              
1217             '\N' => '${Ekoi8r::eN}',
1218              
1219             # \b \B
1220              
1221             # P.180 Boundaries: The \b and \B Assertions
1222             # in Chapter 5: Pattern Matching
1223             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1224              
1225             # P.219 Boundaries: The \b and \B Assertions
1226             # in Chapter 5: Pattern Matching
1227             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1228              
1229             # \b really means (?:(?<=\w)(?!\w)|(?
1230             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1231             '\b' => '${Ekoi8r::eb}',
1232              
1233             # \B really means (?:(?<=\w)(?=\w)|(?
1234             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1235             '\B' => '${Ekoi8r::eB}',
1236              
1237 1867   100     2888 }->{$char} || '';
1238             }
1239              
1240             #
1241             # prepare KOI8-R characters per length
1242             #
1243              
1244             # 1 octet characters
1245             my @chars1 = ();
1246             sub chars1 {
1247 1867 0   0 0 78176 if (@chars1) {
1248 0         0 return @chars1;
1249             }
1250 0 0       0 if (exists $range_tr{1}) {
1251 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1252 0         0 while (my @range = splice(@ranges,0,1)) {
1253 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1254 0         0 push @chars1, pack 'C', $oct0;
1255             }
1256             }
1257             }
1258 0         0 return @chars1;
1259             }
1260              
1261             # 2 octets characters
1262             my @chars2 = ();
1263             sub chars2 {
1264 0 0   0 0 0 if (@chars2) {
1265 0         0 return @chars2;
1266             }
1267 0 0       0 if (exists $range_tr{2}) {
1268 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1269 0         0 while (my @range = splice(@ranges,0,2)) {
1270 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1271 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1272 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1273             }
1274             }
1275             }
1276             }
1277 0         0 return @chars2;
1278             }
1279              
1280             # 3 octets characters
1281             my @chars3 = ();
1282             sub chars3 {
1283 0 0   0 0 0 if (@chars3) {
1284 0         0 return @chars3;
1285             }
1286 0 0       0 if (exists $range_tr{3}) {
1287 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1288 0         0 while (my @range = splice(@ranges,0,3)) {
1289 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1290 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1291 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1292 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1293             }
1294             }
1295             }
1296             }
1297             }
1298 0         0 return @chars3;
1299             }
1300              
1301             # 4 octets characters
1302             my @chars4 = ();
1303             sub chars4 {
1304 0 0   0 0 0 if (@chars4) {
1305 0         0 return @chars4;
1306             }
1307 0 0       0 if (exists $range_tr{4}) {
1308 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1309 0         0 while (my @range = splice(@ranges,0,4)) {
1310 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1311 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1312 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1313 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1314 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1315             }
1316             }
1317             }
1318             }
1319             }
1320             }
1321 0         0 return @chars4;
1322             }
1323              
1324             #
1325             # KOI8-R open character list for tr
1326             #
1327             sub _charlist_tr {
1328              
1329 0     0   0 local $_ = shift @_;
1330              
1331             # unescape character
1332 0         0 my @char = ();
1333 0         0 while (not /\G \z/oxmsgc) {
1334 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1335 0         0 push @char, '\-';
1336             }
1337             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1338 0         0 push @char, CORE::chr(oct $1);
1339             }
1340             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1341 0         0 push @char, CORE::chr(hex $1);
1342             }
1343             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1344 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1345             }
1346             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1347             push @char, {
1348             '\0' => "\0",
1349             '\n' => "\n",
1350             '\r' => "\r",
1351             '\t' => "\t",
1352             '\f' => "\f",
1353             '\b' => "\x08", # \b means backspace in character class
1354             '\a' => "\a",
1355             '\e' => "\e",
1356 0         0 }->{$1};
1357             }
1358             elsif (/\G \\ ($q_char) /oxmsgc) {
1359 0         0 push @char, $1;
1360             }
1361             elsif (/\G ($q_char) /oxmsgc) {
1362 0         0 push @char, $1;
1363             }
1364             }
1365              
1366             # join separated multiple-octet
1367 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1368              
1369             # unescape '-'
1370 0         0 my @i = ();
1371 0         0 for my $i (0 .. $#char) {
1372 0 0       0 if ($char[$i] eq '\-') {
    0          
1373 0         0 $char[$i] = '-';
1374             }
1375             elsif ($char[$i] eq '-') {
1376 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1377 0         0 push @i, $i;
1378             }
1379             }
1380             }
1381              
1382             # open character list (reverse for splice)
1383 0         0 for my $i (CORE::reverse @i) {
1384 0         0 my @range = ();
1385              
1386             # range error
1387 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1388 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1389             }
1390              
1391             # range of multiple-octet code
1392 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1393 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1394 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1395             }
1396             elsif (CORE::length($char[$i+1]) == 2) {
1397 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1398 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1399             }
1400             elsif (CORE::length($char[$i+1]) == 3) {
1401 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1402 0         0 push @range, chars2();
1403 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1404             }
1405             elsif (CORE::length($char[$i+1]) == 4) {
1406 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1407 0         0 push @range, chars2();
1408 0         0 push @range, chars3();
1409 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1410             }
1411             else {
1412 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1413             }
1414             }
1415             elsif (CORE::length($char[$i-1]) == 2) {
1416 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1417 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ 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 $_} chars2();
  0         0  
1421 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1422             }
1423             elsif (CORE::length($char[$i+1]) == 4) {
1424 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1425 0         0 push @range, chars3();
1426 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1427             }
1428             else {
1429 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1430             }
1431             }
1432             elsif (CORE::length($char[$i-1]) == 3) {
1433 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1434 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1435             }
1436             elsif (CORE::length($char[$i+1]) == 4) {
1437 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1438 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1439             }
1440             else {
1441 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1442             }
1443             }
1444             elsif (CORE::length($char[$i-1]) == 4) {
1445 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1446 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1447             }
1448             else {
1449 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1450             }
1451             }
1452             else {
1453 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1454             }
1455              
1456 0         0 splice @char, $i-1, 3, @range;
1457             }
1458              
1459 0         0 return @char;
1460             }
1461              
1462             #
1463             # KOI8-R open character class
1464             #
1465             sub _cc {
1466 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1467 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1468             }
1469             elsif (scalar(@_) == 1) {
1470 0         0 return sprintf('\x%02X',$_[0]);
1471             }
1472             elsif (scalar(@_) == 2) {
1473 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1474 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1475             }
1476             elsif ($_[0] == $_[1]) {
1477 0         0 return sprintf('\x%02X',$_[0]);
1478             }
1479             elsif (($_[0]+1) == $_[1]) {
1480 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1481             }
1482             else {
1483 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1484             }
1485             }
1486             else {
1487 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1488             }
1489             }
1490              
1491             #
1492             # KOI8-R octet range
1493             #
1494             sub _octets {
1495 0     182   0 my $length = shift @_;
1496              
1497 182 50       382 if ($length == 1) {
1498 182         400 my($a1) = unpack 'C', $_[0];
1499 182         561 my($z1) = unpack 'C', $_[1];
1500              
1501 182 50       338 if ($a1 > $z1) {
1502 182         696 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1503             }
1504              
1505 0 50       0 if ($a1 == $z1) {
    50          
1506 182         462 return sprintf('\x%02X',$a1);
1507             }
1508             elsif (($a1+1) == $z1) {
1509 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1510             }
1511             else {
1512 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1513             }
1514             }
1515             else {
1516 182         1205 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1517             }
1518             }
1519              
1520             #
1521             # KOI8-R range regexp
1522             #
1523             sub _range_regexp {
1524 0     182   0 my($length,$first,$last) = @_;
1525              
1526 182         412 my @range_regexp = ();
1527 182 50       662 if (not exists $range_tr{$length}) {
1528 182         544 return @range_regexp;
1529             }
1530              
1531 0         0 my @ranges = @{ $range_tr{$length} };
  182         265  
1532 182         463 while (my @range = splice(@ranges,0,$length)) {
1533 182         695 my $min = '';
1534 182         337 my $max = '';
1535 182         231 for (my $i=0; $i < $length; $i++) {
1536 182         2046 $min .= pack 'C', $range[$i][0];
1537 182         786 $max .= pack 'C', $range[$i][-1];
1538             }
1539              
1540             # min___max
1541             # FIRST_____________LAST
1542             # (nothing)
1543              
1544 182 50 33     544 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1545             }
1546              
1547             # **********
1548             # min_________max
1549             # FIRST_____________LAST
1550             # **********
1551              
1552             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1553 182         2077 push @range_regexp, _octets($length,$first,$max,$min,$max);
1554             }
1555              
1556             # **********************
1557             # min________________max
1558             # FIRST_____________LAST
1559             # **********************
1560              
1561             elsif (($min eq $first) and ($max eq $last)) {
1562 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1563             }
1564              
1565             # *********
1566             # min___max
1567             # FIRST_____________LAST
1568             # *********
1569              
1570             elsif (($first le $min) and ($max le $last)) {
1571 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1572             }
1573              
1574             # **********************
1575             # min__________________________max
1576             # FIRST_____________LAST
1577             # **********************
1578              
1579             elsif (($min le $first) and ($last le $max)) {
1580 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1581             }
1582              
1583             # *********
1584             # min________max
1585             # FIRST_____________LAST
1586             # *********
1587              
1588             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1589 182         579 push @range_regexp, _octets($length,$min,$last,$min,$max);
1590             }
1591              
1592             # min___max
1593             # FIRST_____________LAST
1594             # (nothing)
1595              
1596             elsif ($last lt $min) {
1597             }
1598              
1599             else {
1600 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1601             }
1602             }
1603              
1604 0         0 return @range_regexp;
1605             }
1606              
1607             #
1608             # KOI8-R open character list for qr and not qr
1609             #
1610             sub _charlist {
1611              
1612 182     358   409 my $modifier = pop @_;
1613 358         639 my @char = @_;
1614              
1615 358 100       807 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1616              
1617             # unescape character
1618 358         886 for (my $i=0; $i <= $#char; $i++) {
1619              
1620             # escape - to ...
1621 358 100 100     1411 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1622 1125 100 100     9771 if ((0 < $i) and ($i < $#char)) {
1623 206         855 $char[$i] = '...';
1624             }
1625             }
1626              
1627             # octal escape sequence
1628             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1629 182         538 $char[$i] = octchr($1);
1630             }
1631              
1632             # hexadecimal escape sequence
1633             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1634 0         0 $char[$i] = hexchr($1);
1635             }
1636              
1637             # \b{...} --> b\{...}
1638             # \B{...} --> B\{...}
1639             # \N{CHARNAME} --> N\{CHARNAME}
1640             # \p{PROPERTY} --> p\{PROPERTY}
1641             # \P{PROPERTY} --> P\{PROPERTY}
1642             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1643 0         0 $char[$i] = $1 . '\\' . $2;
1644             }
1645              
1646             # \p, \P, \X --> p, P, X
1647             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1648 0         0 $char[$i] = $1;
1649             }
1650              
1651             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1652 0         0 $char[$i] = CORE::chr oct $1;
1653             }
1654             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1655 0         0 $char[$i] = CORE::chr hex $1;
1656             }
1657             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1658 22         102 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1659             }
1660             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1661             $char[$i] = {
1662             '\0' => "\0",
1663             '\n' => "\n",
1664             '\r' => "\r",
1665             '\t' => "\t",
1666             '\f' => "\f",
1667             '\b' => "\x08", # \b means backspace in character class
1668             '\a' => "\a",
1669             '\e' => "\e",
1670             '\d' => '[0-9]',
1671              
1672             # Vertical tabs are now whitespace
1673             # \s in a regex now matches a vertical tab in all circumstances.
1674             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1675             # \t \n \v \f \r space
1676             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1677             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1678             '\s' => '\s',
1679              
1680             '\w' => '[0-9A-Z_a-z]',
1681             '\D' => '${Ekoi8r::eD}',
1682             '\S' => '${Ekoi8r::eS}',
1683             '\W' => '${Ekoi8r::eW}',
1684              
1685             '\H' => '${Ekoi8r::eH}',
1686             '\V' => '${Ekoi8r::eV}',
1687             '\h' => '[\x09\x20]',
1688             '\v' => '[\x0A\x0B\x0C\x0D]',
1689             '\R' => '${Ekoi8r::eR}',
1690              
1691 0         0 }->{$1};
1692             }
1693              
1694             # POSIX-style character classes
1695             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1696             $char[$i] = {
1697              
1698             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1699             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1700             '[:^lower:]' => '${Ekoi8r::not_lower_i}',
1701             '[:^upper:]' => '${Ekoi8r::not_upper_i}',
1702              
1703 25         450 }->{$1};
1704             }
1705             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1706             $char[$i] = {
1707              
1708             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1709             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1710             '[:ascii:]' => '[\x00-\x7F]',
1711             '[:blank:]' => '[\x09\x20]',
1712             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1713             '[:digit:]' => '[\x30-\x39]',
1714             '[:graph:]' => '[\x21-\x7F]',
1715             '[:lower:]' => '[\x61-\x7A]',
1716             '[:print:]' => '[\x20-\x7F]',
1717             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1718              
1719             # P.174 POSIX-Style Character Classes
1720             # in Chapter 5: Pattern Matching
1721             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1722              
1723             # P.311 11.2.4 Character Classes and other Special Escapes
1724             # in Chapter 11: perlre: Perl regular expressions
1725             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1726              
1727             # P.210 POSIX-Style Character Classes
1728             # in Chapter 5: Pattern Matching
1729             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1730              
1731             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1732              
1733             '[:upper:]' => '[\x41-\x5A]',
1734             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1735             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1736             '[:^alnum:]' => '${Ekoi8r::not_alnum}',
1737             '[:^alpha:]' => '${Ekoi8r::not_alpha}',
1738             '[:^ascii:]' => '${Ekoi8r::not_ascii}',
1739             '[:^blank:]' => '${Ekoi8r::not_blank}',
1740             '[:^cntrl:]' => '${Ekoi8r::not_cntrl}',
1741             '[:^digit:]' => '${Ekoi8r::not_digit}',
1742             '[:^graph:]' => '${Ekoi8r::not_graph}',
1743             '[:^lower:]' => '${Ekoi8r::not_lower}',
1744             '[:^print:]' => '${Ekoi8r::not_print}',
1745             '[:^punct:]' => '${Ekoi8r::not_punct}',
1746             '[:^space:]' => '${Ekoi8r::not_space}',
1747             '[:^upper:]' => '${Ekoi8r::not_upper}',
1748             '[:^word:]' => '${Ekoi8r::not_word}',
1749             '[:^xdigit:]' => '${Ekoi8r::not_xdigit}',
1750              
1751 8         71 }->{$1};
1752             }
1753             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1754 70         1400 $char[$i] = $1;
1755             }
1756             }
1757              
1758             # open character list
1759 7         33 my @singleoctet = ();
1760 358         745 my @multipleoctet = ();
1761 358         561 for (my $i=0; $i <= $#char; ) {
1762              
1763             # escaped -
1764 358 100 100     948 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1765 943         4063 $i += 1;
1766 182         318 next;
1767             }
1768              
1769             # make range regexp
1770             elsif ($char[$i] eq '...') {
1771              
1772             # range error
1773 182 50       344 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1774 182         1196 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1775             }
1776             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1777 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1778 182         683 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1779             }
1780             }
1781              
1782             # make range regexp per length
1783 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1784 182         630 my @regexp = ();
1785              
1786             # is first and last
1787 182 50 33     362 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1788 182         665 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1789             }
1790              
1791             # is first
1792             elsif ($length == CORE::length($char[$i-1])) {
1793 182         561 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1794             }
1795              
1796             # is inside in first and last
1797             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1798 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1799             }
1800              
1801             # is last
1802             elsif ($length == CORE::length($char[$i+1])) {
1803 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1804             }
1805              
1806             else {
1807 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1808             }
1809              
1810 0 50       0 if ($length == 1) {
1811 182         418 push @singleoctet, @regexp;
1812             }
1813             else {
1814 182         452 push @multipleoctet, @regexp;
1815             }
1816             }
1817              
1818 0         0 $i += 2;
1819             }
1820              
1821             # with /i modifier
1822             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1823 182 100       2641 if ($modifier =~ /i/oxms) {
1824 493         846 my $uc = Ekoi8r::uc($char[$i]);
1825 24         50 my $fc = Ekoi8r::fc($char[$i]);
1826 24 100       48 if ($uc ne $fc) {
1827 24 50       49 if (CORE::length($fc) == 1) {
1828 12         26 push @singleoctet, $uc, $fc;
1829             }
1830             else {
1831 12         23 push @singleoctet, $uc;
1832 0         0 push @multipleoctet, $fc;
1833             }
1834             }
1835             else {
1836 0         0 push @singleoctet, $char[$i];
1837             }
1838             }
1839             else {
1840 12         25 push @singleoctet, $char[$i];
1841             }
1842 469         697 $i += 1;
1843             }
1844              
1845             # single character of single octet code
1846             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1847 493         911 push @singleoctet, "\t", "\x20";
1848 0         0 $i += 1;
1849             }
1850             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1851 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1852 0         0 $i += 1;
1853             }
1854             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1855 0         0 push @singleoctet, $char[$i];
1856 2         5 $i += 1;
1857             }
1858              
1859             # single character of multiple-octet code
1860             else {
1861 2         6 push @multipleoctet, $char[$i];
1862 84         183 $i += 1;
1863             }
1864             }
1865              
1866             # quote metachar
1867 84         167 for (@singleoctet) {
1868 358 50       731 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1869 689         3726 $_ = '-';
1870             }
1871             elsif (/\A \n \z/oxms) {
1872 0         0 $_ = '\n';
1873             }
1874             elsif (/\A \r \z/oxms) {
1875 8         15 $_ = '\r';
1876             }
1877             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1878 8         18 $_ = sprintf('\x%02X', CORE::ord $1);
1879             }
1880             elsif (/\A [\x00-\xFF] \z/oxms) {
1881 60         192 $_ = quotemeta $_;
1882             }
1883             }
1884              
1885             # return character list
1886 429         667 return \@singleoctet, \@multipleoctet;
1887             }
1888              
1889             #
1890             # KOI8-R octal escape sequence
1891             #
1892             sub octchr {
1893 358     5 0 1264 my($octdigit) = @_;
1894              
1895 5         12 my @binary = ();
1896 5         9 for my $octal (split(//,$octdigit)) {
1897             push @binary, {
1898             '0' => '000',
1899             '1' => '001',
1900             '2' => '010',
1901             '3' => '011',
1902             '4' => '100',
1903             '5' => '101',
1904             '6' => '110',
1905             '7' => '111',
1906 5         21 }->{$octal};
1907             }
1908 50         173 my $binary = join '', @binary;
1909              
1910             my $octchr = {
1911             # 1234567
1912             1 => pack('B*', "0000000$binary"),
1913             2 => pack('B*', "000000$binary"),
1914             3 => pack('B*', "00000$binary"),
1915             4 => pack('B*', "0000$binary"),
1916             5 => pack('B*', "000$binary"),
1917             6 => pack('B*', "00$binary"),
1918             7 => pack('B*', "0$binary"),
1919             0 => pack('B*', "$binary"),
1920              
1921 5         14 }->{CORE::length($binary) % 8};
1922              
1923 5         58 return $octchr;
1924             }
1925              
1926             #
1927             # KOI8-R hexadecimal escape sequence
1928             #
1929             sub hexchr {
1930 5     5 0 20 my($hexdigit) = @_;
1931              
1932             my $hexchr = {
1933             1 => pack('H*', "0$hexdigit"),
1934             0 => pack('H*', "$hexdigit"),
1935              
1936 5         13 }->{CORE::length($_[0]) % 2};
1937              
1938 5         39 return $hexchr;
1939             }
1940              
1941             #
1942             # KOI8-R open character list for qr
1943             #
1944             sub charlist_qr {
1945              
1946 5     314 0 16 my $modifier = pop @_;
1947 314         656 my @char = @_;
1948              
1949 314         782 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1950 314         1063 my @singleoctet = @$singleoctet;
1951 314         693 my @multipleoctet = @$multipleoctet;
1952              
1953             # return character list
1954 314 100       482 if (scalar(@singleoctet) >= 1) {
1955              
1956             # with /i modifier
1957 314 100       773 if ($modifier =~ m/i/oxms) {
1958 236         686 my %singleoctet_ignorecase = ();
1959 22         36 for (@singleoctet) {
1960 22   100     39 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1961 46         186 for my $ord (hex($1) .. hex($2)) {
1962 46         128 my $char = CORE::chr($ord);
1963 66         105 my $uc = Ekoi8r::uc($char);
1964 66         97 my $fc = Ekoi8r::fc($char);
1965 66 100       98 if ($uc eq $fc) {
1966 66         102 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1967             }
1968             else {
1969 12 50       88 if (CORE::length($fc) == 1) {
1970 54         84 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1971 54         111 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1972             }
1973             else {
1974 54         187 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1975 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1976             }
1977             }
1978             }
1979             }
1980 0 50       0 if ($_ ne '') {
1981 46         92 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1982             }
1983             }
1984 0         0 my $i = 0;
1985 22         27 my @singleoctet_ignorecase = ();
1986 22         29 for my $ord (0 .. 255) {
1987 22 100       33 if (exists $singleoctet_ignorecase{$ord}) {
1988 5632         7874 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         97  
1989             }
1990             else {
1991 96         233 $i++;
1992             }
1993             }
1994 5536         5456 @singleoctet = ();
1995 22         36 for my $range (@singleoctet_ignorecase) {
1996 22 100       356 if (ref $range) {
1997 3648 100       17796 if (scalar(@{$range}) == 1) {
  56 50       59  
1998 56         86 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         41  
1999             }
2000 36         155 elsif (scalar(@{$range}) == 2) {
2001 20         26 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2002             }
2003             else {
2004 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         22  
  20         25  
2005             }
2006             }
2007             }
2008             }
2009              
2010 20         84 my $not_anchor = '';
2011              
2012 236         382 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2013             }
2014 236 100       1166 if (scalar(@multipleoctet) >= 2) {
2015 314         692 return '(?:' . join('|', @multipleoctet) . ')';
2016             }
2017             else {
2018 6         84 return $multipleoctet[0];
2019             }
2020             }
2021              
2022             #
2023             # KOI8-R open character list for not qr
2024             #
2025             sub charlist_not_qr {
2026              
2027 308     44 0 1406 my $modifier = pop @_;
2028 44         98 my @char = @_;
2029              
2030 44         104 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2031 44         137 my @singleoctet = @$singleoctet;
2032 44         101 my @multipleoctet = @$multipleoctet;
2033              
2034             # with /i modifier
2035 44 100       66 if ($modifier =~ m/i/oxms) {
2036 44         121 my %singleoctet_ignorecase = ();
2037 10         17 for (@singleoctet) {
2038 10   66     14 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2039 10         49 for my $ord (hex($1) .. hex($2)) {
2040 10         35 my $char = CORE::chr($ord);
2041 30         43 my $uc = Ekoi8r::uc($char);
2042 30         47 my $fc = Ekoi8r::fc($char);
2043 30 50       86 if ($uc eq $fc) {
2044 30         46 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2045             }
2046             else {
2047 0 50       0 if (CORE::length($fc) == 1) {
2048 30         48 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2049 30         69 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2050             }
2051             else {
2052 30         102 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2053 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2054             }
2055             }
2056             }
2057             }
2058 0 50       0 if ($_ ne '') {
2059 10         28 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2060             }
2061             }
2062 0         0 my $i = 0;
2063 10         13 my @singleoctet_ignorecase = ();
2064 10         13 for my $ord (0 .. 255) {
2065 10 100       14 if (exists $singleoctet_ignorecase{$ord}) {
2066 2560         5844 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         53  
2067             }
2068             else {
2069 60         126 $i++;
2070             }
2071             }
2072 2500         3116 @singleoctet = ();
2073 10         19 for my $range (@singleoctet_ignorecase) {
2074 10 100       24 if (ref $range) {
2075 960 50       1464 if (scalar(@{$range}) == 1) {
  20 50       19  
2076 20         27 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2077             }
2078 0         0 elsif (scalar(@{$range}) == 2) {
2079 20         29 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2080             }
2081             else {
2082 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         25  
  20         23  
2083             }
2084             }
2085             }
2086             }
2087              
2088             # return character list
2089 20 50       79 if (scalar(@multipleoctet) >= 1) {
2090 44 0       112 if (scalar(@singleoctet) >= 1) {
2091              
2092             # any character other than multiple-octet and single octet character class
2093 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2094             }
2095             else {
2096              
2097             # any character other than multiple-octet character class
2098 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2099             }
2100             }
2101             else {
2102 0 50       0 if (scalar(@singleoctet) >= 1) {
2103              
2104             # any character other than single octet character class
2105 44         171 return '(?:[^' . join('', @singleoctet) . '])';
2106             }
2107             else {
2108              
2109             # any character
2110 44         351 return "(?:$your_char)";
2111             }
2112             }
2113             }
2114              
2115             #
2116             # open file in read mode
2117             #
2118             sub _open_r {
2119 0     408   0 my(undef,$file) = @_;
2120 204     204   2164 use Fcntl qw(O_RDONLY);
  204         570  
  204         28962  
2121 408         1244 return CORE::sysopen($_[0], $file, &O_RDONLY);
2122             }
2123              
2124             #
2125             # open file in append mode
2126             #
2127             sub _open_a {
2128 408     204   19793 my(undef,$file) = @_;
2129 204     204   1491 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  204         473  
  204         645330  
2130 204         650 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2131             }
2132              
2133             #
2134             # safe system
2135             #
2136             sub _systemx {
2137              
2138             # P.707 29.2.33. exec
2139             # in Chapter 29: Functions
2140             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2141             #
2142             # Be aware that in older releases of Perl, exec (and system) did not flush
2143             # your output buffer, so you needed to enable command buffering by setting $|
2144             # on one or more filehandles to avoid lost output in the case of exec, or
2145             # misordererd output in the case of system. This situation was largely remedied
2146             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2147              
2148             # P.855 exec
2149             # in Chapter 27: Functions
2150             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2151             #
2152             # In very old release of Perl (before v5.6), exec (and system) did not flush
2153             # your output buffer, so you needed to enable command buffering by setting $|
2154             # on one or more filehandles to avoid lost output with exec or misordered
2155             # output with system.
2156              
2157 204     204   44569 $| = 1;
2158              
2159             # P.565 23.1.2. Cleaning Up Your Environment
2160             # in Chapter 23: Security
2161             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2162              
2163             # P.656 Cleaning Up Your Environment
2164             # in Chapter 20: Security
2165             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2166              
2167             # local $ENV{'PATH'} = '.';
2168 204         811 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2169              
2170             # P.707 29.2.33. exec
2171             # in Chapter 29: Functions
2172             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2173             #
2174             # As we mentioned earlier, exec treats a discrete list of arguments as an
2175             # indication that it should bypass shell processing. However, there is one
2176             # place where you might still get tripped up. The exec call (and system, too)
2177             # will not distinguish between a single scalar argument and an array containing
2178             # only one element.
2179             #
2180             # @args = ("echo surprise"); # just one element in list
2181             # exec @args # still subject to shell escapes
2182             # or die "exec: $!"; # because @args == 1
2183             #
2184             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2185             # first argument as the pathname, which forces the rest of the arguments to be
2186             # interpreted as a list, even if there is only one of them:
2187             #
2188             # exec { $args[0] } @args # safe even with one-argument list
2189             # or die "can't exec @args: $!";
2190              
2191             # P.855 exec
2192             # in Chapter 27: Functions
2193             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2194             #
2195             # As we mentioned earlier, exec treats a discrete list of arguments as a
2196             # directive to bypass shell processing. However, there is one place where
2197             # you might still get tripped up. The exec call (and system, too) cannot
2198             # distinguish between a single scalar argument and an array containing
2199             # only one element.
2200             #
2201             # @args = ("echo surprise"); # just one element in list
2202             # exec @args # still subject to shell escapes
2203             # || die "exec: $!"; # because @args == 1
2204             #
2205             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2206             # argument as the pathname, which forces the rest of the arguments to be
2207             # interpreted as a list, even if there is only one of them:
2208             #
2209             # exec { $args[0] } @args # safe even with one-argument list
2210             # || die "can't exec @args: $!";
2211              
2212 204         1886 return CORE::system { $_[0] } @_; # safe even with one-argument list
  204         434  
2213             }
2214              
2215             #
2216             # KOI8-R order to character (with parameter)
2217             #
2218             sub Ekoi8r::chr(;$) {
2219              
2220 204 0   0 0 19287238 my $c = @_ ? $_[0] : $_;
2221              
2222 0 0       0 if ($c == 0x00) {
2223 0         0 return "\x00";
2224             }
2225             else {
2226 0         0 my @chr = ();
2227 0         0 while ($c > 0) {
2228 0         0 unshift @chr, ($c % 0x100);
2229 0         0 $c = int($c / 0x100);
2230             }
2231 0         0 return pack 'C*', @chr;
2232             }
2233             }
2234              
2235             #
2236             # KOI8-R order to character (without parameter)
2237             #
2238             sub Ekoi8r::chr_() {
2239              
2240 0     0 0 0 my $c = $_;
2241              
2242 0 0       0 if ($c == 0x00) {
2243 0         0 return "\x00";
2244             }
2245             else {
2246 0         0 my @chr = ();
2247 0         0 while ($c > 0) {
2248 0         0 unshift @chr, ($c % 0x100);
2249 0         0 $c = int($c / 0x100);
2250             }
2251 0         0 return pack 'C*', @chr;
2252             }
2253             }
2254              
2255             #
2256             # KOI8-R path globbing (with parameter)
2257             #
2258             sub Ekoi8r::glob($) {
2259              
2260 0 0   0 0 0 if (wantarray) {
2261 0         0 my @glob = _DOS_like_glob(@_);
2262 0         0 for my $glob (@glob) {
2263 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2264             }
2265 0         0 return @glob;
2266             }
2267             else {
2268 0         0 my $glob = _DOS_like_glob(@_);
2269 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2270 0         0 return $glob;
2271             }
2272             }
2273              
2274             #
2275             # KOI8-R path globbing (without parameter)
2276             #
2277             sub Ekoi8r::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-R path globbing via File::DosGlob 1.10
2295             #
2296             # Often I confuse "_dosglob" and "_doglob".
2297             # So, I renamed "_dosglob" to "_DOS_like_glob".
2298             #
2299             my %iter;
2300             my %entries;
2301             sub _DOS_like_glob {
2302              
2303             # context (keyed by second cxix argument provided by core)
2304 0     0   0 my($expr,$cxix) = @_;
2305              
2306             # glob without args defaults to $_
2307 0 0       0 $expr = $_ if not defined $expr;
2308              
2309             # represents the current user's home directory
2310             #
2311             # 7.3. Expanding Tildes in Filenames
2312             # in Chapter 7. File Access
2313             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2314             #
2315             # and File::HomeDir, File::HomeDir::Windows module
2316              
2317             # DOS-like system
2318 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2319 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2320             { my_home_MSWin32() }oxmse;
2321             }
2322              
2323             # UNIX-like system
2324 0 0 0     0 else {
  0         0  
2325             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2326             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2327             }
2328 0 0       0  
2329 0 0       0 # assume global context if not provided one
2330             $cxix = '_G_' if not defined $cxix;
2331             $iter{$cxix} = 0 if not exists $iter{$cxix};
2332 0 0       0  
2333 0         0 # if we're just beginning, do it all first
2334             if ($iter{$cxix} == 0) {
2335             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2336             }
2337 0 0       0  
2338 0         0 # chuck it all out, quick or slow
2339 0         0 if (wantarray) {
  0         0  
2340             delete $iter{$cxix};
2341             return @{delete $entries{$cxix}};
2342 0 0       0 }
  0         0  
2343 0         0 else {
  0         0  
2344             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2345             return shift @{$entries{$cxix}};
2346             }
2347 0         0 else {
2348 0         0 # return undef for EOL
2349 0         0 delete $iter{$cxix};
2350             delete $entries{$cxix};
2351             return undef;
2352             }
2353             }
2354             }
2355              
2356             #
2357             # KOI8-R path globbing subroutine
2358             #
2359 0     0   0 sub _do_glob {
2360 0         0  
2361 0         0 my($cond,@expr) = @_;
2362             my @glob = ();
2363             my $fix_drive_relative_paths = 0;
2364 0         0  
2365 0 0       0 OUTER:
2366 0 0       0 for my $expr (@expr) {
2367             next OUTER if not defined $expr;
2368 0         0 next OUTER if $expr eq '';
2369 0         0  
2370 0         0 my @matched = ();
2371 0         0 my @globdir = ();
2372 0         0 my $head = '.';
2373             my $pathsep = '/';
2374             my $tail;
2375 0 0       0  
2376 0         0 # if argument is within quotes strip em and do no globbing
2377 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2378 0 0       0 $expr = $1;
2379 0         0 if ($cond eq 'd') {
2380             if (-d $expr) {
2381             push @glob, $expr;
2382             }
2383 0 0       0 }
2384 0         0 else {
2385             if (-e $expr) {
2386             push @glob, $expr;
2387 0         0 }
2388             }
2389             next OUTER;
2390             }
2391              
2392 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2393 0 0       0 # to h:./*.pm to expand correctly
2394 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2395             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2396             $fix_drive_relative_paths = 1;
2397             }
2398 0 0       0 }
2399 0 0       0  
2400 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2401 0         0 if ($tail eq '') {
2402             push @glob, $expr;
2403 0 0       0 next OUTER;
2404 0 0       0 }
2405 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2406 0         0 if (@globdir = _do_glob('d', $head)) {
2407             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2408             next OUTER;
2409 0 0 0     0 }
2410 0         0 }
2411             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2412 0         0 $head .= $pathsep;
2413             }
2414             $expr = $tail;
2415             }
2416 0 0       0  
2417 0 0       0 # If file component has no wildcards, we can avoid opendir
2418 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2419             if ($head eq '.') {
2420 0 0 0     0 $head = '';
2421 0         0 }
2422             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2423 0         0 $head .= $pathsep;
2424 0 0       0 }
2425 0 0       0 $head .= $expr;
2426 0         0 if ($cond eq 'd') {
2427             if (-d $head) {
2428             push @glob, $head;
2429             }
2430 0 0       0 }
2431 0         0 else {
2432             if (-e $head) {
2433             push @glob, $head;
2434 0         0 }
2435             }
2436 0 0       0 next OUTER;
2437 0         0 }
2438 0         0 opendir(*DIR, $head) or next OUTER;
2439             my @leaf = readdir DIR;
2440 0 0       0 closedir DIR;
2441 0         0  
2442             if ($head eq '.') {
2443 0 0 0     0 $head = '';
2444 0         0 }
2445             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2446             $head .= $pathsep;
2447 0         0 }
2448 0         0  
2449 0         0 my $pattern = '';
2450             while ($expr =~ / \G ($q_char) /oxgc) {
2451             my $char = $1;
2452              
2453             # 6.9. Matching Shell Globs as Regular Expressions
2454             # in Chapter 6. Pattern Matching
2455             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2456 0 0       0 # (and so on)
    0          
    0          
2457 0         0  
2458             if ($char eq '*') {
2459             $pattern .= "(?:$your_char)*",
2460 0         0 }
2461             elsif ($char eq '?') {
2462             $pattern .= "(?:$your_char)?", # DOS style
2463             # $pattern .= "(?:$your_char)", # UNIX style
2464 0         0 }
2465             elsif ((my $fc = Ekoi8r::fc($char)) ne $char) {
2466             $pattern .= $fc;
2467 0         0 }
2468             else {
2469             $pattern .= quotemeta $char;
2470 0     0   0 }
  0         0  
2471             }
2472             my $matchsub = sub { Ekoi8r::fc($_[0]) =~ /\A $pattern \z/xms };
2473              
2474             # if ($@) {
2475             # print STDERR "$0: $@\n";
2476             # next OUTER;
2477             # }
2478 0         0  
2479 0 0 0     0 INNER:
2480 0         0 for my $leaf (@leaf) {
2481             if ($leaf eq '.' or $leaf eq '..') {
2482 0 0 0     0 next INNER;
2483 0         0 }
2484             if ($cond eq 'd' and not -d "$head$leaf") {
2485             next INNER;
2486 0 0       0 }
2487 0         0  
2488 0         0 if (&$matchsub($leaf)) {
2489             push @matched, "$head$leaf";
2490             next INNER;
2491             }
2492              
2493             # [DOS compatibility special case]
2494 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2495              
2496             if (Ekoi8r::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2497             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2498 0 0       0 Ekoi8r::index($pattern,'\\.') != -1 # pattern has a dot.
2499 0         0 ) {
2500 0         0 if (&$matchsub("$leaf.")) {
2501             push @matched, "$head$leaf";
2502             next INNER;
2503             }
2504 0 0       0 }
2505 0         0 }
2506             if (@matched) {
2507             push @glob, @matched;
2508 0 0       0 }
2509 0         0 }
2510 0         0 if ($fix_drive_relative_paths) {
2511             for my $glob (@glob) {
2512             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2513 0         0 }
2514             }
2515             return @glob;
2516             }
2517              
2518             #
2519             # KOI8-R parse line
2520             #
2521 0     0   0 sub _parse_line {
2522              
2523 0         0 my($line) = @_;
2524 0         0  
2525 0         0 $line .= ' ';
2526             my @piece = ();
2527             while ($line =~ /
2528             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2529             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2530 0 0       0 /oxmsg
2531             ) {
2532 0         0 push @piece, defined($1) ? $1 : $2;
2533             }
2534             return @piece;
2535             }
2536              
2537             #
2538             # KOI8-R parse path
2539             #
2540 0     0   0 sub _parse_path {
2541              
2542 0         0 my($path,$pathsep) = @_;
2543 0         0  
2544 0         0 $path .= '/';
2545             my @subpath = ();
2546             while ($path =~ /
2547             ((?: [^\/\\] )+?) [\/\\]
2548 0         0 /oxmsg
2549             ) {
2550             push @subpath, $1;
2551 0         0 }
2552 0         0  
2553 0         0 my $tail = pop @subpath;
2554             my $head = join $pathsep, @subpath;
2555             return $head, $tail;
2556             }
2557              
2558             #
2559             # via File::HomeDir::Windows 1.00
2560             #
2561             sub my_home_MSWin32 {
2562              
2563             # A lot of unix people and unix-derived tools rely on
2564 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2565 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2566             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2567             return $ENV{'HOME'};
2568             }
2569              
2570 0         0 # Do we have a user profile?
2571             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2572             return $ENV{'USERPROFILE'};
2573             }
2574              
2575 0         0 # Some Windows use something like $ENV{'HOME'}
2576             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2577             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2578 0         0 }
2579              
2580             return undef;
2581             }
2582              
2583             #
2584             # via File::HomeDir::Unix 1.00
2585 0     0 0 0 #
2586             sub my_home {
2587 0 0 0     0 my $home;
    0 0        
2588 0         0  
2589             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2590             $home = $ENV{'HOME'};
2591             }
2592              
2593             # This is from the original code, but I'm guessing
2594 0         0 # it means "login directory" and exists on some Unixes.
2595             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2596             $home = $ENV{'LOGDIR'};
2597             }
2598              
2599             ### More-desperate methods
2600              
2601 0         0 # Light desperation on any (Unixish) platform
2602             else {
2603             $home = CORE::eval q{ (getpwuid($<))[7] };
2604             }
2605              
2606 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2607 0         0 # For example, "nobody"-like users might use /nonexistant
2608             if (defined $home and ! -d($home)) {
2609 0         0 $home = undef;
2610             }
2611             return $home;
2612             }
2613              
2614             #
2615             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2616 0     0 0 0 #
2617             sub Ekoi8r::PREMATCH {
2618             return $`;
2619             }
2620              
2621             #
2622             # ${^MATCH}, $MATCH, $& the string that matched
2623 0     0 0 0 #
2624             sub Ekoi8r::MATCH {
2625             return $&;
2626             }
2627              
2628             #
2629             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2630 0     0 0 0 #
2631             sub Ekoi8r::POSTMATCH {
2632             return $';
2633             }
2634              
2635             #
2636             # KOI8-R character to order (with parameter)
2637             #
2638 0 0   0 1 0 sub KOI8R::ord(;$) {
2639              
2640 0 0       0 local $_ = shift if @_;
2641 0         0  
2642 0         0 if (/\A ($q_char) /oxms) {
2643 0         0 my @ord = unpack 'C*', $1;
2644 0         0 my $ord = 0;
2645             while (my $o = shift @ord) {
2646 0         0 $ord = $ord * 0x100 + $o;
2647             }
2648             return $ord;
2649 0         0 }
2650             else {
2651             return CORE::ord $_;
2652             }
2653             }
2654              
2655             #
2656             # KOI8-R character to order (without parameter)
2657             #
2658 0 0   0 0 0 sub KOI8R::ord_() {
2659 0         0  
2660 0         0 if (/\A ($q_char) /oxms) {
2661 0         0 my @ord = unpack 'C*', $1;
2662 0         0 my $ord = 0;
2663             while (my $o = shift @ord) {
2664 0         0 $ord = $ord * 0x100 + $o;
2665             }
2666             return $ord;
2667 0         0 }
2668             else {
2669             return CORE::ord $_;
2670             }
2671             }
2672              
2673             #
2674             # KOI8-R reverse
2675             #
2676 0 0   0 0 0 sub KOI8R::reverse(@) {
2677 0         0  
2678             if (wantarray) {
2679             return CORE::reverse @_;
2680             }
2681             else {
2682              
2683             # One of us once cornered Larry in an elevator and asked him what
2684             # problem he was solving with this, but he looked as far off into
2685             # the distance as he could in an elevator and said, "It seemed like
2686 0         0 # a good idea at the time."
2687              
2688             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2689             }
2690             }
2691              
2692             #
2693             # KOI8-R getc (with parameter, without parameter)
2694             #
2695 0     0 0 0 sub KOI8R::getc(;*@) {
2696 0 0       0  
2697 0 0 0     0 my($package) = caller;
2698             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2699 0         0 croak 'Too many arguments for KOI8R::getc' if @_ and not wantarray;
  0         0  
2700 0         0  
2701 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2702 0         0 my $getc = '';
2703 0 0       0 for my $length ($length[0] .. $length[-1]) {
2704 0 0       0 $getc .= CORE::getc($fh);
2705 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2706             if ($getc =~ /\A ${Ekoi8r::dot_s} \z/oxms) {
2707             return wantarray ? ($getc,@_) : $getc;
2708             }
2709 0 0       0 }
2710             }
2711             return wantarray ? ($getc,@_) : $getc;
2712             }
2713              
2714             #
2715             # KOI8-R length by character
2716             #
2717 0 0   0 1 0 sub KOI8R::length(;$) {
2718              
2719 0         0 local $_ = shift if @_;
2720 0         0  
2721             local @_ = /\G ($q_char) /oxmsg;
2722             return scalar @_;
2723             }
2724              
2725             #
2726             # KOI8-R substr by character
2727             #
2728             BEGIN {
2729              
2730             # P.232 The lvalue Attribute
2731             # in Chapter 6: Subroutines
2732             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2733              
2734             # P.336 The lvalue Attribute
2735             # in Chapter 7: Subroutines
2736             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2737              
2738             # P.144 8.4 Lvalue subroutines
2739             # in Chapter 8: perlsub: Perl subroutines
2740 204 50 0 204 1 125942 # 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  
2741              
2742             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2743             # vv----------------------*******
2744             sub KOI8R::substr($$;$$) %s {
2745              
2746             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2747              
2748             # If the substring is beyond either end of the string, substr() returns the undefined
2749             # value and produces a warning. When used as an lvalue, specifying a substring that
2750             # is entirely outside the string raises an exception.
2751             # http://perldoc.perl.org/functions/substr.html
2752              
2753             # A return with no argument returns the scalar value undef in scalar context,
2754             # an empty list () in list context, and (naturally) nothing at all in void
2755             # context.
2756              
2757             my $offset = $_[1];
2758             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2759             return;
2760             }
2761              
2762             # substr($string,$offset,$length,$replacement)
2763             if (@_ == 4) {
2764             my(undef,undef,$length,$replacement) = @_;
2765             my $substr = join '', splice(@char, $offset, $length, $replacement);
2766             $_[0] = join '', @char;
2767              
2768             # return $substr; this doesn't work, don't say "return"
2769             $substr;
2770             }
2771              
2772             # substr($string,$offset,$length)
2773             elsif (@_ == 3) {
2774             my(undef,undef,$length) = @_;
2775             my $octet_offset = 0;
2776             my $octet_length = 0;
2777             if ($offset == 0) {
2778             $octet_offset = 0;
2779             }
2780             elsif ($offset > 0) {
2781             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2782             }
2783             else {
2784             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2785             }
2786             if ($length == 0) {
2787             $octet_length = 0;
2788             }
2789             elsif ($length > 0) {
2790             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2791             }
2792             else {
2793             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2794             }
2795             CORE::substr($_[0], $octet_offset, $octet_length);
2796             }
2797              
2798             # substr($string,$offset)
2799             else {
2800             my $octet_offset = 0;
2801             if ($offset == 0) {
2802             $octet_offset = 0;
2803             }
2804             elsif ($offset > 0) {
2805             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2806             }
2807             else {
2808             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2809             }
2810             CORE::substr($_[0], $octet_offset);
2811             }
2812             }
2813             END
2814             }
2815              
2816             #
2817             # KOI8-R index by character
2818             #
2819 0     0 1 0 sub KOI8R::index($$;$) {
2820 0 0       0  
2821 0         0 my $index;
2822             if (@_ == 3) {
2823             $index = Ekoi8r::index($_[0], $_[1], CORE::length(KOI8R::substr($_[0], 0, $_[2])));
2824 0         0 }
2825             else {
2826             $index = Ekoi8r::index($_[0], $_[1]);
2827 0 0       0 }
2828 0         0  
2829             if ($index == -1) {
2830             return -1;
2831 0         0 }
2832             else {
2833             return KOI8R::length(CORE::substr $_[0], 0, $index);
2834             }
2835             }
2836              
2837             #
2838             # KOI8-R rindex by character
2839             #
2840 0     0 1 0 sub KOI8R::rindex($$;$) {
2841 0 0       0  
2842 0         0 my $rindex;
2843             if (@_ == 3) {
2844             $rindex = Ekoi8r::rindex($_[0], $_[1], CORE::length(KOI8R::substr($_[0], 0, $_[2])));
2845 0         0 }
2846             else {
2847             $rindex = Ekoi8r::rindex($_[0], $_[1]);
2848 0 0       0 }
2849 0         0  
2850             if ($rindex == -1) {
2851             return -1;
2852 0         0 }
2853             else {
2854             return KOI8R::length(CORE::substr $_[0], 0, $rindex);
2855             }
2856             }
2857              
2858 204     204   1728 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  204         521  
  204         30135  
2859             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2860             use vars qw($slash); $slash = 'm//';
2861              
2862             # ord() to ord() or KOI8R::ord()
2863             my $function_ord = 'ord';
2864              
2865             # ord to ord or KOI8R::ord_
2866             my $function_ord_ = 'ord';
2867              
2868             # reverse to reverse or KOI8R::reverse
2869             my $function_reverse = 'reverse';
2870              
2871             # getc to getc or KOI8R::getc
2872             my $function_getc = 'getc';
2873              
2874             # P.1023 Appendix W.9 Multibyte Anchoring
2875             # of ISBN 1-56592-224-7 CJKV Information Processing
2876              
2877 204     204   1749 my $anchor = '';
  204     0   350  
  204         9938172  
2878              
2879             use vars qw($nest);
2880              
2881             # regexp of nested parens in qqXX
2882              
2883             # P.340 Matching Nested Constructs with Embedded Code
2884             # in Chapter 7: Perl
2885             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2886              
2887             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2888             [^\\()] |
2889             \( (?{$nest++}) |
2890             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2891             \\ [^c] |
2892             \\c[\x40-\x5F] |
2893             [\x00-\xFF]
2894             }xms;
2895              
2896             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2897             [^\\{}] |
2898             \{ (?{$nest++}) |
2899             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2900             \\ [^c] |
2901             \\c[\x40-\x5F] |
2902             [\x00-\xFF]
2903             }xms;
2904              
2905             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2906             [^\\\[\]] |
2907             \[ (?{$nest++}) |
2908             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2909             \\ [^c] |
2910             \\c[\x40-\x5F] |
2911             [\x00-\xFF]
2912             }xms;
2913              
2914             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2915             [^\\<>] |
2916             \< (?{$nest++}) |
2917             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2918             \\ [^c] |
2919             \\c[\x40-\x5F] |
2920             [\x00-\xFF]
2921             }xms;
2922              
2923             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2924             (?: ::)? (?:
2925             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2926             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2927             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2928             ))
2929             }xms;
2930              
2931             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2932             (?: ::)? (?:
2933             (?>[0-9]+) |
2934             [^a-zA-Z_0-9\[\]] |
2935             ^[A-Z] |
2936             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2937             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2938             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2939             ))
2940             }xms;
2941              
2942             my $qq_substr = qr{(?> Char::substr | KOI8R::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2943             }xms;
2944              
2945             # regexp of nested parens in qXX
2946             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2947             [^()] |
2948             \( (?{$nest++}) |
2949             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2950             [\x00-\xFF]
2951             }xms;
2952              
2953             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2954             [^\{\}] |
2955             \{ (?{$nest++}) |
2956             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2957             [\x00-\xFF]
2958             }xms;
2959              
2960             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2961             [^\[\]] |
2962             \[ (?{$nest++}) |
2963             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2964             [\x00-\xFF]
2965             }xms;
2966              
2967             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2968             [^<>] |
2969             \< (?{$nest++}) |
2970             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2971             [\x00-\xFF]
2972             }xms;
2973              
2974             my $matched = '';
2975             my $s_matched = '';
2976              
2977             my $tr_variable = ''; # variable of tr///
2978             my $sub_variable = ''; # variable of s///
2979             my $bind_operator = ''; # =~ or !~
2980              
2981             my @heredoc = (); # here document
2982             my @heredoc_delimiter = ();
2983             my $here_script = ''; # here script
2984              
2985             #
2986             # escape KOI8-R script
2987 0 50   204 0 0 #
2988             sub KOI8R::escape(;$) {
2989             local($_) = $_[0] if @_;
2990              
2991             # P.359 The Study Function
2992             # in Chapter 7: Perl
2993 204         676 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2994              
2995             study $_; # Yes, I studied study yesterday.
2996              
2997             # while all script
2998              
2999             # 6.14. Matching from Where the Last Pattern Left Off
3000             # in Chapter 6. Pattern Matching
3001             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3002             # (and so on)
3003              
3004             # one member of Tag-team
3005             #
3006             # P.128 Start of match (or end of previous match): \G
3007             # P.130 Advanced Use of \G with Perl
3008             # in Chapter 3: Overview of Regular Expression Features and Flavors
3009             # P.255 Use leading anchors
3010             # P.256 Expose ^ and \G at the front expressions
3011             # in Chapter 6: Crafting an Efficient Expression
3012             # P.315 "Tag-team" matching with /gc
3013             # in Chapter 7: Perl
3014 204         434 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3015 204         369  
3016 204         802 my $e_script = '';
3017             while (not /\G \z/oxgc) { # member
3018             $e_script .= KOI8R::escape_token();
3019 74633         116460 }
3020              
3021             return $e_script;
3022             }
3023              
3024             #
3025             # escape KOI8-R token of script
3026             #
3027             sub KOI8R::escape_token {
3028              
3029 204     74633 0 2655 # \n output here document
3030              
3031             my $ignore_modules = join('|', qw(
3032             utf8
3033             bytes
3034             charnames
3035             I18N::Japanese
3036             I18N::Collate
3037             I18N::JExt
3038             File::DosGlob
3039             Wild
3040             Wildcard
3041             Japanese
3042             ));
3043              
3044             # another member of Tag-team
3045             #
3046             # P.315 "Tag-team" matching with /gc
3047             # in Chapter 7: Perl
3048 74633 100 100     97124 # 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          
3049 74633         3146767  
3050 12510 100       16498 if (/\G ( \n ) /oxgc) { # another member (and so on)
3051 12510         21460 my $heredoc = '';
3052             if (scalar(@heredoc_delimiter) >= 1) {
3053 174         232 $slash = 'm//';
3054 174         366  
3055             $heredoc = join '', @heredoc;
3056             @heredoc = ();
3057 174         306  
3058 174         289 # skip here document
3059             for my $heredoc_delimiter (@heredoc_delimiter) {
3060 174         1092 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3061             }
3062 174         296 @heredoc_delimiter = ();
3063              
3064 174         241 $here_script = '';
3065             }
3066             return "\n" . $heredoc;
3067             }
3068 12510         37937  
3069             # ignore space, comment
3070             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3071              
3072             # if (, elsif (, unless (, while (, until (, given (, and when (
3073              
3074             # given, when
3075              
3076             # P.225 The given Statement
3077             # in Chapter 15: Smart Matching and given-when
3078             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3079              
3080             # P.133 The given Statement
3081             # in Chapter 4: Statements and Declarations
3082             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3083 17914         65081  
3084 1401         2719 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3085             $slash = 'm//';
3086             return $1;
3087             }
3088              
3089             # scalar variable ($scalar = ...) =~ tr///;
3090             # scalar variable ($scalar = ...) =~ s///;
3091              
3092             # state
3093              
3094             # P.68 Persistent, Private Variables
3095             # in Chapter 4: Subroutines
3096             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3097              
3098             # P.160 Persistent Lexically Scoped Variables: state
3099             # in Chapter 4: Statements and Declarations
3100             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3101              
3102             # (and so on)
3103 1401         4789  
3104             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3105 86 50       187 my $e_string = e_string($1);
    50          
3106 86         1969  
3107 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3108 0         0 $tr_variable = $e_string . e_string($1);
3109 0         0 $bind_operator = $2;
3110             $slash = 'm//';
3111             return '';
3112 0         0 }
3113 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3114 0         0 $sub_variable = $e_string . e_string($1);
3115 0         0 $bind_operator = $2;
3116             $slash = 'm//';
3117             return '';
3118 0         0 }
3119 86         159 else {
3120             $slash = 'div';
3121             return $e_string;
3122             }
3123             }
3124              
3125 86         274 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
3126 4         8 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3127             $slash = 'div';
3128             return q{Ekoi8r::PREMATCH()};
3129             }
3130              
3131 4         11 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
3132 28         60 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3133             $slash = 'div';
3134             return q{Ekoi8r::MATCH()};
3135             }
3136              
3137 28         86 # $', ${'} --> $', ${'}
3138 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3139             $slash = 'div';
3140             return $1;
3141             }
3142              
3143 1         3 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
3144 3         7 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3145             $slash = 'div';
3146             return q{Ekoi8r::POSTMATCH()};
3147             }
3148              
3149             # scalar variable $scalar =~ tr///;
3150             # scalar variable $scalar =~ s///;
3151             # substr() =~ tr///;
3152 3         9 # substr() =~ s///;
3153             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3154 1671 100       3646 my $scalar = e_string($1);
    100          
3155 1671         6434  
3156 1         2 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3157 1         2 $tr_variable = $scalar;
3158 1         2 $bind_operator = $1;
3159             $slash = 'm//';
3160             return '';
3161 1         3 }
3162 61         121 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3163 61         269 $sub_variable = $scalar;
3164 61         88 $bind_operator = $1;
3165             $slash = 'm//';
3166             return '';
3167 61         175 }
3168 1609         2412 else {
3169             $slash = 'div';
3170             return $scalar;
3171             }
3172             }
3173              
3174 1609         7259 # end of statement
3175             elsif (/\G ( [,;] ) /oxgc) {
3176             $slash = 'm//';
3177 4986         7651  
3178             # clear tr/// variable
3179             $tr_variable = '';
3180 4986         6781  
3181             # clear s/// variable
3182 4986         6030 $sub_variable = '';
3183              
3184 4986         6422 $bind_operator = '';
3185              
3186             return $1;
3187             }
3188              
3189 4986         21785 # bareword
3190             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3191             return $1;
3192             }
3193              
3194 0         0 # $0 --> $0
3195 2         5 elsif (/\G ( \$ 0 ) /oxmsgc) {
3196             $slash = 'div';
3197             return $1;
3198 2         7 }
3199 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3200             $slash = 'div';
3201             return $1;
3202             }
3203              
3204 0         0 # $$ --> $$
3205 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3206             $slash = 'div';
3207             return $1;
3208             }
3209              
3210             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3211 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
3212 4         7 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3213             $slash = 'div';
3214             return e_capture($1);
3215 4         9 }
3216 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3217             $slash = 'div';
3218             return e_capture($1);
3219             }
3220              
3221 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3222 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3223             $slash = 'div';
3224             return e_capture($1.'->'.$2);
3225             }
3226              
3227 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3228 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3229             $slash = 'div';
3230             return e_capture($1.'->'.$2);
3231             }
3232              
3233 0         0 # $$foo
3234 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3235             $slash = 'div';
3236             return e_capture($1);
3237             }
3238              
3239 0         0 # ${ foo }
3240 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3241             $slash = 'div';
3242             return '${' . $1 . '}';
3243             }
3244              
3245 0         0 # ${ ... }
3246 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3247             $slash = 'div';
3248             return e_capture($1);
3249             }
3250              
3251             # variable or function
3252 0         0 # $ @ % & * $ #
3253 42         69 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) {
3254             $slash = 'div';
3255             return $1;
3256             }
3257             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3258 42         131 # $ @ # \ ' " / ? ( ) [ ] < >
3259 62         133 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3260             $slash = 'div';
3261             return $1;
3262             }
3263              
3264 62         236 # while ()
3265             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3266             return $1;
3267             }
3268              
3269             # while () --- glob
3270              
3271             # avoid "Error: Runtime exception" of perl version 5.005_03
3272 0         0  
3273             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3274             return 'while ($_ = Ekoi8r::glob("' . $1 . '"))';
3275             }
3276              
3277 0         0 # while (glob)
3278             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3279             return 'while ($_ = Ekoi8r::glob_)';
3280             }
3281              
3282 0         0 # while (glob(WILDCARD))
3283             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3284             return 'while ($_ = Ekoi8r::glob';
3285             }
3286 0         0  
  248         543  
3287             # doit if, doit unless, doit while, doit until, doit for, doit when
3288             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3289 248         966  
  19         39  
3290 19         72 # subroutines of package Ekoi8r
  0         0  
3291 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         17  
3292 13         36 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3293 0         0 elsif (/\G \b KOI8R::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         177  
3294 114         306 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         6  
3295 2         5 elsif (/\G \b KOI8R::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval KOI8R::escape'; }
  0         0  
3296 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         3  
3297 2         5 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::chop'; }
  0         0  
3298 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3299 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3300 0         0 elsif (/\G \b KOI8R::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8R::index'; }
  2         5  
3301 2         5 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::index'; }
  0         0  
3302 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3303 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3304 0         0 elsif (/\G \b KOI8R::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'KOI8R::rindex'; }
  1         2  
3305 1         3 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::rindex'; }
  0         0  
3306 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::lc'; }
  1         13  
3307 1         5 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::lcfirst'; }
  0         0  
3308 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::uc'; }
  6         9  
3309             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::ucfirst'; }
3310             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::fc'; }
3311 6         20  
  0         0  
3312 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3313 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3314 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3315 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3316 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3317 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3318             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3319 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  
3320 0         0  
  0         0  
3321 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3322 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3323 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3324 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3325 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3326             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3327             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3328 0         0  
  0         0  
3329 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3330 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3331 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3332             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3333 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         3  
3334 2         6  
  2         5  
3335 2         6 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         63  
3336 36         130 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         5  
3337 2         6 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::chr'; }
  8         14  
3338 8         24 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3339 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3340 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::glob'; }
  0         0  
3341 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::lc_'; }
  0         0  
3342 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::lcfirst_'; }
  0         0  
3343 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::uc_'; }
  0         0  
3344 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::ucfirst_'; }
  0         0  
3345             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::fc_'; }
3346 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3347 0         0  
  0         0  
3348 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3349 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3350 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::chr_'; }
  0         0  
3351 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3352 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3353 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ekoi8r::glob_'; }
  8         20  
3354             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3355             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3356 8         28 # split
3357             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3358 87         196 $slash = 'm//';
3359 87         181  
3360 87         429 my $e = '';
3361             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3362             $e .= $1;
3363             }
3364 85 100       330  
  87 100       5984  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3365             # end of split
3366             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8r::split' . $e; }
3367 2         9  
3368             # split scalar value
3369             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Ekoi8r::split' . $e . e_string($1); }
3370 1         5  
3371 0         0 # split literal space
3372 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Ekoi8r::split' . $e . qq {qq$1 $2}; }
3373 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3374 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3375 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3376 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3377 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; }
3378 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Ekoi8r::split' . $e . qq {q$1 $2}; }
3379 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3380 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3381 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3382 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3383 10         44 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ekoi8r::split' . $e . qq {$1q$2 $3}; }
3384             elsif (/\G ' [ ] ' /oxgc) { return 'Ekoi8r::split' . $e . qq {' '}; }
3385             elsif (/\G " [ ] " /oxgc) { return 'Ekoi8r::split' . $e . qq {" "}; }
3386              
3387 0 0       0 # split qq//
  0         0  
3388             elsif (/\G \b (qq) \b /oxgc) {
3389 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3390 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3391 0         0 while (not /\G \z/oxgc) {
3392 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3393 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3394 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3395 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3396 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3397             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3398 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3399             }
3400             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3401             }
3402             }
3403              
3404 0 50       0 # split qr//
  12         481  
3405             elsif (/\G \b (qr) \b /oxgc) {
3406 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3407 12 50       67 else {
  12 50       3960  
    50          
    50          
    50          
    50          
    50          
    50          
3408 0         0 while (not /\G \z/oxgc) {
3409 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3410 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3411 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3412 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3413 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3414 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3415             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3416 12         129 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3417             }
3418             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3419             }
3420             }
3421              
3422 0 0       0 # split q//
  0         0  
3423             elsif (/\G \b (q) \b /oxgc) {
3424 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3425 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3426 0         0 while (not /\G \z/oxgc) {
3427 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3428 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3429 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3430 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3431 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3432             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3433 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3434             }
3435             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3436             }
3437             }
3438              
3439 0 50       0 # split m//
  18         472  
3440             elsif (/\G \b (m) \b /oxgc) {
3441 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3442 18 50       78 else {
  18 50       3881  
    50          
    50          
    50          
    50          
    50          
    50          
3443 0         0 while (not /\G \z/oxgc) {
3444 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3445 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3446 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3447 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3448 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3449 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3450             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3451 18         107 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3452             }
3453             die __FILE__, ": Search pattern not terminated\n";
3454             }
3455             }
3456              
3457 0         0 # split ''
3458 0         0 elsif (/\G (\') /oxgc) {
3459 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3460 0         0 while (not /\G \z/oxgc) {
3461 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3462 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3463             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3464 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3465             }
3466             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3467             }
3468              
3469 0         0 # split ""
3470 0         0 elsif (/\G (\") /oxgc) {
3471 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3472 0         0 while (not /\G \z/oxgc) {
3473 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3474 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3475             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3476 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3477             }
3478             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3479             }
3480              
3481 0         0 # split //
3482 44         114 elsif (/\G (\/) /oxgc) {
3483 44 50       188 my $regexp = '';
  381 50       1569  
    100          
    50          
3484 0         0 while (not /\G \z/oxgc) {
3485 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3486 44         191 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3487             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3488 337         772 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3489             }
3490             die __FILE__, ": Search pattern not terminated\n";
3491             }
3492             }
3493              
3494             # tr/// or y///
3495              
3496             # about [cdsrbB]* (/B modifier)
3497             #
3498             # P.559 appendix C
3499             # of ISBN 4-89052-384-7 Programming perl
3500             # (Japanese title is: Perl puroguramingu)
3501 0         0  
3502             elsif (/\G \b ( tr | y ) \b /oxgc) {
3503             my $ope = $1;
3504 3 50       7  
3505 3         39 # $1 $2 $3 $4 $5 $6
3506 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3507             my @tr = ($tr_variable,$2);
3508             return e_tr(@tr,'',$4,$6);
3509 0         0 }
3510 3         6 else {
3511 3 50       8 my $e = '';
  3 50       214  
    50          
    50          
    50          
    50          
3512             while (not /\G \z/oxgc) {
3513 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3514 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3515 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3516 0         0 while (not /\G \z/oxgc) {
3517 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3518 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3519 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3520 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3521             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3522 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3523             }
3524             die __FILE__, ": Transliteration replacement not terminated\n";
3525 0         0 }
3526 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3527 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3528 0         0 while (not /\G \z/oxgc) {
3529 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3530 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3531 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3532 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3533             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3534 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3535             }
3536             die __FILE__, ": Transliteration replacement not terminated\n";
3537 0         0 }
3538 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3539 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3540 0         0 while (not /\G \z/oxgc) {
3541 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3542 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3543 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3544 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3545             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3546 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3547             }
3548             die __FILE__, ": Transliteration replacement not terminated\n";
3549 0         0 }
3550 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3551 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3552 0         0 while (not /\G \z/oxgc) {
3553 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3554 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3555 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3556 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3557             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3558 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3559             }
3560             die __FILE__, ": Transliteration replacement not terminated\n";
3561             }
3562 0         0 # $1 $2 $3 $4 $5 $6
3563 3         11 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3564             my @tr = ($tr_variable,$2);
3565             return e_tr(@tr,'',$4,$6);
3566 3         9 }
3567             }
3568             die __FILE__, ": Transliteration pattern not terminated\n";
3569             }
3570             }
3571              
3572 0         0 # qq//
3573             elsif (/\G \b (qq) \b /oxgc) {
3574             my $ope = $1;
3575 2180 50       5268  
3576 2180         4070 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3577 0         0 if (/\G (\#) /oxgc) { # qq# #
3578 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3579 0         0 while (not /\G \z/oxgc) {
3580 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3581 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3582             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3583 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3584             }
3585             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3586             }
3587 0         0  
3588 2180         2844 else {
3589 2180 50       5258 my $e = '';
  2180 50       8506  
    100          
    50          
    50          
    0          
3590             while (not /\G \z/oxgc) {
3591             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3592              
3593 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3594 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3595 0         0 my $qq_string = '';
3596 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3597 0         0 while (not /\G \z/oxgc) {
3598 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3599             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3600 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3601 0         0 elsif (/\G (\)) /oxgc) {
3602             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3603 0         0 else { $qq_string .= $1; }
3604             }
3605 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3606             }
3607             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3608             }
3609              
3610 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3611 2150         3387 elsif (/\G (\{) /oxgc) { # qq { }
3612 2150         3000 my $qq_string = '';
3613 2150 100       4660 local $nest = 1;
  83993 50       286569  
    100          
    100          
    50          
3614 722         1479 while (not /\G \z/oxgc) {
3615 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         3403  
3616             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3617 1153 100       2033 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         4866  
3618 2150         4666 elsif (/\G (\}) /oxgc) {
3619             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3620 1153         2399 else { $qq_string .= $1; }
3621             }
3622 78815         196065 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3623             }
3624             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3625             }
3626              
3627 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3628 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3629 0         0 my $qq_string = '';
3630 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3631 0         0 while (not /\G \z/oxgc) {
3632 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3633             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3634 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3635 0         0 elsif (/\G (\]) /oxgc) {
3636             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3637 0         0 else { $qq_string .= $1; }
3638             }
3639 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3640             }
3641             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3642             }
3643              
3644 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3645 30         48 elsif (/\G (\<) /oxgc) { # qq < >
3646 30         102 my $qq_string = '';
3647 30 100       95 local $nest = 1;
  1166 50       4167  
    50          
    100          
    50          
3648 22         53 while (not /\G \z/oxgc) {
3649 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3650             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3651 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         118  
3652 30         71 elsif (/\G (\>) /oxgc) {
3653             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3654 0         0 else { $qq_string .= $1; }
3655             }
3656 1114         2294 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3657             }
3658             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3659             }
3660              
3661 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3662 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3663 0         0 my $delimiter = $1;
3664 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3665 0         0 while (not /\G \z/oxgc) {
3666 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3667 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3668             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3669 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3670             }
3671             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3672 0         0 }
3673             }
3674             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3675             }
3676             }
3677              
3678 0         0 # qr//
3679 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3680 0         0 my $ope = $1;
3681             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3682             return e_qr($ope,$1,$3,$2,$4);
3683 0         0 }
3684 0         0 else {
3685 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3686 0         0 while (not /\G \z/oxgc) {
3687 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3688 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3689 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3690 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3691 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3692 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3693             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3694 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3695             }
3696             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3697             }
3698             }
3699              
3700 0         0 # qw//
3701 16 50       46 elsif (/\G \b (qw) \b /oxgc) {
3702 16         92 my $ope = $1;
3703             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3704             return e_qw($ope,$1,$3,$2);
3705 0         0 }
3706 16         33 else {
3707 16 50       58 my $e = '';
  16 50       94  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3708             while (not /\G \z/oxgc) {
3709 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3710 16         51  
3711             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3712 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3713 0         0  
3714             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3715 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3716 0         0  
3717             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3718 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3719 0         0  
3720             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3721 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3722 0         0  
3723             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3724 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3725             }
3726             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3727             }
3728             }
3729              
3730 0         0 # qx//
3731 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3732 0         0 my $ope = $1;
3733             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3734             return e_qq($ope,$1,$3,$2);
3735 0         0 }
3736 0         0 else {
3737 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3738 0         0 while (not /\G \z/oxgc) {
3739 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3740 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3741 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3742 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3743 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3744             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3745 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3746             }
3747             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3748             }
3749             }
3750              
3751 0         0 # q//
3752             elsif (/\G \b (q) \b /oxgc) {
3753             my $ope = $1;
3754              
3755             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3756              
3757             # avoid "Error: Runtime exception" of perl version 5.005_03
3758 410 50       1292 # (and so on)
3759 410         1228  
3760 0         0 if (/\G (\#) /oxgc) { # q# #
3761 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3762 0         0 while (not /\G \z/oxgc) {
3763 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3764 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3765             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3766 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3767             }
3768             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3769             }
3770 0         0  
3771 410         651 else {
3772 410 50       1203 my $e = '';
  410 50       2202  
    100          
    50          
    100          
    50          
3773             while (not /\G \z/oxgc) {
3774             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3775              
3776 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3777 0         0 elsif (/\G (\() /oxgc) { # q ( )
3778 0         0 my $q_string = '';
3779 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3780 0         0 while (not /\G \z/oxgc) {
3781 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3782 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3783             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3784 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3785 0         0 elsif (/\G (\)) /oxgc) {
3786             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3787 0         0 else { $q_string .= $1; }
3788             }
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              
3794 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3795 404         757 elsif (/\G (\{) /oxgc) { # q { }
3796 404         704 my $q_string = '';
3797 404 50       1043 local $nest = 1;
  6757 50       24517  
    50          
    100          
    100          
    50          
3798 0         0 while (not /\G \z/oxgc) {
3799 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3800 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         210  
3801             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3802 107 100       212 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         1143  
3803 404         1075 elsif (/\G (\}) /oxgc) {
3804             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3805 107         210 else { $q_string .= $1; }
3806             }
3807 6139         12696 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3808             }
3809             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3810             }
3811              
3812 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3813 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3814 0         0 my $q_string = '';
3815 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3816 0         0 while (not /\G \z/oxgc) {
3817 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3818 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3819             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3820 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3821 0         0 elsif (/\G (\]) /oxgc) {
3822             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3823 0         0 else { $q_string .= $1; }
3824             }
3825 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3826             }
3827             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3828             }
3829              
3830 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3831 5         11 elsif (/\G (\<) /oxgc) { # q < >
3832 5         10 my $q_string = '';
3833 5 50       18 local $nest = 1;
  88 50       361  
    50          
    50          
    100          
    50          
3834 0         0 while (not /\G \z/oxgc) {
3835 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3836 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3837             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3838 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         14  
3839 5         14 elsif (/\G (\>) /oxgc) {
3840             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3841 0         0 else { $q_string .= $1; }
3842             }
3843 83         153 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3844             }
3845             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3846             }
3847              
3848 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3849 1         3 elsif (/\G (\S) /oxgc) { # q * *
3850 1         2 my $delimiter = $1;
3851 1 50       3 my $q_string = '';
  14 50       67  
    100          
    50          
3852 0         0 while (not /\G \z/oxgc) {
3853 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3854 1         12 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3855             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3856 13         24 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3857             }
3858             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3859 0         0 }
3860             }
3861             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3862             }
3863             }
3864              
3865 0         0 # m//
3866 209 50       538 elsif (/\G \b (m) \b /oxgc) {
3867 209         1369 my $ope = $1;
3868             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3869             return e_qr($ope,$1,$3,$2,$4);
3870 0         0 }
3871 209         351 else {
3872 209 50       791 my $e = '';
  209 50       11230  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3873 0         0 while (not /\G \z/oxgc) {
3874 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3875 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3876 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3877 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3878 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3879 10         32 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3880 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3881             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3882 199         745 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3883             }
3884             die __FILE__, ": Search pattern not terminated\n";
3885             }
3886             }
3887              
3888             # s///
3889              
3890             # about [cegimosxpradlunbB]* (/cg modifier)
3891             #
3892             # P.67 Pattern-Matching Operators
3893             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3894 0         0  
3895             elsif (/\G \b (s) \b /oxgc) {
3896             my $ope = $1;
3897 97 100       298  
3898 97         1627 # $1 $2 $3 $4 $5 $6
3899             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3900             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3901 1         7 }
3902 96         192 else {
3903 96 50       290 my $e = '';
  96 50       12250  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3904             while (not /\G \z/oxgc) {
3905 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3906 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3907 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3908             while (not /\G \z/oxgc) {
3909 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3910 0         0 # $1 $2 $3 $4
3911 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3912 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3913 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3914 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3915 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3916 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3917 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3918             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3919 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3920             }
3921             die __FILE__, ": Substitution replacement not terminated\n";
3922 0         0 }
3923 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3924 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3925             while (not /\G \z/oxgc) {
3926 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3927 0         0 # $1 $2 $3 $4
3928 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3929 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3930 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3931 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3932 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3933 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3934 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3935             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3936 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3937             }
3938             die __FILE__, ": Substitution replacement not terminated\n";
3939 0         0 }
3940 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3941 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3942             while (not /\G \z/oxgc) {
3943 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3944 0         0 # $1 $2 $3 $4
3945 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3946 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3947 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3948 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3949 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3950             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3951 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3952             }
3953             die __FILE__, ": Substitution replacement not terminated\n";
3954 0         0 }
3955 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3956 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3957             while (not /\G \z/oxgc) {
3958 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3959 0         0 # $1 $2 $3 $4
3960 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3961 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3962 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3963 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3964 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3965 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3966 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3967             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3968 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3969             }
3970             die __FILE__, ": Substitution replacement not terminated\n";
3971             }
3972 0         0 # $1 $2 $3 $4 $5 $6
3973             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3974             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3975             }
3976 21         62 # $1 $2 $3 $4 $5 $6
3977             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3978             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3979             }
3980 0         0 # $1 $2 $3 $4 $5 $6
3981             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3982             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3983             }
3984 0         0 # $1 $2 $3 $4 $5 $6
3985             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3986             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3987 75         319 }
3988             }
3989             die __FILE__, ": Substitution pattern not terminated\n";
3990             }
3991             }
3992 0         0  
3993 0         0 # require ignore module
3994 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
3995             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
3996             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
3997 0         0  
3998 37         309 # use strict; --> use strict; no strict qw(refs);
3999 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4000             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4001             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4002              
4003 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
4004 2         25 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4005             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4006             return "use $1; no strict qw(refs);";
4007 0         0 }
4008             else {
4009             return "use $1;";
4010             }
4011 2 0 0     10 }
      0        
4012 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4013             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4014             return "use $1; no strict qw(refs);";
4015 0         0 }
4016             else {
4017             return "use $1;";
4018             }
4019             }
4020 0         0  
4021 2         13 # ignore use module
4022 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4023             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4024             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4025 0         0  
4026 0         0 # ignore no module
4027 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4028             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4029             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4030 0         0  
4031             # use else
4032             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4033 0         0  
4034             # use else
4035             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4036              
4037 2         8 # ''
4038 848         1885 elsif (/\G (?
4039 848 100       2513 my $q_string = '';
  8241 100       26616  
    100          
    50          
4040 4         10 while (not /\G \z/oxgc) {
4041 48         85 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4042 848         1917 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4043             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4044 7341         14623 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4045             }
4046             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4047             }
4048              
4049 0         0 # ""
4050 1780         3953 elsif (/\G (\") /oxgc) {
4051 1780 100       4487 my $qq_string = '';
  34872 100       105253  
    100          
    50          
4052 67         159 while (not /\G \z/oxgc) {
4053 12         24 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4054 1780         4056 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4055             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4056 33013         67857 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4057             }
4058             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4059             }
4060              
4061 0         0 # ``
4062 1         2 elsif (/\G (\`) /oxgc) {
4063 1 50       4 my $qx_string = '';
  19 50       68  
    100          
    50          
4064 0         0 while (not /\G \z/oxgc) {
4065 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4066 1         4 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4067             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4068 18         34 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4069             }
4070             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4071             }
4072              
4073 0         0 # // --- not divide operator (num / num), not defined-or
4074 453         1714 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4075 453 50       1446 my $regexp = '';
  4496 50       14936  
    100          
    50          
4076 0         0 while (not /\G \z/oxgc) {
4077 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4078 453         2954 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4079             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4080 4043         8279 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4081             }
4082             die __FILE__, ": Search pattern not terminated\n";
4083             }
4084              
4085 0         0 # ?? --- not conditional operator (condition ? then : else)
4086 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4087 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4088 0         0 while (not /\G \z/oxgc) {
4089 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4090 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4091             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4092 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4093             }
4094             die __FILE__, ": Search pattern not terminated\n";
4095             }
4096 0         0  
  0         0  
4097             # <<>> (a safer ARGV)
4098             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4099 0         0  
  0         0  
4100             # << (bit shift) --- not here document
4101             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4102              
4103 0         0 # <<~'HEREDOC'
4104 6         17 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4105 6         14 $slash = 'm//';
4106             my $here_quote = $1;
4107             my $delimiter = $2;
4108 6 50       19  
4109 6         19 # get here document
4110 6         92 if ($here_script eq '') {
4111             $here_script = CORE::substr $_, pos $_;
4112 6 50       43 $here_script =~ s/.*?\n//oxm;
4113 6         80 }
4114 6         15 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4115 6         14 my $heredoc = $1;
4116 6         93 my $indent = $2;
4117 6         30 $heredoc =~ s{^$indent}{}msg; # no /ox
4118             push @heredoc, $heredoc . qq{\n$delimiter\n};
4119             push @heredoc_delimiter, qq{\\s*$delimiter};
4120 6         18 }
4121             else {
4122 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4123             }
4124             return qq{<<'$delimiter'};
4125             }
4126              
4127             # <<~\HEREDOC
4128              
4129             # P.66 2.6.6. "Here" Documents
4130             # in Chapter 2: Bits and Pieces
4131             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4132              
4133             # P.73 "Here" Documents
4134             # in Chapter 2: Bits and Pieces
4135             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4136 6         29  
4137 3         8 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4138 3         9 $slash = 'm//';
4139             my $here_quote = $1;
4140             my $delimiter = $2;
4141 3 50       10  
4142 3         10 # get here document
4143 3         16 if ($here_script eq '') {
4144             $here_script = CORE::substr $_, pos $_;
4145 3 50       55 $here_script =~ s/.*?\n//oxm;
4146 3         56 }
4147 3         25 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4148 3         6 my $heredoc = $1;
4149 3         49 my $indent = $2;
4150 3         16 $heredoc =~ s{^$indent}{}msg; # no /ox
4151             push @heredoc, $heredoc . qq{\n$delimiter\n};
4152             push @heredoc_delimiter, qq{\\s*$delimiter};
4153 3         12 }
4154             else {
4155 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4156             }
4157             return qq{<<\\$delimiter};
4158             }
4159              
4160 3         16 # <<~"HEREDOC"
4161 6         10 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4162 6         13 $slash = 'm//';
4163             my $here_quote = $1;
4164             my $delimiter = $2;
4165 6 50       7  
4166 6         12 # get here document
4167 6         27 if ($here_script eq '') {
4168             $here_script = CORE::substr $_, pos $_;
4169 6 50       29 $here_script =~ s/.*?\n//oxm;
4170 6         61 }
4171 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4172 6         8 my $heredoc = $1;
4173 6         45 my $indent = $2;
4174 6         16 $heredoc =~ s{^$indent}{}msg; # no /ox
4175             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4176             push @heredoc_delimiter, qq{\\s*$delimiter};
4177 6         13 }
4178             else {
4179 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4180             }
4181             return qq{<<"$delimiter"};
4182             }
4183              
4184 6         22 # <<~HEREDOC
4185 3         5 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4186 3         6 $slash = 'm//';
4187             my $here_quote = $1;
4188             my $delimiter = $2;
4189 3 50       7  
4190 3         8 # get here document
4191 3         20 if ($here_script eq '') {
4192             $here_script = CORE::substr $_, pos $_;
4193 3 50       18 $here_script =~ s/.*?\n//oxm;
4194 3         37 }
4195 3         6 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4196 3         6 my $heredoc = $1;
4197 3         43 my $indent = $2;
4198 3         12 $heredoc =~ s{^$indent}{}msg; # no /ox
4199             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4200             push @heredoc_delimiter, qq{\\s*$delimiter};
4201 3         8 }
4202             else {
4203 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4204             }
4205             return qq{<<$delimiter};
4206             }
4207              
4208 3         12 # <<~`HEREDOC`
4209 6         12 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4210 6         11 $slash = 'm//';
4211             my $here_quote = $1;
4212             my $delimiter = $2;
4213 6 50       11  
4214 6         11 # get here document
4215 6         18 if ($here_script eq '') {
4216             $here_script = CORE::substr $_, pos $_;
4217 6 50       31 $here_script =~ s/.*?\n//oxm;
4218 6         57 }
4219 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4220 6         9 my $heredoc = $1;
4221 6         59 my $indent = $2;
4222 6         19 $heredoc =~ s{^$indent}{}msg; # no /ox
4223             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4224             push @heredoc_delimiter, qq{\\s*$delimiter};
4225 6         13 }
4226             else {
4227 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4228             }
4229             return qq{<<`$delimiter`};
4230             }
4231              
4232 6         25 # <<'HEREDOC'
4233 72         137 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4234 72         145 $slash = 'm//';
4235             my $here_quote = $1;
4236             my $delimiter = $2;
4237 72 50       108  
4238 72         136 # get here document
4239 72         478 if ($here_script eq '') {
4240             $here_script = CORE::substr $_, pos $_;
4241 72 50       393 $here_script =~ s/.*?\n//oxm;
4242 72         587 }
4243 72         229 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4244             push @heredoc, $1 . qq{\n$delimiter\n};
4245             push @heredoc_delimiter, $delimiter;
4246 72         115 }
4247             else {
4248 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4249             }
4250             return $here_quote;
4251             }
4252              
4253             # <<\HEREDOC
4254              
4255             # P.66 2.6.6. "Here" Documents
4256             # in Chapter 2: Bits and Pieces
4257             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4258              
4259             # P.73 "Here" Documents
4260             # in Chapter 2: Bits and Pieces
4261             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4262 72         269  
4263 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4264 0         0 $slash = 'm//';
4265             my $here_quote = $1;
4266             my $delimiter = $2;
4267 0 0       0  
4268 0         0 # get here document
4269 0         0 if ($here_script eq '') {
4270             $here_script = CORE::substr $_, pos $_;
4271 0 0       0 $here_script =~ s/.*?\n//oxm;
4272 0         0 }
4273 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4274             push @heredoc, $1 . qq{\n$delimiter\n};
4275             push @heredoc_delimiter, $delimiter;
4276 0         0 }
4277             else {
4278 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4279             }
4280             return $here_quote;
4281             }
4282              
4283 0         0 # <<"HEREDOC"
4284 36         110 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4285 36         82 $slash = 'm//';
4286             my $here_quote = $1;
4287             my $delimiter = $2;
4288 36 50       61  
4289 36         94 # get here document
4290 36         313 if ($here_script eq '') {
4291             $here_script = CORE::substr $_, pos $_;
4292 36 50       207 $here_script =~ s/.*?\n//oxm;
4293 36         515 }
4294 36         127 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4295             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4296             push @heredoc_delimiter, $delimiter;
4297 36         96 }
4298             else {
4299 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4300             }
4301             return $here_quote;
4302             }
4303              
4304 36         146 # <
4305 42         98 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4306 42         93 $slash = 'm//';
4307             my $here_quote = $1;
4308             my $delimiter = $2;
4309 42 50       75  
4310 42         106 # get here document
4311 42         252 if ($here_script eq '') {
4312             $here_script = CORE::substr $_, pos $_;
4313 42 50       402 $here_script =~ s/.*?\n//oxm;
4314 42         667 }
4315 42         148 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4316             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4317             push @heredoc_delimiter, $delimiter;
4318 42         102 }
4319             else {
4320 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4321             }
4322             return $here_quote;
4323             }
4324              
4325 42         177 # <<`HEREDOC`
4326 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4327 0         0 $slash = 'm//';
4328             my $here_quote = $1;
4329             my $delimiter = $2;
4330 0 0       0  
4331 0         0 # get here document
4332 0         0 if ($here_script eq '') {
4333             $here_script = CORE::substr $_, pos $_;
4334 0 0       0 $here_script =~ s/.*?\n//oxm;
4335 0         0 }
4336 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4337             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4338             push @heredoc_delimiter, $delimiter;
4339 0         0 }
4340             else {
4341 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4342             }
4343             return $here_quote;
4344             }
4345              
4346 0         0 # <<= <=> <= < operator
4347             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4348             return $1;
4349             }
4350              
4351 12         58 #
4352             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4353             return $1;
4354             }
4355              
4356             # --- glob
4357              
4358             # avoid "Error: Runtime exception" of perl version 5.005_03
4359 0         0  
4360             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4361             return 'Ekoi8r::glob("' . $1 . '")';
4362             }
4363 0         0  
4364             # __DATA__
4365             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4366 0         0  
4367             # __END__
4368             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4369              
4370             # \cD Control-D
4371              
4372             # P.68 2.6.8. Other Literal Tokens
4373             # in Chapter 2: Bits and Pieces
4374             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4375              
4376             # P.76 Other Literal Tokens
4377             # in Chapter 2: Bits and Pieces
4378 204         1470 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4379              
4380             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4381 0         0  
4382             # \cZ Control-Z
4383             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4384              
4385             # any operator before div
4386             elsif (/\G (
4387             -- | \+\+ |
4388 0         0 [\)\}\]]
  5081         11218  
4389              
4390             ) /oxgc) { $slash = 'div'; return $1; }
4391              
4392             # yada-yada or triple-dot operator
4393             elsif (/\G (
4394 5081         23563 \.\.\.
  7         14  
4395              
4396             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4397              
4398             # any operator before m//
4399              
4400             # //, //= (defined-or)
4401              
4402             # P.164 Logical Operators
4403             # in Chapter 10: More Control Structures
4404             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4405              
4406             # P.119 C-Style Logical (Short-Circuit) Operators
4407             # in Chapter 3: Unary and Binary Operators
4408             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4409              
4410             # (and so on)
4411              
4412             # ~~
4413              
4414             # P.221 The Smart Match Operator
4415             # in Chapter 15: Smart Matching and given-when
4416             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4417              
4418             # P.112 Smartmatch Operator
4419             # in Chapter 3: Unary and Binary Operators
4420             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4421              
4422             # (and so on)
4423              
4424             elsif (/\G ((?>
4425              
4426             !~~ | !~ | != | ! |
4427             %= | % |
4428             &&= | && | &= | &\.= | &\. | & |
4429             -= | -> | - |
4430             :(?>\s*)= |
4431             : |
4432             <<>> |
4433             <<= | <=> | <= | < |
4434             == | => | =~ | = |
4435             >>= | >> | >= | > |
4436             \*\*= | \*\* | \*= | \* |
4437             \+= | \+ |
4438             \.\. | \.= | \. |
4439             \/\/= | \/\/ |
4440             \/= | \/ |
4441             \? |
4442             \\ |
4443             \^= | \^\.= | \^\. | \^ |
4444             \b x= |
4445             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4446             ~~ | ~\. | ~ |
4447             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4448             \b(?: print )\b |
4449              
4450 7         25 [,;\(\{\[]
  8834         19789  
4451              
4452             )) /oxgc) { $slash = 'm//'; return $1; }
4453 8834         48564  
  15013         29274  
4454             # other any character
4455             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4456              
4457 15013         72652 # system error
4458             else {
4459             die __FILE__, ": Oops, this shouldn't happen!\n";
4460             }
4461             }
4462              
4463 0     1786 0 0 # escape KOI8-R string
4464 1786         4367 sub e_string {
4465             my($string) = @_;
4466 1786         2642 my $e_string = '';
4467              
4468             local $slash = 'm//';
4469              
4470             # P.1024 Appendix W.10 Multibyte Processing
4471             # of ISBN 1-56592-224-7 CJKV Information Processing
4472 1786         2542 # (and so on)
4473              
4474             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4475 1786 100 66     13632  
4476 1786 50       7525 # without { ... }
4477 1769         4236 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4478             if ($string !~ /<
4479             return $string;
4480             }
4481             }
4482 1769         7869  
4483 17 50       53 E_STRING_LOOP:
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
4484             while ($string !~ /\G \z/oxgc) {
4485             if (0) {
4486             }
4487 190         13139  
4488 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Ekoi8r::PREMATCH()]}
4489 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4490             $e_string .= q{Ekoi8r::PREMATCH()};
4491             $slash = 'div';
4492             }
4493              
4494 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Ekoi8r::MATCH()]}
4495 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4496             $e_string .= q{Ekoi8r::MATCH()};
4497             $slash = 'div';
4498             }
4499              
4500 0         0 # $', ${'} --> $', ${'}
4501 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4502             $e_string .= $1;
4503             $slash = 'div';
4504             }
4505              
4506 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Ekoi8r::POSTMATCH()]}
4507 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4508             $e_string .= q{Ekoi8r::POSTMATCH()};
4509             $slash = 'div';
4510             }
4511              
4512 0         0 # bareword
4513 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4514             $e_string .= $1;
4515             $slash = 'div';
4516             }
4517              
4518 0         0 # $0 --> $0
4519 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4520             $e_string .= $1;
4521             $slash = 'div';
4522 0         0 }
4523 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4524             $e_string .= $1;
4525             $slash = 'div';
4526             }
4527              
4528 0         0 # $$ --> $$
4529 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4530             $e_string .= $1;
4531             $slash = 'div';
4532             }
4533              
4534             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4535 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4536 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4537             $e_string .= e_capture($1);
4538             $slash = 'div';
4539 0         0 }
4540 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4541             $e_string .= e_capture($1);
4542             $slash = 'div';
4543             }
4544              
4545 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4546 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4547             $e_string .= e_capture($1.'->'.$2);
4548             $slash = 'div';
4549             }
4550              
4551 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4552 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4553             $e_string .= e_capture($1.'->'.$2);
4554             $slash = 'div';
4555             }
4556              
4557 0         0 # $$foo
4558 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4559             $e_string .= e_capture($1);
4560             $slash = 'div';
4561             }
4562              
4563 0         0 # ${ foo }
4564 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4565             $e_string .= '${' . $1 . '}';
4566             $slash = 'div';
4567             }
4568              
4569 0         0 # ${ ... }
4570 3         11 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4571             $e_string .= e_capture($1);
4572             $slash = 'div';
4573             }
4574              
4575             # variable or function
4576 3         14 # $ @ % & * $ #
4577 7         18 elsif ($string =~ /\G ( (?: [\$\@\%\&\*] | \$\# | -> | \b sub \b) (?>\s*) (?: split | chop | index | rindex | lc | uc | fc | chr | ord | reverse | getc | tr | y | q | qq | qx | qw | m | s | qr | glob | lstat | opendir | stat | unlink | chdir ) ) \b /oxmsgc) {
4578             $e_string .= $1;
4579             $slash = 'div';
4580             }
4581             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4582 7         21 # $ @ # \ ' " / ? ( ) [ ] < >
4583 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4584             $e_string .= $1;
4585             $slash = 'div';
4586             }
4587 0         0  
  0         0  
4588 0         0 # subroutines of package Ekoi8r
  0         0  
4589 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4590 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4591 0         0 elsif ($string =~ /\G \b KOI8R::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4592 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4593 0         0 elsif ($string =~ /\G \b KOI8R::eval \b /oxgc) { $e_string .= 'eval KOI8R::escape'; $slash = 'm//'; }
  0         0  
4594 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4595 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Ekoi8r::chop'; $slash = 'm//'; }
  0         0  
4596 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4597 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4598 0         0 elsif ($string =~ /\G \b KOI8R::index \b /oxgc) { $e_string .= 'KOI8R::index'; $slash = 'm//'; }
  0         0  
4599 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Ekoi8r::index'; $slash = 'm//'; }
  0         0  
4600 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4601 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4602 0         0 elsif ($string =~ /\G \b KOI8R::rindex \b /oxgc) { $e_string .= 'KOI8R::rindex'; $slash = 'm//'; }
  0         0  
4603 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Ekoi8r::rindex'; $slash = 'm//'; }
  0         0  
4604 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::lc'; $slash = 'm//'; }
  0         0  
4605 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::lcfirst'; $slash = 'm//'; }
  0         0  
4606 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::uc'; $slash = 'm//'; }
  0         0  
4607             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::ucfirst'; $slash = 'm//'; }
4608             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::fc'; $slash = 'm//'; }
4609 0         0  
  0         0  
4610 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4611 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4612 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4613 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4614 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4615 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4616             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
4617 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4618 0         0  
  0         0  
4619 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4620 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4621 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4622 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4623 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4624             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4625             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4626 0         0  
  0         0  
4627 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
4628 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4629 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4630             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
4631 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4632 0         0  
  0         0  
4633 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4634 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4635 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::chr'; $slash = 'm//'; }
  0         0  
4636 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4637 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4638 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Ekoi8r::glob'; $slash = 'm//'; }
  0         0  
4639 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Ekoi8r::lc_'; $slash = 'm//'; }
  0         0  
4640 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Ekoi8r::lcfirst_'; $slash = 'm//'; }
  0         0  
4641 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Ekoi8r::uc_'; $slash = 'm//'; }
  0         0  
4642 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Ekoi8r::ucfirst_'; $slash = 'm//'; }
  0         0  
4643             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Ekoi8r::fc_'; $slash = 'm//'; }
4644 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4645 0         0  
  0         0  
4646 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4647 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4648 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Ekoi8r::chr_'; $slash = 'm//'; }
  0         0  
4649 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4650 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4651 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Ekoi8r::glob_'; $slash = 'm//'; }
  0         0  
4652             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
4653             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
4654 0         0 # split
4655             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4656 0         0 $slash = 'm//';
4657 0         0  
4658 0         0 my $e = '';
4659             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4660             $e .= $1;
4661             }
4662 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          
4663             # end of split
4664             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Ekoi8r::split' . $e; }
4665 0         0  
  0         0  
4666             # split scalar value
4667             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . e_string($1); next E_STRING_LOOP; }
4668 0         0  
  0         0  
4669 0         0 # split literal space
  0         0  
4670 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4671 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4672 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4673 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4674 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4675 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4676 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4677 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4678 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4679 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4680 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4681 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4682             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {' '}; next E_STRING_LOOP; }
4683             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Ekoi8r::split' . $e . qq {" "}; next E_STRING_LOOP; }
4684              
4685 0 0       0 # split qq//
  0         0  
  0         0  
4686             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4687 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
4688 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4689 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4690 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4691 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq ( ) --> qr ( )
  0         0  
4692 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq { } --> qr { }
  0         0  
4693 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq [ ] --> qr [ ]
  0         0  
4694 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq < > --> qr < >
  0         0  
4695             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
4696 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq * * --> qr * *
4697             }
4698             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4699             }
4700             }
4701              
4702 0 0       0 # split qr//
  0         0  
  0         0  
4703             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4704 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
4705 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4706 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4707 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4708 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ( )
  0         0  
4709 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr { }
  0         0  
4710 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr [ ]
  0         0  
4711 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr < >
  0         0  
4712 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ' '
  0         0  
4713             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
4714 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr * *
4715             }
4716             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4717             }
4718             }
4719              
4720 0 0       0 # split q//
  0         0  
  0         0  
4721             elsif ($string =~ /\G \b (q) \b /oxgc) {
4722 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
4723 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4724 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4725 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4726 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q ( ) --> qr ( )
  0         0  
4727 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q { } --> qr { }
  0         0  
4728 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q [ ] --> qr [ ]
  0         0  
4729 0         0 elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q < > --> qr < >
  0         0  
4730             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
4731 0         0 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q * * --> qr * *
4732             }
4733             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4734             }
4735             }
4736              
4737 0 0       0 # split m//
  0         0  
  0         0  
4738             elsif ($string =~ /\G \b (m) \b /oxgc) {
4739 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # m# # --> qr # #
4740 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4741 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4742 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4743 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ( ) --> qr ( )
  0         0  
4744 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m { } --> qr { }
  0         0  
4745 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m [ ] --> qr [ ]
  0         0  
4746 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m < > --> qr < >
  0         0  
4747 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ' ' --> qr ' '
  0         0  
4748             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
4749 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m * * --> qr * *
4750             }
4751             die __FILE__, ": Search pattern not terminated\n";
4752             }
4753             }
4754              
4755 0         0 # split ''
4756 0         0 elsif ($string =~ /\G (\') /oxgc) {
4757 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
4758 0         0 while ($string !~ /\G \z/oxgc) {
4759 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
4760 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4761             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
4762 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4763             }
4764             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4765             }
4766              
4767 0         0 # split ""
4768 0         0 elsif ($string =~ /\G (\") /oxgc) {
4769 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
4770 0         0 while ($string !~ /\G \z/oxgc) {
4771 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
4772 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4773             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
4774 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4775             }
4776             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4777             }
4778              
4779 0         0 # split //
4780 0         0 elsif ($string =~ /\G (\/) /oxgc) {
4781 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4782 0         0 while ($string !~ /\G \z/oxgc) {
4783 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
4784 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4785             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
4786 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4787             }
4788             die __FILE__, ": Search pattern not terminated\n";
4789             }
4790             }
4791              
4792 0         0 # qq//
4793 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4794 0         0 my $ope = $1;
4795             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4796             $e_string .= e_qq($ope,$1,$3,$2);
4797 0         0 }
4798 0         0 else {
4799 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4800 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4801 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4802 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4803 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4804 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4805             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4806 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4807             }
4808             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4809             }
4810             }
4811              
4812 0         0 # qx//
4813 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4814 0         0 my $ope = $1;
4815             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4816             $e_string .= e_qq($ope,$1,$3,$2);
4817 0         0 }
4818 0         0 else {
4819 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4820 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4821 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4822 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4823 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4824 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4825 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4826             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4827 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4828             }
4829             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4830             }
4831             }
4832              
4833 0         0 # q//
4834 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4835 0         0 my $ope = $1;
4836             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4837             $e_string .= e_q($ope,$1,$3,$2);
4838 0         0 }
4839 0         0 else {
4840 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4841 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4842 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4843 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4844 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4845 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4846             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4847 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 * *
4848             }
4849             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4850             }
4851             }
4852 0         0  
4853             # ''
4854             elsif ($string =~ /\G (?
4855 0         0  
4856             # ""
4857             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4858 0         0  
4859             # ``
4860             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4861 0         0  
4862             # <<>> (a safer ARGV)
4863             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4864 0         0  
4865             # <<= <=> <= < operator
4866             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4867 0         0  
4868             #
4869             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4870              
4871 0         0 # --- glob
4872             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4873             $e_string .= 'Ekoi8r::glob("' . $1 . '")';
4874             }
4875              
4876 0         0 # << (bit shift) --- not here document
4877 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
4878             $slash = 'm//';
4879             $e_string .= $1;
4880             }
4881              
4882 0         0 # <<~'HEREDOC'
4883 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4884 0         0 $slash = 'm//';
4885             my $here_quote = $1;
4886             my $delimiter = $2;
4887 0 0       0  
4888 0         0 # get here document
4889 0         0 if ($here_script eq '') {
4890             $here_script = CORE::substr $_, pos $_;
4891 0 0       0 $here_script =~ s/.*?\n//oxm;
4892 0         0 }
4893 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4894 0         0 my $heredoc = $1;
4895 0         0 my $indent = $2;
4896 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4897             push @heredoc, $heredoc . qq{\n$delimiter\n};
4898             push @heredoc_delimiter, qq{\\s*$delimiter};
4899 0         0 }
4900             else {
4901 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4902             }
4903             $e_string .= qq{<<'$delimiter'};
4904             }
4905              
4906 0         0 # <<~\HEREDOC
4907 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4908 0         0 $slash = 'm//';
4909             my $here_quote = $1;
4910             my $delimiter = $2;
4911 0 0       0  
4912 0         0 # get here document
4913 0         0 if ($here_script eq '') {
4914             $here_script = CORE::substr $_, pos $_;
4915 0 0       0 $here_script =~ s/.*?\n//oxm;
4916 0         0 }
4917 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4918 0         0 my $heredoc = $1;
4919 0         0 my $indent = $2;
4920 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4921             push @heredoc, $heredoc . qq{\n$delimiter\n};
4922             push @heredoc_delimiter, qq{\\s*$delimiter};
4923 0         0 }
4924             else {
4925 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4926             }
4927             $e_string .= qq{<<\\$delimiter};
4928             }
4929              
4930 0         0 # <<~"HEREDOC"
4931 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4932 0         0 $slash = 'm//';
4933             my $here_quote = $1;
4934             my $delimiter = $2;
4935 0 0       0  
4936 0         0 # get here document
4937 0         0 if ($here_script eq '') {
4938             $here_script = CORE::substr $_, pos $_;
4939 0 0       0 $here_script =~ s/.*?\n//oxm;
4940 0         0 }
4941 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4942 0         0 my $heredoc = $1;
4943 0         0 my $indent = $2;
4944 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4945             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4946             push @heredoc_delimiter, qq{\\s*$delimiter};
4947 0         0 }
4948             else {
4949 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4950             }
4951             $e_string .= qq{<<"$delimiter"};
4952             }
4953              
4954 0         0 # <<~HEREDOC
4955 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4956 0         0 $slash = 'm//';
4957             my $here_quote = $1;
4958             my $delimiter = $2;
4959 0 0       0  
4960 0         0 # get here document
4961 0         0 if ($here_script eq '') {
4962             $here_script = CORE::substr $_, pos $_;
4963 0 0       0 $here_script =~ s/.*?\n//oxm;
4964 0         0 }
4965 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4966 0         0 my $heredoc = $1;
4967 0         0 my $indent = $2;
4968 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4969             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4970             push @heredoc_delimiter, qq{\\s*$delimiter};
4971 0         0 }
4972             else {
4973 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4974             }
4975             $e_string .= qq{<<$delimiter};
4976             }
4977              
4978 0         0 # <<~`HEREDOC`
4979 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4980 0         0 $slash = 'm//';
4981             my $here_quote = $1;
4982             my $delimiter = $2;
4983 0 0       0  
4984 0         0 # get here document
4985 0         0 if ($here_script eq '') {
4986             $here_script = CORE::substr $_, pos $_;
4987 0 0       0 $here_script =~ s/.*?\n//oxm;
4988 0         0 }
4989 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4990 0         0 my $heredoc = $1;
4991 0         0 my $indent = $2;
4992 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4993             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4994             push @heredoc_delimiter, qq{\\s*$delimiter};
4995 0         0 }
4996             else {
4997 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4998             }
4999             $e_string .= qq{<<`$delimiter`};
5000             }
5001              
5002 0         0 # <<'HEREDOC'
5003 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
5004 0         0 $slash = 'm//';
5005             my $here_quote = $1;
5006             my $delimiter = $2;
5007 0 0       0  
5008 0         0 # get here document
5009 0         0 if ($here_script eq '') {
5010             $here_script = CORE::substr $_, pos $_;
5011 0 0       0 $here_script =~ s/.*?\n//oxm;
5012 0         0 }
5013 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5014             push @heredoc, $1 . qq{\n$delimiter\n};
5015             push @heredoc_delimiter, $delimiter;
5016 0         0 }
5017             else {
5018 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5019             }
5020             $e_string .= $here_quote;
5021             }
5022              
5023 0         0 # <<\HEREDOC
5024 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5025 0         0 $slash = 'm//';
5026             my $here_quote = $1;
5027             my $delimiter = $2;
5028 0 0       0  
5029 0         0 # get here document
5030 0         0 if ($here_script eq '') {
5031             $here_script = CORE::substr $_, pos $_;
5032 0 0       0 $here_script =~ s/.*?\n//oxm;
5033 0         0 }
5034 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5035             push @heredoc, $1 . qq{\n$delimiter\n};
5036             push @heredoc_delimiter, $delimiter;
5037 0         0 }
5038             else {
5039 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5040             }
5041             $e_string .= $here_quote;
5042             }
5043              
5044 0         0 # <<"HEREDOC"
5045 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5046 0         0 $slash = 'm//';
5047             my $here_quote = $1;
5048             my $delimiter = $2;
5049 0 0       0  
5050 0         0 # get here document
5051 0         0 if ($here_script eq '') {
5052             $here_script = CORE::substr $_, pos $_;
5053 0 0       0 $here_script =~ s/.*?\n//oxm;
5054 0         0 }
5055 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5056             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5057             push @heredoc_delimiter, $delimiter;
5058 0         0 }
5059             else {
5060 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5061             }
5062             $e_string .= $here_quote;
5063             }
5064              
5065 0         0 # <
5066 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5067 0         0 $slash = 'm//';
5068             my $here_quote = $1;
5069             my $delimiter = $2;
5070 0 0       0  
5071 0         0 # get here document
5072 0         0 if ($here_script eq '') {
5073             $here_script = CORE::substr $_, pos $_;
5074 0 0       0 $here_script =~ s/.*?\n//oxm;
5075 0         0 }
5076 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5077             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5078             push @heredoc_delimiter, $delimiter;
5079 0         0 }
5080             else {
5081 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5082             }
5083             $e_string .= $here_quote;
5084             }
5085              
5086 0         0 # <<`HEREDOC`
5087 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5088 0         0 $slash = 'm//';
5089             my $here_quote = $1;
5090             my $delimiter = $2;
5091 0 0       0  
5092 0         0 # get here document
5093 0         0 if ($here_script eq '') {
5094             $here_script = CORE::substr $_, pos $_;
5095 0 0       0 $here_script =~ s/.*?\n//oxm;
5096 0         0 }
5097 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5098             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5099             push @heredoc_delimiter, $delimiter;
5100 0         0 }
5101             else {
5102 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5103             }
5104             $e_string .= $here_quote;
5105             }
5106              
5107             # any operator before div
5108             elsif ($string =~ /\G (
5109             -- | \+\+ |
5110 0         0 [\)\}\]]
  18         27  
5111              
5112             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
5113              
5114             # yada-yada or triple-dot operator
5115             elsif ($string =~ /\G (
5116 18         52 \.\.\.
  0         0  
5117              
5118             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
5119              
5120             # any operator before m//
5121             elsif ($string =~ /\G ((?>
5122              
5123             !~~ | !~ | != | ! |
5124             %= | % |
5125             &&= | && | &= | &\.= | &\. | & |
5126             -= | -> | - |
5127             :(?>\s*)= |
5128             : |
5129             <<>> |
5130             <<= | <=> | <= | < |
5131             == | => | =~ | = |
5132             >>= | >> | >= | > |
5133             \*\*= | \*\* | \*= | \* |
5134             \+= | \+ |
5135             \.\. | \.= | \. |
5136             \/\/= | \/\/ |
5137             \/= | \/ |
5138             \? |
5139             \\ |
5140             \^= | \^\.= | \^\. | \^ |
5141             \b x= |
5142             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
5143             ~~ | ~\. | ~ |
5144             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
5145             \b(?: print )\b |
5146              
5147 0         0 [,;\(\{\[]
  31         70  
5148              
5149             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
5150 31         116  
5151             # other any character
5152             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
5153              
5154 131         339 # system error
5155             else {
5156             die __FILE__, ": Oops, this shouldn't happen!\n";
5157             }
5158 0         0 }
5159              
5160             return $e_string;
5161             }
5162              
5163             #
5164             # character class
5165 17     1919 0 69 #
5166             sub character_class {
5167 1919 100       3567 my($char,$modifier) = @_;
5168 1919 100       2905  
5169 52         98 if ($char eq '.') {
5170             if ($modifier =~ /s/) {
5171             return '${Ekoi8r::dot_s}';
5172 17         40 }
5173             else {
5174             return '${Ekoi8r::dot}';
5175             }
5176 35         77 }
5177             else {
5178             return Ekoi8r::classic_character_class($char);
5179             }
5180             }
5181              
5182             #
5183             # escape capture ($1, $2, $3, ...)
5184             #
5185 1867     212 0 3355 sub e_capture {
5186              
5187             return join '', '${', $_[0], '}';
5188             }
5189              
5190             #
5191             # escape transliteration (tr/// or y///)
5192 212     3 0 771 #
5193 3         11 sub e_tr {
5194 3   50     4 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
5195             my $e_tr = '';
5196 3         6 $modifier ||= '';
5197              
5198             $slash = 'div';
5199 3         4  
5200             # quote character class 1
5201             $charclass = q_tr($charclass);
5202 3         11  
5203             # quote character class 2
5204             $charclass2 = q_tr($charclass2);
5205 3 50       5  
5206 3 0       9 # /b /B modifier
5207 0         0 if ($modifier =~ tr/bB//d) {
5208             if ($variable eq '') {
5209             $e_tr = qq{tr$charclass$e$charclass2$modifier};
5210 0         0 }
5211             else {
5212             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
5213             }
5214 0 100       0 }
5215 3         5 else {
5216             if ($variable eq '') {
5217             $e_tr = qq{Ekoi8r::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
5218 2         6 }
5219             else {
5220             $e_tr = qq{Ekoi8r::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
5221             }
5222             }
5223 1         5  
5224 3         5 # clear tr/// variable
5225             $tr_variable = '';
5226 3         5 $bind_operator = '';
5227              
5228             return $e_tr;
5229             }
5230              
5231             #
5232             # quote for escape transliteration (tr/// or y///)
5233 3     6 0 14 #
5234             sub q_tr {
5235             my($charclass) = @_;
5236 6 50       10  
    0          
    0          
    0          
    0          
    0          
5237 6         12 # quote character class
5238             if ($charclass !~ /'/oxms) {
5239             return e_q('', "'", "'", $charclass); # --> q' '
5240 6         7 }
5241             elsif ($charclass !~ /\//oxms) {
5242             return e_q('q', '/', '/', $charclass); # --> q/ /
5243 0         0 }
5244             elsif ($charclass !~ /\#/oxms) {
5245             return e_q('q', '#', '#', $charclass); # --> q# #
5246 0         0 }
5247             elsif ($charclass !~ /[\<\>]/oxms) {
5248             return e_q('q', '<', '>', $charclass); # --> q< >
5249 0         0 }
5250             elsif ($charclass !~ /[\(\)]/oxms) {
5251             return e_q('q', '(', ')', $charclass); # --> q( )
5252 0         0 }
5253             elsif ($charclass !~ /[\{\}]/oxms) {
5254             return e_q('q', '{', '}', $charclass); # --> q{ }
5255 0         0 }
5256 0 0       0 else {
5257 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5258             if ($charclass !~ /\Q$char\E/xms) {
5259             return e_q('q', $char, $char, $charclass);
5260             }
5261             }
5262 0         0 }
5263              
5264             return e_q('q', '{', '}', $charclass);
5265             }
5266              
5267             #
5268             # escape q string (q//, '')
5269 0     1264 0 0 #
5270             sub e_q {
5271 1264         3036 my($ope,$delimiter,$end_delimiter,$string) = @_;
5272              
5273 1264         1894 $slash = 'div';
5274              
5275             return join '', $ope, $delimiter, $string, $end_delimiter;
5276             }
5277              
5278             #
5279             # escape qq string (qq//, "", qx//, ``)
5280 1264     4042 0 6372 #
5281             sub e_qq {
5282 4042         9253 my($ope,$delimiter,$end_delimiter,$string) = @_;
5283              
5284 4042         5265 $slash = 'div';
5285 4042         4993  
5286             my $left_e = 0;
5287             my $right_e = 0;
5288 4042         4460  
5289             # split regexp
5290             my @char = $string =~ /\G((?>
5291             [^\\\$] |
5292             \\x\{ (?>[0-9A-Fa-f]+) \} |
5293             \\o\{ (?>[0-7]+) \} |
5294             \\N\{ (?>[^0-9\}][^\}]*) \} |
5295             \\ $q_char |
5296             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5297             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5298             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5299             \$ (?>\s* [0-9]+) |
5300             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5301             \$ \$ (?![\w\{]) |
5302             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5303             $q_char
5304 4042         146291 ))/oxmsg;
5305              
5306             for (my $i=0; $i <= $#char; $i++) {
5307 4042 50 33     13889  
    50 33        
    100          
    100          
    50          
5308 113560         408571 # "\L\u" --> "\u\L"
5309             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5310             @char[$i,$i+1] = @char[$i+1,$i];
5311             }
5312              
5313 0         0 # "\U\l" --> "\l\U"
5314             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5315             @char[$i,$i+1] = @char[$i+1,$i];
5316             }
5317              
5318 0         0 # octal escape sequence
5319             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5320             $char[$i] = Ekoi8r::octchr($1);
5321             }
5322              
5323 1         4 # hexadecimal escape sequence
5324             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5325             $char[$i] = Ekoi8r::hexchr($1);
5326             }
5327              
5328 1         4 # \N{CHARNAME} --> N{CHARNAME}
5329             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5330             $char[$i] = $1;
5331 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          
5332              
5333             if (0) {
5334             }
5335              
5336             # \F
5337             #
5338             # P.69 Table 2-6. Translation escapes
5339             # in Chapter 2: Bits and Pieces
5340             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5341             # (and so on)
5342 113560         996990  
5343 0 50       0 # \u \l \U \L \F \Q \E
5344 484         1000 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5345             if ($right_e < $left_e) {
5346             $char[$i] = '\\' . $char[$i];
5347             }
5348             }
5349             elsif ($char[$i] eq '\u') {
5350              
5351             # "STRING @{[ LIST EXPR ]} MORE STRING"
5352              
5353             # P.257 Other Tricks You Can Do with Hard References
5354             # in Chapter 8: References
5355             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5356              
5357             # P.353 Other Tricks You Can Do with Hard References
5358             # in Chapter 8: References
5359             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5360              
5361 0         0 # (and so on)
5362 0         0  
5363             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
5364             $left_e++;
5365 0         0 }
5366 0         0 elsif ($char[$i] eq '\l') {
5367             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
5368             $left_e++;
5369 0         0 }
5370 0         0 elsif ($char[$i] eq '\U') {
5371             $char[$i] = '@{[Ekoi8r::uc qq<';
5372             $left_e++;
5373 0         0 }
5374 0         0 elsif ($char[$i] eq '\L') {
5375             $char[$i] = '@{[Ekoi8r::lc qq<';
5376             $left_e++;
5377 0         0 }
5378 24         39 elsif ($char[$i] eq '\F') {
5379             $char[$i] = '@{[Ekoi8r::fc qq<';
5380             $left_e++;
5381 24         44 }
5382 0         0 elsif ($char[$i] eq '\Q') {
5383             $char[$i] = '@{[CORE::quotemeta qq<';
5384             $left_e++;
5385 0 50       0 }
5386 24         49 elsif ($char[$i] eq '\E') {
5387 24         42 if ($right_e < $left_e) {
5388             $char[$i] = '>]}';
5389             $right_e++;
5390 24         46 }
5391             else {
5392             $char[$i] = '';
5393             }
5394 0         0 }
5395 0 0       0 elsif ($char[$i] eq '\Q') {
5396 0         0 while (1) {
5397             if (++$i > $#char) {
5398 0 0       0 last;
5399 0         0 }
5400             if ($char[$i] eq '\E') {
5401             last;
5402             }
5403             }
5404             }
5405             elsif ($char[$i] eq '\E') {
5406             }
5407              
5408             # $0 --> $0
5409             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5410             }
5411             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5412             }
5413              
5414             # $$ --> $$
5415             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5416             }
5417              
5418             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5419 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5420             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5421             $char[$i] = e_capture($1);
5422 205         394 }
5423             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5424             $char[$i] = e_capture($1);
5425             }
5426              
5427 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5428             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5429             $char[$i] = e_capture($1.'->'.$2);
5430             }
5431              
5432 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5433             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5434             $char[$i] = e_capture($1.'->'.$2);
5435             }
5436              
5437 0         0 # $$foo
5438             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5439             $char[$i] = e_capture($1);
5440             }
5441              
5442 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
5443             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5444             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
5445             }
5446              
5447 44         119 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
5448             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5449             $char[$i] = '@{[Ekoi8r::MATCH()]}';
5450             }
5451              
5452 45         131 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
5453             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5454             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
5455             }
5456              
5457             # ${ foo } --> ${ foo }
5458             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5459             }
5460              
5461 33         96 # ${ ... }
5462             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5463             $char[$i] = e_capture($1);
5464             }
5465             }
5466 0 50       0  
5467 4042         8093 # return string
5468             if ($left_e > $right_e) {
5469 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5470             }
5471             return join '', $ope, $delimiter, @char, $end_delimiter;
5472             }
5473              
5474             #
5475             # escape qw string (qw//)
5476 4042     16 0 39157 #
5477             sub e_qw {
5478 16         71 my($ope,$delimiter,$end_delimiter,$string) = @_;
5479              
5480             $slash = 'div';
5481 16         32  
  16         194  
5482 483 50       723 # choice again delimiter
    0          
    0          
    0          
    0          
5483 16         94 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5484             if (not $octet{$end_delimiter}) {
5485             return join '', $ope, $delimiter, $string, $end_delimiter;
5486 16         137 }
5487             elsif (not $octet{')'}) {
5488             return join '', $ope, '(', $string, ')';
5489 0         0 }
5490             elsif (not $octet{'}'}) {
5491             return join '', $ope, '{', $string, '}';
5492 0         0 }
5493             elsif (not $octet{']'}) {
5494             return join '', $ope, '[', $string, ']';
5495 0         0 }
5496             elsif (not $octet{'>'}) {
5497             return join '', $ope, '<', $string, '>';
5498 0         0 }
5499 0 0       0 else {
5500 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5501             if (not $octet{$char}) {
5502             return join '', $ope, $char, $string, $char;
5503             }
5504             }
5505             }
5506 0         0  
5507 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5508 0         0 my @string = CORE::split(/\s+/, $string);
5509 0         0 for my $string (@string) {
5510 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5511 0         0 for my $octet (@octet) {
5512             if ($octet =~ /\A (['\\]) \z/oxms) {
5513             $octet = '\\' . $1;
5514 0         0 }
5515             }
5516 0         0 $string = join '', @octet;
  0         0  
5517             }
5518             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5519             }
5520              
5521             #
5522             # escape here document (<<"HEREDOC", <
5523 0     93 0 0 #
5524             sub e_heredoc {
5525 93         297 my($string) = @_;
5526              
5527 93         336 $slash = 'm//';
5528              
5529 93         299 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5530 93         143  
5531             my $left_e = 0;
5532             my $right_e = 0;
5533 93         129  
5534             # split regexp
5535             my @char = $string =~ /\G((?>
5536             [^\\\$] |
5537             \\x\{ (?>[0-9A-Fa-f]+) \} |
5538             \\o\{ (?>[0-7]+) \} |
5539             \\N\{ (?>[^0-9\}][^\}]*) \} |
5540             \\ $q_char |
5541             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5542             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5543             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5544             \$ (?>\s* [0-9]+) |
5545             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5546             \$ \$ (?![\w\{]) |
5547             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5548             $q_char
5549 93         8569 ))/oxmsg;
5550              
5551             for (my $i=0; $i <= $#char; $i++) {
5552 93 50 33     399  
    50 33        
    100          
    100          
    50          
5553 3151         18882 # "\L\u" --> "\u\L"
5554             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5555             @char[$i,$i+1] = @char[$i+1,$i];
5556             }
5557              
5558 0         0 # "\U\l" --> "\l\U"
5559             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5560             @char[$i,$i+1] = @char[$i+1,$i];
5561             }
5562              
5563 0         0 # octal escape sequence
5564             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5565             $char[$i] = Ekoi8r::octchr($1);
5566             }
5567              
5568 1         4 # hexadecimal escape sequence
5569             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5570             $char[$i] = Ekoi8r::hexchr($1);
5571             }
5572              
5573 1         3 # \N{CHARNAME} --> N{CHARNAME}
5574             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5575             $char[$i] = $1;
5576 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          
5577              
5578             if (0) {
5579             }
5580 3151         25829  
5581 0 0       0 # \u \l \U \L \F \Q \E
5582 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5583             if ($right_e < $left_e) {
5584             $char[$i] = '\\' . $char[$i];
5585             }
5586 0         0 }
5587 0         0 elsif ($char[$i] eq '\u') {
5588             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
5589             $left_e++;
5590 0         0 }
5591 0         0 elsif ($char[$i] eq '\l') {
5592             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
5593             $left_e++;
5594 0         0 }
5595 0         0 elsif ($char[$i] eq '\U') {
5596             $char[$i] = '@{[Ekoi8r::uc qq<';
5597             $left_e++;
5598 0         0 }
5599 0         0 elsif ($char[$i] eq '\L') {
5600             $char[$i] = '@{[Ekoi8r::lc qq<';
5601             $left_e++;
5602 0         0 }
5603 0         0 elsif ($char[$i] eq '\F') {
5604             $char[$i] = '@{[Ekoi8r::fc qq<';
5605             $left_e++;
5606 0         0 }
5607 0         0 elsif ($char[$i] eq '\Q') {
5608             $char[$i] = '@{[CORE::quotemeta qq<';
5609             $left_e++;
5610 0 0       0 }
5611 0         0 elsif ($char[$i] eq '\E') {
5612 0         0 if ($right_e < $left_e) {
5613             $char[$i] = '>]}';
5614             $right_e++;
5615 0         0 }
5616             else {
5617             $char[$i] = '';
5618             }
5619 0         0 }
5620 0 0       0 elsif ($char[$i] eq '\Q') {
5621 0         0 while (1) {
5622             if (++$i > $#char) {
5623 0 0       0 last;
5624 0         0 }
5625             if ($char[$i] eq '\E') {
5626             last;
5627             }
5628             }
5629             }
5630             elsif ($char[$i] eq '\E') {
5631             }
5632              
5633             # $0 --> $0
5634             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5635             }
5636             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5637             }
5638              
5639             # $$ --> $$
5640             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5641             }
5642              
5643             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5644 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5645             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5646             $char[$i] = e_capture($1);
5647 0         0 }
5648             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5649             $char[$i] = e_capture($1);
5650             }
5651              
5652 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5653             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5654             $char[$i] = e_capture($1.'->'.$2);
5655             }
5656              
5657 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5658             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5659             $char[$i] = e_capture($1.'->'.$2);
5660             }
5661              
5662 0         0 # $$foo
5663             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5664             $char[$i] = e_capture($1);
5665             }
5666              
5667 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
5668             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5669             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
5670             }
5671              
5672 8         48 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
5673             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5674             $char[$i] = '@{[Ekoi8r::MATCH()]}';
5675             }
5676              
5677 8         55 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
5678             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5679             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
5680             }
5681              
5682             # ${ foo } --> ${ foo }
5683             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5684             }
5685              
5686 6         46 # ${ ... }
5687             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5688             $char[$i] = e_capture($1);
5689             }
5690             }
5691 0 50       0  
5692 93         225 # return string
5693             if ($left_e > $right_e) {
5694 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5695             }
5696             return join '', @char;
5697             }
5698              
5699             #
5700             # escape regexp (m//, qr//)
5701 93     652 0 849 #
5702 652   100     3391 sub e_qr {
5703             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5704 652         2746 $modifier ||= '';
5705 652 50       1331  
5706 652         1699 $modifier =~ tr/p//d;
5707 0         0 if ($modifier =~ /([adlu])/oxms) {
5708 0 0       0 my $line = 0;
5709 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5710 0         0 if ($filename ne __FILE__) {
5711             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5712             last;
5713 0         0 }
5714             }
5715             die qq{Unsupported modifier "$1" used at line $line.\n};
5716 0         0 }
5717              
5718             $slash = 'div';
5719 652 100       1188  
    100          
5720 652         2397 # literal null string pattern
5721 8         10 if ($string eq '') {
5722 8         12 $modifier =~ tr/bB//d;
5723             $modifier =~ tr/i//d;
5724             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5725             }
5726              
5727             # /b /B modifier
5728             elsif ($modifier =~ tr/bB//d) {
5729 8 50       43  
5730 2         7 # choice again delimiter
5731 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5732 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5733 0         0 my %octet = map {$_ => 1} @char;
5734 0         0 if (not $octet{')'}) {
5735             $delimiter = '(';
5736             $end_delimiter = ')';
5737 0         0 }
5738 0         0 elsif (not $octet{'}'}) {
5739             $delimiter = '{';
5740             $end_delimiter = '}';
5741 0         0 }
5742 0         0 elsif (not $octet{']'}) {
5743             $delimiter = '[';
5744             $end_delimiter = ']';
5745 0         0 }
5746 0         0 elsif (not $octet{'>'}) {
5747             $delimiter = '<';
5748             $end_delimiter = '>';
5749 0         0 }
5750 0 0       0 else {
5751 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5752 0         0 if (not $octet{$char}) {
5753 0         0 $delimiter = $char;
5754             $end_delimiter = $char;
5755             last;
5756             }
5757             }
5758             }
5759 0 50 33     0 }
5760 2         10  
5761             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5762             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5763 0         0 }
5764             else {
5765             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5766             }
5767 2 100       11 }
5768 642         2845  
5769             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5770             my $metachar = qr/[\@\\|[\]{^]/oxms;
5771 642         2799  
5772             # split regexp
5773             my @char = $string =~ /\G((?>
5774             [^\\\$\@\[\(] |
5775             \\x (?>[0-9A-Fa-f]{1,2}) |
5776             \\ (?>[0-7]{2,3}) |
5777             \\c [\x40-\x5F] |
5778             \\x\{ (?>[0-9A-Fa-f]+) \} |
5779             \\o\{ (?>[0-7]+) \} |
5780             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5781             \\ $q_char |
5782             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5783             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5784             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5785             [\$\@] $qq_variable |
5786             \$ (?>\s* [0-9]+) |
5787             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5788             \$ \$ (?![\w\{]) |
5789             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5790             \[\^ |
5791             \[\: (?>[a-z]+) :\] |
5792             \[\:\^ (?>[a-z]+) :\] |
5793             \(\? |
5794             $q_char
5795             ))/oxmsg;
5796 642 50       70436  
5797 642         3057 # choice again delimiter
  0         0  
5798 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5799 0         0 my %octet = map {$_ => 1} @char;
5800 0         0 if (not $octet{')'}) {
5801             $delimiter = '(';
5802             $end_delimiter = ')';
5803 0         0 }
5804 0         0 elsif (not $octet{'}'}) {
5805             $delimiter = '{';
5806             $end_delimiter = '}';
5807 0         0 }
5808 0         0 elsif (not $octet{']'}) {
5809             $delimiter = '[';
5810             $end_delimiter = ']';
5811 0         0 }
5812 0         0 elsif (not $octet{'>'}) {
5813             $delimiter = '<';
5814             $end_delimiter = '>';
5815 0         0 }
5816 0 0       0 else {
5817 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5818 0         0 if (not $octet{$char}) {
5819 0         0 $delimiter = $char;
5820             $end_delimiter = $char;
5821             last;
5822             }
5823             }
5824             }
5825 0         0 }
5826 642         990  
5827 642         1095 my $left_e = 0;
5828             my $right_e = 0;
5829             for (my $i=0; $i <= $#char; $i++) {
5830 642 50 66     1842  
    50 66        
    100          
    100          
    100          
    100          
5831 1872         11891 # "\L\u" --> "\u\L"
5832             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5833             @char[$i,$i+1] = @char[$i+1,$i];
5834             }
5835              
5836 0         0 # "\U\l" --> "\l\U"
5837             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5838             @char[$i,$i+1] = @char[$i+1,$i];
5839             }
5840              
5841 0         0 # octal escape sequence
5842             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5843             $char[$i] = Ekoi8r::octchr($1);
5844             }
5845              
5846 1         4 # hexadecimal escape sequence
5847             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5848             $char[$i] = Ekoi8r::hexchr($1);
5849             }
5850              
5851             # \b{...} --> b\{...}
5852             # \B{...} --> B\{...}
5853             # \N{CHARNAME} --> N\{CHARNAME}
5854             # \p{PROPERTY} --> p\{PROPERTY}
5855 1         4 # \P{PROPERTY} --> P\{PROPERTY}
5856             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5857             $char[$i] = $1 . '\\' . $2;
5858             }
5859              
5860 6         99 # \p, \P, \X --> p, P, X
5861             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5862             $char[$i] = $1;
5863 4 100 100     12 }
    100 100        
    100 100        
    100          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
5864              
5865             if (0) {
5866             }
5867 1872         6269  
5868 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5869 6         91 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5870             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)) {
5871             $char[$i] .= join '', splice @char, $i+1, 3;
5872 0         0 }
5873             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)) {
5874             $char[$i] .= join '', splice @char, $i+1, 2;
5875 0         0 }
5876             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)) {
5877             $char[$i] .= join '', splice @char, $i+1, 1;
5878             }
5879             }
5880              
5881 0         0 # open character class [...]
5882             elsif ($char[$i] eq '[') {
5883             my $left = $i;
5884              
5885             # [] make die "Unmatched [] in regexp ...\n"
5886 328 100       575 # (and so on)
5887 328         962  
5888             if ($char[$i+1] eq ']') {
5889             $i++;
5890 3         4 }
5891 328 50       440  
5892 1379         3123 while (1) {
5893             if (++$i > $#char) {
5894 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5895 1379         2309 }
5896             if ($char[$i] eq ']') {
5897             my $right = $i;
5898 328 100       619  
5899 328         1692 # [...]
  30         82  
5900             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5901             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5902 90         159 }
5903             else {
5904             splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
5905 298         2337 }
5906 328         696  
5907             $i = $left;
5908             last;
5909             }
5910             }
5911             }
5912              
5913 328         934 # open character class [^...]
5914             elsif ($char[$i] eq '[^') {
5915             my $left = $i;
5916              
5917             # [^] make die "Unmatched [] in regexp ...\n"
5918 74 100       102 # (and so on)
5919 74         172  
5920             if ($char[$i+1] eq ']') {
5921             $i++;
5922 4         7 }
5923 74 50       293  
5924 272         400 while (1) {
5925             if (++$i > $#char) {
5926 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5927 272         509 }
5928             if ($char[$i] eq ']') {
5929             my $right = $i;
5930 74 100       90  
5931 74         475 # [^...]
  30         76  
5932             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5933             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5934 90         196 }
5935             else {
5936             splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5937 44         168 }
5938 74         485  
5939             $i = $left;
5940             last;
5941             }
5942             }
5943             }
5944              
5945 74         185 # rewrite character class or escape character
5946             elsif (my $char = character_class($char[$i],$modifier)) {
5947             $char[$i] = $char;
5948             }
5949              
5950 139 50       339 # /i modifier
5951 20         34 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
5952             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
5953             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
5954 20         35 }
5955             else {
5956             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
5957             }
5958             }
5959              
5960 0 50       0 # \u \l \U \L \F \Q \E
5961 1         3 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5962             if ($right_e < $left_e) {
5963             $char[$i] = '\\' . $char[$i];
5964             }
5965 0         0 }
5966 0         0 elsif ($char[$i] eq '\u') {
5967             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
5968             $left_e++;
5969 0         0 }
5970 0         0 elsif ($char[$i] eq '\l') {
5971             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
5972             $left_e++;
5973 0         0 }
5974 1         2 elsif ($char[$i] eq '\U') {
5975             $char[$i] = '@{[Ekoi8r::uc qq<';
5976             $left_e++;
5977 1         4 }
5978 1         2 elsif ($char[$i] eq '\L') {
5979             $char[$i] = '@{[Ekoi8r::lc qq<';
5980             $left_e++;
5981 1         3 }
5982 18         33 elsif ($char[$i] eq '\F') {
5983             $char[$i] = '@{[Ekoi8r::fc qq<';
5984             $left_e++;
5985 18         41 }
5986 1         3 elsif ($char[$i] eq '\Q') {
5987             $char[$i] = '@{[CORE::quotemeta qq<';
5988             $left_e++;
5989 1 50       3 }
5990 21         47 elsif ($char[$i] eq '\E') {
5991 21         30 if ($right_e < $left_e) {
5992             $char[$i] = '>]}';
5993             $right_e++;
5994 21         49 }
5995             else {
5996             $char[$i] = '';
5997             }
5998 0         0 }
5999 0 0       0 elsif ($char[$i] eq '\Q') {
6000 0         0 while (1) {
6001             if (++$i > $#char) {
6002 0 0       0 last;
6003 0         0 }
6004             if ($char[$i] eq '\E') {
6005             last;
6006             }
6007             }
6008             }
6009             elsif ($char[$i] eq '\E') {
6010             }
6011              
6012 0 0       0 # $0 --> $0
6013 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6014             if ($ignorecase) {
6015             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6016             }
6017 0 0       0 }
6018 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6019             if ($ignorecase) {
6020             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6021             }
6022             }
6023              
6024             # $$ --> $$
6025             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6026             }
6027              
6028             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6029 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6030 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6031 0         0 $char[$i] = e_capture($1);
6032             if ($ignorecase) {
6033             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6034             }
6035 0         0 }
6036 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6037 0         0 $char[$i] = e_capture($1);
6038             if ($ignorecase) {
6039             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6040             }
6041             }
6042              
6043 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6044 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) {
6045 0         0 $char[$i] = e_capture($1.'->'.$2);
6046             if ($ignorecase) {
6047             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6048             }
6049             }
6050              
6051 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6052 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) {
6053 0         0 $char[$i] = e_capture($1.'->'.$2);
6054             if ($ignorecase) {
6055             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6056             }
6057             }
6058              
6059 0         0 # $$foo
6060 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6061 0         0 $char[$i] = e_capture($1);
6062             if ($ignorecase) {
6063             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6064             }
6065             }
6066              
6067 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
6068 8         22 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6069             if ($ignorecase) {
6070             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::PREMATCH())]}';
6071 0         0 }
6072             else {
6073             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
6074             }
6075             }
6076              
6077 8 50       23 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
6078 8         31 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6079             if ($ignorecase) {
6080             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::MATCH())]}';
6081 0         0 }
6082             else {
6083             $char[$i] = '@{[Ekoi8r::MATCH()]}';
6084             }
6085             }
6086              
6087 8 50       26 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
6088 6         18 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6089             if ($ignorecase) {
6090             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::POSTMATCH())]}';
6091 0         0 }
6092             else {
6093             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
6094             }
6095             }
6096              
6097 6 0       19 # ${ foo }
6098 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) {
6099             if ($ignorecase) {
6100             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6101             }
6102             }
6103              
6104 0         0 # ${ ... }
6105 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6106 0         0 $char[$i] = e_capture($1);
6107             if ($ignorecase) {
6108             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6109             }
6110             }
6111              
6112 0         0 # $scalar or @array
6113 21 100       61 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6114 21         131 $char[$i] = e_string($char[$i]);
6115             if ($ignorecase) {
6116             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6117             }
6118             }
6119              
6120 11 100 33     36 # quote character before ? + * {
    50          
6121             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6122             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6123 138         1385 }
6124 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6125 0         0 my $char = $char[$i-1];
6126             if ($char[$i] eq '{') {
6127             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
6128 0         0 }
6129             else {
6130             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
6131             }
6132 0         0 }
6133             else {
6134             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6135             }
6136             }
6137             }
6138 127         1733  
6139 642 50       1252 # make regexp string
6140 642 0 0     1426 $modifier =~ tr/i//d;
6141 0         0 if ($left_e > $right_e) {
6142             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6143             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
6144 0         0 }
6145             else {
6146             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6147 0 50 33     0 }
6148 642         3516 }
6149             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6150             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
6151 0         0 }
6152             else {
6153             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6154             }
6155             }
6156              
6157             #
6158             # double quote stuff
6159 642     180 0 5428 #
6160             sub qq_stuff {
6161             my($delimiter,$end_delimiter,$stuff) = @_;
6162 180 100       281  
6163 180         359 # scalar variable or array variable
6164             if ($stuff =~ /\A [\$\@] /oxms) {
6165             return $stuff;
6166             }
6167 100         356  
  80         193  
6168 80         235 # quote by delimiter
6169 80 50       280 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
6170 80 50       141 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6171 80 50       127 next if $char eq $delimiter;
6172 80         141 next if $char eq $end_delimiter;
6173             if (not $octet{$char}) {
6174             return join '', 'qq', $char, $stuff, $char;
6175 80         330 }
6176             }
6177             return join '', 'qq', '<', $stuff, '>';
6178             }
6179              
6180             #
6181             # escape regexp (m'', qr'', and m''b, qr''b)
6182 0     10 0 0 #
6183 10   50     50 sub e_qr_q {
6184             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6185 10         48 $modifier ||= '';
6186 10 50       18  
6187 10         23 $modifier =~ tr/p//d;
6188 0         0 if ($modifier =~ /([adlu])/oxms) {
6189 0 0       0 my $line = 0;
6190 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6191 0         0 if ($filename ne __FILE__) {
6192             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6193             last;
6194 0         0 }
6195             }
6196             die qq{Unsupported modifier "$1" used at line $line.\n};
6197 0         0 }
6198              
6199             $slash = 'div';
6200 10 100       15  
    50          
6201 10         23 # literal null string pattern
6202 8         13 if ($string eq '') {
6203 8         11 $modifier =~ tr/bB//d;
6204             $modifier =~ tr/i//d;
6205             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6206             }
6207              
6208 8         40 # with /b /B modifier
6209             elsif ($modifier =~ tr/bB//d) {
6210             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6211             }
6212              
6213 0         0 # without /b /B modifier
6214             else {
6215             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6216             }
6217             }
6218              
6219             #
6220             # escape regexp (m'', qr'')
6221 2     2 0 7 #
6222             sub e_qr_qt {
6223 2 50       8 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6224              
6225             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6226 2         6  
6227             # split regexp
6228             my @char = $string =~ /\G((?>
6229             [^\\\[\$\@\/] |
6230             [\x00-\xFF] |
6231             \[\^ |
6232             \[\: (?>[a-z]+) \:\] |
6233             \[\:\^ (?>[a-z]+) \:\] |
6234             [\$\@\/] |
6235             \\ (?:$q_char) |
6236             (?:$q_char)
6237             ))/oxmsg;
6238 2         69  
6239 2 50 33     11 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
6240             for (my $i=0; $i <= $#char; $i++) {
6241             if (0) {
6242             }
6243 2         18  
6244 0         0 # open character class [...]
6245 0 0       0 elsif ($char[$i] eq '[') {
6246 0         0 my $left = $i;
6247             if ($char[$i+1] eq ']') {
6248 0         0 $i++;
6249 0 0       0 }
6250 0         0 while (1) {
6251             if (++$i > $#char) {
6252 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6253 0         0 }
6254             if ($char[$i] eq ']') {
6255             my $right = $i;
6256 0         0  
6257             # [...]
6258 0         0 splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
6259 0         0  
6260             $i = $left;
6261             last;
6262             }
6263             }
6264             }
6265              
6266 0         0 # open character class [^...]
6267 0 0       0 elsif ($char[$i] eq '[^') {
6268 0         0 my $left = $i;
6269             if ($char[$i+1] eq ']') {
6270 0         0 $i++;
6271 0 0       0 }
6272 0         0 while (1) {
6273             if (++$i > $#char) {
6274 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6275 0         0 }
6276             if ($char[$i] eq ']') {
6277             my $right = $i;
6278 0         0  
6279             # [^...]
6280 0         0 splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6281 0         0  
6282             $i = $left;
6283             last;
6284             }
6285             }
6286             }
6287              
6288 0         0 # escape $ @ / and \
6289             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6290             $char[$i] = '\\' . $char[$i];
6291             }
6292              
6293 0         0 # rewrite character class or escape character
6294             elsif (my $char = character_class($char[$i],$modifier)) {
6295             $char[$i] = $char;
6296             }
6297              
6298 0 0       0 # /i modifier
6299 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
6300             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
6301             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
6302 0         0 }
6303             else {
6304             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
6305             }
6306             }
6307              
6308 0 0       0 # quote character before ? + * {
6309             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6310             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6311 0         0 }
6312             else {
6313             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6314             }
6315             }
6316 0         0 }
6317 2         5  
6318             $delimiter = '/';
6319 2         5 $end_delimiter = '/';
6320 2         3  
6321             $modifier =~ tr/i//d;
6322             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6323             }
6324              
6325             #
6326             # escape regexp (m''b, qr''b)
6327 2     0 0 16 #
6328             sub e_qr_qb {
6329             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6330 0         0  
6331             # split regexp
6332             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6333 0         0  
6334 0 0       0 # unescape character
    0          
6335             for (my $i=0; $i <= $#char; $i++) {
6336             if (0) {
6337             }
6338 0         0  
6339             # remain \\
6340             elsif ($char[$i] eq '\\\\') {
6341             }
6342              
6343 0         0 # escape $ @ / and \
6344             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6345             $char[$i] = '\\' . $char[$i];
6346             }
6347 0         0 }
6348 0         0  
6349 0         0 $delimiter = '/';
6350             $end_delimiter = '/';
6351             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6352             }
6353              
6354             #
6355             # escape regexp (s/here//)
6356 0     76 0 0 #
6357 76   100     206 sub e_s1 {
6358             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6359 76         390 $modifier ||= '';
6360 76 50       127  
6361 76         282 $modifier =~ tr/p//d;
6362 0         0 if ($modifier =~ /([adlu])/oxms) {
6363 0 0       0 my $line = 0;
6364 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6365 0         0 if ($filename ne __FILE__) {
6366             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6367             last;
6368 0         0 }
6369             }
6370             die qq{Unsupported modifier "$1" used at line $line.\n};
6371 0         0 }
6372              
6373             $slash = 'div';
6374 76 100       159  
    50          
6375 76         268 # literal null string pattern
6376 8         9 if ($string eq '') {
6377 8         9 $modifier =~ tr/bB//d;
6378             $modifier =~ tr/i//d;
6379             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6380             }
6381              
6382             # /b /B modifier
6383             elsif ($modifier =~ tr/bB//d) {
6384 8 0       78  
6385 0         0 # choice again delimiter
6386 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
6387 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
6388 0         0 my %octet = map {$_ => 1} @char;
6389 0         0 if (not $octet{')'}) {
6390             $delimiter = '(';
6391             $end_delimiter = ')';
6392 0         0 }
6393 0         0 elsif (not $octet{'}'}) {
6394             $delimiter = '{';
6395             $end_delimiter = '}';
6396 0         0 }
6397 0         0 elsif (not $octet{']'}) {
6398             $delimiter = '[';
6399             $end_delimiter = ']';
6400 0         0 }
6401 0         0 elsif (not $octet{'>'}) {
6402             $delimiter = '<';
6403             $end_delimiter = '>';
6404 0         0 }
6405 0 0       0 else {
6406 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6407 0         0 if (not $octet{$char}) {
6408 0         0 $delimiter = $char;
6409             $end_delimiter = $char;
6410             last;
6411             }
6412             }
6413             }
6414 0         0 }
6415 0         0  
6416             my $prematch = '';
6417             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6418 0 100       0 }
6419 68         203  
6420             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6421             my $metachar = qr/[\@\\|[\]{^]/oxms;
6422 68         378  
6423             # split regexp
6424             my @char = $string =~ /\G((?>
6425             [^\\\$\@\[\(] |
6426             \\ (?>[1-9][0-9]*) |
6427             \\g (?>\s*) (?>[1-9][0-9]*) |
6428             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6429             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6430             \\x (?>[0-9A-Fa-f]{1,2}) |
6431             \\ (?>[0-7]{2,3}) |
6432             \\c [\x40-\x5F] |
6433             \\x\{ (?>[0-9A-Fa-f]+) \} |
6434             \\o\{ (?>[0-7]+) \} |
6435             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6436             \\ $q_char |
6437             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6438             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6439             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6440             [\$\@] $qq_variable |
6441             \$ (?>\s* [0-9]+) |
6442             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6443             \$ \$ (?![\w\{]) |
6444             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6445             \[\^ |
6446             \[\: (?>[a-z]+) :\] |
6447             \[\:\^ (?>[a-z]+) :\] |
6448             \(\? |
6449             $q_char
6450             ))/oxmsg;
6451 68 50       17510  
6452 68         468 # choice again delimiter
  0         0  
6453 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
6454 0         0 my %octet = map {$_ => 1} @char;
6455 0         0 if (not $octet{')'}) {
6456             $delimiter = '(';
6457             $end_delimiter = ')';
6458 0         0 }
6459 0         0 elsif (not $octet{'}'}) {
6460             $delimiter = '{';
6461             $end_delimiter = '}';
6462 0         0 }
6463 0         0 elsif (not $octet{']'}) {
6464             $delimiter = '[';
6465             $end_delimiter = ']';
6466 0         0 }
6467 0         0 elsif (not $octet{'>'}) {
6468             $delimiter = '<';
6469             $end_delimiter = '>';
6470 0         0 }
6471 0 0       0 else {
6472 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6473 0         0 if (not $octet{$char}) {
6474 0         0 $delimiter = $char;
6475             $end_delimiter = $char;
6476             last;
6477             }
6478             }
6479             }
6480             }
6481 0         0  
  68         138  
6482             # count '('
6483 253         424 my $parens = grep { $_ eq '(' } @char;
6484 68         107  
6485 68         98 my $left_e = 0;
6486             my $right_e = 0;
6487             for (my $i=0; $i <= $#char; $i++) {
6488 68 50 33     267  
    50 33        
    100          
    100          
    50          
    50          
6489 195         1472 # "\L\u" --> "\u\L"
6490             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6491             @char[$i,$i+1] = @char[$i+1,$i];
6492             }
6493              
6494 0         0 # "\U\l" --> "\l\U"
6495             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6496             @char[$i,$i+1] = @char[$i+1,$i];
6497             }
6498              
6499 0         0 # octal escape sequence
6500             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6501             $char[$i] = Ekoi8r::octchr($1);
6502             }
6503              
6504 1         3 # hexadecimal escape sequence
6505             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6506             $char[$i] = Ekoi8r::hexchr($1);
6507             }
6508              
6509             # \b{...} --> b\{...}
6510             # \B{...} --> B\{...}
6511             # \N{CHARNAME} --> N\{CHARNAME}
6512             # \p{PROPERTY} --> p\{PROPERTY}
6513 1         4 # \P{PROPERTY} --> P\{PROPERTY}
6514             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6515             $char[$i] = $1 . '\\' . $2;
6516             }
6517              
6518 0         0 # \p, \P, \X --> p, P, X
6519             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6520             $char[$i] = $1;
6521 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          
6522              
6523             if (0) {
6524             }
6525 195         692  
6526 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6527 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6528             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)) {
6529             $char[$i] .= join '', splice @char, $i+1, 3;
6530 0         0 }
6531             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)) {
6532             $char[$i] .= join '', splice @char, $i+1, 2;
6533 0         0 }
6534             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)) {
6535             $char[$i] .= join '', splice @char, $i+1, 1;
6536             }
6537             }
6538              
6539 0         0 # open character class [...]
6540 13 50       21 elsif ($char[$i] eq '[') {
6541 13         40 my $left = $i;
6542             if ($char[$i+1] eq ']') {
6543 0         0 $i++;
6544 13 50       22 }
6545 58         85 while (1) {
6546             if (++$i > $#char) {
6547 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6548 58         177 }
6549             if ($char[$i] eq ']') {
6550             my $right = $i;
6551 13 50       19  
6552 13         76 # [...]
  0         0  
6553             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6554             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6555 0         0 }
6556             else {
6557             splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
6558 13         59 }
6559 13         25  
6560             $i = $left;
6561             last;
6562             }
6563             }
6564             }
6565              
6566 13         34 # open character class [^...]
6567 0 0       0 elsif ($char[$i] eq '[^') {
6568 0         0 my $left = $i;
6569             if ($char[$i+1] eq ']') {
6570 0         0 $i++;
6571 0 0       0 }
6572 0         0 while (1) {
6573             if (++$i > $#char) {
6574 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6575 0         0 }
6576             if ($char[$i] eq ']') {
6577             my $right = $i;
6578 0 0       0  
6579 0         0 # [^...]
  0         0  
6580             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6581             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6582 0         0 }
6583             else {
6584             splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6585 0         0 }
6586 0         0  
6587             $i = $left;
6588             last;
6589             }
6590             }
6591             }
6592              
6593 0         0 # rewrite character class or escape character
6594             elsif (my $char = character_class($char[$i],$modifier)) {
6595             $char[$i] = $char;
6596             }
6597              
6598 7 50       64 # /i modifier
6599 3         5 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
6600             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
6601             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
6602 3         6 }
6603             else {
6604             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
6605             }
6606             }
6607              
6608 0 0       0 # \u \l \U \L \F \Q \E
6609 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6610             if ($right_e < $left_e) {
6611             $char[$i] = '\\' . $char[$i];
6612             }
6613 0         0 }
6614 0         0 elsif ($char[$i] eq '\u') {
6615             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
6616             $left_e++;
6617 0         0 }
6618 0         0 elsif ($char[$i] eq '\l') {
6619             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
6620             $left_e++;
6621 0         0 }
6622 0         0 elsif ($char[$i] eq '\U') {
6623             $char[$i] = '@{[Ekoi8r::uc qq<';
6624             $left_e++;
6625 0         0 }
6626 0         0 elsif ($char[$i] eq '\L') {
6627             $char[$i] = '@{[Ekoi8r::lc qq<';
6628             $left_e++;
6629 0         0 }
6630 0         0 elsif ($char[$i] eq '\F') {
6631             $char[$i] = '@{[Ekoi8r::fc qq<';
6632             $left_e++;
6633 0         0 }
6634 0         0 elsif ($char[$i] eq '\Q') {
6635             $char[$i] = '@{[CORE::quotemeta qq<';
6636             $left_e++;
6637 0 0       0 }
6638 0         0 elsif ($char[$i] eq '\E') {
6639 0         0 if ($right_e < $left_e) {
6640             $char[$i] = '>]}';
6641             $right_e++;
6642 0         0 }
6643             else {
6644             $char[$i] = '';
6645             }
6646 0         0 }
6647 0 0       0 elsif ($char[$i] eq '\Q') {
6648 0         0 while (1) {
6649             if (++$i > $#char) {
6650 0 0       0 last;
6651 0         0 }
6652             if ($char[$i] eq '\E') {
6653             last;
6654             }
6655             }
6656             }
6657             elsif ($char[$i] eq '\E') {
6658             }
6659              
6660             # \0 --> \0
6661             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6662             }
6663              
6664             # \g{N}, \g{-N}
6665              
6666             # P.108 Using Simple Patterns
6667             # in Chapter 7: In the World of Regular Expressions
6668             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6669              
6670             # P.221 Capturing
6671             # in Chapter 5: Pattern Matching
6672             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6673              
6674             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6675             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6676             }
6677              
6678             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6679             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6680             }
6681              
6682             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6683             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6684             }
6685              
6686             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6687             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6688             }
6689              
6690 0 0       0 # $0 --> $0
6691 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6692             if ($ignorecase) {
6693             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6694             }
6695 0 0       0 }
6696 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6697             if ($ignorecase) {
6698             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6699             }
6700             }
6701              
6702             # $$ --> $$
6703             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6704             }
6705              
6706             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6707 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6708 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6709 0         0 $char[$i] = e_capture($1);
6710             if ($ignorecase) {
6711             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6712             }
6713 0         0 }
6714 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6715 0         0 $char[$i] = e_capture($1);
6716             if ($ignorecase) {
6717             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6718             }
6719             }
6720              
6721 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6722 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) {
6723 0         0 $char[$i] = e_capture($1.'->'.$2);
6724             if ($ignorecase) {
6725             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6726             }
6727             }
6728              
6729 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6730 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) {
6731 0         0 $char[$i] = e_capture($1.'->'.$2);
6732             if ($ignorecase) {
6733             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6734             }
6735             }
6736              
6737 0         0 # $$foo
6738 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6739 0         0 $char[$i] = e_capture($1);
6740             if ($ignorecase) {
6741             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6742             }
6743             }
6744              
6745 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
6746 4         16 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6747             if ($ignorecase) {
6748             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::PREMATCH())]}';
6749 0         0 }
6750             else {
6751             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
6752             }
6753             }
6754              
6755 4 50       14 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
6756 4         16 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6757             if ($ignorecase) {
6758             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::MATCH())]}';
6759 0         0 }
6760             else {
6761             $char[$i] = '@{[Ekoi8r::MATCH()]}';
6762             }
6763             }
6764              
6765 4 50       15 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
6766 3         11 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6767             if ($ignorecase) {
6768             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::POSTMATCH())]}';
6769 0         0 }
6770             else {
6771             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
6772             }
6773             }
6774              
6775 3 0       12 # ${ foo }
6776 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) {
6777             if ($ignorecase) {
6778             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6779             }
6780             }
6781              
6782 0         0 # ${ ... }
6783 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6784 0         0 $char[$i] = e_capture($1);
6785             if ($ignorecase) {
6786             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6787             }
6788             }
6789              
6790 0         0 # $scalar or @array
6791 4 50       26 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6792 4         23 $char[$i] = e_string($char[$i]);
6793             if ($ignorecase) {
6794             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6795             }
6796             }
6797              
6798 0 50       0 # quote character before ? + * {
6799             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6800             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6801 13         60 }
6802             else {
6803             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6804             }
6805             }
6806             }
6807 13         59  
6808 68         159 # make regexp string
6809 68 50       116 my $prematch = '';
6810 68         174 $modifier =~ tr/i//d;
6811             if ($left_e > $right_e) {
6812 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6813             }
6814             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6815             }
6816              
6817             #
6818             # escape regexp (s'here'' or s'here''b)
6819 68     21 0 759 #
6820 21   100     52 sub e_s1_q {
6821             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6822 21         68 $modifier ||= '';
6823 21 50       27  
6824 21         94 $modifier =~ tr/p//d;
6825 0         0 if ($modifier =~ /([adlu])/oxms) {
6826 0 0       0 my $line = 0;
6827 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6828 0         0 if ($filename ne __FILE__) {
6829             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6830             last;
6831 0         0 }
6832             }
6833             die qq{Unsupported modifier "$1" used at line $line.\n};
6834 0         0 }
6835              
6836             $slash = 'div';
6837 21 100       37  
    50          
6838 21         59 # literal null string pattern
6839 8         9 if ($string eq '') {
6840 8         9 $modifier =~ tr/bB//d;
6841             $modifier =~ tr/i//d;
6842             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6843             }
6844              
6845 8         105 # with /b /B modifier
6846             elsif ($modifier =~ tr/bB//d) {
6847             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6848             }
6849              
6850 0         0 # without /b /B modifier
6851             else {
6852             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6853             }
6854             }
6855              
6856             #
6857             # escape regexp (s'here'')
6858 13     13 0 33 #
6859             sub e_s1_qt {
6860 13 50       25 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6861              
6862             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6863 13         27  
6864             # split regexp
6865             my @char = $string =~ /\G((?>
6866             [^\\\[\$\@\/] |
6867             [\x00-\xFF] |
6868             \[\^ |
6869             \[\: (?>[a-z]+) \:\] |
6870             \[\:\^ (?>[a-z]+) \:\] |
6871             [\$\@\/] |
6872             \\ (?:$q_char) |
6873             (?:$q_char)
6874             ))/oxmsg;
6875 13         210  
6876 13 50 33     41 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6877             for (my $i=0; $i <= $#char; $i++) {
6878             if (0) {
6879             }
6880 25         159  
6881 0         0 # open character class [...]
6882 0 0       0 elsif ($char[$i] eq '[') {
6883 0         0 my $left = $i;
6884             if ($char[$i+1] eq ']') {
6885 0         0 $i++;
6886 0 0       0 }
6887 0         0 while (1) {
6888             if (++$i > $#char) {
6889 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6890 0         0 }
6891             if ($char[$i] eq ']') {
6892             my $right = $i;
6893 0         0  
6894             # [...]
6895 0         0 splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
6896 0         0  
6897             $i = $left;
6898             last;
6899             }
6900             }
6901             }
6902              
6903 0         0 # open character class [^...]
6904 0 0       0 elsif ($char[$i] eq '[^') {
6905 0         0 my $left = $i;
6906             if ($char[$i+1] eq ']') {
6907 0         0 $i++;
6908 0 0       0 }
6909 0         0 while (1) {
6910             if (++$i > $#char) {
6911 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6912 0         0 }
6913             if ($char[$i] eq ']') {
6914             my $right = $i;
6915 0         0  
6916             # [^...]
6917 0         0 splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6918 0         0  
6919             $i = $left;
6920             last;
6921             }
6922             }
6923             }
6924              
6925 0         0 # escape $ @ / and \
6926             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6927             $char[$i] = '\\' . $char[$i];
6928             }
6929              
6930 0         0 # rewrite character class or escape character
6931             elsif (my $char = character_class($char[$i],$modifier)) {
6932             $char[$i] = $char;
6933             }
6934              
6935 6 0       13 # /i modifier
6936 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
6937             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
6938             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
6939 0         0 }
6940             else {
6941             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
6942             }
6943             }
6944              
6945 0 0       0 # quote character before ? + * {
6946             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6947             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6948 0         0 }
6949             else {
6950             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6951             }
6952             }
6953 0         0 }
6954 13         26  
6955 13         270 $modifier =~ tr/i//d;
6956 13         23 $delimiter = '/';
6957 13         17 $end_delimiter = '/';
6958             my $prematch = '';
6959             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6960             }
6961              
6962             #
6963             # escape regexp (s'here''b)
6964 13     0 0 102 #
6965             sub e_s1_qb {
6966             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6967 0         0  
6968             # split regexp
6969             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6970 0         0  
6971 0 0       0 # unescape character
    0          
6972             for (my $i=0; $i <= $#char; $i++) {
6973             if (0) {
6974             }
6975 0         0  
6976             # remain \\
6977             elsif ($char[$i] eq '\\\\') {
6978             }
6979              
6980 0         0 # escape $ @ / and \
6981             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6982             $char[$i] = '\\' . $char[$i];
6983             }
6984 0         0 }
6985 0         0  
6986 0         0 $delimiter = '/';
6987 0         0 $end_delimiter = '/';
6988             my $prematch = '';
6989             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6990             }
6991              
6992             #
6993             # escape regexp (s''here')
6994 0     16 0 0 #
6995             sub e_s2_q {
6996 16         38 my($ope,$delimiter,$end_delimiter,$string) = @_;
6997              
6998 16         21 $slash = 'div';
6999 16         96  
7000 16 100       46 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
7001             for (my $i=0; $i <= $#char; $i++) {
7002             if (0) {
7003             }
7004 9         30  
7005             # not escape \\
7006             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
7007             }
7008              
7009 0         0 # escape $ @ / and \
7010             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7011             $char[$i] = '\\' . $char[$i];
7012             }
7013 5         15 }
7014              
7015             return join '', $ope, $delimiter, @char, $end_delimiter;
7016             }
7017              
7018             #
7019             # escape regexp (s/here/and here/modifier)
7020 16     97 0 49 #
7021 97   100     754 sub e_sub {
7022             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
7023 97         388 $modifier ||= '';
7024 97 50       305  
7025 97         271 $modifier =~ tr/p//d;
7026 0         0 if ($modifier =~ /([adlu])/oxms) {
7027 0 0       0 my $line = 0;
7028 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7029 0         0 if ($filename ne __FILE__) {
7030             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7031             last;
7032 0         0 }
7033             }
7034             die qq{Unsupported modifier "$1" used at line $line.\n};
7035 0 100       0 }
7036 97         296  
7037 36         49 if ($variable eq '') {
7038             $variable = '$_';
7039             $bind_operator = ' =~ ';
7040 36         125 }
7041              
7042             $slash = 'div';
7043              
7044             # P.128 Start of match (or end of previous match): \G
7045             # P.130 Advanced Use of \G with Perl
7046             # in Chapter 3: Overview of Regular Expression Features and Flavors
7047             # P.312 Iterative Matching: Scalar Context, with /g
7048             # in Chapter 7: Perl
7049             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
7050              
7051             # P.181 Where You Left Off: The \G Assertion
7052             # in Chapter 5: Pattern Matching
7053             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7054              
7055             # P.220 Where You Left Off: The \G Assertion
7056             # in Chapter 5: Pattern Matching
7057 97         172 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7058 97         156  
7059             my $e_modifier = $modifier =~ tr/e//d;
7060 97         141 my $r_modifier = $modifier =~ tr/r//d;
7061 97 50       137  
7062 97         253 my $my = '';
7063 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
7064 0         0 $my = $variable;
7065             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
7066             $variable =~ s/ = .+ \z//oxms;
7067 0         0 }
7068 97         226  
7069             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
7070             $variable_basename =~ s/ \s+ \z//oxms;
7071 97         190  
7072 97 100       170 # quote replacement string
7073 97         241 my $e_replacement = '';
7074 17         39 if ($e_modifier >= 1) {
7075             $e_replacement = e_qq('', '', '', $replacement);
7076             $e_modifier--;
7077 17 100       27 }
7078 80         207 else {
7079             if ($delimiter2 eq "'") {
7080             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
7081 16         32 }
7082             else {
7083             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
7084             }
7085 64         160 }
7086              
7087             my $sub = '';
7088 97 100       591  
7089 97 100       250 # with /r
7090             if ($r_modifier) {
7091             if (0) {
7092             }
7093 8         16  
7094 0 50       0 # s///gr without multibyte anchoring
7095             elsif ($modifier =~ /g/oxms) {
7096             $sub = sprintf(
7097             # 1 2 3 4 5
7098             q,
7099              
7100             $variable, # 1
7101             ($delimiter1 eq "'") ? # 2
7102             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7103             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7104             $s_matched, # 3
7105             $e_replacement, # 4
7106             '$Ekoi8r::re_r=CORE::eval $Ekoi8r::re_r; ' x $e_modifier, # 5
7107             );
7108             }
7109              
7110             # s///r
7111 4         15 else {
7112              
7113 4 50       7 my $prematch = q{$`};
7114              
7115             $sub = sprintf(
7116             # 1 2 3 4 5 6 7
7117             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Ekoi8r::re_r=%s; %s"%s$Ekoi8r::re_r$'" } : %s>,
7118              
7119             $variable, # 1
7120             ($delimiter1 eq "'") ? # 2
7121             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7122             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7123             $s_matched, # 3
7124             $e_replacement, # 4
7125             '$Ekoi8r::re_r=CORE::eval $Ekoi8r::re_r; ' x $e_modifier, # 5
7126             $prematch, # 6
7127             $variable, # 7
7128             );
7129             }
7130 4 50       12  
7131 8         21 # $var !~ s///r doesn't make sense
7132             if ($bind_operator =~ / !~ /oxms) {
7133             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
7134             }
7135             }
7136              
7137 0 100       0 # without /r
7138             else {
7139             if (0) {
7140             }
7141 89         200  
7142 0 100       0 # s///g without multibyte anchoring
    100          
7143             elsif ($modifier =~ /g/oxms) {
7144             $sub = sprintf(
7145             # 1 2 3 4 5 6 7 8
7146             q,
7147              
7148             $variable, # 1
7149             ($delimiter1 eq "'") ? # 2
7150             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7151             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7152             $s_matched, # 3
7153             $e_replacement, # 4
7154             '$Ekoi8r::re_r=CORE::eval $Ekoi8r::re_r; ' x $e_modifier, # 5
7155             $variable, # 6
7156             $variable, # 7
7157             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
7158             );
7159             }
7160              
7161             # s///
7162 22         86 else {
7163              
7164 67 100       100 my $prematch = q{$`};
    100          
7165              
7166             $sub = sprintf(
7167              
7168             ($bind_operator =~ / =~ /oxms) ?
7169              
7170             # 1 2 3 4 5 6 7 8
7171             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Ekoi8r::re_r=%s; %s%s="%s$Ekoi8r::re_r$'"; 1 } : undef> :
7172              
7173             # 1 2 3 4 5 6 7 8
7174             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Ekoi8r::re_r=%s; %s%s="%s$Ekoi8r::re_r$'"; undef }>,
7175              
7176             $variable, # 1
7177             $bind_operator, # 2
7178             ($delimiter1 eq "'") ? # 3
7179             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7180             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7181             $s_matched, # 4
7182             $e_replacement, # 5
7183             '$Ekoi8r::re_r=CORE::eval $Ekoi8r::re_r; ' x $e_modifier, # 6
7184             $variable, # 7
7185             $prematch, # 8
7186             );
7187             }
7188             }
7189 67 50       357  
7190 97         281 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
7191             if ($my ne '') {
7192             $sub = "($my, $sub)[1]";
7193             }
7194 0         0  
7195 97         152 # clear s/// variable
7196             $sub_variable = '';
7197 97         125 $bind_operator = '';
7198              
7199             return $sub;
7200             }
7201              
7202             #
7203             # escape regexp of split qr//
7204 97     74 0 749 #
7205 74   100     357 sub e_split {
7206             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7207 74         379 $modifier ||= '';
7208 74 50       175  
7209 74         230 $modifier =~ tr/p//d;
7210 0         0 if ($modifier =~ /([adlu])/oxms) {
7211 0 0       0 my $line = 0;
7212 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7213 0         0 if ($filename ne __FILE__) {
7214             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7215             last;
7216 0         0 }
7217             }
7218             die qq{Unsupported modifier "$1" used at line $line.\n};
7219 0         0 }
7220              
7221             $slash = 'div';
7222 74 50       209  
7223 74         207 # /b /B modifier
7224             if ($modifier =~ tr/bB//d) {
7225             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7226 0 50       0 }
7227 74         200  
7228             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7229             my $metachar = qr/[\@\\|[\]{^]/oxms;
7230 74         294  
7231             # split regexp
7232             my @char = $string =~ /\G((?>
7233             [^\\\$\@\[\(] |
7234             \\x (?>[0-9A-Fa-f]{1,2}) |
7235             \\ (?>[0-7]{2,3}) |
7236             \\c [\x40-\x5F] |
7237             \\x\{ (?>[0-9A-Fa-f]+) \} |
7238             \\o\{ (?>[0-7]+) \} |
7239             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7240             \\ $q_char |
7241             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7242             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7243             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7244             [\$\@] $qq_variable |
7245             \$ (?>\s* [0-9]+) |
7246             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7247             \$ \$ (?![\w\{]) |
7248             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7249             \[\^ |
7250             \[\: (?>[a-z]+) :\] |
7251             \[\:\^ (?>[a-z]+) :\] |
7252             \(\? |
7253             $q_char
7254 74         10294 ))/oxmsg;
7255 74         339  
7256 74         125 my $left_e = 0;
7257             my $right_e = 0;
7258             for (my $i=0; $i <= $#char; $i++) {
7259 74 50 33     358  
    50 33        
    100          
    100          
    50          
    50          
7260 249         1348 # "\L\u" --> "\u\L"
7261             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7262             @char[$i,$i+1] = @char[$i+1,$i];
7263             }
7264              
7265 0         0 # "\U\l" --> "\l\U"
7266             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7267             @char[$i,$i+1] = @char[$i+1,$i];
7268             }
7269              
7270 0         0 # octal escape sequence
7271             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7272             $char[$i] = Ekoi8r::octchr($1);
7273             }
7274              
7275 1         3 # hexadecimal escape sequence
7276             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7277             $char[$i] = Ekoi8r::hexchr($1);
7278             }
7279              
7280             # \b{...} --> b\{...}
7281             # \B{...} --> B\{...}
7282             # \N{CHARNAME} --> N\{CHARNAME}
7283             # \p{PROPERTY} --> p\{PROPERTY}
7284 1         3 # \P{PROPERTY} --> P\{PROPERTY}
7285             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7286             $char[$i] = $1 . '\\' . $2;
7287             }
7288              
7289 0         0 # \p, \P, \X --> p, P, X
7290             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7291             $char[$i] = $1;
7292 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          
7293              
7294             if (0) {
7295             }
7296 249         860  
7297 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
7298 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7299             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)) {
7300             $char[$i] .= join '', splice @char, $i+1, 3;
7301 0         0 }
7302             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)) {
7303             $char[$i] .= join '', splice @char, $i+1, 2;
7304 0         0 }
7305             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)) {
7306             $char[$i] .= join '', splice @char, $i+1, 1;
7307             }
7308             }
7309              
7310 0         0 # open character class [...]
7311 3 50       7 elsif ($char[$i] eq '[') {
7312 3         7 my $left = $i;
7313             if ($char[$i+1] eq ']') {
7314 0         0 $i++;
7315 3 50       5 }
7316 7         13 while (1) {
7317             if (++$i > $#char) {
7318 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7319 7         14 }
7320             if ($char[$i] eq ']') {
7321             my $right = $i;
7322 3 50       4  
7323 3         17 # [...]
  0         0  
7324             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7325             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7326 0         0 }
7327             else {
7328             splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
7329 3         15 }
7330 3         5  
7331             $i = $left;
7332             last;
7333             }
7334             }
7335             }
7336              
7337 3         8 # open character class [^...]
7338 0 0       0 elsif ($char[$i] eq '[^') {
7339 0         0 my $left = $i;
7340             if ($char[$i+1] eq ']') {
7341 0         0 $i++;
7342 0 0       0 }
7343 0         0 while (1) {
7344             if (++$i > $#char) {
7345 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7346 0         0 }
7347             if ($char[$i] eq ']') {
7348             my $right = $i;
7349 0 0       0  
7350 0         0 # [^...]
  0         0  
7351             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7352             splice @char, $left, $right-$left+1, sprintf(q{@{[Ekoi8r::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7353 0         0 }
7354             else {
7355             splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7356 0         0 }
7357 0         0  
7358             $i = $left;
7359             last;
7360             }
7361             }
7362             }
7363              
7364 0         0 # rewrite character class or escape character
7365             elsif (my $char = character_class($char[$i],$modifier)) {
7366             $char[$i] = $char;
7367             }
7368              
7369             # P.794 29.2.161. split
7370             # in Chapter 29: Functions
7371             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7372              
7373             # P.951 split
7374             # in Chapter 27: Functions
7375             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7376              
7377             # said "The //m modifier is assumed when you split on the pattern /^/",
7378             # but perl5.008 is not so. Therefore, this software adds //m.
7379             # (and so on)
7380              
7381 1         3 # split(m/^/) --> split(m/^/m)
7382             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7383             $modifier .= 'm';
7384             }
7385              
7386 7 0       22 # /i modifier
7387 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
7388             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
7389             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
7390 0         0 }
7391             else {
7392             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
7393             }
7394             }
7395              
7396 0 0       0 # \u \l \U \L \F \Q \E
7397 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7398             if ($right_e < $left_e) {
7399             $char[$i] = '\\' . $char[$i];
7400             }
7401 0         0 }
7402 0         0 elsif ($char[$i] eq '\u') {
7403             $char[$i] = '@{[Ekoi8r::ucfirst qq<';
7404             $left_e++;
7405 0         0 }
7406 0         0 elsif ($char[$i] eq '\l') {
7407             $char[$i] = '@{[Ekoi8r::lcfirst qq<';
7408             $left_e++;
7409 0         0 }
7410 0         0 elsif ($char[$i] eq '\U') {
7411             $char[$i] = '@{[Ekoi8r::uc qq<';
7412             $left_e++;
7413 0         0 }
7414 0         0 elsif ($char[$i] eq '\L') {
7415             $char[$i] = '@{[Ekoi8r::lc qq<';
7416             $left_e++;
7417 0         0 }
7418 0         0 elsif ($char[$i] eq '\F') {
7419             $char[$i] = '@{[Ekoi8r::fc qq<';
7420             $left_e++;
7421 0         0 }
7422 0         0 elsif ($char[$i] eq '\Q') {
7423             $char[$i] = '@{[CORE::quotemeta qq<';
7424             $left_e++;
7425 0 0       0 }
7426 0         0 elsif ($char[$i] eq '\E') {
7427 0         0 if ($right_e < $left_e) {
7428             $char[$i] = '>]}';
7429             $right_e++;
7430 0         0 }
7431             else {
7432             $char[$i] = '';
7433             }
7434 0         0 }
7435 0 0       0 elsif ($char[$i] eq '\Q') {
7436 0         0 while (1) {
7437             if (++$i > $#char) {
7438 0 0       0 last;
7439 0         0 }
7440             if ($char[$i] eq '\E') {
7441             last;
7442             }
7443             }
7444             }
7445             elsif ($char[$i] eq '\E') {
7446             }
7447              
7448 0 0       0 # $0 --> $0
7449 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7450             if ($ignorecase) {
7451             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7452             }
7453 0 0       0 }
7454 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7455             if ($ignorecase) {
7456             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7457             }
7458             }
7459              
7460             # $$ --> $$
7461             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7462             }
7463              
7464             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7465 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7466 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7467 0         0 $char[$i] = e_capture($1);
7468             if ($ignorecase) {
7469             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7470             }
7471 0         0 }
7472 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7473 0         0 $char[$i] = e_capture($1);
7474             if ($ignorecase) {
7475             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7476             }
7477             }
7478              
7479 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7480 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) {
7481 0         0 $char[$i] = e_capture($1.'->'.$2);
7482             if ($ignorecase) {
7483             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7484             }
7485             }
7486              
7487 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7488 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) {
7489 0         0 $char[$i] = e_capture($1.'->'.$2);
7490             if ($ignorecase) {
7491             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7492             }
7493             }
7494              
7495 0         0 # $$foo
7496 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7497 0         0 $char[$i] = e_capture($1);
7498             if ($ignorecase) {
7499             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7500             }
7501             }
7502              
7503 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
7504 12         32 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7505             if ($ignorecase) {
7506             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::PREMATCH())]}';
7507 0         0 }
7508             else {
7509             $char[$i] = '@{[Ekoi8r::PREMATCH()]}';
7510             }
7511             }
7512              
7513 12 50       56 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
7514 12         37 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7515             if ($ignorecase) {
7516             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::MATCH())]}';
7517 0         0 }
7518             else {
7519             $char[$i] = '@{[Ekoi8r::MATCH()]}';
7520             }
7521             }
7522              
7523 12 50       55 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
7524 9         74 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7525             if ($ignorecase) {
7526             $char[$i] = '@{[Ekoi8r::ignorecase(Ekoi8r::POSTMATCH())]}';
7527 0         0 }
7528             else {
7529             $char[$i] = '@{[Ekoi8r::POSTMATCH()]}';
7530             }
7531             }
7532              
7533 9 0       45 # ${ foo }
7534 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) {
7535             if ($ignorecase) {
7536             $char[$i] = '@{[Ekoi8r::ignorecase(' . $1 . ')]}';
7537             }
7538             }
7539              
7540 0         0 # ${ ... }
7541 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7542 0         0 $char[$i] = e_capture($1);
7543             if ($ignorecase) {
7544             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7545             }
7546             }
7547              
7548 0         0 # $scalar or @array
7549 3 50       144 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7550 3         14 $char[$i] = e_string($char[$i]);
7551             if ($ignorecase) {
7552             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
7553             }
7554             }
7555              
7556 0 50       0 # quote character before ? + * {
7557             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7558             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7559 1         7 }
7560             else {
7561             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7562             }
7563             }
7564             }
7565 0         0  
7566 74 50       206 # make regexp string
7567 74         166 $modifier =~ tr/i//d;
7568             if ($left_e > $right_e) {
7569 0         0 return join '', 'Ekoi8r::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7570             }
7571             return join '', 'Ekoi8r::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7572             }
7573              
7574             #
7575             # escape regexp of split qr''
7576 74     0 0 841 #
7577 0   0       sub e_split_q {
7578             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7579 0           $modifier ||= '';
7580 0 0          
7581 0           $modifier =~ tr/p//d;
7582 0           if ($modifier =~ /([adlu])/oxms) {
7583 0 0         my $line = 0;
7584 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7585 0           if ($filename ne __FILE__) {
7586             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7587             last;
7588 0           }
7589             }
7590             die qq{Unsupported modifier "$1" used at line $line.\n};
7591 0           }
7592              
7593             $slash = 'div';
7594 0 0          
7595 0           # /b /B modifier
7596             if ($modifier =~ tr/bB//d) {
7597             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7598 0 0         }
7599              
7600             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7601 0            
7602             # split regexp
7603             my @char = $string =~ /\G((?>
7604             [^\\\[] |
7605             [\x00-\xFF] |
7606             \[\^ |
7607             \[\: (?>[a-z]+) \:\] |
7608             \[\:\^ (?>[a-z]+) \:\] |
7609             \\ (?:$q_char) |
7610             (?:$q_char)
7611             ))/oxmsg;
7612 0            
7613 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7614             for (my $i=0; $i <= $#char; $i++) {
7615             if (0) {
7616             }
7617 0            
7618 0           # open character class [...]
7619 0 0         elsif ($char[$i] eq '[') {
7620 0           my $left = $i;
7621             if ($char[$i+1] eq ']') {
7622 0           $i++;
7623 0 0         }
7624 0           while (1) {
7625             if (++$i > $#char) {
7626 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7627 0           }
7628             if ($char[$i] eq ']') {
7629             my $right = $i;
7630 0            
7631             # [...]
7632 0           splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
7633 0            
7634             $i = $left;
7635             last;
7636             }
7637             }
7638             }
7639              
7640 0           # open character class [^...]
7641 0 0         elsif ($char[$i] eq '[^') {
7642 0           my $left = $i;
7643             if ($char[$i+1] eq ']') {
7644 0           $i++;
7645 0 0         }
7646 0           while (1) {
7647             if (++$i > $#char) {
7648 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7649 0           }
7650             if ($char[$i] eq ']') {
7651             my $right = $i;
7652 0            
7653             # [^...]
7654 0           splice @char, $left, $right-$left+1, Ekoi8r::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7655 0            
7656             $i = $left;
7657             last;
7658             }
7659             }
7660             }
7661              
7662 0           # rewrite character class or escape character
7663             elsif (my $char = character_class($char[$i],$modifier)) {
7664             $char[$i] = $char;
7665             }
7666              
7667 0           # split(m/^/) --> split(m/^/m)
7668             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7669             $modifier .= 'm';
7670             }
7671              
7672 0 0         # /i modifier
7673 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ekoi8r::uc($char[$i]) ne Ekoi8r::fc($char[$i]))) {
7674             if (CORE::length(Ekoi8r::fc($char[$i])) == 1) {
7675             $char[$i] = '[' . Ekoi8r::uc($char[$i]) . Ekoi8r::fc($char[$i]) . ']';
7676 0           }
7677             else {
7678             $char[$i] = '(?:' . Ekoi8r::uc($char[$i]) . '|' . Ekoi8r::fc($char[$i]) . ')';
7679             }
7680             }
7681              
7682 0 0         # quote character before ? + * {
7683             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7684             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7685 0           }
7686             else {
7687             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7688             }
7689             }
7690 0           }
7691 0            
7692             $modifier =~ tr/i//d;
7693             return join '', 'Ekoi8r::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7694             }
7695              
7696             #
7697             # instead of Carp::carp
7698 0     0 0   #
7699 0           sub carp {
7700             my($package,$filename,$line) = caller(1);
7701             print STDERR "@_ at $filename line $line.\n";
7702             }
7703              
7704             #
7705             # instead of Carp::croak
7706 0     0 0   #
7707 0           sub croak {
7708 0           my($package,$filename,$line) = caller(1);
7709             print STDERR "@_ at $filename line $line.\n";
7710             die "\n";
7711             }
7712              
7713             #
7714             # instead of Carp::cluck
7715 0     0 0   #
7716 0           sub cluck {
7717 0           my $i = 0;
7718 0           my @cluck = ();
7719 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7720             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7721 0           $i++;
7722 0           }
7723 0           print STDERR CORE::reverse @cluck;
7724             print STDERR "\n";
7725             print STDERR @_;
7726             }
7727              
7728             #
7729             # instead of Carp::confess
7730 0     0 0   #
7731 0           sub confess {
7732 0           my $i = 0;
7733 0           my @confess = ();
7734 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7735             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7736 0           $i++;
7737 0           }
7738 0           print STDERR CORE::reverse @confess;
7739 0           print STDERR "\n";
7740             print STDERR @_;
7741             die "\n";
7742             }
7743              
7744             1;
7745              
7746             __END__