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   1168 use strict;
  204         491  
  204         11618  
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   3078 use 5.00503; # Galapagos Consensus 1998 for primetools
  204         628  
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   1315 use vars qw($VERSION);
  204         435  
  204         33763  
28             $VERSION = '1.13';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 204 50   204   2766 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 204         355 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 204         50233 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   17656 CORE::eval q{
  204     204   1301  
  204     70   491  
  204         24909  
  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       87787 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   1675 no strict qw(refs);
  204         363  
  204         18075  
118 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
119             }
120             else {
121 204     204   1296 no strict qw(refs);
  204     0   456  
  204         65645  
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   1362 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  204         372  
  204         14323  
154 204     204   1351 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  204         479  
  204         379509  
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         20556 use vars qw(
406             $re_a
407             $re_t
408             $re_n
409             $re_r
410 204     204   1808 );
  204         398  
411              
412             #
413             # Character class
414             #
415 204         2286060 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   1266 );
  204         352  
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         274 my $s = shift @_;
965 174 50 33     210 if (@_ and wantarray) {
966 174 0       312 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         536  
970             }
971             }
972             else {
973 174         614 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         268 my $s = shift @_;
991 197 50 33     229 if (@_ and wantarray) {
992 197 0       331 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         466  
996             }
997             }
998             else {
999 197         1060 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     2705 }->{$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 68155 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       317 if ($length == 1) {
1498 182         386 my($a1) = unpack 'C', $_[0];
1499 182         491 my($z1) = unpack 'C', $_[1];
1500              
1501 182 50       402 if ($a1 > $z1) {
1502 182         645 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         519 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         1144 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         414 my @range_regexp = ();
1527 182 50       279 if (not exists $range_tr{$length}) {
1528 182         445 return @range_regexp;
1529             }
1530              
1531 0         0 my @ranges = @{ $range_tr{$length} };
  182         264  
1532 182         396 while (my @range = splice(@ranges,0,$length)) {
1533 182         544 my $min = '';
1534 182         261 my $max = '';
1535 182         262 for (my $i=0; $i < $length; $i++) {
1536 182         463 $min .= pack 'C', $range[$i][0];
1537 182         704 $max .= pack 'C', $range[$i][-1];
1538             }
1539              
1540             # min___max
1541             # FIRST_____________LAST
1542             # (nothing)
1543              
1544 182 50 33     732 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         2031 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         578 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   468 my $modifier = pop @_;
1613 358         565 my @char = @_;
1614              
1615 358 100       861 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1616              
1617             # unescape character
1618 358         837 for (my $i=0; $i <= $#char; $i++) {
1619              
1620             # escape - to ...
1621 358 100 100     1204 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1622 1125 100 100     8881 if ((0 < $i) and ($i < $#char)) {
1623 206         2098 $char[$i] = '...';
1624             }
1625             }
1626              
1627             # octal escape sequence
1628             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1629 182         375 $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         108 $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         467 }->{$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         84 }->{$1};
1752             }
1753             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1754 70         1199 $char[$i] = $1;
1755             }
1756             }
1757              
1758             # open character list
1759 7         33 my @singleoctet = ();
1760 358         773 my @multipleoctet = ();
1761 358         499 for (my $i=0; $i <= $#char; ) {
1762              
1763             # escaped -
1764 358 100 100     893 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1765 943         5075 $i += 1;
1766 182         228 next;
1767             }
1768              
1769             # make range regexp
1770             elsif ($char[$i] eq '...') {
1771              
1772             # range error
1773 182 50       322 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1774 182         800 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         447 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         669 my @regexp = ();
1785              
1786             # is first and last
1787 182 50 33     297 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1788 182         735 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         502 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         431 push @singleoctet, @regexp;
1812             }
1813             else {
1814 182         858 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       423 if ($modifier =~ /i/oxms) {
1824 493         744 my $uc = Ekoi8r::uc($char[$i]);
1825 24         49 my $fc = Ekoi8r::fc($char[$i]);
1826 24 100       50 if ($uc ne $fc) {
1827 24 50       44 if (CORE::length($fc) == 1) {
1828 12         32 push @singleoctet, $uc, $fc;
1829             }
1830             else {
1831 12         50 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         28 push @singleoctet, $char[$i];
1841             }
1842 469         816 $i += 1;
1843             }
1844              
1845             # single character of single octet code
1846             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1847 493         1015 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         5 push @multipleoctet, $char[$i];
1862 84         168 $i += 1;
1863             }
1864             }
1865              
1866             # quote metachar
1867 84         159 for (@singleoctet) {
1868 358 50       726 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1869 689         3124 $_ = '-';
1870             }
1871             elsif (/\A \n \z/oxms) {
1872 0         0 $_ = '\n';
1873             }
1874             elsif (/\A \r \z/oxms) {
1875 8         18 $_ = '\r';
1876             }
1877             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1878 8         25 $_ = sprintf('\x%02X', CORE::ord $1);
1879             }
1880             elsif (/\A [\x00-\xFF] \z/oxms) {
1881 60         203 $_ = quotemeta $_;
1882             }
1883             }
1884              
1885             # return character list
1886 429         709 return \@singleoctet, \@multipleoctet;
1887             }
1888              
1889             #
1890             # KOI8-R octal escape sequence
1891             #
1892             sub octchr {
1893 358     5 0 1302 my($octdigit) = @_;
1894              
1895 5         15 my @binary = ();
1896 5         8 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         30 }->{$octal};
1907             }
1908 50         170 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         60 return $octchr;
1924             }
1925              
1926             #
1927             # KOI8-R hexadecimal escape sequence
1928             #
1929             sub hexchr {
1930 5     5 0 19 my($hexdigit) = @_;
1931              
1932             my $hexchr = {
1933             1 => pack('H*', "0$hexdigit"),
1934             0 => pack('H*', "$hexdigit"),
1935              
1936 5         16 }->{CORE::length($_[0]) % 2};
1937              
1938 5         48 return $hexchr;
1939             }
1940              
1941             #
1942             # KOI8-R open character list for qr
1943             #
1944             sub charlist_qr {
1945              
1946 5     314 0 17 my $modifier = pop @_;
1947 314         609 my @char = @_;
1948              
1949 314         771 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1950 314         914 my @singleoctet = @$singleoctet;
1951 314         649 my @multipleoctet = @$multipleoctet;
1952              
1953             # return character list
1954 314 100       488 if (scalar(@singleoctet) >= 1) {
1955              
1956             # with /i modifier
1957 314 100       723 if ($modifier =~ m/i/oxms) {
1958 236         560 my %singleoctet_ignorecase = ();
1959 22         34 for (@singleoctet) {
1960 22   100     42 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1961 46         197 for my $ord (hex($1) .. hex($2)) {
1962 46         137 my $char = CORE::chr($ord);
1963 66         99 my $uc = Ekoi8r::uc($char);
1964 66         97 my $fc = Ekoi8r::fc($char);
1965 66 100       133 if ($uc eq $fc) {
1966 66         165 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1967             }
1968             else {
1969 12 50       89 if (CORE::length($fc) == 1) {
1970 54         85 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1971 54         115 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1972             }
1973             else {
1974 54         221 $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         106 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1982             }
1983             }
1984 0         0 my $i = 0;
1985 22         36 my @singleoctet_ignorecase = ();
1986 22         36 for my $ord (0 .. 255) {
1987 22 100       35 if (exists $singleoctet_ignorecase{$ord}) {
1988 5632         7131 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         104  
1989             }
1990             else {
1991 96         256 $i++;
1992             }
1993             }
1994 5536         5735 @singleoctet = ();
1995 22         40 for my $range (@singleoctet_ignorecase) {
1996 22 100       66 if (ref $range) {
1997 3648 100       5601 if (scalar(@{$range}) == 1) {
  56 50       57  
1998 56         84 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         42  
1999             }
2000 36         117 elsif (scalar(@{$range}) == 2) {
2001 20         28 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         28  
2005             }
2006             }
2007             }
2008             }
2009              
2010 20         79 my $not_anchor = '';
2011              
2012 236         380 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2013             }
2014 236 100       636 if (scalar(@multipleoctet) >= 2) {
2015 314         669 return '(?:' . join('|', @multipleoctet) . ')';
2016             }
2017             else {
2018 6         32 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 1274 my $modifier = pop @_;
2028 44         85 my @char = @_;
2029              
2030 44         124 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2031 44         129 my @singleoctet = @$singleoctet;
2032 44         143 my @multipleoctet = @$multipleoctet;
2033              
2034             # with /i modifier
2035 44 100       201 if ($modifier =~ m/i/oxms) {
2036 44         214 my %singleoctet_ignorecase = ();
2037 10         13 for (@singleoctet) {
2038 10   66     15 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2039 10         43 for my $ord (hex($1) .. hex($2)) {
2040 10         30 my $char = CORE::chr($ord);
2041 30         46 my $uc = Ekoi8r::uc($char);
2042 30         43 my $fc = Ekoi8r::fc($char);
2043 30 50       45 if ($uc eq $fc) {
2044 30         42 $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         57 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2050             }
2051             else {
2052 30         96 $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         23 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2060             }
2061             }
2062 0         0 my $i = 0;
2063 10         11 my @singleoctet_ignorecase = ();
2064 10         15 for my $ord (0 .. 255) {
2065 10 100       13 if (exists $singleoctet_ignorecase{$ord}) {
2066 2560         2850 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         55  
2067             }
2068             else {
2069 60         109 $i++;
2070             }
2071             }
2072 2500         2456 @singleoctet = ();
2073 10         16 for my $range (@singleoctet_ignorecase) {
2074 10 100       22 if (ref $range) {
2075 960 50       1400 if (scalar(@{$range}) == 1) {
  20 50       23  
2076 20         33 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2077             }
2078 0         0 elsif (scalar(@{$range}) == 2) {
2079 20         27 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         21  
  20         24  
2083             }
2084             }
2085             }
2086             }
2087              
2088             # return character list
2089 20 50       70 if (scalar(@multipleoctet) >= 1) {
2090 44 0       132 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         93 return '(?:[^' . join('', @singleoctet) . '])';
2106             }
2107             else {
2108              
2109             # any character
2110 44         288 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   2306 use Fcntl qw(O_RDONLY);
  204         443  
  204         37241  
2121 408         1212 return CORE::sysopen($_[0], $file, &O_RDONLY);
2122             }
2123              
2124             #
2125             # open file in append mode
2126             #
2127             sub _open_a {
2128 408     204   17395 my(undef,$file) = @_;
2129 204     204   1666 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  204         466  
  204         686815  
2130 204         630 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   23117 $| = 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         659 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         2548 return CORE::system { $_[0] } @_; # safe even with one-argument list
  204         429  
2213             }
2214              
2215             #
2216             # KOI8-R order to character (with parameter)
2217             #
2218             sub Ekoi8r::chr(;$) {
2219              
2220 204 0   0 0 20559604 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 138555 # 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   2129 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  204         523  
  204         47705  
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   1483 my $anchor = '';
  204     0   378  
  204         10132475  
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         641 # 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         397 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3015 204         357  
3016 204         750 my $e_script = '';
3017             while (not /\G \z/oxgc) { # member
3018             $e_script .= KOI8R::escape_token();
3019 74633         131156 }
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 2461 # \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     107914 # 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         3045697  
3050 12510 100       16528 if (/\G ( \n ) /oxgc) { # another member (and so on)
3051 12510         37030 my $heredoc = '';
3052             if (scalar(@heredoc_delimiter) >= 1) {
3053 174         216 $slash = 'm//';
3054 174         833  
3055             $heredoc = join '', @heredoc;
3056             @heredoc = ();
3057 174         294  
3058 174         414 # skip here document
3059             for my $heredoc_delimiter (@heredoc_delimiter) {
3060 174         1251 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3061             }
3062 174         309 @heredoc_delimiter = ();
3063              
3064 174         232 $here_script = '';
3065             }
3066             return "\n" . $heredoc;
3067             }
3068 12510         36369  
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         53878  
3084 1401         2185 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         4104  
3104             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3105 86 50       204 my $e_string = e_string($1);
    50          
3106 86         2219  
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         148 else {
3120             $slash = 'div';
3121             return $e_string;
3122             }
3123             }
3124              
3125 86         251 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ekoi8r::PREMATCH()
3126 4         9 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3127             $slash = 'div';
3128             return q{Ekoi8r::PREMATCH()};
3129             }
3130              
3131 4         13 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
3132 28         83 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         5 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3139             $slash = 'div';
3140             return $1;
3141             }
3142              
3143 1         7 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
3144 3         6 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         61 # substr() =~ s///;
3153             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3154 1671 100       3445 my $scalar = e_string($1);
    100          
3155 1671         6053  
3156 1         3 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3157 1         2 $tr_variable = $scalar;
3158 1         1 $bind_operator = $1;
3159             $slash = 'm//';
3160             return '';
3161 1         3 }
3162 61         118 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3163 61         120 $sub_variable = $scalar;
3164 61         86 $bind_operator = $1;
3165             $slash = 'm//';
3166             return '';
3167 61         165 }
3168 1609         3389 else {
3169             $slash = 'div';
3170             return $scalar;
3171             }
3172             }
3173              
3174 1609         4352 # end of statement
3175             elsif (/\G ( [,;] ) /oxgc) {
3176             $slash = 'm//';
3177 4986         7399  
3178             # clear tr/// variable
3179             $tr_variable = '';
3180 4986         5849  
3181             # clear s/// variable
3182 4986         10388 $sub_variable = '';
3183              
3184 4986         5394 $bind_operator = '';
3185              
3186             return $1;
3187             }
3188              
3189 4986         18147 # bareword
3190             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3191             return $1;
3192             }
3193              
3194 0         0 # $0 --> $0
3195 2         4 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         2 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         3 # $1, $2, $3 --> $1, $2, $3 otherwise
3212 4         8 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3213             $slash = 'div';
3214             return e_capture($1);
3215 4         7 }
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         80 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         137 # $ @ # \ ' " / ? ( ) [ ] < >
3259 62         130 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3260             $slash = 'div';
3261             return $1;
3262             }
3263              
3264 62         232 # 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         544  
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         1013  
  19         67  
3290 19         66 # 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         19  
3292 13         33 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         176  
3294 114         305 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         4  
3295 2         9 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         5  
3297 2         7 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         6  
3301 2         7 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         4 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         3  
3307 1         4 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         15  
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         21  
  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         5  
3334 2         7  
  2         5  
3335 2         5 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         60  
3336 36         109 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         5  
3337 2         7 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ekoi8r::chr'; }
  8         12  
3338 8         26 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         27 # split
3357             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3358 87         173 $slash = 'm//';
3359 87         128  
3360 87         303 my $e = '';
3361             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3362             $e .= $1;
3363             }
3364 85 100       307  
  87 100       5604  
    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         8  
3368             # split scalar value
3369             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Ekoi8r::split' . $e . e_string($1); }
3370 1         6  
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         41 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         422  
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       62 else {
  12 50       4316  
    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         83 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         515  
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       87 else {
  18 50       4896  
    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         117 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         158 elsif (/\G (\/) /oxgc) {
3483 44 50       211 my $regexp = '';
  381 50       1673  
    100          
    50          
3484 0         0 while (not /\G \z/oxgc) {
3485 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3486 44         186 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3487             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3488 337         697 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         42 # $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       220  
    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         10 }
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       4867  
3576 2180         4059 # 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         2872 else {
3589 2180 50       5818 my $e = '';
  2180 50       8219  
    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         2788 elsif (/\G (\{) /oxgc) { # qq { }
3612 2150         2915 my $qq_string = '';
3613 2150 100       4436 local $nest = 1;
  83993 50       294189  
    100          
    100          
    50          
3614 722         1490 while (not /\G \z/oxgc) {
3615 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         2276  
3616             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3617 1153 100       1996 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         4926  
3618 2150         4094 elsif (/\G (\}) /oxgc) {
3619             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3620 1153         2484 else { $qq_string .= $1; }
3621             }
3622 78815         160791 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         50 elsif (/\G (\<) /oxgc) { # qq < >
3646 30         49 my $qq_string = '';
3647 30 100       97 local $nest = 1;
  1166 50       4114  
    50          
    100          
    50          
3648 22         50 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         64  
3652 30         67 elsif (/\G (\>) /oxgc) {
3653             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3654 0         0 else { $qq_string .= $1; }
3655             }
3656 1114         2050 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       43 elsif (/\G \b (qw) \b /oxgc) {
3702 16         90 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       53 my $e = '';
  16 50       116  
    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         59  
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       1039 # (and so on)
3759 410         1277  
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         734 else {
3772 410 50       1160 my $e = '';
  410 50       2057  
    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         717 elsif (/\G (\{) /oxgc) { # q { }
3796 404         663 my $q_string = '';
3797 404 50       1152 local $nest = 1;
  6757 50       24820  
    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         176  
3801             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3802 107 100       181 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         1073  
3803 404         1037 elsif (/\G (\}) /oxgc) {
3804             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3805 107         218 else { $q_string .= $1; }
3806             }
3807 6139         11565 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         10 elsif (/\G (\<) /oxgc) { # q < >
3832 5         10 my $q_string = '';
3833 5 50       20 local $nest = 1;
  88 50       353  
    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         15  
3839 5         25 elsif (/\G (\>) /oxgc) {
3840             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3841 0         0 else { $q_string .= $1; }
3842             }
3843 83         165 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         2 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         26 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       582 elsif (/\G \b (m) \b /oxgc) {
3867 209         1316 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         309 else {
3872 209 50       693 my $e = '';
  209 50       10434  
    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         30 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         780 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       247  
3898 97         1745 # $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         6 }
3902 96         186 else {
3903 96 50       307 my $e = '';
  96 50       12389  
    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         56 # $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         359 }
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         291 # 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         23 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     11 }
      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         15 # 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         1881 elsif (/\G (?
4039 848 100       2565 my $q_string = '';
  8241 100       24429  
    100          
    50          
4040 4         9 while (not /\G \z/oxgc) {
4041 48         88 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4042 848         1844 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4043             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4044 7341         17433 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         3634 elsif (/\G (\") /oxgc) {
4051 1780 100       4079 my $qq_string = '';
  34872 100       96418  
    100          
    50          
4052 67         150 while (not /\G \z/oxgc) {
4053 12         26 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4054 1780         4078 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4055             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4056 33013         66587 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         3 elsif (/\G (\`) /oxgc) {
4063 1 50       4 my $qx_string = '';
  19 50       110  
    100          
    50          
4064 0         0 while (not /\G \z/oxgc) {
4065 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4066 1         3 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4067             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4068 18         44 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         1407 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4075 453 50       1324 my $regexp = '';
  4496 50       15370  
    100          
    50          
4076 0         0 while (not /\G \z/oxgc) {
4077 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4078 453         1643 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4079             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4080 4043         8191 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         12 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4105 6         34 $slash = 'm//';
4106             my $here_quote = $1;
4107             my $delimiter = $2;
4108 6 50       9  
4109 6         13 # get here document
4110 6         20 if ($here_script eq '') {
4111             $here_script = CORE::substr $_, pos $_;
4112 6 50       30 $here_script =~ s/.*?\n//oxm;
4113 6         63 }
4114 6         15 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4115 6         7 my $heredoc = $1;
4116 6         46 my $indent = $2;
4117 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4118             push @heredoc, $heredoc . qq{\n$delimiter\n};
4119             push @heredoc_delimiter, qq{\\s*$delimiter};
4120 6         12 }
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         23  
4137 3         7 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4138 3         7 $slash = 'm//';
4139             my $here_quote = $1;
4140             my $delimiter = $2;
4141 3 50       7  
4142 3         8 # get here document
4143 3         9 if ($here_script eq '') {
4144             $here_script = CORE::substr $_, pos $_;
4145 3 50       24 $here_script =~ s/.*?\n//oxm;
4146 3         37 }
4147 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4148 3         5 my $heredoc = $1;
4149 3         35 my $indent = $2;
4150 3         20 $heredoc =~ s{^$indent}{}msg; # no /ox
4151             push @heredoc, $heredoc . qq{\n$delimiter\n};
4152             push @heredoc_delimiter, qq{\\s*$delimiter};
4153 3         8 }
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         13 # <<~"HEREDOC"
4161 6         13 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4162 6         11 $slash = 'm//';
4163             my $here_quote = $1;
4164             my $delimiter = $2;
4165 6 50       8  
4166 6         14 # get here document
4167 6         25 if ($here_script eq '') {
4168             $here_script = CORE::substr $_, pos $_;
4169 6 50       28 $here_script =~ s/.*?\n//oxm;
4170 6         61 }
4171 6         15 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4172 6         8 my $heredoc = $1;
4173 6         45 my $indent = $2;
4174 6         15 $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         15 }
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         20 # <<~HEREDOC
4185 3         5 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4186 3         7 $slash = 'm//';
4187             my $here_quote = $1;
4188             my $delimiter = $2;
4189 3 50       4  
4190 3         9 # get here document
4191 3         19 if ($here_script eq '') {
4192             $here_script = CORE::substr $_, pos $_;
4193 3 50       18 $here_script =~ s/.*?\n//oxm;
4194 3         35 }
4195 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4196 3         5 my $heredoc = $1;
4197 3         42 my $indent = $2;
4198 3         10 $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         7 }
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         13 # <<~`HEREDOC`
4209 6         18 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4210 6         13 $slash = 'm//';
4211             my $here_quote = $1;
4212             my $delimiter = $2;
4213 6 50       12  
4214 6         11 # get here document
4215 6         20 if ($here_script eq '') {
4216             $here_script = CORE::substr $_, pos $_;
4217 6 50       34 $here_script =~ s/.*?\n//oxm;
4218 6         58 }
4219 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4220 6         11 my $heredoc = $1;
4221 6         51 my $indent = $2;
4222 6         25 $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         15 }
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         26 # <<'HEREDOC'
4233 72         142 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4234 72         450 $slash = 'm//';
4235             my $here_quote = $1;
4236             my $delimiter = $2;
4237 72 50       127  
4238 72         142 # get here document
4239 72         410 if ($here_script eq '') {
4240             $here_script = CORE::substr $_, pos $_;
4241 72 50       603 $here_script =~ s/.*?\n//oxm;
4242 72         562 }
4243 72         243 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4244             push @heredoc, $1 . qq{\n$delimiter\n};
4245             push @heredoc_delimiter, $delimiter;
4246 72         119 }
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         262  
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         90 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4285 36         84 $slash = 'm//';
4286             my $here_quote = $1;
4287             my $delimiter = $2;
4288 36 50       67  
4289 36         88 # get here document
4290 36         255 if ($here_script eq '') {
4291             $here_script = CORE::substr $_, pos $_;
4292 36 50       205 $here_script =~ s/.*?\n//oxm;
4293 36         507 }
4294 36         126 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         85 }
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         143 # <
4305 42         98 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4306 42         88 $slash = 'm//';
4307             my $here_quote = $1;
4308             my $delimiter = $2;
4309 42 50       74  
4310 42         99 # get here document
4311 42         267 if ($here_script eq '') {
4312             $here_script = CORE::substr $_, pos $_;
4313 42 50       404 $here_script =~ s/.*?\n//oxm;
4314 42         613 }
4315 42         139 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         96 }
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         176 # <<`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         1428 # 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         10572  
4389              
4390             ) /oxgc) { $slash = 'div'; return $1; }
4391              
4392             # yada-yada or triple-dot operator
4393             elsif (/\G (
4394 5081         22502 \.\.\.
  7         15  
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         23 [,;\(\{\[]
  8834         24835  
4451              
4452             )) /oxgc) { $slash = 'm//'; return $1; }
4453 8834         54707  
  15013         27153  
4454             # other any character
4455             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4456              
4457 15013         69023 # 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         3921 sub e_string {
4465             my($string) = @_;
4466 1786         2653 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         2463 # (and so on)
4473              
4474             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4475 1786 100 66     12766  
4476 1786 50       9568 # without { ... }
4477 1769         4976 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4478             if ($string !~ /<
4479             return $string;
4480             }
4481             }
4482 1769         4291  
4483 17 50       56 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         11427  
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         9 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         15 # $ @ % & * $ #
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         34 # $ @ # \ ' " / ? ( ) [ ] < >
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         33  
5111              
5112             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
5113              
5114             # yada-yada or triple-dot operator
5115             elsif ($string =~ /\G (
5116 18         53 \.\.\.
  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         73  
5148              
5149             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
5150 31         108  
5151             # other any character
5152             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
5153              
5154 131         435 # 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 73 #
5166             sub character_class {
5167 1919 100       3376 my($char,$modifier) = @_;
5168 1919 100       2899  
5169 52         93 if ($char eq '.') {
5170             if ($modifier =~ /s/) {
5171             return '${Ekoi8r::dot_s}';
5172 17         37 }
5173             else {
5174             return '${Ekoi8r::dot}';
5175             }
5176 35         73 }
5177             else {
5178             return Ekoi8r::classic_character_class($char);
5179             }
5180             }
5181              
5182             #
5183             # escape capture ($1, $2, $3, ...)
5184             #
5185 1867     212 0 3278 sub e_capture {
5186              
5187             return join '', '${', $_[0], '}';
5188             }
5189              
5190             #
5191             # escape transliteration (tr/// or y///)
5192 212     3 0 728 #
5193 3         16 sub e_tr {
5194 3   50     5 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
5195             my $e_tr = '';
5196 3         11 $modifier ||= '';
5197              
5198             $slash = 'div';
5199 3         4  
5200             # quote character class 1
5201             $charclass = q_tr($charclass);
5202 3         6  
5203             # quote character class 2
5204             $charclass2 = q_tr($charclass2);
5205 3 50       5  
5206 3 0       7 # /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         6 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         4  
5224 3         4 # clear tr/// variable
5225             $tr_variable = '';
5226 3         4 $bind_operator = '';
5227              
5228             return $e_tr;
5229             }
5230              
5231             #
5232             # quote for escape transliteration (tr/// or y///)
5233 3     6 0 15 #
5234             sub q_tr {
5235             my($charclass) = @_;
5236 6 50       9  
    0          
    0          
    0          
    0          
    0          
5237 6         10 # quote character class
5238             if ($charclass !~ /'/oxms) {
5239             return e_q('', "'", "'", $charclass); # --> q' '
5240 6         9 }
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         23025 my($ope,$delimiter,$end_delimiter,$string) = @_;
5272              
5273 1264         1645 $slash = 'div';
5274              
5275             return join '', $ope, $delimiter, $string, $end_delimiter;
5276             }
5277              
5278             #
5279             # escape qq string (qq//, "", qx//, ``)
5280 1264     4042 0 6708 #
5281             sub e_qq {
5282 4042         9042 my($ope,$delimiter,$end_delimiter,$string) = @_;
5283              
5284 4042         5374 $slash = 'div';
5285 4042         4792  
5286             my $left_e = 0;
5287             my $right_e = 0;
5288 4042         5672  
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         140058 ))/oxmsg;
5305              
5306             for (my $i=0; $i <= $#char; $i++) {
5307 4042 50 33     12679  
    50 33        
    100          
    100          
    50          
5308 113560         391259 # "\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         3 # 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         943505  
5343 0 50       0 # \u \l \U \L \F \Q \E
5344 484         1006 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         31 elsif ($char[$i] eq '\F') {
5379             $char[$i] = '@{[Ekoi8r::fc qq<';
5380             $left_e++;
5381 24         45 }
5382 0         0 elsif ($char[$i] eq '\Q') {
5383             $char[$i] = '@{[CORE::quotemeta qq<';
5384             $left_e++;
5385 0 50       0 }
5386 24         48 elsif ($char[$i] eq '\E') {
5387 24         30 if ($right_e < $left_e) {
5388             $char[$i] = '>]}';
5389             $right_e++;
5390 24         42 }
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         383 }
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         126 # $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         88 # ${ ... }
5462             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5463             $char[$i] = e_capture($1);
5464             }
5465             }
5466 0 50       0  
5467 4042         7060 # 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 33212 #
5477             sub e_qw {
5478 16         79 my($ope,$delimiter,$end_delimiter,$string) = @_;
5479              
5480             $slash = 'div';
5481 16         37  
  16         205  
5482 483 50       805 # choice again delimiter
    0          
    0          
    0          
    0          
5483 16         101 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         140 }
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         245 my($string) = @_;
5526              
5527 93         153 $slash = 'm//';
5528              
5529 93         313 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5530 93         170  
5531             my $left_e = 0;
5532             my $right_e = 0;
5533 93         114  
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         8277 ))/oxmsg;
5550              
5551             for (my $i=0; $i <= $#char; $i++) {
5552 93 50 33     417  
    50 33        
    100          
    100          
    50          
5553 3151         9882 # "\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         3 # 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         4 # \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         25103  
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         50 # $&, ${&}, $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         51 # $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         43 # ${ ... }
5687             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5688             $char[$i] = e_capture($1);
5689             }
5690             }
5691 0 50       0  
5692 93         229 # 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 716 #
5702 652   100     6686 sub e_qr {
5703             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5704 652         2915 $modifier ||= '';
5705 652 50       1157  
5706 652         1415 $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       992  
    100          
5720 652         1949 # literal null string pattern
5721 8         9 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       40  
5730 2         6 # 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         12  
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       10 }
5768 642         1581  
5769             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5770             my $metachar = qr/[\@\\|[\]{^]/oxms;
5771 642         2735  
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       66318  
5797 642         3590 # 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         965  
5827 642         1004 my $left_e = 0;
5828             my $right_e = 0;
5829             for (my $i=0; $i <= $#char; $i++) {
5830 642 50 66     1578  
    50 66        
    100          
    100          
    100          
    100          
5831 1872         10001 # "\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         3 # \P{PROPERTY} --> P\{PROPERTY}
5856             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5857             $char[$i] = $1 . '\\' . $2;
5858             }
5859              
5860 6         18 # \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         5902  
5868 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5869 6         81 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       457 # (and so on)
5887 328         3003  
5888             if ($char[$i+1] eq ']') {
5889             $i++;
5890 3         4 }
5891 328 50       419  
5892 1379         1916 while (1) {
5893             if (++$i > $#char) {
5894 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5895 1379         2143 }
5896             if ($char[$i] eq ']') {
5897             my $right = $i;
5898 328 100       415  
5899 328         3575 # [...]
  30         68  
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         148 }
5903             else {
5904             splice @char, $left, $right-$left+1, Ekoi8r::charlist_qr(@char[$left+1..$right-1], $modifier);
5905 298         1164 }
5906 328         666  
5907             $i = $left;
5908             last;
5909             }
5910             }
5911             }
5912              
5913 328         1061 # open character class [^...]
5914             elsif ($char[$i] eq '[^') {
5915             my $left = $i;
5916              
5917             # [^] make die "Unmatched [] in regexp ...\n"
5918 74 100       101 # (and so on)
5919 74         169  
5920             if ($char[$i+1] eq ']') {
5921             $i++;
5922 4         7 }
5923 74 50       88  
5924 272         838 while (1) {
5925             if (++$i > $#char) {
5926 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5927 272         531 }
5928             if ($char[$i] eq ']') {
5929             my $right = $i;
5930 74 100       180  
5931 74         482 # [^...]
  30         150  
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         214 }
5938 74         140  
5939             $i = $left;
5940             last;
5941             }
5942             }
5943             }
5944              
5945 74         191 # rewrite character class or escape character
5946             elsif (my $char = character_class($char[$i],$modifier)) {
5947             $char[$i] = $char;
5948             }
5949              
5950 139 50       360 # /i modifier
5951 20         33 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         5 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         3 elsif ($char[$i] eq '\U') {
5975             $char[$i] = '@{[Ekoi8r::uc qq<';
5976             $left_e++;
5977 1         2 }
5978 1         3 elsif ($char[$i] eq '\L') {
5979             $char[$i] = '@{[Ekoi8r::lc qq<';
5980             $left_e++;
5981 1         3 }
5982 18         32 elsif ($char[$i] eq '\F') {
5983             $char[$i] = '@{[Ekoi8r::fc qq<';
5984             $left_e++;
5985 18         42 }
5986 1         2 elsif ($char[$i] eq '\Q') {
5987             $char[$i] = '@{[CORE::quotemeta qq<';
5988             $left_e++;
5989 1 50       3 }
5990 21         46 elsif ($char[$i] eq '\E') {
5991 21         27 if ($right_e < $left_e) {
5992             $char[$i] = '>]}';
5993             $right_e++;
5994 21         46 }
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         21 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       21 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
6078 8         20 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       25 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
6088 6         17 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       18 # ${ 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       56 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6114 21         207 $char[$i] = e_string($char[$i]);
6115             if ($ignorecase) {
6116             $char[$i] = '@{[Ekoi8r::ignorecase(' . $char[$i] . ')]}';
6117             }
6118             }
6119              
6120 11 100 33     32 # 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         1138 }
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         535  
6139 642 50       1123 # make regexp string
6140 642 0 0     1319 $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         3651 }
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 5133 #
6160             sub qq_stuff {
6161             my($delimiter,$end_delimiter,$stuff) = @_;
6162 180 100       282  
6163 180         404 # scalar variable or array variable
6164             if ($stuff =~ /\A [\$\@] /oxms) {
6165             return $stuff;
6166             }
6167 100         471  
  80         194  
6168 80         223 # quote by delimiter
6169 80 50       299 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
6170 80 50       225 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6171 80 50       114 next if $char eq $delimiter;
6172 80         161 next if $char eq $end_delimiter;
6173             if (not $octet{$char}) {
6174             return join '', 'qq', $char, $stuff, $char;
6175 80         367 }
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     41 sub e_qr_q {
6184             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6185 10         44 $modifier ||= '';
6186 10 50       14  
6187 10         22 $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       12  
    50          
6201 10         25 # literal null string pattern
6202 8         10 if ($string eq '') {
6203 8         10 $modifier =~ tr/bB//d;
6204             $modifier =~ tr/i//d;
6205             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6206             }
6207              
6208 8         38 # 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 8 #
6222             sub e_qr_qt {
6223 2 50       7 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         58  
6239 2 50 33     10 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
6240             for (my $i=0; $i <= $#char; $i++) {
6241             if (0) {
6242             }
6243 2         16  
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         6  
6318             $delimiter = '/';
6319 2         3 $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 15 #
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     202 sub e_s1 {
6358             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6359 76         310 $modifier ||= '';
6360 76 50       174  
6361 76         221 $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       161  
    50          
6375 76         302 # 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       47  
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         170  
6420             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6421             my $metachar = qr/[\@\\|[\]{^]/oxms;
6422 68         303  
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       16511  
6452 68         485 # 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         428 my $parens = grep { $_ eq '(' } @char;
6484 68         107  
6485 68         97 my $left_e = 0;
6486             my $right_e = 0;
6487             for (my $i=0; $i <= $#char; $i++) {
6488 68 50 33     218  
    50 33        
    100          
    100          
    50          
    50          
6489 195         1115 # "\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         681  
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       19 elsif ($char[$i] eq '[') {
6541 13         42 my $left = $i;
6542             if ($char[$i+1] eq ']') {
6543 0         0 $i++;
6544 13 50       21 }
6545 58         82 while (1) {
6546             if (++$i > $#char) {
6547 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6548 58         133 }
6549             if ($char[$i] eq ']') {
6550             my $right = $i;
6551 13 50       21  
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         27  
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       15 # /i modifier
6599 3         4 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         5 }
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         14 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       15 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
6756 4         13 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         9 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       10 # ${ 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       58 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6792 4         21 $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         65 }
6802             else {
6803             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6804             }
6805             }
6806             }
6807 13         62  
6808 68         156 # make regexp string
6809 68 50       117 my $prematch = '';
6810 68         172 $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 859 #
6820 21   100     46 sub e_s1_q {
6821             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6822 21         69 $modifier ||= '';
6823 21 50       28  
6824 21         42 $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       29  
    50          
6838 21         52 # literal null string pattern
6839 8         11 if ($string eq '') {
6840 8         13 $modifier =~ tr/bB//d;
6841             $modifier =~ tr/i//d;
6842             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6843             }
6844              
6845 8         42 # 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 30 #
6859             sub e_s1_qt {
6860 13 50       30 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6861              
6862             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6863 13         22  
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         186  
6876 13 50 33     37 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6877             for (my $i=0; $i <= $#char; $i++) {
6878             if (0) {
6879             }
6880 25         107  
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         23  
6955 13         19 $modifier =~ tr/i//d;
6956 13         15 $delimiter = '/';
6957 13         16 $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 89 #
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         40 my($ope,$delimiter,$end_delimiter,$string) = @_;
6997              
6998 16         19 $slash = 'div';
6999 16         92  
7000 16 100       49 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
7001             for (my $i=0; $i <= $#char; $i++) {
7002             if (0) {
7003             }
7004 9         29  
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 45 #
7021 97   100     915 sub e_sub {
7022             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
7023 97         381 $modifier ||= '';
7024 97 50       182  
7025 97         268 $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         252  
7037 36         46 if ($variable eq '') {
7038             $variable = '$_';
7039             $bind_operator = ' =~ ';
7040 36         45 }
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         158 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7058 97         143  
7059             my $e_modifier = $modifier =~ tr/e//d;
7060 97         147 my $r_modifier = $modifier =~ tr/r//d;
7061 97 50       173  
7062 97         520 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         215  
7069             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
7070             $variable_basename =~ s/ \s+ \z//oxms;
7071 97         182  
7072 97 100       164 # quote replacement string
7073 97         220 my $e_replacement = '';
7074 17         35 if ($e_modifier >= 1) {
7075             $e_replacement = e_qq('', '', '', $replacement);
7076             $e_modifier--;
7077 17 100       24 }
7078 80         220 else {
7079             if ($delimiter2 eq "'") {
7080             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
7081 16         57 }
7082             else {
7083             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
7084             }
7085 64         151 }
7086              
7087             my $sub = '';
7088 97 100       182  
7089 97 100       280 # with /r
7090             if ($r_modifier) {
7091             if (0) {
7092             }
7093 8         21  
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         18 else {
7112              
7113 4 50       5 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       9  
7131 8         25 # $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         201  
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         83 else {
7163              
7164 67 100       105 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       362  
7190 97         271 # (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         156 # clear s/// variable
7196             $sub_variable = '';
7197 97         133 $bind_operator = '';
7198              
7199             return $sub;
7200             }
7201              
7202             #
7203             # escape regexp of split qr//
7204 97     74 0 655 #
7205 74   100     468 sub e_split {
7206             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7207 74         360 $modifier ||= '';
7208 74 50       119  
7209 74         170 $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       1203  
7223 74         190 # /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         198  
7228             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7229             my $metachar = qr/[\@\\|[\]{^]/oxms;
7230 74         273  
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         9063 ))/oxmsg;
7255 74         295  
7256 74         119 my $left_e = 0;
7257             my $right_e = 0;
7258             for (my $i=0; $i <= $#char; $i++) {
7259 74 50 33     360  
    50 33        
    100          
    100          
    50          
    50          
7260 249         1372 # "\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         4 # 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         5 # \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         875  
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       6 elsif ($char[$i] eq '[') {
7312 3         10 my $left = $i;
7313             if ($char[$i+1] eq ']') {
7314 0         0 $i++;
7315 3 50       4 }
7316 7         14 while (1) {
7317             if (++$i > $#char) {
7318 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7319 7         11 }
7320             if ($char[$i] eq ']') {
7321             my $right = $i;
7322 3 50       3  
7323 3         16 # [...]
  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         39 }
7330 3         8  
7331             $i = $left;
7332             last;
7333             }
7334             }
7335             }
7336              
7337 3         6 # 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         36 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       55 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ekoi8r::MATCH()
7514 12         33 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       49 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ekoi8r::POSTMATCH()
7524 9         24 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       42 # ${ 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       10 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         6 }
7560             else {
7561             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7562             }
7563             }
7564             }
7565 0         0  
7566 74 50       308 # make regexp string
7567 74         191 $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 749 #
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__