File Coverage

blib/lib/Elatin3.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 Elatin3;
2 204     204   1482 use strict;
  204         332  
  204         6718  
3             ######################################################################
4             #
5             # Elatin3 - Run-time routines for Latin3.pm
6             #
7             # http://search.cpan.org/dist/Char-Latin3/
8             #
9             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
10             ######################################################################
11              
12 204     204   3946 use 5.00503; # Galapagos Consensus 1998 for primetools
  204         689  
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   964 use vars qw($VERSION);
  204         359  
  204         35026  
28             $VERSION = '1.13';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 204 50   204   2470 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         30477 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   18828 CORE::eval q{
  204     204   1226  
  204     88   384  
  204         25854  
  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       97084 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 (Elatin3::index($name,'::') >= 0) {
83 0         0 return $name;
84             }
85             elsif (Elatin3::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   1576 no strict qw(refs);
  204         1657  
  204         31728  
118 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
119             }
120             else {
121 204     204   1300 no strict qw(refs);
  204     0   369  
  204         42219  
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   1298 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  204         1089  
  204         14375  
154 204     204   1252 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  204         390  
  204         385887  
155              
156             #
157             # Latin-3 character range per length
158             #
159             my %range_tr = ();
160              
161             #
162             # Latin-3 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 Elatin3 \z/oxms) {
178             %range_tr = (
179             1 => [ [0x00..0xFF],
180             ],
181             );
182              
183             %lc = (%lc,
184             "\xA1" => "\xB1", # LATIN LETTER H WITH STROKE
185             "\xA6" => "\xB6", # LATIN LETTER H WITH CIRCUMFLEX
186             "\xAA" => "\xBA", # LATIN LETTER S WITH CEDILLA
187             "\xAB" => "\xBB", # LATIN LETTER G WITH BREVE
188             "\xAC" => "\xBC", # LATIN LETTER J WITH CIRCUMFLEX
189             "\xAF" => "\xBF", # LATIN LETTER Z WITH DOT ABOVE
190             "\xC0" => "\xE0", # LATIN LETTER A WITH GRAVE
191             "\xC1" => "\xE1", # LATIN LETTER A WITH ACUTE
192             "\xC2" => "\xE2", # LATIN LETTER A WITH CIRCUMFLEX
193             "\xC4" => "\xE4", # LATIN LETTER A WITH DIAERESIS
194             "\xC5" => "\xE5", # LATIN LETTER C WITH DOT ABOVE
195             "\xC6" => "\xE6", # LATIN LETTER C WITH CIRCUMFLEX
196             "\xC7" => "\xE7", # LATIN LETTER C WITH CEDILLA
197             "\xC8" => "\xE8", # LATIN LETTER E WITH GRAVE
198             "\xC9" => "\xE9", # LATIN LETTER E WITH ACUTE
199             "\xCA" => "\xEA", # LATIN LETTER E WITH CIRCUMFLEX
200             "\xCB" => "\xEB", # LATIN LETTER E WITH DIAERESIS
201             "\xCC" => "\xEC", # LATIN LETTER I WITH GRAVE
202             "\xCD" => "\xED", # LATIN LETTER I WITH ACUTE
203             "\xCE" => "\xEE", # LATIN LETTER I WITH CIRCUMFLEX
204             "\xCF" => "\xEF", # LATIN LETTER I WITH DIAERESIS
205             "\xD1" => "\xF1", # LATIN LETTER N WITH TILDE
206             "\xD2" => "\xF2", # LATIN LETTER O WITH GRAVE
207             "\xD3" => "\xF3", # LATIN LETTER O WITH ACUTE
208             "\xD4" => "\xF4", # LATIN LETTER O WITH CIRCUMFLEX
209             "\xD5" => "\xF5", # LATIN LETTER G WITH DOT ABOVE
210             "\xD6" => "\xF6", # LATIN LETTER O WITH DIAERESIS
211             "\xD8" => "\xF8", # LATIN LETTER G WITH CIRCUMFLEX
212             "\xD9" => "\xF9", # LATIN LETTER U WITH GRAVE
213             "\xDA" => "\xFA", # LATIN LETTER U WITH ACUTE
214             "\xDB" => "\xFB", # LATIN LETTER U WITH CIRCUMFLEX
215             "\xDC" => "\xFC", # LATIN LETTER U WITH DIAERESIS
216             "\xDD" => "\xFD", # LATIN LETTER U WITH BREVE
217             "\xDE" => "\xFE", # LATIN LETTER S WITH CIRCUMFLEX
218             );
219              
220             %uc = (%uc,
221             "\xB1" => "\xA1", # LATIN LETTER H WITH STROKE
222             "\xB6" => "\xA6", # LATIN LETTER H WITH CIRCUMFLEX
223             "\xBA" => "\xAA", # LATIN LETTER S WITH CEDILLA
224             "\xBB" => "\xAB", # LATIN LETTER G WITH BREVE
225             "\xBC" => "\xAC", # LATIN LETTER J WITH CIRCUMFLEX
226             "\xBF" => "\xAF", # LATIN LETTER Z WITH DOT ABOVE
227             "\xE0" => "\xC0", # LATIN LETTER A WITH GRAVE
228             "\xE1" => "\xC1", # LATIN LETTER A WITH ACUTE
229             "\xE2" => "\xC2", # LATIN LETTER A WITH CIRCUMFLEX
230             "\xE4" => "\xC4", # LATIN LETTER A WITH DIAERESIS
231             "\xE5" => "\xC5", # LATIN LETTER C WITH DOT ABOVE
232             "\xE6" => "\xC6", # LATIN LETTER C WITH CIRCUMFLEX
233             "\xE7" => "\xC7", # LATIN LETTER C WITH CEDILLA
234             "\xE8" => "\xC8", # LATIN LETTER E WITH GRAVE
235             "\xE9" => "\xC9", # LATIN LETTER E WITH ACUTE
236             "\xEA" => "\xCA", # LATIN LETTER E WITH CIRCUMFLEX
237             "\xEB" => "\xCB", # LATIN LETTER E WITH DIAERESIS
238             "\xEC" => "\xCC", # LATIN LETTER I WITH GRAVE
239             "\xED" => "\xCD", # LATIN LETTER I WITH ACUTE
240             "\xEE" => "\xCE", # LATIN LETTER I WITH CIRCUMFLEX
241             "\xEF" => "\xCF", # LATIN LETTER I WITH DIAERESIS
242             "\xF1" => "\xD1", # LATIN LETTER N WITH TILDE
243             "\xF2" => "\xD2", # LATIN LETTER O WITH GRAVE
244             "\xF3" => "\xD3", # LATIN LETTER O WITH ACUTE
245             "\xF4" => "\xD4", # LATIN LETTER O WITH CIRCUMFLEX
246             "\xF5" => "\xD5", # LATIN LETTER G WITH DOT ABOVE
247             "\xF6" => "\xD6", # LATIN LETTER O WITH DIAERESIS
248             "\xF8" => "\xD8", # LATIN LETTER G WITH CIRCUMFLEX
249             "\xF9" => "\xD9", # LATIN LETTER U WITH GRAVE
250             "\xFA" => "\xDA", # LATIN LETTER U WITH ACUTE
251             "\xFB" => "\xDB", # LATIN LETTER U WITH CIRCUMFLEX
252             "\xFC" => "\xDC", # LATIN LETTER U WITH DIAERESIS
253             "\xFD" => "\xDD", # LATIN LETTER U WITH BREVE
254             "\xFE" => "\xDE", # LATIN LETTER S WITH CIRCUMFLEX
255             );
256              
257             %fc = (%fc,
258             "\xA1" => "\xB1", # LATIN CAPITAL LETTER H WITH STROKE --> LATIN SMALL LETTER H WITH STROKE
259             "\xA6" => "\xB6", # LATIN CAPITAL LETTER H WITH CIRCUMFLEX --> LATIN SMALL LETTER H WITH CIRCUMFLEX
260              
261             # CaseFolding-6.1.0.txt
262             # Date: 2011-07-25, 21:21:56 GMT [MD]
263             #
264             # T: special case for uppercase I and dotted uppercase I
265             # - For non-Turkic languages, this mapping is normally not used.
266             # - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
267             # Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
268             # See the discussions of case mapping in the Unicode Standard for more information.
269              
270             #-------------------------------------------------------------------------------
271             "\xA9" => "\x69", # LATIN CAPITAL LETTER I WITH DOT ABOVE
272             # --> LATIN SMALL LETTER I (without COMBINING DOT ABOVE)
273             #-------------------------------------------------------------------------------
274              
275             "\xAA" => "\xBA", # LATIN CAPITAL LETTER S WITH CEDILLA --> LATIN SMALL LETTER S WITH CEDILLA
276             "\xAB" => "\xBB", # LATIN CAPITAL LETTER G WITH BREVE --> LATIN SMALL LETTER G WITH BREVE
277             "\xAC" => "\xBC", # LATIN CAPITAL LETTER J WITH CIRCUMFLEX --> LATIN SMALL LETTER J WITH CIRCUMFLEX
278             "\xAF" => "\xBF", # LATIN CAPITAL LETTER Z WITH DOT ABOVE --> LATIN SMALL LETTER Z WITH DOT ABOVE
279             "\xC0" => "\xE0", # LATIN CAPITAL LETTER A WITH GRAVE --> LATIN SMALL LETTER A WITH GRAVE
280             "\xC1" => "\xE1", # LATIN CAPITAL LETTER A WITH ACUTE --> LATIN SMALL LETTER A WITH ACUTE
281             "\xC2" => "\xE2", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX --> LATIN SMALL LETTER A WITH CIRCUMFLEX
282             "\xC4" => "\xE4", # LATIN CAPITAL LETTER A WITH DIAERESIS --> LATIN SMALL LETTER A WITH DIAERESIS
283             "\xC5" => "\xE5", # LATIN CAPITAL LETTER C WITH DOT ABOVE --> LATIN SMALL LETTER C WITH DOT ABOVE
284             "\xC6" => "\xE6", # LATIN CAPITAL LETTER C WITH CIRCUMFLEX --> LATIN SMALL LETTER C WITH CIRCUMFLEX
285             "\xC7" => "\xE7", # LATIN CAPITAL LETTER C WITH CEDILLA --> LATIN SMALL LETTER C WITH CEDILLA
286             "\xC8" => "\xE8", # LATIN CAPITAL LETTER E WITH GRAVE --> LATIN SMALL LETTER E WITH GRAVE
287             "\xC9" => "\xE9", # LATIN CAPITAL LETTER E WITH ACUTE --> LATIN SMALL LETTER E WITH ACUTE
288             "\xCA" => "\xEA", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX --> LATIN SMALL LETTER E WITH CIRCUMFLEX
289             "\xCB" => "\xEB", # LATIN CAPITAL LETTER E WITH DIAERESIS --> LATIN SMALL LETTER E WITH DIAERESIS
290             "\xCC" => "\xEC", # LATIN CAPITAL LETTER I WITH GRAVE --> LATIN SMALL LETTER I WITH GRAVE
291             "\xCD" => "\xED", # LATIN CAPITAL LETTER I WITH ACUTE --> LATIN SMALL LETTER I WITH ACUTE
292             "\xCE" => "\xEE", # LATIN CAPITAL LETTER I WITH CIRCUMFLEX --> LATIN SMALL LETTER I WITH CIRCUMFLEX
293             "\xCF" => "\xEF", # LATIN CAPITAL LETTER I WITH DIAERESIS --> LATIN SMALL LETTER I WITH DIAERESIS
294             "\xD1" => "\xF1", # LATIN CAPITAL LETTER N WITH TILDE --> LATIN SMALL LETTER N WITH TILDE
295             "\xD2" => "\xF2", # LATIN CAPITAL LETTER O WITH GRAVE --> LATIN SMALL LETTER O WITH GRAVE
296             "\xD3" => "\xF3", # LATIN CAPITAL LETTER O WITH ACUTE --> LATIN SMALL LETTER O WITH ACUTE
297             "\xD4" => "\xF4", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX --> LATIN SMALL LETTER O WITH CIRCUMFLEX
298             "\xD5" => "\xF5", # LATIN CAPITAL LETTER G WITH DOT ABOVE --> LATIN SMALL LETTER G WITH DOT ABOVE
299             "\xD6" => "\xF6", # LATIN CAPITAL LETTER O WITH DIAERESIS --> LATIN SMALL LETTER O WITH DIAERESIS
300             "\xD8" => "\xF8", # LATIN CAPITAL LETTER G WITH CIRCUMFLEX --> LATIN SMALL LETTER G WITH CIRCUMFLEX
301             "\xD9" => "\xF9", # LATIN CAPITAL LETTER U WITH GRAVE --> LATIN SMALL LETTER U WITH GRAVE
302             "\xDA" => "\xFA", # LATIN CAPITAL LETTER U WITH ACUTE --> LATIN SMALL LETTER U WITH ACUTE
303             "\xDB" => "\xFB", # LATIN CAPITAL LETTER U WITH CIRCUMFLEX --> LATIN SMALL LETTER U WITH CIRCUMFLEX
304             "\xDC" => "\xFC", # LATIN CAPITAL LETTER U WITH DIAERESIS --> LATIN SMALL LETTER U WITH DIAERESIS
305             "\xDD" => "\xFD", # LATIN CAPITAL LETTER U WITH BREVE --> LATIN SMALL LETTER U WITH BREVE
306             "\xDE" => "\xFE", # LATIN CAPITAL LETTER S WITH CIRCUMFLEX --> LATIN SMALL LETTER S WITH CIRCUMFLEX
307             "\xDF" => "\x73\x73", # LATIN SMALL LETTER SHARP S --> LATIN SMALL LETTER S, LATIN SMALL LETTER S
308             );
309             }
310              
311             else {
312             croak "Don't know my package name '@{[__PACKAGE__]}'";
313             }
314              
315             #
316             # @ARGV wildcard globbing
317             #
318             sub import {
319              
320 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
321 0         0 my @argv = ();
322 0         0 for (@ARGV) {
323              
324             # has space
325 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
326 0 0       0 if (my @glob = Elatin3::glob(qq{"$_"})) {
327 0         0 push @argv, @glob;
328             }
329             else {
330 0         0 push @argv, $_;
331             }
332             }
333              
334             # has wildcard metachar
335             elsif (/\A (?:$q_char)*? [*?] /oxms) {
336 0 0       0 if (my @glob = Elatin3::glob($_)) {
337 0         0 push @argv, @glob;
338             }
339             else {
340 0         0 push @argv, $_;
341             }
342             }
343              
344             # no wildcard globbing
345             else {
346 0         0 push @argv, $_;
347             }
348             }
349 0         0 @ARGV = @argv;
350             }
351              
352 0         0 *Char::ord = \&Latin3::ord;
353 0         0 *Char::ord_ = \&Latin3::ord_;
354 0         0 *Char::reverse = \&Latin3::reverse;
355 0         0 *Char::getc = \&Latin3::getc;
356 0         0 *Char::length = \&Latin3::length;
357 0         0 *Char::substr = \&Latin3::substr;
358 0         0 *Char::index = \&Latin3::index;
359 0         0 *Char::rindex = \&Latin3::rindex;
360 0         0 *Char::eval = \&Latin3::eval;
361 0         0 *Char::escape = \&Latin3::escape;
362 0         0 *Char::escape_token = \&Latin3::escape_token;
363 0         0 *Char::escape_script = \&Latin3::escape_script;
364             }
365              
366             # P.230 Care with Prototypes
367             # in Chapter 6: Subroutines
368             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
369             #
370             # If you aren't careful, you can get yourself into trouble with prototypes.
371             # But if you are careful, you can do a lot of neat things with them. This is
372             # all very powerful, of course, and should only be used in moderation to make
373             # the world a better place.
374              
375             # P.332 Care with Prototypes
376             # in Chapter 7: Subroutines
377             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
378             #
379             # If you aren't careful, you can get yourself into trouble with prototypes.
380             # But if you are careful, you can do a lot of neat things with them. This is
381             # all very powerful, of course, and should only be used in moderation to make
382             # the world a better place.
383              
384             #
385             # Prototypes of subroutines
386             #
387       0     sub unimport {}
388             sub Elatin3::split(;$$$);
389             sub Elatin3::tr($$$$;$);
390             sub Elatin3::chop(@);
391             sub Elatin3::index($$;$);
392             sub Elatin3::rindex($$;$);
393             sub Elatin3::lcfirst(@);
394             sub Elatin3::lcfirst_();
395             sub Elatin3::lc(@);
396             sub Elatin3::lc_();
397             sub Elatin3::ucfirst(@);
398             sub Elatin3::ucfirst_();
399             sub Elatin3::uc(@);
400             sub Elatin3::uc_();
401             sub Elatin3::fc(@);
402             sub Elatin3::fc_();
403             sub Elatin3::ignorecase;
404             sub Elatin3::classic_character_class;
405             sub Elatin3::capture;
406             sub Elatin3::chr(;$);
407             sub Elatin3::chr_();
408             sub Elatin3::glob($);
409             sub Elatin3::glob_();
410              
411             sub Latin3::ord(;$);
412             sub Latin3::ord_();
413             sub Latin3::reverse(@);
414             sub Latin3::getc(;*@);
415             sub Latin3::length(;$);
416             sub Latin3::substr($$;$$);
417             sub Latin3::index($$;$);
418             sub Latin3::rindex($$;$);
419             sub Latin3::escape(;$);
420              
421             #
422             # Regexp work
423             #
424 204         18387 use vars qw(
425             $re_a
426             $re_t
427             $re_n
428             $re_r
429 204     204   1936 );
  204         498  
430              
431             #
432             # Character class
433             #
434 204         2187873 use vars qw(
435             $dot
436             $dot_s
437             $eD
438             $eS
439             $eW
440             $eH
441             $eV
442             $eR
443             $eN
444             $not_alnum
445             $not_alpha
446             $not_ascii
447             $not_blank
448             $not_cntrl
449             $not_digit
450             $not_graph
451             $not_lower
452             $not_lower_i
453             $not_print
454             $not_punct
455             $not_space
456             $not_upper
457             $not_upper_i
458             $not_word
459             $not_xdigit
460             $eb
461             $eB
462 204     204   1198 );
  204         891  
463              
464             ${Elatin3::dot} = qr{(?>[^\x0A])};
465             ${Elatin3::dot_s} = qr{(?>[\x00-\xFF])};
466             ${Elatin3::eD} = qr{(?>[^0-9])};
467              
468             # Vertical tabs are now whitespace
469             # \s in a regex now matches a vertical tab in all circumstances.
470             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
471             # ${Elatin3::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
472             # ${Elatin3::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
473             ${Elatin3::eS} = qr{(?>[^\s])};
474              
475             ${Elatin3::eW} = qr{(?>[^0-9A-Z_a-z])};
476             ${Elatin3::eH} = qr{(?>[^\x09\x20])};
477             ${Elatin3::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
478             ${Elatin3::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
479             ${Elatin3::eN} = qr{(?>[^\x0A])};
480             ${Elatin3::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
481             ${Elatin3::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
482             ${Elatin3::not_ascii} = qr{(?>[^\x00-\x7F])};
483             ${Elatin3::not_blank} = qr{(?>[^\x09\x20])};
484             ${Elatin3::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
485             ${Elatin3::not_digit} = qr{(?>[^\x30-\x39])};
486             ${Elatin3::not_graph} = qr{(?>[^\x21-\x7F])};
487             ${Elatin3::not_lower} = qr{(?>[^\x61-\x7A])};
488             ${Elatin3::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
489             # ${Elatin3::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
490             ${Elatin3::not_print} = qr{(?>[^\x20-\x7F])};
491             ${Elatin3::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
492             ${Elatin3::not_space} = qr{(?>[^\s\x0B])};
493             ${Elatin3::not_upper} = qr{(?>[^\x41-\x5A])};
494             ${Elatin3::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
495             # ${Elatin3::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
496             ${Elatin3::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
497             ${Elatin3::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
498             ${Elatin3::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))};
499             ${Elatin3::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]))};
500              
501             # avoid: Name "Elatin3::foo" used only once: possible typo at here.
502             ${Elatin3::dot} = ${Elatin3::dot};
503             ${Elatin3::dot_s} = ${Elatin3::dot_s};
504             ${Elatin3::eD} = ${Elatin3::eD};
505             ${Elatin3::eS} = ${Elatin3::eS};
506             ${Elatin3::eW} = ${Elatin3::eW};
507             ${Elatin3::eH} = ${Elatin3::eH};
508             ${Elatin3::eV} = ${Elatin3::eV};
509             ${Elatin3::eR} = ${Elatin3::eR};
510             ${Elatin3::eN} = ${Elatin3::eN};
511             ${Elatin3::not_alnum} = ${Elatin3::not_alnum};
512             ${Elatin3::not_alpha} = ${Elatin3::not_alpha};
513             ${Elatin3::not_ascii} = ${Elatin3::not_ascii};
514             ${Elatin3::not_blank} = ${Elatin3::not_blank};
515             ${Elatin3::not_cntrl} = ${Elatin3::not_cntrl};
516             ${Elatin3::not_digit} = ${Elatin3::not_digit};
517             ${Elatin3::not_graph} = ${Elatin3::not_graph};
518             ${Elatin3::not_lower} = ${Elatin3::not_lower};
519             ${Elatin3::not_lower_i} = ${Elatin3::not_lower_i};
520             ${Elatin3::not_print} = ${Elatin3::not_print};
521             ${Elatin3::not_punct} = ${Elatin3::not_punct};
522             ${Elatin3::not_space} = ${Elatin3::not_space};
523             ${Elatin3::not_upper} = ${Elatin3::not_upper};
524             ${Elatin3::not_upper_i} = ${Elatin3::not_upper_i};
525             ${Elatin3::not_word} = ${Elatin3::not_word};
526             ${Elatin3::not_xdigit} = ${Elatin3::not_xdigit};
527             ${Elatin3::eb} = ${Elatin3::eb};
528             ${Elatin3::eB} = ${Elatin3::eB};
529              
530             #
531             # Latin-3 split
532             #
533             sub Elatin3::split(;$$$) {
534              
535             # P.794 29.2.161. split
536             # in Chapter 29: Functions
537             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
538              
539             # P.951 split
540             # in Chapter 27: Functions
541             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
542              
543 0     0 0 0 my $pattern = $_[0];
544 0         0 my $string = $_[1];
545 0         0 my $limit = $_[2];
546              
547             # if $pattern is also omitted or is the literal space, " "
548 0 0       0 if (not defined $pattern) {
549 0         0 $pattern = ' ';
550             }
551              
552             # if $string is omitted, the function splits the $_ string
553 0 0       0 if (not defined $string) {
554 0 0       0 if (defined $_) {
555 0         0 $string = $_;
556             }
557             else {
558 0         0 $string = '';
559             }
560             }
561              
562 0         0 my @split = ();
563              
564             # when string is empty
565 0 0       0 if ($string eq '') {
    0          
566              
567             # resulting list value in list context
568 0 0       0 if (wantarray) {
569 0         0 return @split;
570             }
571              
572             # count of substrings in scalar context
573             else {
574 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
575 0         0 @_ = @split;
576 0         0 return scalar @_;
577             }
578             }
579              
580             # split's first argument is more consistently interpreted
581             #
582             # After some changes earlier in v5.17, split's behavior has been simplified:
583             # if the PATTERN argument evaluates to a string containing one space, it is
584             # treated the way that a literal string containing one space once was.
585             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
586              
587             # if $pattern is also omitted or is the literal space, " ", the function splits
588             # on whitespace, /\s+/, after skipping any leading whitespace
589             # (and so on)
590              
591             elsif ($pattern eq ' ') {
592 0 0       0 if (not defined $limit) {
593 0         0 return CORE::split(' ', $string);
594             }
595             else {
596 0         0 return CORE::split(' ', $string, $limit);
597             }
598             }
599              
600             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
601 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
602              
603             # a pattern capable of matching either the null string or something longer than the
604             # null string will split the value of $string into separate characters wherever it
605             # matches the null string between characters
606             # (and so on)
607              
608 0 0       0 if ('' =~ / \A $pattern \z /xms) {
609 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
610 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
611              
612             # P.1024 Appendix W.10 Multibyte Processing
613             # of ISBN 1-56592-224-7 CJKV Information Processing
614             # (and so on)
615              
616             # the //m modifier is assumed when you split on the pattern /^/
617             # (and so on)
618              
619             # V
620 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
621              
622             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
623             # is included in the resulting list, interspersed with the fields that are ordinarily returned
624             # (and so on)
625              
626 0         0 local $@;
627 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
628 0         0 push @split, CORE::eval('$' . $digit);
629             }
630             }
631             }
632              
633             else {
634 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
635              
636             # V
637 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
638 0         0 local $@;
639 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
640 0         0 push @split, CORE::eval('$' . $digit);
641             }
642             }
643             }
644             }
645              
646             elsif ($limit > 0) {
647 0 0       0 if ('' =~ / \A $pattern \z /xms) {
648 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
649 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
650              
651             # V
652 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
653 0         0 local $@;
654 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
655 0         0 push @split, CORE::eval('$' . $digit);
656             }
657             }
658             }
659             }
660             else {
661 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
662 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
663              
664             # V
665 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
666 0         0 local $@;
667 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
668 0         0 push @split, CORE::eval('$' . $digit);
669             }
670             }
671             }
672             }
673             }
674              
675 0 0       0 if (CORE::length($string) > 0) {
676 0         0 push @split, $string;
677             }
678              
679             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
680 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
681 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
682 0         0 pop @split;
683             }
684             }
685              
686             # resulting list value in list context
687 0 0       0 if (wantarray) {
688 0         0 return @split;
689             }
690              
691             # count of substrings in scalar context
692             else {
693 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
694 0         0 @_ = @split;
695 0         0 return scalar @_;
696             }
697             }
698              
699             #
700             # get last subexpression offsets
701             #
702             sub _last_subexpression_offsets {
703 0     0   0 my $pattern = $_[0];
704              
705             # remove comment
706 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
707              
708 0         0 my $modifier = '';
709 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
710 0         0 $modifier = $1;
711 0         0 $modifier =~ s/-[A-Za-z]*//;
712             }
713              
714             # with /x modifier
715 0         0 my @char = ();
716 0 0       0 if ($modifier =~ /x/oxms) {
717 0         0 @char = $pattern =~ /\G((?>
718             [^\\\#\[\(] |
719             \\ $q_char |
720             \# (?>[^\n]*) $ |
721             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
722             \(\? |
723             $q_char
724             ))/oxmsg;
725             }
726              
727             # without /x modifier
728             else {
729 0         0 @char = $pattern =~ /\G((?>
730             [^\\\[\(] |
731             \\ $q_char |
732             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
733             \(\? |
734             $q_char
735             ))/oxmsg;
736             }
737              
738 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
739             }
740              
741             #
742             # Latin-3 transliteration (tr///)
743             #
744             sub Elatin3::tr($$$$;$) {
745              
746 0     0 0 0 my $bind_operator = $_[1];
747 0         0 my $searchlist = $_[2];
748 0         0 my $replacementlist = $_[3];
749 0   0     0 my $modifier = $_[4] || '';
750              
751 0 0       0 if ($modifier =~ /r/oxms) {
752 0 0       0 if ($bind_operator =~ / !~ /oxms) {
753 0         0 croak "Using !~ with tr///r doesn't make sense";
754             }
755             }
756              
757 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
758 0         0 my @searchlist = _charlist_tr($searchlist);
759 0         0 my @replacementlist = _charlist_tr($replacementlist);
760              
761 0         0 my %tr = ();
762 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
763 0 0       0 if (not exists $tr{$searchlist[$i]}) {
764 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
765 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
766             }
767             elsif ($modifier =~ /d/oxms) {
768 0         0 $tr{$searchlist[$i]} = '';
769             }
770             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
771 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
772             }
773             else {
774 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
775             }
776             }
777             }
778              
779 0         0 my $tr = 0;
780 0         0 my $replaced = '';
781 0 0       0 if ($modifier =~ /c/oxms) {
782 0         0 while (defined(my $char = shift @char)) {
783 0 0       0 if (not exists $tr{$char}) {
784 0 0       0 if (defined $replacementlist[0]) {
785 0         0 $replaced .= $replacementlist[0];
786             }
787 0         0 $tr++;
788 0 0       0 if ($modifier =~ /s/oxms) {
789 0   0     0 while (@char and (not exists $tr{$char[0]})) {
790 0         0 shift @char;
791 0         0 $tr++;
792             }
793             }
794             }
795             else {
796 0         0 $replaced .= $char;
797             }
798             }
799             }
800             else {
801 0         0 while (defined(my $char = shift @char)) {
802 0 0       0 if (exists $tr{$char}) {
803 0         0 $replaced .= $tr{$char};
804 0         0 $tr++;
805 0 0       0 if ($modifier =~ /s/oxms) {
806 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
807 0         0 shift @char;
808 0         0 $tr++;
809             }
810             }
811             }
812             else {
813 0         0 $replaced .= $char;
814             }
815             }
816             }
817              
818 0 0       0 if ($modifier =~ /r/oxms) {
819 0         0 return $replaced;
820             }
821             else {
822 0         0 $_[0] = $replaced;
823 0 0       0 if ($bind_operator =~ / !~ /oxms) {
824 0         0 return not $tr;
825             }
826             else {
827 0         0 return $tr;
828             }
829             }
830             }
831              
832             #
833             # Latin-3 chop
834             #
835             sub Elatin3::chop(@) {
836              
837 0     0 0 0 my $chop;
838 0 0       0 if (@_ == 0) {
839 0         0 my @char = /\G (?>$q_char) /oxmsg;
840 0         0 $chop = pop @char;
841 0         0 $_ = join '', @char;
842             }
843             else {
844 0         0 for (@_) {
845 0         0 my @char = /\G (?>$q_char) /oxmsg;
846 0         0 $chop = pop @char;
847 0         0 $_ = join '', @char;
848             }
849             }
850 0         0 return $chop;
851             }
852              
853             #
854             # Latin-3 index by octet
855             #
856             sub Elatin3::index($$;$) {
857              
858 0     0 1 0 my($str,$substr,$position) = @_;
859 0   0     0 $position ||= 0;
860 0         0 my $pos = 0;
861              
862 0         0 while ($pos < CORE::length($str)) {
863 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
864 0 0       0 if ($pos >= $position) {
865 0         0 return $pos;
866             }
867             }
868 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
869 0         0 $pos += CORE::length($1);
870             }
871             else {
872 0         0 $pos += 1;
873             }
874             }
875 0         0 return -1;
876             }
877              
878             #
879             # Latin-3 reverse index
880             #
881             sub Elatin3::rindex($$;$) {
882              
883 0     0 0 0 my($str,$substr,$position) = @_;
884 0   0     0 $position ||= CORE::length($str) - 1;
885 0         0 my $pos = 0;
886 0         0 my $rindex = -1;
887              
888 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
889 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
890 0         0 $rindex = $pos;
891             }
892 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
893 0         0 $pos += CORE::length($1);
894             }
895             else {
896 0         0 $pos += 1;
897             }
898             }
899 0         0 return $rindex;
900             }
901              
902             #
903             # Latin-3 lower case first with parameter
904             #
905             sub Elatin3::lcfirst(@) {
906 0 0   0 0 0 if (@_) {
907 0         0 my $s = shift @_;
908 0 0 0     0 if (@_ and wantarray) {
909 0         0 return Elatin3::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
910             }
911             else {
912 0         0 return Elatin3::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
913             }
914             }
915             else {
916 0         0 return Elatin3::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
917             }
918             }
919              
920             #
921             # Latin-3 lower case first without parameter
922             #
923             sub Elatin3::lcfirst_() {
924 0     0 0 0 return Elatin3::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
925             }
926              
927             #
928             # Latin-3 lower case with parameter
929             #
930             sub Elatin3::lc(@) {
931 0 0   0 0 0 if (@_) {
932 0         0 my $s = shift @_;
933 0 0 0     0 if (@_ and wantarray) {
934 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
935             }
936             else {
937 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
938             }
939             }
940             else {
941 0         0 return Elatin3::lc_();
942             }
943             }
944              
945             #
946             # Latin-3 lower case without parameter
947             #
948             sub Elatin3::lc_() {
949 0     0 0 0 my $s = $_;
950 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
951             }
952              
953             #
954             # Latin-3 upper case first with parameter
955             #
956             sub Elatin3::ucfirst(@) {
957 0 0   0 0 0 if (@_) {
958 0         0 my $s = shift @_;
959 0 0 0     0 if (@_ and wantarray) {
960 0         0 return Elatin3::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
961             }
962             else {
963 0         0 return Elatin3::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
964             }
965             }
966             else {
967 0         0 return Elatin3::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
968             }
969             }
970              
971             #
972             # Latin-3 upper case first without parameter
973             #
974             sub Elatin3::ucfirst_() {
975 0     0 0 0 return Elatin3::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
976             }
977              
978             #
979             # Latin-3 upper case with parameter
980             #
981             sub Elatin3::uc(@) {
982 0 50   174 0 0 if (@_) {
983 174         257 my $s = shift @_;
984 174 50 33     211 if (@_ and wantarray) {
985 174 0       369 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
986             }
987             else {
988 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         537  
989             }
990             }
991             else {
992 174         630 return Elatin3::uc_();
993             }
994             }
995              
996             #
997             # Latin-3 upper case without parameter
998             #
999             sub Elatin3::uc_() {
1000 0     0 0 0 my $s = $_;
1001 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1002             }
1003              
1004             #
1005             # Latin-3 fold case with parameter
1006             #
1007             sub Elatin3::fc(@) {
1008 0 50   197 0 0 if (@_) {
1009 197         290 my $s = shift @_;
1010 197 50 33     264 if (@_ and wantarray) {
1011 197 0       428 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1012             }
1013             else {
1014 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         544  
1015             }
1016             }
1017             else {
1018 197         1122 return Elatin3::fc_();
1019             }
1020             }
1021              
1022             #
1023             # Latin-3 fold case without parameter
1024             #
1025             sub Elatin3::fc_() {
1026 0     0 0 0 my $s = $_;
1027 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1028             }
1029              
1030             #
1031             # Latin-3 regexp capture
1032             #
1033             {
1034             sub Elatin3::capture {
1035 0     0 1 0 return $_[0];
1036             }
1037             }
1038              
1039             #
1040             # Latin-3 regexp ignore case modifier
1041             #
1042             sub Elatin3::ignorecase {
1043              
1044 0     0 0 0 my @string = @_;
1045 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1046              
1047             # ignore case of $scalar or @array
1048 0         0 for my $string (@string) {
1049              
1050             # split regexp
1051 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1052              
1053             # unescape character
1054 0         0 for (my $i=0; $i <= $#char; $i++) {
1055 0 0       0 next if not defined $char[$i];
1056              
1057             # open character class [...]
1058 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1059 0         0 my $left = $i;
1060              
1061             # [] make die "unmatched [] in regexp ...\n"
1062              
1063 0 0       0 if ($char[$i+1] eq ']') {
1064 0         0 $i++;
1065             }
1066              
1067 0         0 while (1) {
1068 0 0       0 if (++$i > $#char) {
1069 0         0 croak "Unmatched [] in regexp";
1070             }
1071 0 0       0 if ($char[$i] eq ']') {
1072 0         0 my $right = $i;
1073 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1074              
1075             # escape character
1076 0         0 for my $char (@charlist) {
1077 0 0       0 if (0) {
1078             }
1079              
1080 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1081 0         0 $char = '\\' . $char;
1082             }
1083             }
1084              
1085             # [...]
1086 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1087              
1088 0         0 $i = $left;
1089 0         0 last;
1090             }
1091             }
1092             }
1093              
1094             # open character class [^...]
1095             elsif ($char[$i] eq '[^') {
1096 0         0 my $left = $i;
1097              
1098             # [^] make die "unmatched [] in regexp ...\n"
1099              
1100 0 0       0 if ($char[$i+1] eq ']') {
1101 0         0 $i++;
1102             }
1103              
1104 0         0 while (1) {
1105 0 0       0 if (++$i > $#char) {
1106 0         0 croak "Unmatched [] in regexp";
1107             }
1108 0 0       0 if ($char[$i] eq ']') {
1109 0         0 my $right = $i;
1110 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1111              
1112             # escape character
1113 0         0 for my $char (@charlist) {
1114 0 0       0 if (0) {
1115             }
1116              
1117 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1118 0         0 $char = '\\' . $char;
1119             }
1120             }
1121              
1122             # [^...]
1123 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1124              
1125 0         0 $i = $left;
1126 0         0 last;
1127             }
1128             }
1129             }
1130              
1131             # rewrite classic character class or escape character
1132             elsif (my $char = classic_character_class($char[$i])) {
1133 0         0 $char[$i] = $char;
1134             }
1135              
1136             # with /i modifier
1137             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1138 0         0 my $uc = Elatin3::uc($char[$i]);
1139 0         0 my $fc = Elatin3::fc($char[$i]);
1140 0 0       0 if ($uc ne $fc) {
1141 0 0       0 if (CORE::length($fc) == 1) {
1142 0         0 $char[$i] = '[' . $uc . $fc . ']';
1143             }
1144             else {
1145 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1146             }
1147             }
1148             }
1149             }
1150              
1151             # characterize
1152 0         0 for (my $i=0; $i <= $#char; $i++) {
1153 0 0       0 next if not defined $char[$i];
1154              
1155 0 0       0 if (0) {
1156             }
1157              
1158             # quote character before ? + * {
1159 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1160 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1161 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1162             }
1163             }
1164             }
1165              
1166 0         0 $string = join '', @char;
1167             }
1168              
1169             # make regexp string
1170 0         0 return @string;
1171             }
1172              
1173             #
1174             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1175             #
1176             sub Elatin3::classic_character_class {
1177 0     1867 0 0 my($char) = @_;
1178              
1179             return {
1180             '\D' => '${Elatin3::eD}',
1181             '\S' => '${Elatin3::eS}',
1182             '\W' => '${Elatin3::eW}',
1183             '\d' => '[0-9]',
1184              
1185             # Before Perl 5.6, \s only matched the five whitespace characters
1186             # tab, newline, form-feed, carriage return, and the space character
1187             # itself, which, taken together, is the character class [\t\n\f\r ].
1188              
1189             # Vertical tabs are now whitespace
1190             # \s in a regex now matches a vertical tab in all circumstances.
1191             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1192             # \t \n \v \f \r space
1193             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1194             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1195             '\s' => '\s',
1196              
1197             '\w' => '[0-9A-Z_a-z]',
1198             '\C' => '[\x00-\xFF]',
1199             '\X' => 'X',
1200              
1201             # \h \v \H \V
1202              
1203             # P.114 Character Class Shortcuts
1204             # in Chapter 7: In the World of Regular Expressions
1205             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1206              
1207             # P.357 13.2.3 Whitespace
1208             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1209             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1210             #
1211             # 0x00009 CHARACTER TABULATION h s
1212             # 0x0000a LINE FEED (LF) vs
1213             # 0x0000b LINE TABULATION v
1214             # 0x0000c FORM FEED (FF) vs
1215             # 0x0000d CARRIAGE RETURN (CR) vs
1216             # 0x00020 SPACE h s
1217              
1218             # P.196 Table 5-9. Alphanumeric regex metasymbols
1219             # in Chapter 5. Pattern Matching
1220             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1221              
1222             # (and so on)
1223              
1224             '\H' => '${Elatin3::eH}',
1225             '\V' => '${Elatin3::eV}',
1226             '\h' => '[\x09\x20]',
1227             '\v' => '[\x0A\x0B\x0C\x0D]',
1228             '\R' => '${Elatin3::eR}',
1229              
1230             # \N
1231             #
1232             # http://perldoc.perl.org/perlre.html
1233             # Character Classes and other Special Escapes
1234             # Any character but \n (experimental). Not affected by /s modifier
1235              
1236             '\N' => '${Elatin3::eN}',
1237              
1238             # \b \B
1239              
1240             # P.180 Boundaries: The \b and \B Assertions
1241             # in Chapter 5: Pattern Matching
1242             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1243              
1244             # P.219 Boundaries: The \b and \B Assertions
1245             # in Chapter 5: Pattern Matching
1246             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1247              
1248             # \b really means (?:(?<=\w)(?!\w)|(?
1249             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1250             '\b' => '${Elatin3::eb}',
1251              
1252             # \B really means (?:(?<=\w)(?=\w)|(?
1253             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1254             '\B' => '${Elatin3::eB}',
1255              
1256 1867   100     2575 }->{$char} || '';
1257             }
1258              
1259             #
1260             # prepare Latin-3 characters per length
1261             #
1262              
1263             # 1 octet characters
1264             my @chars1 = ();
1265             sub chars1 {
1266 1867 0   0 0 71614 if (@chars1) {
1267 0         0 return @chars1;
1268             }
1269 0 0       0 if (exists $range_tr{1}) {
1270 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1271 0         0 while (my @range = splice(@ranges,0,1)) {
1272 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1273 0         0 push @chars1, pack 'C', $oct0;
1274             }
1275             }
1276             }
1277 0         0 return @chars1;
1278             }
1279              
1280             # 2 octets characters
1281             my @chars2 = ();
1282             sub chars2 {
1283 0 0   0 0 0 if (@chars2) {
1284 0         0 return @chars2;
1285             }
1286 0 0       0 if (exists $range_tr{2}) {
1287 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1288 0         0 while (my @range = splice(@ranges,0,2)) {
1289 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1290 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1291 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1292             }
1293             }
1294             }
1295             }
1296 0         0 return @chars2;
1297             }
1298              
1299             # 3 octets characters
1300             my @chars3 = ();
1301             sub chars3 {
1302 0 0   0 0 0 if (@chars3) {
1303 0         0 return @chars3;
1304             }
1305 0 0       0 if (exists $range_tr{3}) {
1306 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1307 0         0 while (my @range = splice(@ranges,0,3)) {
1308 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1309 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1310 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1311 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1312             }
1313             }
1314             }
1315             }
1316             }
1317 0         0 return @chars3;
1318             }
1319              
1320             # 4 octets characters
1321             my @chars4 = ();
1322             sub chars4 {
1323 0 0   0 0 0 if (@chars4) {
1324 0         0 return @chars4;
1325             }
1326 0 0       0 if (exists $range_tr{4}) {
1327 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1328 0         0 while (my @range = splice(@ranges,0,4)) {
1329 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1330 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1331 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1332 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1333 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1334             }
1335             }
1336             }
1337             }
1338             }
1339             }
1340 0         0 return @chars4;
1341             }
1342              
1343             #
1344             # Latin-3 open character list for tr
1345             #
1346             sub _charlist_tr {
1347              
1348 0     0   0 local $_ = shift @_;
1349              
1350             # unescape character
1351 0         0 my @char = ();
1352 0         0 while (not /\G \z/oxmsgc) {
1353 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1354 0         0 push @char, '\-';
1355             }
1356             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1357 0         0 push @char, CORE::chr(oct $1);
1358             }
1359             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1360 0         0 push @char, CORE::chr(hex $1);
1361             }
1362             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1363 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1364             }
1365             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1366             push @char, {
1367             '\0' => "\0",
1368             '\n' => "\n",
1369             '\r' => "\r",
1370             '\t' => "\t",
1371             '\f' => "\f",
1372             '\b' => "\x08", # \b means backspace in character class
1373             '\a' => "\a",
1374             '\e' => "\e",
1375 0         0 }->{$1};
1376             }
1377             elsif (/\G \\ ($q_char) /oxmsgc) {
1378 0         0 push @char, $1;
1379             }
1380             elsif (/\G ($q_char) /oxmsgc) {
1381 0         0 push @char, $1;
1382             }
1383             }
1384              
1385             # join separated multiple-octet
1386 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1387              
1388             # unescape '-'
1389 0         0 my @i = ();
1390 0         0 for my $i (0 .. $#char) {
1391 0 0       0 if ($char[$i] eq '\-') {
    0          
1392 0         0 $char[$i] = '-';
1393             }
1394             elsif ($char[$i] eq '-') {
1395 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1396 0         0 push @i, $i;
1397             }
1398             }
1399             }
1400              
1401             # open character list (reverse for splice)
1402 0         0 for my $i (CORE::reverse @i) {
1403 0         0 my @range = ();
1404              
1405             # range error
1406 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1407 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1408             }
1409              
1410             # range of multiple-octet code
1411 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1412 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1413 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1414             }
1415             elsif (CORE::length($char[$i+1]) == 2) {
1416 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1417 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1418             }
1419             elsif (CORE::length($char[$i+1]) == 3) {
1420 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1421 0         0 push @range, chars2();
1422 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1423             }
1424             elsif (CORE::length($char[$i+1]) == 4) {
1425 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1426 0         0 push @range, chars2();
1427 0         0 push @range, chars3();
1428 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1429             }
1430             else {
1431 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1432             }
1433             }
1434             elsif (CORE::length($char[$i-1]) == 2) {
1435 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1436 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1437             }
1438             elsif (CORE::length($char[$i+1]) == 3) {
1439 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1440 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1441             }
1442             elsif (CORE::length($char[$i+1]) == 4) {
1443 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1444 0         0 push @range, chars3();
1445 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1446             }
1447             else {
1448 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1449             }
1450             }
1451             elsif (CORE::length($char[$i-1]) == 3) {
1452 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1453 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1454             }
1455             elsif (CORE::length($char[$i+1]) == 4) {
1456 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1457 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1458             }
1459             else {
1460 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1461             }
1462             }
1463             elsif (CORE::length($char[$i-1]) == 4) {
1464 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1465 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1466             }
1467             else {
1468 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1469             }
1470             }
1471             else {
1472 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1473             }
1474              
1475 0         0 splice @char, $i-1, 3, @range;
1476             }
1477              
1478 0         0 return @char;
1479             }
1480              
1481             #
1482             # Latin-3 open character class
1483             #
1484             sub _cc {
1485 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1486 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1487             }
1488             elsif (scalar(@_) == 1) {
1489 0         0 return sprintf('\x%02X',$_[0]);
1490             }
1491             elsif (scalar(@_) == 2) {
1492 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1493 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1494             }
1495             elsif ($_[0] == $_[1]) {
1496 0         0 return sprintf('\x%02X',$_[0]);
1497             }
1498             elsif (($_[0]+1) == $_[1]) {
1499 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1500             }
1501             else {
1502 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1503             }
1504             }
1505             else {
1506 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1507             }
1508             }
1509              
1510             #
1511             # Latin-3 octet range
1512             #
1513             sub _octets {
1514 0     182   0 my $length = shift @_;
1515              
1516 182 50       350 if ($length == 1) {
1517 182         400 my($a1) = unpack 'C', $_[0];
1518 182         552 my($z1) = unpack 'C', $_[1];
1519              
1520 182 50       336 if ($a1 > $z1) {
1521 182         351 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1522             }
1523              
1524 0 50       0 if ($a1 == $z1) {
    50          
1525 182         517 return sprintf('\x%02X',$a1);
1526             }
1527             elsif (($a1+1) == $z1) {
1528 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1529             }
1530             else {
1531 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1532             }
1533             }
1534             else {
1535 182         1294 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1536             }
1537             }
1538              
1539             #
1540             # Latin-3 range regexp
1541             #
1542             sub _range_regexp {
1543 0     182   0 my($length,$first,$last) = @_;
1544              
1545 182         455 my @range_regexp = ();
1546 182 50       255 if (not exists $range_tr{$length}) {
1547 182         665 return @range_regexp;
1548             }
1549              
1550 0         0 my @ranges = @{ $range_tr{$length} };
  182         299  
1551 182         402 while (my @range = splice(@ranges,0,$length)) {
1552 182         592 my $min = '';
1553 182         263 my $max = '';
1554 182         251 for (my $i=0; $i < $length; $i++) {
1555 182         549 $min .= pack 'C', $range[$i][0];
1556 182         831 $max .= pack 'C', $range[$i][-1];
1557             }
1558              
1559             # min___max
1560             # FIRST_____________LAST
1561             # (nothing)
1562              
1563 182 50 33     502 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1564             }
1565              
1566             # **********
1567             # min_________max
1568             # FIRST_____________LAST
1569             # **********
1570              
1571             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1572 182         2660 push @range_regexp, _octets($length,$first,$max,$min,$max);
1573             }
1574              
1575             # **********************
1576             # min________________max
1577             # FIRST_____________LAST
1578             # **********************
1579              
1580             elsif (($min eq $first) and ($max eq $last)) {
1581 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1582             }
1583              
1584             # *********
1585             # min___max
1586             # FIRST_____________LAST
1587             # *********
1588              
1589             elsif (($first le $min) and ($max le $last)) {
1590 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1591             }
1592              
1593             # **********************
1594             # min__________________________max
1595             # FIRST_____________LAST
1596             # **********************
1597              
1598             elsif (($min le $first) and ($last le $max)) {
1599 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1600             }
1601              
1602             # *********
1603             # min________max
1604             # FIRST_____________LAST
1605             # *********
1606              
1607             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1608 182         509 push @range_regexp, _octets($length,$min,$last,$min,$max);
1609             }
1610              
1611             # min___max
1612             # FIRST_____________LAST
1613             # (nothing)
1614              
1615             elsif ($last lt $min) {
1616             }
1617              
1618             else {
1619 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1620             }
1621             }
1622              
1623 0         0 return @range_regexp;
1624             }
1625              
1626             #
1627             # Latin-3 open character list for qr and not qr
1628             #
1629             sub _charlist {
1630              
1631 182     358   396 my $modifier = pop @_;
1632 358         673 my @char = @_;
1633              
1634 358 100       788 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1635              
1636             # unescape character
1637 358         833 for (my $i=0; $i <= $#char; $i++) {
1638              
1639             # escape - to ...
1640 358 100 100     1315 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1641 1125 100 100     12358 if ((0 < $i) and ($i < $#char)) {
1642 206         796 $char[$i] = '...';
1643             }
1644             }
1645              
1646             # octal escape sequence
1647             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1648 182         410 $char[$i] = octchr($1);
1649             }
1650              
1651             # hexadecimal escape sequence
1652             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1653 0         0 $char[$i] = hexchr($1);
1654             }
1655              
1656             # \b{...} --> b\{...}
1657             # \B{...} --> B\{...}
1658             # \N{CHARNAME} --> N\{CHARNAME}
1659             # \p{PROPERTY} --> p\{PROPERTY}
1660             # \P{PROPERTY} --> P\{PROPERTY}
1661             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1662 0         0 $char[$i] = $1 . '\\' . $2;
1663             }
1664              
1665             # \p, \P, \X --> p, P, X
1666             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1667 0         0 $char[$i] = $1;
1668             }
1669              
1670             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1671 0         0 $char[$i] = CORE::chr oct $1;
1672             }
1673             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1674 0         0 $char[$i] = CORE::chr hex $1;
1675             }
1676             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1677 22         94 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1678             }
1679             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1680             $char[$i] = {
1681             '\0' => "\0",
1682             '\n' => "\n",
1683             '\r' => "\r",
1684             '\t' => "\t",
1685             '\f' => "\f",
1686             '\b' => "\x08", # \b means backspace in character class
1687             '\a' => "\a",
1688             '\e' => "\e",
1689             '\d' => '[0-9]',
1690              
1691             # Vertical tabs are now whitespace
1692             # \s in a regex now matches a vertical tab in all circumstances.
1693             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1694             # \t \n \v \f \r space
1695             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1696             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1697             '\s' => '\s',
1698              
1699             '\w' => '[0-9A-Z_a-z]',
1700             '\D' => '${Elatin3::eD}',
1701             '\S' => '${Elatin3::eS}',
1702             '\W' => '${Elatin3::eW}',
1703              
1704             '\H' => '${Elatin3::eH}',
1705             '\V' => '${Elatin3::eV}',
1706             '\h' => '[\x09\x20]',
1707             '\v' => '[\x0A\x0B\x0C\x0D]',
1708             '\R' => '${Elatin3::eR}',
1709              
1710 0         0 }->{$1};
1711             }
1712              
1713             # POSIX-style character classes
1714             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1715             $char[$i] = {
1716              
1717             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1718             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1719             '[:^lower:]' => '${Elatin3::not_lower_i}',
1720             '[:^upper:]' => '${Elatin3::not_upper_i}',
1721              
1722 25         430 }->{$1};
1723             }
1724             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1725             $char[$i] = {
1726              
1727             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1728             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1729             '[:ascii:]' => '[\x00-\x7F]',
1730             '[:blank:]' => '[\x09\x20]',
1731             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1732             '[:digit:]' => '[\x30-\x39]',
1733             '[:graph:]' => '[\x21-\x7F]',
1734             '[:lower:]' => '[\x61-\x7A]',
1735             '[:print:]' => '[\x20-\x7F]',
1736             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1737              
1738             # P.174 POSIX-Style Character Classes
1739             # in Chapter 5: Pattern Matching
1740             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1741              
1742             # P.311 11.2.4 Character Classes and other Special Escapes
1743             # in Chapter 11: perlre: Perl regular expressions
1744             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1745              
1746             # P.210 POSIX-Style Character Classes
1747             # in Chapter 5: Pattern Matching
1748             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1749              
1750             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1751              
1752             '[:upper:]' => '[\x41-\x5A]',
1753             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1754             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1755             '[:^alnum:]' => '${Elatin3::not_alnum}',
1756             '[:^alpha:]' => '${Elatin3::not_alpha}',
1757             '[:^ascii:]' => '${Elatin3::not_ascii}',
1758             '[:^blank:]' => '${Elatin3::not_blank}',
1759             '[:^cntrl:]' => '${Elatin3::not_cntrl}',
1760             '[:^digit:]' => '${Elatin3::not_digit}',
1761             '[:^graph:]' => '${Elatin3::not_graph}',
1762             '[:^lower:]' => '${Elatin3::not_lower}',
1763             '[:^print:]' => '${Elatin3::not_print}',
1764             '[:^punct:]' => '${Elatin3::not_punct}',
1765             '[:^space:]' => '${Elatin3::not_space}',
1766             '[:^upper:]' => '${Elatin3::not_upper}',
1767             '[:^word:]' => '${Elatin3::not_word}',
1768             '[:^xdigit:]' => '${Elatin3::not_xdigit}',
1769              
1770 8         81 }->{$1};
1771             }
1772             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1773 70         1358 $char[$i] = $1;
1774             }
1775             }
1776              
1777             # open character list
1778 7         30 my @singleoctet = ();
1779 358         668 my @multipleoctet = ();
1780 358         599 for (my $i=0; $i <= $#char; ) {
1781              
1782             # escaped -
1783 358 100 100     1029 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1784 943         4604 $i += 1;
1785 182         246 next;
1786             }
1787              
1788             # make range regexp
1789             elsif ($char[$i] eq '...') {
1790              
1791             # range error
1792 182 50       334 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1793 182         783 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1794             }
1795             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1796 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1797 182         505 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1798             }
1799             }
1800              
1801             # make range regexp per length
1802 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1803 182         541 my @regexp = ();
1804              
1805             # is first and last
1806 182 50 33     305 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1807 182         653 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1808             }
1809              
1810             # is first
1811             elsif ($length == CORE::length($char[$i-1])) {
1812 182         524 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1813             }
1814              
1815             # is inside in first and last
1816             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1817 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1818             }
1819              
1820             # is last
1821             elsif ($length == CORE::length($char[$i+1])) {
1822 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1823             }
1824              
1825             else {
1826 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1827             }
1828              
1829 0 50       0 if ($length == 1) {
1830 182         396 push @singleoctet, @regexp;
1831             }
1832             else {
1833 182         421 push @multipleoctet, @regexp;
1834             }
1835             }
1836              
1837 0         0 $i += 2;
1838             }
1839              
1840             # with /i modifier
1841             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1842 182 100       392 if ($modifier =~ /i/oxms) {
1843 493         748 my $uc = Elatin3::uc($char[$i]);
1844 24         49 my $fc = Elatin3::fc($char[$i]);
1845 24 100       51 if ($uc ne $fc) {
1846 24 50       48 if (CORE::length($fc) == 1) {
1847 12         24 push @singleoctet, $uc, $fc;
1848             }
1849             else {
1850 12         20 push @singleoctet, $uc;
1851 0         0 push @multipleoctet, $fc;
1852             }
1853             }
1854             else {
1855 0         0 push @singleoctet, $char[$i];
1856             }
1857             }
1858             else {
1859 12         25 push @singleoctet, $char[$i];
1860             }
1861 469         847 $i += 1;
1862             }
1863              
1864             # single character of single octet code
1865             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1866 493         854 push @singleoctet, "\t", "\x20";
1867 0         0 $i += 1;
1868             }
1869             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1870 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1871 0         0 $i += 1;
1872             }
1873             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1874 0         0 push @singleoctet, $char[$i];
1875 2         5 $i += 1;
1876             }
1877              
1878             # single character of multiple-octet code
1879             else {
1880 2         5 push @multipleoctet, $char[$i];
1881 84         185 $i += 1;
1882             }
1883             }
1884              
1885             # quote metachar
1886 84         156 for (@singleoctet) {
1887 358 50       733 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1888 689         3376 $_ = '-';
1889             }
1890             elsif (/\A \n \z/oxms) {
1891 0         0 $_ = '\n';
1892             }
1893             elsif (/\A \r \z/oxms) {
1894 8         22 $_ = '\r';
1895             }
1896             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1897 8         20 $_ = sprintf('\x%02X', CORE::ord $1);
1898             }
1899             elsif (/\A [\x00-\xFF] \z/oxms) {
1900 60         207 $_ = quotemeta $_;
1901             }
1902             }
1903              
1904             # return character list
1905 429         788 return \@singleoctet, \@multipleoctet;
1906             }
1907              
1908             #
1909             # Latin-3 octal escape sequence
1910             #
1911             sub octchr {
1912 358     5 0 1238 my($octdigit) = @_;
1913              
1914 5         11 my @binary = ();
1915 5         8 for my $octal (split(//,$octdigit)) {
1916             push @binary, {
1917             '0' => '000',
1918             '1' => '001',
1919             '2' => '010',
1920             '3' => '011',
1921             '4' => '100',
1922             '5' => '101',
1923             '6' => '110',
1924             '7' => '111',
1925 5         29 }->{$octal};
1926             }
1927 50         170 my $binary = join '', @binary;
1928              
1929             my $octchr = {
1930             # 1234567
1931             1 => pack('B*', "0000000$binary"),
1932             2 => pack('B*', "000000$binary"),
1933             3 => pack('B*', "00000$binary"),
1934             4 => pack('B*', "0000$binary"),
1935             5 => pack('B*', "000$binary"),
1936             6 => pack('B*', "00$binary"),
1937             7 => pack('B*', "0$binary"),
1938             0 => pack('B*', "$binary"),
1939              
1940 5         14 }->{CORE::length($binary) % 8};
1941              
1942 5         61 return $octchr;
1943             }
1944              
1945             #
1946             # Latin-3 hexadecimal escape sequence
1947             #
1948             sub hexchr {
1949 5     5 0 19 my($hexdigit) = @_;
1950              
1951             my $hexchr = {
1952             1 => pack('H*', "0$hexdigit"),
1953             0 => pack('H*', "$hexdigit"),
1954              
1955 5         16 }->{CORE::length($_[0]) % 2};
1956              
1957 5         35 return $hexchr;
1958             }
1959              
1960             #
1961             # Latin-3 open character list for qr
1962             #
1963             sub charlist_qr {
1964              
1965 5     314 0 19 my $modifier = pop @_;
1966 314         677 my @char = @_;
1967              
1968 314         995 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1969 314         1127 my @singleoctet = @$singleoctet;
1970 314         954 my @multipleoctet = @$multipleoctet;
1971              
1972             # return character list
1973 314 100       526 if (scalar(@singleoctet) >= 1) {
1974              
1975             # with /i modifier
1976 314 100       725 if ($modifier =~ m/i/oxms) {
1977 236         591 my %singleoctet_ignorecase = ();
1978 22         32 for (@singleoctet) {
1979 22   100     34 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1980 46         192 for my $ord (hex($1) .. hex($2)) {
1981 46         130 my $char = CORE::chr($ord);
1982 66         106 my $uc = Elatin3::uc($char);
1983 66         97 my $fc = Elatin3::fc($char);
1984 66 100       98 if ($uc eq $fc) {
1985 66         117 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1986             }
1987             else {
1988 12 50       98 if (CORE::length($fc) == 1) {
1989 54         72 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1990 54         113 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1991             }
1992             else {
1993 54         190 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1994 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1995             }
1996             }
1997             }
1998             }
1999 0 50       0 if ($_ ne '') {
2000 46         90 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2001             }
2002             }
2003 0         0 my $i = 0;
2004 22         26 my @singleoctet_ignorecase = ();
2005 22         38 for my $ord (0 .. 255) {
2006 22 100       36 if (exists $singleoctet_ignorecase{$ord}) {
2007 5632         6445 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         102  
2008             }
2009             else {
2010 96         202 $i++;
2011             }
2012             }
2013 5536         5877 @singleoctet = ();
2014 22         37 for my $range (@singleoctet_ignorecase) {
2015 22 100       61 if (ref $range) {
2016 3648 100       5652 if (scalar(@{$range}) == 1) {
  56 50       54  
2017 56         83 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         48  
2018             }
2019 36         132 elsif (scalar(@{$range}) == 2) {
2020 20         25 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2021             }
2022             else {
2023 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         22  
  20         24  
2024             }
2025             }
2026             }
2027             }
2028              
2029 20         72 my $not_anchor = '';
2030              
2031 236         382 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2032             }
2033 236 100       664 if (scalar(@multipleoctet) >= 2) {
2034 314         752 return '(?:' . join('|', @multipleoctet) . ')';
2035             }
2036             else {
2037 6         30 return $multipleoctet[0];
2038             }
2039             }
2040              
2041             #
2042             # Latin-3 open character list for not qr
2043             #
2044             sub charlist_not_qr {
2045              
2046 308     44 0 1668 my $modifier = pop @_;
2047 44         86 my @char = @_;
2048              
2049 44         114 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2050 44         139 my @singleoctet = @$singleoctet;
2051 44         102 my @multipleoctet = @$multipleoctet;
2052              
2053             # with /i modifier
2054 44 100       76 if ($modifier =~ m/i/oxms) {
2055 44         125 my %singleoctet_ignorecase = ();
2056 10         14 for (@singleoctet) {
2057 10   66     13 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2058 10         79 for my $ord (hex($1) .. hex($2)) {
2059 10         32 my $char = CORE::chr($ord);
2060 30         50 my $uc = Elatin3::uc($char);
2061 30         47 my $fc = Elatin3::fc($char);
2062 30 50       79 if ($uc eq $fc) {
2063 30         57 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2064             }
2065             else {
2066 0 50       0 if (CORE::length($fc) == 1) {
2067 30         38 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2068 30         62 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2069             }
2070             else {
2071 30         119 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2072 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2073             }
2074             }
2075             }
2076             }
2077 0 50       0 if ($_ ne '') {
2078 10         22 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2079             }
2080             }
2081 0         0 my $i = 0;
2082 10         11 my @singleoctet_ignorecase = ();
2083 10         12 for my $ord (0 .. 255) {
2084 10 100       18 if (exists $singleoctet_ignorecase{$ord}) {
2085 2560         3284 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         59  
2086             }
2087             else {
2088 60         102 $i++;
2089             }
2090             }
2091 2500         2948 @singleoctet = ();
2092 10         27 for my $range (@singleoctet_ignorecase) {
2093 10 100       40 if (ref $range) {
2094 960 50       1787 if (scalar(@{$range}) == 1) {
  20 50       20  
2095 20         35 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2096             }
2097 0         0 elsif (scalar(@{$range}) == 2) {
2098 20         45 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2099             }
2100             else {
2101 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         25  
  20         23  
2102             }
2103             }
2104             }
2105             }
2106              
2107             # return character list
2108 20 50       95 if (scalar(@multipleoctet) >= 1) {
2109 44 0       100 if (scalar(@singleoctet) >= 1) {
2110              
2111             # any character other than multiple-octet and single octet character class
2112 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2113             }
2114             else {
2115              
2116             # any character other than multiple-octet character class
2117 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2118             }
2119             }
2120             else {
2121 0 50       0 if (scalar(@singleoctet) >= 1) {
2122              
2123             # any character other than single octet character class
2124 44         132 return '(?:[^' . join('', @singleoctet) . '])';
2125             }
2126             else {
2127              
2128             # any character
2129 44         250 return "(?:$your_char)";
2130             }
2131             }
2132             }
2133              
2134             #
2135             # open file in read mode
2136             #
2137             sub _open_r {
2138 0     408   0 my(undef,$file) = @_;
2139 204     204   8173 use Fcntl qw(O_RDONLY);
  204         710  
  204         30558  
2140 408         1342 return CORE::sysopen($_[0], $file, &O_RDONLY);
2141             }
2142              
2143             #
2144             # open file in append mode
2145             #
2146             sub _open_a {
2147 408     204   18900 my(undef,$file) = @_;
2148 204     204   1560 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  204         445  
  204         672010  
2149 204         642 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2150             }
2151              
2152             #
2153             # safe system
2154             #
2155             sub _systemx {
2156              
2157             # P.707 29.2.33. exec
2158             # in Chapter 29: Functions
2159             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2160             #
2161             # Be aware that in older releases of Perl, exec (and system) did not flush
2162             # your output buffer, so you needed to enable command buffering by setting $|
2163             # on one or more filehandles to avoid lost output in the case of exec, or
2164             # misordererd output in the case of system. This situation was largely remedied
2165             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2166              
2167             # P.855 exec
2168             # in Chapter 27: Functions
2169             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2170             #
2171             # In very old release of Perl (before v5.6), exec (and system) did not flush
2172             # your output buffer, so you needed to enable command buffering by setting $|
2173             # on one or more filehandles to avoid lost output with exec or misordered
2174             # output with system.
2175              
2176 204     204   113072 $| = 1;
2177              
2178             # P.565 23.1.2. Cleaning Up Your Environment
2179             # in Chapter 23: Security
2180             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2181              
2182             # P.656 Cleaning Up Your Environment
2183             # in Chapter 20: Security
2184             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2185              
2186             # local $ENV{'PATH'} = '.';
2187 204         753 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2188              
2189             # P.707 29.2.33. exec
2190             # in Chapter 29: Functions
2191             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2192             #
2193             # As we mentioned earlier, exec treats a discrete list of arguments as an
2194             # indication that it should bypass shell processing. However, there is one
2195             # place where you might still get tripped up. The exec call (and system, too)
2196             # will not distinguish between a single scalar argument and an array containing
2197             # only one element.
2198             #
2199             # @args = ("echo surprise"); # just one element in list
2200             # exec @args # still subject to shell escapes
2201             # or die "exec: $!"; # because @args == 1
2202             #
2203             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2204             # first argument as the pathname, which forces the rest of the arguments to be
2205             # interpreted as a list, even if there is only one of them:
2206             #
2207             # exec { $args[0] } @args # safe even with one-argument list
2208             # or die "can't exec @args: $!";
2209              
2210             # P.855 exec
2211             # in Chapter 27: Functions
2212             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2213             #
2214             # As we mentioned earlier, exec treats a discrete list of arguments as a
2215             # directive to bypass shell processing. However, there is one place where
2216             # you might still get tripped up. The exec call (and system, too) cannot
2217             # distinguish between a single scalar argument and an array containing
2218             # only one element.
2219             #
2220             # @args = ("echo surprise"); # just one element in list
2221             # exec @args # still subject to shell escapes
2222             # || die "exec: $!"; # because @args == 1
2223             #
2224             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2225             # argument as the pathname, which forces the rest of the arguments to be
2226             # interpreted as a list, even if there is only one of them:
2227             #
2228             # exec { $args[0] } @args # safe even with one-argument list
2229             # || die "can't exec @args: $!";
2230              
2231 204         1762 return CORE::system { $_[0] } @_; # safe even with one-argument list
  204         738  
2232             }
2233              
2234             #
2235             # Latin-3 order to character (with parameter)
2236             #
2237             sub Elatin3::chr(;$) {
2238              
2239 204 0   0 0 18898561 my $c = @_ ? $_[0] : $_;
2240              
2241 0 0       0 if ($c == 0x00) {
2242 0         0 return "\x00";
2243             }
2244             else {
2245 0         0 my @chr = ();
2246 0         0 while ($c > 0) {
2247 0         0 unshift @chr, ($c % 0x100);
2248 0         0 $c = int($c / 0x100);
2249             }
2250 0         0 return pack 'C*', @chr;
2251             }
2252             }
2253              
2254             #
2255             # Latin-3 order to character (without parameter)
2256             #
2257             sub Elatin3::chr_() {
2258              
2259 0     0 0 0 my $c = $_;
2260              
2261 0 0       0 if ($c == 0x00) {
2262 0         0 return "\x00";
2263             }
2264             else {
2265 0         0 my @chr = ();
2266 0         0 while ($c > 0) {
2267 0         0 unshift @chr, ($c % 0x100);
2268 0         0 $c = int($c / 0x100);
2269             }
2270 0         0 return pack 'C*', @chr;
2271             }
2272             }
2273              
2274             #
2275             # Latin-3 path globbing (with parameter)
2276             #
2277             sub Elatin3::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             # Latin-3 path globbing (without parameter)
2295             #
2296             sub Elatin3::glob_() {
2297              
2298 0 0   0 0 0 if (wantarray) {
2299 0         0 my @glob = _DOS_like_glob();
2300 0         0 for my $glob (@glob) {
2301 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2302             }
2303 0         0 return @glob;
2304             }
2305             else {
2306 0         0 my $glob = _DOS_like_glob();
2307 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2308 0         0 return $glob;
2309             }
2310             }
2311              
2312             #
2313             # Latin-3 path globbing via File::DosGlob 1.10
2314             #
2315             # Often I confuse "_dosglob" and "_doglob".
2316             # So, I renamed "_dosglob" to "_DOS_like_glob".
2317             #
2318             my %iter;
2319             my %entries;
2320             sub _DOS_like_glob {
2321              
2322             # context (keyed by second cxix argument provided by core)
2323 0     0   0 my($expr,$cxix) = @_;
2324              
2325             # glob without args defaults to $_
2326 0 0       0 $expr = $_ if not defined $expr;
2327              
2328             # represents the current user's home directory
2329             #
2330             # 7.3. Expanding Tildes in Filenames
2331             # in Chapter 7. File Access
2332             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2333             #
2334             # and File::HomeDir, File::HomeDir::Windows module
2335              
2336             # DOS-like system
2337 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2338 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2339             { my_home_MSWin32() }oxmse;
2340             }
2341              
2342             # UNIX-like system
2343 0 0 0     0 else {
  0         0  
2344             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2345             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2346             }
2347 0 0       0  
2348 0 0       0 # assume global context if not provided one
2349             $cxix = '_G_' if not defined $cxix;
2350             $iter{$cxix} = 0 if not exists $iter{$cxix};
2351 0 0       0  
2352 0         0 # if we're just beginning, do it all first
2353             if ($iter{$cxix} == 0) {
2354             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2355             }
2356 0 0       0  
2357 0         0 # chuck it all out, quick or slow
2358 0         0 if (wantarray) {
  0         0  
2359             delete $iter{$cxix};
2360             return @{delete $entries{$cxix}};
2361 0 0       0 }
  0         0  
2362 0         0 else {
  0         0  
2363             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2364             return shift @{$entries{$cxix}};
2365             }
2366 0         0 else {
2367 0         0 # return undef for EOL
2368 0         0 delete $iter{$cxix};
2369             delete $entries{$cxix};
2370             return undef;
2371             }
2372             }
2373             }
2374              
2375             #
2376             # Latin-3 path globbing subroutine
2377             #
2378 0     0   0 sub _do_glob {
2379 0         0  
2380 0         0 my($cond,@expr) = @_;
2381             my @glob = ();
2382             my $fix_drive_relative_paths = 0;
2383 0         0  
2384 0 0       0 OUTER:
2385 0 0       0 for my $expr (@expr) {
2386             next OUTER if not defined $expr;
2387 0         0 next OUTER if $expr eq '';
2388 0         0  
2389 0         0 my @matched = ();
2390 0         0 my @globdir = ();
2391 0         0 my $head = '.';
2392             my $pathsep = '/';
2393             my $tail;
2394 0 0       0  
2395 0         0 # if argument is within quotes strip em and do no globbing
2396 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2397 0 0       0 $expr = $1;
2398 0         0 if ($cond eq 'd') {
2399             if (-d $expr) {
2400             push @glob, $expr;
2401             }
2402 0 0       0 }
2403 0         0 else {
2404             if (-e $expr) {
2405             push @glob, $expr;
2406 0         0 }
2407             }
2408             next OUTER;
2409             }
2410              
2411 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2412 0 0       0 # to h:./*.pm to expand correctly
2413 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2414             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2415             $fix_drive_relative_paths = 1;
2416             }
2417 0 0       0 }
2418 0 0       0  
2419 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2420 0         0 if ($tail eq '') {
2421             push @glob, $expr;
2422 0 0       0 next OUTER;
2423 0 0       0 }
2424 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2425 0         0 if (@globdir = _do_glob('d', $head)) {
2426             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2427             next OUTER;
2428 0 0 0     0 }
2429 0         0 }
2430             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2431 0         0 $head .= $pathsep;
2432             }
2433             $expr = $tail;
2434             }
2435 0 0       0  
2436 0 0       0 # If file component has no wildcards, we can avoid opendir
2437 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2438             if ($head eq '.') {
2439 0 0 0     0 $head = '';
2440 0         0 }
2441             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2442 0         0 $head .= $pathsep;
2443 0 0       0 }
2444 0 0       0 $head .= $expr;
2445 0         0 if ($cond eq 'd') {
2446             if (-d $head) {
2447             push @glob, $head;
2448             }
2449 0 0       0 }
2450 0         0 else {
2451             if (-e $head) {
2452             push @glob, $head;
2453 0         0 }
2454             }
2455 0 0       0 next OUTER;
2456 0         0 }
2457 0         0 opendir(*DIR, $head) or next OUTER;
2458             my @leaf = readdir DIR;
2459 0 0       0 closedir DIR;
2460 0         0  
2461             if ($head eq '.') {
2462 0 0 0     0 $head = '';
2463 0         0 }
2464             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2465             $head .= $pathsep;
2466 0         0 }
2467 0         0  
2468 0         0 my $pattern = '';
2469             while ($expr =~ / \G ($q_char) /oxgc) {
2470             my $char = $1;
2471              
2472             # 6.9. Matching Shell Globs as Regular Expressions
2473             # in Chapter 6. Pattern Matching
2474             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2475 0 0       0 # (and so on)
    0          
    0          
2476 0         0  
2477             if ($char eq '*') {
2478             $pattern .= "(?:$your_char)*",
2479 0         0 }
2480             elsif ($char eq '?') {
2481             $pattern .= "(?:$your_char)?", # DOS style
2482             # $pattern .= "(?:$your_char)", # UNIX style
2483 0         0 }
2484             elsif ((my $fc = Elatin3::fc($char)) ne $char) {
2485             $pattern .= $fc;
2486 0         0 }
2487             else {
2488             $pattern .= quotemeta $char;
2489 0     0   0 }
  0         0  
2490             }
2491             my $matchsub = sub { Elatin3::fc($_[0]) =~ /\A $pattern \z/xms };
2492              
2493             # if ($@) {
2494             # print STDERR "$0: $@\n";
2495             # next OUTER;
2496             # }
2497 0         0  
2498 0 0 0     0 INNER:
2499 0         0 for my $leaf (@leaf) {
2500             if ($leaf eq '.' or $leaf eq '..') {
2501 0 0 0     0 next INNER;
2502 0         0 }
2503             if ($cond eq 'd' and not -d "$head$leaf") {
2504             next INNER;
2505 0 0       0 }
2506 0         0  
2507 0         0 if (&$matchsub($leaf)) {
2508             push @matched, "$head$leaf";
2509             next INNER;
2510             }
2511              
2512             # [DOS compatibility special case]
2513 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2514              
2515             if (Elatin3::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2516             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2517 0 0       0 Elatin3::index($pattern,'\\.') != -1 # pattern has a dot.
2518 0         0 ) {
2519 0         0 if (&$matchsub("$leaf.")) {
2520             push @matched, "$head$leaf";
2521             next INNER;
2522             }
2523 0 0       0 }
2524 0         0 }
2525             if (@matched) {
2526             push @glob, @matched;
2527 0 0       0 }
2528 0         0 }
2529 0         0 if ($fix_drive_relative_paths) {
2530             for my $glob (@glob) {
2531             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2532 0         0 }
2533             }
2534             return @glob;
2535             }
2536              
2537             #
2538             # Latin-3 parse line
2539             #
2540 0     0   0 sub _parse_line {
2541              
2542 0         0 my($line) = @_;
2543 0         0  
2544 0         0 $line .= ' ';
2545             my @piece = ();
2546             while ($line =~ /
2547             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2548             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2549 0 0       0 /oxmsg
2550             ) {
2551 0         0 push @piece, defined($1) ? $1 : $2;
2552             }
2553             return @piece;
2554             }
2555              
2556             #
2557             # Latin-3 parse path
2558             #
2559 0     0   0 sub _parse_path {
2560              
2561 0         0 my($path,$pathsep) = @_;
2562 0         0  
2563 0         0 $path .= '/';
2564             my @subpath = ();
2565             while ($path =~ /
2566             ((?: [^\/\\] )+?) [\/\\]
2567 0         0 /oxmsg
2568             ) {
2569             push @subpath, $1;
2570 0         0 }
2571 0         0  
2572 0         0 my $tail = pop @subpath;
2573             my $head = join $pathsep, @subpath;
2574             return $head, $tail;
2575             }
2576              
2577             #
2578             # via File::HomeDir::Windows 1.00
2579             #
2580             sub my_home_MSWin32 {
2581              
2582             # A lot of unix people and unix-derived tools rely on
2583 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2584 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2585             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2586             return $ENV{'HOME'};
2587             }
2588              
2589 0         0 # Do we have a user profile?
2590             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2591             return $ENV{'USERPROFILE'};
2592             }
2593              
2594 0         0 # Some Windows use something like $ENV{'HOME'}
2595             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2596             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2597 0         0 }
2598              
2599             return undef;
2600             }
2601              
2602             #
2603             # via File::HomeDir::Unix 1.00
2604 0     0 0 0 #
2605             sub my_home {
2606 0 0 0     0 my $home;
    0 0        
2607 0         0  
2608             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2609             $home = $ENV{'HOME'};
2610             }
2611              
2612             # This is from the original code, but I'm guessing
2613 0         0 # it means "login directory" and exists on some Unixes.
2614             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2615             $home = $ENV{'LOGDIR'};
2616             }
2617              
2618             ### More-desperate methods
2619              
2620 0         0 # Light desperation on any (Unixish) platform
2621             else {
2622             $home = CORE::eval q{ (getpwuid($<))[7] };
2623             }
2624              
2625 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2626 0         0 # For example, "nobody"-like users might use /nonexistant
2627             if (defined $home and ! -d($home)) {
2628 0         0 $home = undef;
2629             }
2630             return $home;
2631             }
2632              
2633             #
2634             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2635 0     0 0 0 #
2636             sub Elatin3::PREMATCH {
2637             return $`;
2638             }
2639              
2640             #
2641             # ${^MATCH}, $MATCH, $& the string that matched
2642 0     0 0 0 #
2643             sub Elatin3::MATCH {
2644             return $&;
2645             }
2646              
2647             #
2648             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2649 0     0 0 0 #
2650             sub Elatin3::POSTMATCH {
2651             return $';
2652             }
2653              
2654             #
2655             # Latin-3 character to order (with parameter)
2656             #
2657 0 0   0 1 0 sub Latin3::ord(;$) {
2658              
2659 0 0       0 local $_ = shift if @_;
2660 0         0  
2661 0         0 if (/\A ($q_char) /oxms) {
2662 0         0 my @ord = unpack 'C*', $1;
2663 0         0 my $ord = 0;
2664             while (my $o = shift @ord) {
2665 0         0 $ord = $ord * 0x100 + $o;
2666             }
2667             return $ord;
2668 0         0 }
2669             else {
2670             return CORE::ord $_;
2671             }
2672             }
2673              
2674             #
2675             # Latin-3 character to order (without parameter)
2676             #
2677 0 0   0 0 0 sub Latin3::ord_() {
2678 0         0  
2679 0         0 if (/\A ($q_char) /oxms) {
2680 0         0 my @ord = unpack 'C*', $1;
2681 0         0 my $ord = 0;
2682             while (my $o = shift @ord) {
2683 0         0 $ord = $ord * 0x100 + $o;
2684             }
2685             return $ord;
2686 0         0 }
2687             else {
2688             return CORE::ord $_;
2689             }
2690             }
2691              
2692             #
2693             # Latin-3 reverse
2694             #
2695 0 0   0 0 0 sub Latin3::reverse(@) {
2696 0         0  
2697             if (wantarray) {
2698             return CORE::reverse @_;
2699             }
2700             else {
2701              
2702             # One of us once cornered Larry in an elevator and asked him what
2703             # problem he was solving with this, but he looked as far off into
2704             # the distance as he could in an elevator and said, "It seemed like
2705 0         0 # a good idea at the time."
2706              
2707             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2708             }
2709             }
2710              
2711             #
2712             # Latin-3 getc (with parameter, without parameter)
2713             #
2714 0     0 0 0 sub Latin3::getc(;*@) {
2715 0 0       0  
2716 0 0 0     0 my($package) = caller;
2717             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2718 0         0 croak 'Too many arguments for Latin3::getc' if @_ and not wantarray;
  0         0  
2719 0         0  
2720 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2721 0         0 my $getc = '';
2722 0 0       0 for my $length ($length[0] .. $length[-1]) {
2723 0 0       0 $getc .= CORE::getc($fh);
2724 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2725             if ($getc =~ /\A ${Elatin3::dot_s} \z/oxms) {
2726             return wantarray ? ($getc,@_) : $getc;
2727             }
2728 0 0       0 }
2729             }
2730             return wantarray ? ($getc,@_) : $getc;
2731             }
2732              
2733             #
2734             # Latin-3 length by character
2735             #
2736 0 0   0 1 0 sub Latin3::length(;$) {
2737              
2738 0         0 local $_ = shift if @_;
2739 0         0  
2740             local @_ = /\G ($q_char) /oxmsg;
2741             return scalar @_;
2742             }
2743              
2744             #
2745             # Latin-3 substr by character
2746             #
2747             BEGIN {
2748              
2749             # P.232 The lvalue Attribute
2750             # in Chapter 6: Subroutines
2751             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2752              
2753             # P.336 The lvalue Attribute
2754             # in Chapter 7: Subroutines
2755             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2756              
2757             # P.144 8.4 Lvalue subroutines
2758             # in Chapter 8: perlsub: Perl subroutines
2759 204 50 0 204 1 124227 # 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  
2760              
2761             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2762             # vv----------------------*******
2763             sub Latin3::substr($$;$$) %s {
2764              
2765             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2766              
2767             # If the substring is beyond either end of the string, substr() returns the undefined
2768             # value and produces a warning. When used as an lvalue, specifying a substring that
2769             # is entirely outside the string raises an exception.
2770             # http://perldoc.perl.org/functions/substr.html
2771              
2772             # A return with no argument returns the scalar value undef in scalar context,
2773             # an empty list () in list context, and (naturally) nothing at all in void
2774             # context.
2775              
2776             my $offset = $_[1];
2777             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2778             return;
2779             }
2780              
2781             # substr($string,$offset,$length,$replacement)
2782             if (@_ == 4) {
2783             my(undef,undef,$length,$replacement) = @_;
2784             my $substr = join '', splice(@char, $offset, $length, $replacement);
2785             $_[0] = join '', @char;
2786              
2787             # return $substr; this doesn't work, don't say "return"
2788             $substr;
2789             }
2790              
2791             # substr($string,$offset,$length)
2792             elsif (@_ == 3) {
2793             my(undef,undef,$length) = @_;
2794             my $octet_offset = 0;
2795             my $octet_length = 0;
2796             if ($offset == 0) {
2797             $octet_offset = 0;
2798             }
2799             elsif ($offset > 0) {
2800             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2801             }
2802             else {
2803             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2804             }
2805             if ($length == 0) {
2806             $octet_length = 0;
2807             }
2808             elsif ($length > 0) {
2809             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2810             }
2811             else {
2812             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2813             }
2814             CORE::substr($_[0], $octet_offset, $octet_length);
2815             }
2816              
2817             # substr($string,$offset)
2818             else {
2819             my $octet_offset = 0;
2820             if ($offset == 0) {
2821             $octet_offset = 0;
2822             }
2823             elsif ($offset > 0) {
2824             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2825             }
2826             else {
2827             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2828             }
2829             CORE::substr($_[0], $octet_offset);
2830             }
2831             }
2832             END
2833             }
2834              
2835             #
2836             # Latin-3 index by character
2837             #
2838 0     0 1 0 sub Latin3::index($$;$) {
2839 0 0       0  
2840 0         0 my $index;
2841             if (@_ == 3) {
2842             $index = Elatin3::index($_[0], $_[1], CORE::length(Latin3::substr($_[0], 0, $_[2])));
2843 0         0 }
2844             else {
2845             $index = Elatin3::index($_[0], $_[1]);
2846 0 0       0 }
2847 0         0  
2848             if ($index == -1) {
2849             return -1;
2850 0         0 }
2851             else {
2852             return Latin3::length(CORE::substr $_[0], 0, $index);
2853             }
2854             }
2855              
2856             #
2857             # Latin-3 rindex by character
2858             #
2859 0     0 1 0 sub Latin3::rindex($$;$) {
2860 0 0       0  
2861 0         0 my $rindex;
2862             if (@_ == 3) {
2863             $rindex = Elatin3::rindex($_[0], $_[1], CORE::length(Latin3::substr($_[0], 0, $_[2])));
2864 0         0 }
2865             else {
2866             $rindex = Elatin3::rindex($_[0], $_[1]);
2867 0 0       0 }
2868 0         0  
2869             if ($rindex == -1) {
2870             return -1;
2871 0         0 }
2872             else {
2873             return Latin3::length(CORE::substr $_[0], 0, $rindex);
2874             }
2875             }
2876              
2877 204     204   1792 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  204         522  
  204         51875  
2878             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2879             use vars qw($slash); $slash = 'm//';
2880              
2881             # ord() to ord() or Latin3::ord()
2882             my $function_ord = 'ord';
2883              
2884             # ord to ord or Latin3::ord_
2885             my $function_ord_ = 'ord';
2886              
2887             # reverse to reverse or Latin3::reverse
2888             my $function_reverse = 'reverse';
2889              
2890             # getc to getc or Latin3::getc
2891             my $function_getc = 'getc';
2892              
2893             # P.1023 Appendix W.9 Multibyte Anchoring
2894             # of ISBN 1-56592-224-7 CJKV Information Processing
2895              
2896 204     204   1699 my $anchor = '';
  204     0   404  
  204         9757566  
2897              
2898             use vars qw($nest);
2899              
2900             # regexp of nested parens in qqXX
2901              
2902             # P.340 Matching Nested Constructs with Embedded Code
2903             # in Chapter 7: Perl
2904             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2905              
2906             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2907             [^\\()] |
2908             \( (?{$nest++}) |
2909             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2910             \\ [^c] |
2911             \\c[\x40-\x5F] |
2912             [\x00-\xFF]
2913             }xms;
2914              
2915             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2916             [^\\{}] |
2917             \{ (?{$nest++}) |
2918             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2919             \\ [^c] |
2920             \\c[\x40-\x5F] |
2921             [\x00-\xFF]
2922             }xms;
2923              
2924             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2925             [^\\\[\]] |
2926             \[ (?{$nest++}) |
2927             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2928             \\ [^c] |
2929             \\c[\x40-\x5F] |
2930             [\x00-\xFF]
2931             }xms;
2932              
2933             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2934             [^\\<>] |
2935             \< (?{$nest++}) |
2936             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2937             \\ [^c] |
2938             \\c[\x40-\x5F] |
2939             [\x00-\xFF]
2940             }xms;
2941              
2942             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2943             (?: ::)? (?:
2944             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2945             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2946             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2947             ))
2948             }xms;
2949              
2950             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2951             (?: ::)? (?:
2952             (?>[0-9]+) |
2953             [^a-zA-Z_0-9\[\]] |
2954             ^[A-Z] |
2955             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2956             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2957             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2958             ))
2959             }xms;
2960              
2961             my $qq_substr = qr{(?> Char::substr | Latin3::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2962             }xms;
2963              
2964             # regexp of nested parens in qXX
2965             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2966             [^()] |
2967             \( (?{$nest++}) |
2968             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2969             [\x00-\xFF]
2970             }xms;
2971              
2972             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2973             [^\{\}] |
2974             \{ (?{$nest++}) |
2975             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2976             [\x00-\xFF]
2977             }xms;
2978              
2979             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2980             [^\[\]] |
2981             \[ (?{$nest++}) |
2982             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2983             [\x00-\xFF]
2984             }xms;
2985              
2986             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2987             [^<>] |
2988             \< (?{$nest++}) |
2989             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2990             [\x00-\xFF]
2991             }xms;
2992              
2993             my $matched = '';
2994             my $s_matched = '';
2995              
2996             my $tr_variable = ''; # variable of tr///
2997             my $sub_variable = ''; # variable of s///
2998             my $bind_operator = ''; # =~ or !~
2999              
3000             my @heredoc = (); # here document
3001             my @heredoc_delimiter = ();
3002             my $here_script = ''; # here script
3003              
3004             #
3005             # escape Latin-3 script
3006 0 50   204 0 0 #
3007             sub Latin3::escape(;$) {
3008             local($_) = $_[0] if @_;
3009              
3010             # P.359 The Study Function
3011             # in Chapter 7: Perl
3012 204         669 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3013              
3014             study $_; # Yes, I studied study yesterday.
3015              
3016             # while all script
3017              
3018             # 6.14. Matching from Where the Last Pattern Left Off
3019             # in Chapter 6. Pattern Matching
3020             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3021             # (and so on)
3022              
3023             # one member of Tag-team
3024             #
3025             # P.128 Start of match (or end of previous match): \G
3026             # P.130 Advanced Use of \G with Perl
3027             # in Chapter 3: Overview of Regular Expression Features and Flavors
3028             # P.255 Use leading anchors
3029             # P.256 Expose ^ and \G at the front expressions
3030             # in Chapter 6: Crafting an Efficient Expression
3031             # P.315 "Tag-team" matching with /gc
3032             # in Chapter 7: Perl
3033 204         392 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3034 204         386  
3035 204         778 my $e_script = '';
3036             while (not /\G \z/oxgc) { # member
3037             $e_script .= Latin3::escape_token();
3038 74843         111053 }
3039              
3040             return $e_script;
3041             }
3042              
3043             #
3044             # escape Latin-3 token of script
3045             #
3046             sub Latin3::escape_token {
3047              
3048 204     74843 0 2873 # \n output here document
3049              
3050             my $ignore_modules = join('|', qw(
3051             utf8
3052             bytes
3053             charnames
3054             I18N::Japanese
3055             I18N::Collate
3056             I18N::JExt
3057             File::DosGlob
3058             Wild
3059             Wildcard
3060             Japanese
3061             ));
3062              
3063             # another member of Tag-team
3064             #
3065             # P.315 "Tag-team" matching with /gc
3066             # in Chapter 7: Perl
3067 74843 100 100     88392 # 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          
3068 74843         2920657  
3069 12529 100       16980 if (/\G ( \n ) /oxgc) { # another member (and so on)
3070 12529         20890 my $heredoc = '';
3071             if (scalar(@heredoc_delimiter) >= 1) {
3072 174         397 $slash = 'm//';
3073 174         346  
3074             $heredoc = join '', @heredoc;
3075             @heredoc = ();
3076 174         291  
3077 174         289 # skip here document
3078             for my $heredoc_delimiter (@heredoc_delimiter) {
3079 174         1055 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3080             }
3081 174         325 @heredoc_delimiter = ();
3082              
3083 174         248 $here_script = '';
3084             }
3085             return "\n" . $heredoc;
3086             }
3087 12529         36284  
3088             # ignore space, comment
3089             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3090              
3091             # if (, elsif (, unless (, while (, until (, given (, and when (
3092              
3093             # given, when
3094              
3095             # P.225 The given Statement
3096             # in Chapter 15: Smart Matching and given-when
3097             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3098              
3099             # P.133 The given Statement
3100             # in Chapter 4: Statements and Declarations
3101             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3102 17961         55826  
3103 1401         2185 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3104             $slash = 'm//';
3105             return $1;
3106             }
3107              
3108             # scalar variable ($scalar = ...) =~ tr///;
3109             # scalar variable ($scalar = ...) =~ s///;
3110              
3111             # state
3112              
3113             # P.68 Persistent, Private Variables
3114             # in Chapter 4: Subroutines
3115             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3116              
3117             # P.160 Persistent Lexically Scoped Variables: state
3118             # in Chapter 4: Statements and Declarations
3119             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3120              
3121             # (and so on)
3122 1401         4311  
3123             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3124 86 50       200 my $e_string = e_string($1);
    50          
3125 86         2109  
3126 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3127 0         0 $tr_variable = $e_string . e_string($1);
3128 0         0 $bind_operator = $2;
3129             $slash = 'm//';
3130             return '';
3131 0         0 }
3132 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3133 0         0 $sub_variable = $e_string . e_string($1);
3134 0         0 $bind_operator = $2;
3135             $slash = 'm//';
3136             return '';
3137 0         0 }
3138 86         158 else {
3139             $slash = 'div';
3140             return $e_string;
3141             }
3142             }
3143              
3144 86         287 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
3145 4         7 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3146             $slash = 'div';
3147             return q{Elatin3::PREMATCH()};
3148             }
3149              
3150 4         14 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
3151 28         83 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3152             $slash = 'div';
3153             return q{Elatin3::MATCH()};
3154             }
3155              
3156 28         103 # $', ${'} --> $', ${'}
3157 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3158             $slash = 'div';
3159             return $1;
3160             }
3161              
3162 1         5 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
3163 3         8 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3164             $slash = 'div';
3165             return q{Elatin3::POSTMATCH()};
3166             }
3167              
3168             # scalar variable $scalar =~ tr///;
3169             # scalar variable $scalar =~ s///;
3170             # substr() =~ tr///;
3171 3         10 # substr() =~ s///;
3172             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3173 1671 100       3826 my $scalar = e_string($1);
    100          
3174 1671         6868  
3175 1         3 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3176 1         2 $tr_variable = $scalar;
3177 1         2 $bind_operator = $1;
3178             $slash = 'm//';
3179             return '';
3180 1         4 }
3181 61         136 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3182 61         123 $sub_variable = $scalar;
3183 61         100 $bind_operator = $1;
3184             $slash = 'm//';
3185             return '';
3186 61         181 }
3187 1609         2303 else {
3188             $slash = 'div';
3189             return $scalar;
3190             }
3191             }
3192              
3193 1609         4202 # end of statement
3194             elsif (/\G ( [,;] ) /oxgc) {
3195             $slash = 'm//';
3196 4991         7398  
3197             # clear tr/// variable
3198             $tr_variable = '';
3199 4991         6154  
3200             # clear s/// variable
3201 4991         6049 $sub_variable = '';
3202              
3203 4991         5456 $bind_operator = '';
3204              
3205             return $1;
3206             }
3207              
3208 4991         17221 # bareword
3209             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3210             return $1;
3211             }
3212              
3213 0         0 # $0 --> $0
3214 2         4 elsif (/\G ( \$ 0 ) /oxmsgc) {
3215             $slash = 'div';
3216             return $1;
3217 2         7 }
3218 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3219             $slash = 'div';
3220             return $1;
3221             }
3222              
3223 0         0 # $$ --> $$
3224 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3225             $slash = 'div';
3226             return $1;
3227             }
3228              
3229             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3230 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
3231 4         7 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3232             $slash = 'div';
3233             return e_capture($1);
3234 4         10 }
3235 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3236             $slash = 'div';
3237             return e_capture($1);
3238             }
3239              
3240 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3241 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3242             $slash = 'div';
3243             return e_capture($1.'->'.$2);
3244             }
3245              
3246 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3247 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3248             $slash = 'div';
3249             return e_capture($1.'->'.$2);
3250             }
3251              
3252 0         0 # $$foo
3253 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3254             $slash = 'div';
3255             return e_capture($1);
3256             }
3257              
3258 0         0 # ${ foo }
3259 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3260             $slash = 'div';
3261             return '${' . $1 . '}';
3262             }
3263              
3264 0         0 # ${ ... }
3265 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3266             $slash = 'div';
3267             return e_capture($1);
3268             }
3269              
3270             # variable or function
3271 0         0 # $ @ % & * $ #
3272 42         66 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) {
3273             $slash = 'div';
3274             return $1;
3275             }
3276             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3277 42         134 # $ @ # \ ' " / ? ( ) [ ] < >
3278 62         116 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3279             $slash = 'div';
3280             return $1;
3281             }
3282              
3283 62         218 # while ()
3284             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3285             return $1;
3286             }
3287              
3288             # while () --- glob
3289              
3290             # avoid "Error: Runtime exception" of perl version 5.005_03
3291 0         0  
3292             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3293             return 'while ($_ = Elatin3::glob("' . $1 . '"))';
3294             }
3295              
3296 0         0 # while (glob)
3297             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3298             return 'while ($_ = Elatin3::glob_)';
3299             }
3300              
3301 0         0 # while (glob(WILDCARD))
3302             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3303             return 'while ($_ = Elatin3::glob';
3304             }
3305 0         0  
  248         582  
3306             # doit if, doit unless, doit while, doit until, doit for, doit when
3307             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3308 248         903  
  19         36  
3309 19         65 # subroutines of package Elatin3
  0         0  
3310 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         19  
3311 13         33 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3312 0         0 elsif (/\G \b Latin3::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         166  
3313 114         306 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         4  
3314 2         6 elsif (/\G \b Latin3::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Latin3::escape'; }
  0         0  
3315 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         3  
3316 2         6 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::chop'; }
  0         0  
3317 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3318 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3319 0         0 elsif (/\G \b Latin3::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin3::index'; }
  2         4  
3320 2         7 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::index'; }
  0         0  
3321 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3322 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3323 0         0 elsif (/\G \b Latin3::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin3::rindex'; }
  1         3  
3324 1         3 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::rindex'; }
  0         0  
3325 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::lc'; }
  1         2  
3326 1         4 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::lcfirst'; }
  0         0  
3327 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::uc'; }
  6         11  
3328             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::ucfirst'; }
3329             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::fc'; }
3330 6         17  
  0         0  
3331 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3332 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3333 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3334 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3335 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3336 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3337             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3338 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  
3339 0         0  
  0         0  
3340 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3341 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3342 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3343 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3344 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3345             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3346             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3347 0         0  
  0         0  
3348 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3349 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3350 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3351             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3352 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         6  
3353 2         7  
  2         4  
3354 2         7 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         66  
3355 36         118 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         4  
3356 2         7 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::chr'; }
  8         15  
3357 8         27 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3358 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3359 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::glob'; }
  0         0  
3360 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::lc_'; }
  0         0  
3361 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::lcfirst_'; }
  0         0  
3362 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::uc_'; }
  0         0  
3363 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::ucfirst_'; }
  0         0  
3364             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::fc_'; }
3365 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3366 0         0  
  0         0  
3367 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3368 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3369 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::chr_'; }
  0         0  
3370 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3371 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3372 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::glob_'; }
  8         19  
3373             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3374             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3375 8         32 # split
3376             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3377 87         180 $slash = 'm//';
3378 87         138  
3379 87         335 my $e = '';
3380             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3381             $e .= $1;
3382             }
3383 85 100       345  
  87 100       5880  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3384             # end of split
3385             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Elatin3::split' . $e; }
3386 2         9  
3387             # split scalar value
3388             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Elatin3::split' . $e . e_string($1); }
3389 1         5  
3390 0         0 # split literal space
3391 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Elatin3::split' . $e . qq {qq$1 $2}; }
3392 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3393 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3394 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3395 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3396 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3397 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Elatin3::split' . $e . qq {q$1 $2}; }
3398 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3399 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3400 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3401 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3402 10         43 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3403             elsif (/\G ' [ ] ' /oxgc) { return 'Elatin3::split' . $e . qq {' '}; }
3404             elsif (/\G " [ ] " /oxgc) { return 'Elatin3::split' . $e . qq {" "}; }
3405              
3406 0 0       0 # split qq//
  0         0  
3407             elsif (/\G \b (qq) \b /oxgc) {
3408 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3409 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3410 0         0 while (not /\G \z/oxgc) {
3411 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3412 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3413 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3414 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3415 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3416             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3417 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3418             }
3419             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3420             }
3421             }
3422              
3423 0 50       0 # split qr//
  12         422  
3424             elsif (/\G \b (qr) \b /oxgc) {
3425 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3426 12 50       64 else {
  12 50       3636  
    50          
    50          
    50          
    50          
    50          
    50          
3427 0         0 while (not /\G \z/oxgc) {
3428 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3429 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3430 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3431 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3432 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3433 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3434             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3435 12         93 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3436             }
3437             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3438             }
3439             }
3440              
3441 0 0       0 # split q//
  0         0  
3442             elsif (/\G \b (q) \b /oxgc) {
3443 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3444 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3445 0         0 while (not /\G \z/oxgc) {
3446 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3447 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3448 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3449 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3450 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3451             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3452 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3453             }
3454             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3455             }
3456             }
3457              
3458 0 50       0 # split m//
  18         475  
3459             elsif (/\G \b (m) \b /oxgc) {
3460 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3461 18 50       76 else {
  18 50       3733  
    50          
    50          
    50          
    50          
    50          
    50          
3462 0         0 while (not /\G \z/oxgc) {
3463 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3464 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3465 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3466 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3467 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3468 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3469             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3470 18         108 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3471             }
3472             die __FILE__, ": Search pattern not terminated\n";
3473             }
3474             }
3475              
3476 0         0 # split ''
3477 0         0 elsif (/\G (\') /oxgc) {
3478 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3479 0         0 while (not /\G \z/oxgc) {
3480 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3481 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3482             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3483 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3484             }
3485             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3486             }
3487              
3488 0         0 # split ""
3489 0         0 elsif (/\G (\") /oxgc) {
3490 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3491 0         0 while (not /\G \z/oxgc) {
3492 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3493 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3494             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3495 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3496             }
3497             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3498             }
3499              
3500 0         0 # split //
3501 44         116 elsif (/\G (\/) /oxgc) {
3502 44 50       186 my $regexp = '';
  381 50       1544  
    100          
    50          
3503 0         0 while (not /\G \z/oxgc) {
3504 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3505 44         215 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3506             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3507 337         962 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3508             }
3509             die __FILE__, ": Search pattern not terminated\n";
3510             }
3511             }
3512              
3513             # tr/// or y///
3514              
3515             # about [cdsrbB]* (/B modifier)
3516             #
3517             # P.559 appendix C
3518             # of ISBN 4-89052-384-7 Programming perl
3519             # (Japanese title is: Perl puroguramingu)
3520 0         0  
3521             elsif (/\G \b ( tr | y ) \b /oxgc) {
3522             my $ope = $1;
3523 3 50       8  
3524 3         52 # $1 $2 $3 $4 $5 $6
3525 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3526             my @tr = ($tr_variable,$2);
3527             return e_tr(@tr,'',$4,$6);
3528 0         0 }
3529 3         8 else {
3530 3 50       9 my $e = '';
  3 50       232  
    50          
    50          
    50          
    50          
3531             while (not /\G \z/oxgc) {
3532 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3533 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3534 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3535 0         0 while (not /\G \z/oxgc) {
3536 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3537 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3538 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3539 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3540             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3541 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3542             }
3543             die __FILE__, ": Transliteration replacement not terminated\n";
3544 0         0 }
3545 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3546 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3547 0         0 while (not /\G \z/oxgc) {
3548 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3549 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3550 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3551 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3552             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3553 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3554             }
3555             die __FILE__, ": Transliteration replacement not terminated\n";
3556 0         0 }
3557 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3558 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3559 0         0 while (not /\G \z/oxgc) {
3560 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3561 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3562 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3563 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3564             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3565 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3566             }
3567             die __FILE__, ": Transliteration replacement not terminated\n";
3568 0         0 }
3569 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3570 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3571 0         0 while (not /\G \z/oxgc) {
3572 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3573 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3574 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3575 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3576             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3577 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3578             }
3579             die __FILE__, ": Transliteration replacement not terminated\n";
3580             }
3581 0         0 # $1 $2 $3 $4 $5 $6
3582 3         12 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3583             my @tr = ($tr_variable,$2);
3584             return e_tr(@tr,'',$4,$6);
3585 3         12 }
3586             }
3587             die __FILE__, ": Transliteration pattern not terminated\n";
3588             }
3589             }
3590              
3591 0         0 # qq//
3592             elsif (/\G \b (qq) \b /oxgc) {
3593             my $ope = $1;
3594 2180 50       5100  
3595 2180         4260 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3596 0         0 if (/\G (\#) /oxgc) { # qq# #
3597 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3598 0         0 while (not /\G \z/oxgc) {
3599 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3600 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3601             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3602 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3603             }
3604             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3605             }
3606 0         0  
3607 2180         2904 else {
3608 2180 50       5123 my $e = '';
  2180 50       8057  
    100          
    50          
    50          
    0          
3609             while (not /\G \z/oxgc) {
3610             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3611              
3612 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3613 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3614 0         0 my $qq_string = '';
3615 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3616 0         0 while (not /\G \z/oxgc) {
3617 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3618             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3619 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3620 0         0 elsif (/\G (\)) /oxgc) {
3621             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3622 0         0 else { $qq_string .= $1; }
3623             }
3624 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3625             }
3626             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3627             }
3628              
3629 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3630 2150         2906 elsif (/\G (\{) /oxgc) { # qq { }
3631 2150         3176 my $qq_string = '';
3632 2150 100       4299 local $nest = 1;
  84006 50       260164  
    100          
    100          
    50          
3633 722         1377 while (not /\G \z/oxgc) {
3634 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         1595  
3635             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3636 1153 100       2053 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         5015  
3637 2150         4275 elsif (/\G (\}) /oxgc) {
3638             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3639 1153         2627 else { $qq_string .= $1; }
3640             }
3641 78828         153027 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3642             }
3643             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3644             }
3645              
3646 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3647 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3648 0         0 my $qq_string = '';
3649 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3650 0         0 while (not /\G \z/oxgc) {
3651 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3652             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3653 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3654 0         0 elsif (/\G (\]) /oxgc) {
3655             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3656 0         0 else { $qq_string .= $1; }
3657             }
3658 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3659             }
3660             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3661             }
3662              
3663 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3664 30         124 elsif (/\G (\<) /oxgc) { # qq < >
3665 30         58 my $qq_string = '';
3666 30 100       110 local $nest = 1;
  1166 50       4588  
    50          
    100          
    50          
3667 22         52 while (not /\G \z/oxgc) {
3668 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3669             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3670 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         67  
3671 30         76 elsif (/\G (\>) /oxgc) {
3672             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3673 0         0 else { $qq_string .= $1; }
3674             }
3675 1114         2161 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3676             }
3677             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3678             }
3679              
3680 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3681 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3682 0         0 my $delimiter = $1;
3683 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3684 0         0 while (not /\G \z/oxgc) {
3685 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3686 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3687             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3688 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3689             }
3690             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3691 0         0 }
3692             }
3693             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3694             }
3695             }
3696              
3697 0         0 # qr//
3698 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3699 0         0 my $ope = $1;
3700             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3701             return e_qr($ope,$1,$3,$2,$4);
3702 0         0 }
3703 0         0 else {
3704 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3705 0         0 while (not /\G \z/oxgc) {
3706 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3707 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3708 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3709 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3710 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3711 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3712             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3713 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3714             }
3715             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3716             }
3717             }
3718              
3719 0         0 # qw//
3720 16 50       47 elsif (/\G \b (qw) \b /oxgc) {
3721 16         77 my $ope = $1;
3722             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3723             return e_qw($ope,$1,$3,$2);
3724 0         0 }
3725 16         30 else {
3726 16 50       52 my $e = '';
  16 50       97  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3727             while (not /\G \z/oxgc) {
3728 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3729 16         56  
3730             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3731 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3732 0         0  
3733             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3734 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3735 0         0  
3736             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3737 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3738 0         0  
3739             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3740 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3741 0         0  
3742             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3743 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3744             }
3745             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3746             }
3747             }
3748              
3749 0         0 # qx//
3750 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3751 0         0 my $ope = $1;
3752             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3753             return e_qq($ope,$1,$3,$2);
3754 0         0 }
3755 0         0 else {
3756 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3757 0         0 while (not /\G \z/oxgc) {
3758 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3759 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3760 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3761 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3762 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3763             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3764 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3765             }
3766             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3767             }
3768             }
3769              
3770 0         0 # q//
3771             elsif (/\G \b (q) \b /oxgc) {
3772             my $ope = $1;
3773              
3774             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3775              
3776             # avoid "Error: Runtime exception" of perl version 5.005_03
3777 410 50       2407 # (and so on)
3778 410         1059  
3779 0         0 if (/\G (\#) /oxgc) { # q# #
3780 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3781 0         0 while (not /\G \z/oxgc) {
3782 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3783 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3784             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3785 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3786             }
3787             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3788             }
3789 0         0  
3790 410         715 else {
3791 410 50       1286 my $e = '';
  410 50       2379  
    100          
    50          
    100          
    50          
3792             while (not /\G \z/oxgc) {
3793             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3794              
3795 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3796 0         0 elsif (/\G (\() /oxgc) { # q ( )
3797 0         0 my $q_string = '';
3798 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3799 0         0 while (not /\G \z/oxgc) {
3800 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3801 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3802             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3803 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3804 0         0 elsif (/\G (\)) /oxgc) {
3805             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3806 0         0 else { $q_string .= $1; }
3807             }
3808 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3809             }
3810             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3811             }
3812              
3813 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3814 404         728 elsif (/\G (\{) /oxgc) { # q { }
3815 404         641 my $q_string = '';
3816 404 50       1113 local $nest = 1;
  6770 50       25639  
    50          
    100          
    100          
    50          
3817 0         0 while (not /\G \z/oxgc) {
3818 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3819 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         163  
3820             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3821 107 100       220 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         1151  
3822 404         1074 elsif (/\G (\}) /oxgc) {
3823             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3824 107         213 else { $q_string .= $1; }
3825             }
3826 6152         11591 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3827             }
3828             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3829             }
3830              
3831 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3832 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3833 0         0 my $q_string = '';
3834 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3835 0         0 while (not /\G \z/oxgc) {
3836 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3837 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3838             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3839 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3840 0         0 elsif (/\G (\]) /oxgc) {
3841             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3842 0         0 else { $q_string .= $1; }
3843             }
3844 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3845             }
3846             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3847             }
3848              
3849 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3850 5         14 elsif (/\G (\<) /oxgc) { # q < >
3851 5         10 my $q_string = '';
3852 5 50       20 local $nest = 1;
  88 50       680  
    50          
    50          
    100          
    50          
3853 0         0 while (not /\G \z/oxgc) {
3854 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3855 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3856             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3857 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         15  
3858 5         14 elsif (/\G (\>) /oxgc) {
3859             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3860 0         0 else { $q_string .= $1; }
3861             }
3862 83         163 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3863             }
3864             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3865             }
3866              
3867 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3868 1         3 elsif (/\G (\S) /oxgc) { # q * *
3869 1         3 my $delimiter = $1;
3870 1 50       4 my $q_string = '';
  14 50       165  
    100          
    50          
3871 0         0 while (not /\G \z/oxgc) {
3872 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3873 1         3 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3874             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3875 13         31 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3876             }
3877             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3878 0         0 }
3879             }
3880             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3881             }
3882             }
3883              
3884 0         0 # m//
3885 209 50       585 elsif (/\G \b (m) \b /oxgc) {
3886 209         1358 my $ope = $1;
3887             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3888             return e_qr($ope,$1,$3,$2,$4);
3889 0         0 }
3890 209         434 else {
3891 209 50       585 my $e = '';
  209 50       11557  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3892 0         0 while (not /\G \z/oxgc) {
3893 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3894 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3895 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3896 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3897 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3898 10         32 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3899 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3900             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3901 199         718 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3902             }
3903             die __FILE__, ": Search pattern not terminated\n";
3904             }
3905             }
3906              
3907             # s///
3908              
3909             # about [cegimosxpradlunbB]* (/cg modifier)
3910             #
3911             # P.67 Pattern-Matching Operators
3912             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3913 0         0  
3914             elsif (/\G \b (s) \b /oxgc) {
3915             my $ope = $1;
3916 97 100       250  
3917 97         1781 # $1 $2 $3 $4 $5 $6
3918             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3919             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3920 1         5 }
3921 96         174 else {
3922 96 50       322 my $e = '';
  96 50       12222  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3923             while (not /\G \z/oxgc) {
3924 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3925 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3926 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3927             while (not /\G \z/oxgc) {
3928 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3929 0         0 # $1 $2 $3 $4
3930 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3931 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3932 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3933 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([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 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3936 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3937             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3938 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3939             }
3940             die __FILE__, ": Substitution replacement not terminated\n";
3941 0         0 }
3942 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3943 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3944             while (not /\G \z/oxgc) {
3945 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3946 0         0 # $1 $2 $3 $4
3947 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3948 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3949 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3950 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3951 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3952 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3953 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3954             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3955 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3956             }
3957             die __FILE__, ": Substitution replacement not terminated\n";
3958 0         0 }
3959 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3960 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3961             while (not /\G \z/oxgc) {
3962 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3963 0         0 # $1 $2 $3 $4
3964 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3965 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3966 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3967 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3968 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3969             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3970 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3971             }
3972             die __FILE__, ": Substitution replacement not terminated\n";
3973 0         0 }
3974 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3975 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3976             while (not /\G \z/oxgc) {
3977 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3978 0         0 # $1 $2 $3 $4
3979 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3980 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3981 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3982 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3983 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3984 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3985 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3986             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3987 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3988             }
3989             die __FILE__, ": Substitution replacement not terminated\n";
3990             }
3991 0         0 # $1 $2 $3 $4 $5 $6
3992             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3993             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3994             }
3995 21         59 # $1 $2 $3 $4 $5 $6
3996             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3997             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3998             }
3999 0         0 # $1 $2 $3 $4 $5 $6
4000             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4001             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4002             }
4003 0         0 # $1 $2 $3 $4 $5 $6
4004             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4005             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4006 75         382 }
4007             }
4008             die __FILE__, ": Substitution pattern not terminated\n";
4009             }
4010             }
4011 0         0  
4012 0         0 # require ignore module
4013 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
4014             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
4015             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4016 0         0  
4017 37         302 # use strict; --> use strict; no strict qw(refs);
4018 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4019             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4020             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4021              
4022 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
4023 2         23 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4024             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4025             return "use $1; no strict qw(refs);";
4026 0         0 }
4027             else {
4028             return "use $1;";
4029             }
4030 2 0 0     11 }
      0        
4031 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4032             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4033             return "use $1; no strict qw(refs);";
4034 0         0 }
4035             else {
4036             return "use $1;";
4037             }
4038             }
4039 0         0  
4040 2         14 # ignore use module
4041 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4042             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4043             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4044 0         0  
4045 0         0 # ignore no module
4046 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4047             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4048             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4049 0         0  
4050             # use else
4051             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4052 0         0  
4053             # use else
4054             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4055              
4056 2         8 # ''
4057 848         1957 elsif (/\G (?
4058 848 100       2548 my $q_string = '';
  8254 100       26186  
    100          
    50          
4059 4         11 while (not /\G \z/oxgc) {
4060 48         100 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4061 848         2375 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4062             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4063 7354         15203 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4064             }
4065             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4066             }
4067              
4068 0         0 # ""
4069 1790         3507 elsif (/\G (\") /oxgc) {
4070 1790 100       4334 my $qq_string = '';
  35119 100       98904  
    100          
    50          
4071 67         157 while (not /\G \z/oxgc) {
4072 12         25 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4073 1790         3912 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4074             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4075 33250         66090 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4076             }
4077             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4078             }
4079              
4080 0         0 # ``
4081 1         5 elsif (/\G (\`) /oxgc) {
4082 1 50       4 my $qx_string = '';
  19 50       69  
    100          
    50          
4083 0         0 while (not /\G \z/oxgc) {
4084 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4085 1         4 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4086             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4087 18         36 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4088             }
4089             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4090             }
4091              
4092 0         0 # // --- not divide operator (num / num), not defined-or
4093 453         1463 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4094 453 50       1302 my $regexp = '';
  4496 50       15192  
    100          
    50          
4095 0         0 while (not /\G \z/oxgc) {
4096 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4097 453         1613 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4098             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4099 4043         8076 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4100             }
4101             die __FILE__, ": Search pattern not terminated\n";
4102             }
4103              
4104 0         0 # ?? --- not conditional operator (condition ? then : else)
4105 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4106 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4107 0         0 while (not /\G \z/oxgc) {
4108 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4109 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4110             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4111 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4112             }
4113             die __FILE__, ": Search pattern not terminated\n";
4114             }
4115 0         0  
  0         0  
4116             # <<>> (a safer ARGV)
4117             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4118 0         0  
  0         0  
4119             # << (bit shift) --- not here document
4120             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4121              
4122 0         0 # <<~'HEREDOC'
4123 6         45 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4124 6         11 $slash = 'm//';
4125             my $here_quote = $1;
4126             my $delimiter = $2;
4127 6 50       9  
4128 6         11 # get here document
4129 6         28 if ($here_script eq '') {
4130             $here_script = CORE::substr $_, pos $_;
4131 6 50       30 $here_script =~ s/.*?\n//oxm;
4132 6         61 }
4133 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4134 6         8 my $heredoc = $1;
4135 6         46 my $indent = $2;
4136 6         16 $heredoc =~ s{^$indent}{}msg; # no /ox
4137             push @heredoc, $heredoc . qq{\n$delimiter\n};
4138             push @heredoc_delimiter, qq{\\s*$delimiter};
4139 6         13 }
4140             else {
4141 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4142             }
4143             return qq{<<'$delimiter'};
4144             }
4145              
4146             # <<~\HEREDOC
4147              
4148             # P.66 2.6.6. "Here" Documents
4149             # in Chapter 2: Bits and Pieces
4150             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4151              
4152             # P.73 "Here" Documents
4153             # in Chapter 2: Bits and Pieces
4154             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4155 6         23  
4156 3         7 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4157 3         7 $slash = 'm//';
4158             my $here_quote = $1;
4159             my $delimiter = $2;
4160 3 50       6  
4161 3         8 # get here document
4162 3         21 if ($here_script eq '') {
4163             $here_script = CORE::substr $_, pos $_;
4164 3 50       17 $here_script =~ s/.*?\n//oxm;
4165 3         49 }
4166 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4167 3         6 my $heredoc = $1;
4168 3         36 my $indent = $2;
4169 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
4170             push @heredoc, $heredoc . qq{\n$delimiter\n};
4171             push @heredoc_delimiter, qq{\\s*$delimiter};
4172 3         6 }
4173             else {
4174 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4175             }
4176             return qq{<<\\$delimiter};
4177             }
4178              
4179 3         13 # <<~"HEREDOC"
4180 6         12 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4181 6         11 $slash = 'm//';
4182             my $here_quote = $1;
4183             my $delimiter = $2;
4184 6 50       9  
4185 6         12 # get here document
4186 6         27 if ($here_script eq '') {
4187             $here_script = CORE::substr $_, pos $_;
4188 6 50       33 $here_script =~ s/.*?\n//oxm;
4189 6         93 }
4190 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4191 6         7 my $heredoc = $1;
4192 6         143 my $indent = $2;
4193 6         18 $heredoc =~ s{^$indent}{}msg; # no /ox
4194             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4195             push @heredoc_delimiter, qq{\\s*$delimiter};
4196 6         15 }
4197             else {
4198 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4199             }
4200             return qq{<<"$delimiter"};
4201             }
4202              
4203 6         25 # <<~HEREDOC
4204 3         15 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4205 3         7 $slash = 'm//';
4206             my $here_quote = $1;
4207             my $delimiter = $2;
4208 3 50       5  
4209 3         9 # get here document
4210 3         10 if ($here_script eq '') {
4211             $here_script = CORE::substr $_, pos $_;
4212 3 50       23 $here_script =~ s/.*?\n//oxm;
4213 3         40 }
4214 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4215 3         5 my $heredoc = $1;
4216 3         35 my $indent = $2;
4217 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
4218             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4219             push @heredoc_delimiter, qq{\\s*$delimiter};
4220 3         6 }
4221             else {
4222 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4223             }
4224             return qq{<<$delimiter};
4225             }
4226              
4227 3         15 # <<~`HEREDOC`
4228 6         13 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4229 6         9 $slash = 'm//';
4230             my $here_quote = $1;
4231             my $delimiter = $2;
4232 6 50       10  
4233 6         12 # get here document
4234 6         16 if ($here_script eq '') {
4235             $here_script = CORE::substr $_, pos $_;
4236 6 50       29 $here_script =~ s/.*?\n//oxm;
4237 6         53 }
4238 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4239 6         7 my $heredoc = $1;
4240 6         54 my $indent = $2;
4241 6         16 $heredoc =~ s{^$indent}{}msg; # no /ox
4242             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4243             push @heredoc_delimiter, qq{\\s*$delimiter};
4244 6         15 }
4245             else {
4246 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4247             }
4248             return qq{<<`$delimiter`};
4249             }
4250              
4251 6         22 # <<'HEREDOC'
4252 72         135 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4253 72         140 $slash = 'm//';
4254             my $here_quote = $1;
4255             my $delimiter = $2;
4256 72 50       140  
4257 72         138 # get here document
4258 72         343 if ($here_script eq '') {
4259             $here_script = CORE::substr $_, pos $_;
4260 72 50       380 $here_script =~ s/.*?\n//oxm;
4261 72         592 }
4262 72         257 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4263             push @heredoc, $1 . qq{\n$delimiter\n};
4264             push @heredoc_delimiter, $delimiter;
4265 72         114 }
4266             else {
4267 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4268             }
4269             return $here_quote;
4270             }
4271              
4272             # <<\HEREDOC
4273              
4274             # P.66 2.6.6. "Here" Documents
4275             # in Chapter 2: Bits and Pieces
4276             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4277              
4278             # P.73 "Here" Documents
4279             # in Chapter 2: Bits and Pieces
4280             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4281 72         265  
4282 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4283 0         0 $slash = 'm//';
4284             my $here_quote = $1;
4285             my $delimiter = $2;
4286 0 0       0  
4287 0         0 # get here document
4288 0         0 if ($here_script eq '') {
4289             $here_script = CORE::substr $_, pos $_;
4290 0 0       0 $here_script =~ s/.*?\n//oxm;
4291 0         0 }
4292 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4293             push @heredoc, $1 . qq{\n$delimiter\n};
4294             push @heredoc_delimiter, $delimiter;
4295 0         0 }
4296             else {
4297 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4298             }
4299             return $here_quote;
4300             }
4301              
4302 0         0 # <<"HEREDOC"
4303 36         80 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4304 36         82 $slash = 'm//';
4305             my $here_quote = $1;
4306             my $delimiter = $2;
4307 36 50       66  
4308 36         90 # get here document
4309 36         267 if ($here_script eq '') {
4310             $here_script = CORE::substr $_, pos $_;
4311 36 50       200 $here_script =~ s/.*?\n//oxm;
4312 36         524 }
4313 36         120 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4314             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4315             push @heredoc_delimiter, $delimiter;
4316 36         81 }
4317             else {
4318 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4319             }
4320             return $here_quote;
4321             }
4322              
4323 36         143 # <
4324 42         97 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4325 42         89 $slash = 'm//';
4326             my $here_quote = $1;
4327             my $delimiter = $2;
4328 42 50       75  
4329 42         130 # get here document
4330 42         301 if ($here_script eq '') {
4331             $here_script = CORE::substr $_, pos $_;
4332 42 50       429 $here_script =~ s/.*?\n//oxm;
4333 42         639 }
4334 42         141 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4335             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4336             push @heredoc_delimiter, $delimiter;
4337 42         91 }
4338             else {
4339 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4340             }
4341             return $here_quote;
4342             }
4343              
4344 42         197 # <<`HEREDOC`
4345 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4346 0         0 $slash = 'm//';
4347             my $here_quote = $1;
4348             my $delimiter = $2;
4349 0 0       0  
4350 0         0 # get here document
4351 0         0 if ($here_script eq '') {
4352             $here_script = CORE::substr $_, pos $_;
4353 0 0       0 $here_script =~ s/.*?\n//oxm;
4354 0         0 }
4355 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4356             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4357             push @heredoc_delimiter, $delimiter;
4358 0         0 }
4359             else {
4360 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4361             }
4362             return $here_quote;
4363             }
4364              
4365 0         0 # <<= <=> <= < operator
4366             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4367             return $1;
4368             }
4369              
4370 12         58 #
4371             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4372             return $1;
4373             }
4374              
4375             # --- glob
4376              
4377             # avoid "Error: Runtime exception" of perl version 5.005_03
4378 0         0  
4379             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4380             return 'Elatin3::glob("' . $1 . '")';
4381             }
4382 0         0  
4383             # __DATA__
4384             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4385 0         0  
4386             # __END__
4387             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4388              
4389             # \cD Control-D
4390              
4391             # P.68 2.6.8. Other Literal Tokens
4392             # in Chapter 2: Bits and Pieces
4393             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4394              
4395             # P.76 Other Literal Tokens
4396             # in Chapter 2: Bits and Pieces
4397 204         2079 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4398              
4399             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4400 0         0  
4401             # \cZ Control-Z
4402             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4403              
4404             # any operator before div
4405             elsif (/\G (
4406             -- | \+\+ |
4407 0         0 [\)\}\]]
  5081         10484  
4408              
4409             ) /oxgc) { $slash = 'div'; return $1; }
4410              
4411             # yada-yada or triple-dot operator
4412             elsif (/\G (
4413 5081         27003 \.\.\.
  7         13  
4414              
4415             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4416              
4417             # any operator before m//
4418              
4419             # //, //= (defined-or)
4420              
4421             # P.164 Logical Operators
4422             # in Chapter 10: More Control Structures
4423             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4424              
4425             # P.119 C-Style Logical (Short-Circuit) Operators
4426             # in Chapter 3: Unary and Binary Operators
4427             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4428              
4429             # (and so on)
4430              
4431             # ~~
4432              
4433             # P.221 The Smart Match Operator
4434             # in Chapter 15: Smart Matching and given-when
4435             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4436              
4437             # P.112 Smartmatch Operator
4438             # in Chapter 3: Unary and Binary Operators
4439             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4440              
4441             # (and so on)
4442              
4443             elsif (/\G ((?>
4444              
4445             !~~ | !~ | != | ! |
4446             %= | % |
4447             &&= | && | &= | &\.= | &\. | & |
4448             -= | -> | - |
4449             :(?>\s*)= |
4450             : |
4451             <<>> |
4452             <<= | <=> | <= | < |
4453             == | => | =~ | = |
4454             >>= | >> | >= | > |
4455             \*\*= | \*\* | \*= | \* |
4456             \+= | \+ |
4457             \.\. | \.= | \. |
4458             \/\/= | \/\/ |
4459             \/= | \/ |
4460             \? |
4461             \\ |
4462             \^= | \^\.= | \^\. | \^ |
4463             \b x= |
4464             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4465             ~~ | ~\. | ~ |
4466             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4467             \b(?: print )\b |
4468              
4469 7         77 [,;\(\{\[]
  8839         16586  
4470              
4471             )) /oxgc) { $slash = 'm//'; return $1; }
4472 8839         39103  
  15137         27786  
4473             # other any character
4474             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4475              
4476 15137         78428 # system error
4477             else {
4478             die __FILE__, ": Oops, this shouldn't happen!\n";
4479             }
4480             }
4481              
4482 0     1786 0 0 # escape Latin-3 string
4483 1786         4111 sub e_string {
4484             my($string) = @_;
4485 1786         2675 my $e_string = '';
4486              
4487             local $slash = 'm//';
4488              
4489             # P.1024 Appendix W.10 Multibyte Processing
4490             # of ISBN 1-56592-224-7 CJKV Information Processing
4491 1786         2624 # (and so on)
4492              
4493             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4494 1786 100 66     13649  
4495 1786 50       7828 # without { ... }
4496 1769         4351 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4497             if ($string !~ /<
4498             return $string;
4499             }
4500             }
4501 1769         4495  
4502 17 50       58 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          
4503             while ($string !~ /\G \z/oxgc) {
4504             if (0) {
4505             }
4506 190         11986  
4507 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Elatin3::PREMATCH()]}
4508 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4509             $e_string .= q{Elatin3::PREMATCH()};
4510             $slash = 'div';
4511             }
4512              
4513 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Elatin3::MATCH()]}
4514 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4515             $e_string .= q{Elatin3::MATCH()};
4516             $slash = 'div';
4517             }
4518              
4519 0         0 # $', ${'} --> $', ${'}
4520 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4521             $e_string .= $1;
4522             $slash = 'div';
4523             }
4524              
4525 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Elatin3::POSTMATCH()]}
4526 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4527             $e_string .= q{Elatin3::POSTMATCH()};
4528             $slash = 'div';
4529             }
4530              
4531 0         0 # bareword
4532 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4533             $e_string .= $1;
4534             $slash = 'div';
4535             }
4536              
4537 0         0 # $0 --> $0
4538 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4539             $e_string .= $1;
4540             $slash = 'div';
4541 0         0 }
4542 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4543             $e_string .= $1;
4544             $slash = 'div';
4545             }
4546              
4547 0         0 # $$ --> $$
4548 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4549             $e_string .= $1;
4550             $slash = 'div';
4551             }
4552              
4553             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4554 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4555 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4556             $e_string .= e_capture($1);
4557             $slash = 'div';
4558 0         0 }
4559 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4560             $e_string .= e_capture($1);
4561             $slash = 'div';
4562             }
4563              
4564 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4565 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4566             $e_string .= e_capture($1.'->'.$2);
4567             $slash = 'div';
4568             }
4569              
4570 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4571 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4572             $e_string .= e_capture($1.'->'.$2);
4573             $slash = 'div';
4574             }
4575              
4576 0         0 # $$foo
4577 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4578             $e_string .= e_capture($1);
4579             $slash = 'div';
4580             }
4581              
4582 0         0 # ${ foo }
4583 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4584             $e_string .= '${' . $1 . '}';
4585             $slash = 'div';
4586             }
4587              
4588 0         0 # ${ ... }
4589 3         12 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4590             $e_string .= e_capture($1);
4591             $slash = 'div';
4592             }
4593              
4594             # variable or function
4595 3         14 # $ @ % & * $ #
4596 7         19 elsif ($string =~ /\G ( (?: [\$\@\%\&\*] | \$\# | -> | \b sub \b) (?>\s*) (?: split | chop | index | rindex | lc | uc | fc | chr | ord | reverse | getc | tr | y | q | qq | qx | qw | m | s | qr | glob | lstat | opendir | stat | unlink | chdir ) ) \b /oxmsgc) {
4597             $e_string .= $1;
4598             $slash = 'div';
4599             }
4600             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4601 7         23 # $ @ # \ ' " / ? ( ) [ ] < >
4602 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4603             $e_string .= $1;
4604             $slash = 'div';
4605             }
4606 0         0  
  0         0  
4607 0         0 # subroutines of package Elatin3
  0         0  
4608 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4609 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4610 0         0 elsif ($string =~ /\G \b Latin3::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4611 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4612 0         0 elsif ($string =~ /\G \b Latin3::eval \b /oxgc) { $e_string .= 'eval Latin3::escape'; $slash = 'm//'; }
  0         0  
4613 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4614 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Elatin3::chop'; $slash = 'm//'; }
  0         0  
4615 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4616 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4617 0         0 elsif ($string =~ /\G \b Latin3::index \b /oxgc) { $e_string .= 'Latin3::index'; $slash = 'm//'; }
  0         0  
4618 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Elatin3::index'; $slash = 'm//'; }
  0         0  
4619 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4620 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4621 0         0 elsif ($string =~ /\G \b Latin3::rindex \b /oxgc) { $e_string .= 'Latin3::rindex'; $slash = 'm//'; }
  0         0  
4622 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Elatin3::rindex'; $slash = 'm//'; }
  0         0  
4623 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::lc'; $slash = 'm//'; }
  0         0  
4624 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::lcfirst'; $slash = 'm//'; }
  0         0  
4625 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::uc'; $slash = 'm//'; }
  0         0  
4626             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::ucfirst'; $slash = 'm//'; }
4627             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::fc'; $slash = 'm//'; }
4628 0         0  
  0         0  
4629 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4630 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4631 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  
4632 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  
4633 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  
4634 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  
4635             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
4636 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  
4637 0         0  
  0         0  
4638 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4639 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  
4640 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  
4641 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  
4642 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  
4643             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4644             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4645 0         0  
  0         0  
4646 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
4647 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4648 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4649             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
4650 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4651 0         0  
  0         0  
4652 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4653 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4654 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::chr'; $slash = 'm//'; }
  0         0  
4655 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4656 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4657 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::glob'; $slash = 'm//'; }
  0         0  
4658 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Elatin3::lc_'; $slash = 'm//'; }
  0         0  
4659 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Elatin3::lcfirst_'; $slash = 'm//'; }
  0         0  
4660 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Elatin3::uc_'; $slash = 'm//'; }
  0         0  
4661 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Elatin3::ucfirst_'; $slash = 'm//'; }
  0         0  
4662             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Elatin3::fc_'; $slash = 'm//'; }
4663 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4664 0         0  
  0         0  
4665 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4666 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4667 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Elatin3::chr_'; $slash = 'm//'; }
  0         0  
4668 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4669 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4670 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Elatin3::glob_'; $slash = 'm//'; }
  0         0  
4671             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
4672             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
4673 0         0 # split
4674             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4675 0         0 $slash = 'm//';
4676 0         0  
4677 0         0 my $e = '';
4678             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4679             $e .= $1;
4680             }
4681 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          
4682             # end of split
4683             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Elatin3::split' . $e; }
4684 0         0  
  0         0  
4685             # split scalar value
4686             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Elatin3::split' . $e . e_string($1); next E_STRING_LOOP; }
4687 0         0  
  0         0  
4688 0         0 # split literal space
  0         0  
4689 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4690 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4691 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4692 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4693 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4694 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4695 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4696 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4697 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4698 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4699 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4700 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4701             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {' '}; next E_STRING_LOOP; }
4702             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {" "}; next E_STRING_LOOP; }
4703              
4704 0 0       0 # split qq//
  0         0  
  0         0  
4705             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4706 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
4707 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4708 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4709 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4710 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  
4711 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  
4712 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  
4713 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  
4714             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
4715 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 * *
4716             }
4717             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4718             }
4719             }
4720              
4721 0 0       0 # split qr//
  0         0  
  0         0  
4722             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4723 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
4724 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4725 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4726 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4727 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  
4728 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  
4729 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  
4730 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  
4731 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  
4732             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
4733 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 * *
4734             }
4735             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4736             }
4737             }
4738              
4739 0 0       0 # split q//
  0         0  
  0         0  
4740             elsif ($string =~ /\G \b (q) \b /oxgc) {
4741 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
4742 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4743 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4744 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4745 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  
4746 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  
4747 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  
4748 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  
4749             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
4750 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 * *
4751             }
4752             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4753             }
4754             }
4755              
4756 0 0       0 # split m//
  0         0  
  0         0  
4757             elsif ($string =~ /\G \b (m) \b /oxgc) {
4758 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 # #
4759 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4760 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4761 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4762 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  
4763 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  
4764 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  
4765 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  
4766 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  
4767             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
4768 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 * *
4769             }
4770             die __FILE__, ": Search pattern not terminated\n";
4771             }
4772             }
4773              
4774 0         0 # split ''
4775 0         0 elsif ($string =~ /\G (\') /oxgc) {
4776 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
4777 0         0 while ($string !~ /\G \z/oxgc) {
4778 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
4779 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4780             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
4781 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4782             }
4783             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4784             }
4785              
4786 0         0 # split ""
4787 0         0 elsif ($string =~ /\G (\") /oxgc) {
4788 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
4789 0         0 while ($string !~ /\G \z/oxgc) {
4790 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
4791 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4792             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
4793 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4794             }
4795             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4796             }
4797              
4798 0         0 # split //
4799 0         0 elsif ($string =~ /\G (\/) /oxgc) {
4800 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4801 0         0 while ($string !~ /\G \z/oxgc) {
4802 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
4803 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4804             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
4805 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4806             }
4807             die __FILE__, ": Search pattern not terminated\n";
4808             }
4809             }
4810              
4811 0         0 # qq//
4812 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4813 0         0 my $ope = $1;
4814             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4815             $e_string .= e_qq($ope,$1,$3,$2);
4816 0         0 }
4817 0         0 else {
4818 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4819 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4820 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4821 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4822 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4823 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4824             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4825 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4826             }
4827             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4828             }
4829             }
4830              
4831 0         0 # qx//
4832 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4833 0         0 my $ope = $1;
4834             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4835             $e_string .= e_qq($ope,$1,$3,$2);
4836 0         0 }
4837 0         0 else {
4838 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4839 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4840 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4841 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4842 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4843 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4844 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4845             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4846 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4847             }
4848             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4849             }
4850             }
4851              
4852 0         0 # q//
4853 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4854 0         0 my $ope = $1;
4855             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4856             $e_string .= e_q($ope,$1,$3,$2);
4857 0         0 }
4858 0         0 else {
4859 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4860 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4861 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4862 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4863 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4864 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4865             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4866 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 * *
4867             }
4868             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4869             }
4870             }
4871 0         0  
4872             # ''
4873             elsif ($string =~ /\G (?
4874 0         0  
4875             # ""
4876             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4877 0         0  
4878             # ``
4879             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4880 0         0  
4881             # <<>> (a safer ARGV)
4882             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4883 0         0  
4884             # <<= <=> <= < operator
4885             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4886 0         0  
4887             #
4888             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4889              
4890 0         0 # --- glob
4891             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4892             $e_string .= 'Elatin3::glob("' . $1 . '")';
4893             }
4894              
4895 0         0 # << (bit shift) --- not here document
4896 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
4897             $slash = 'm//';
4898             $e_string .= $1;
4899             }
4900              
4901 0         0 # <<~'HEREDOC'
4902 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4903 0         0 $slash = 'm//';
4904             my $here_quote = $1;
4905             my $delimiter = $2;
4906 0 0       0  
4907 0         0 # get here document
4908 0         0 if ($here_script eq '') {
4909             $here_script = CORE::substr $_, pos $_;
4910 0 0       0 $here_script =~ s/.*?\n//oxm;
4911 0         0 }
4912 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4913 0         0 my $heredoc = $1;
4914 0         0 my $indent = $2;
4915 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4916             push @heredoc, $heredoc . qq{\n$delimiter\n};
4917             push @heredoc_delimiter, qq{\\s*$delimiter};
4918 0         0 }
4919             else {
4920 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4921             }
4922             $e_string .= qq{<<'$delimiter'};
4923             }
4924              
4925 0         0 # <<~\HEREDOC
4926 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4927 0         0 $slash = 'm//';
4928             my $here_quote = $1;
4929             my $delimiter = $2;
4930 0 0       0  
4931 0         0 # get here document
4932 0         0 if ($here_script eq '') {
4933             $here_script = CORE::substr $_, pos $_;
4934 0 0       0 $here_script =~ s/.*?\n//oxm;
4935 0         0 }
4936 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4937 0         0 my $heredoc = $1;
4938 0         0 my $indent = $2;
4939 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4940             push @heredoc, $heredoc . qq{\n$delimiter\n};
4941             push @heredoc_delimiter, qq{\\s*$delimiter};
4942 0         0 }
4943             else {
4944 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4945             }
4946             $e_string .= qq{<<\\$delimiter};
4947             }
4948              
4949 0         0 # <<~"HEREDOC"
4950 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4951 0         0 $slash = 'm//';
4952             my $here_quote = $1;
4953             my $delimiter = $2;
4954 0 0       0  
4955 0         0 # get here document
4956 0         0 if ($here_script eq '') {
4957             $here_script = CORE::substr $_, pos $_;
4958 0 0       0 $here_script =~ s/.*?\n//oxm;
4959 0         0 }
4960 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4961 0         0 my $heredoc = $1;
4962 0         0 my $indent = $2;
4963 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4964             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4965             push @heredoc_delimiter, qq{\\s*$delimiter};
4966 0         0 }
4967             else {
4968 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4969             }
4970             $e_string .= qq{<<"$delimiter"};
4971             }
4972              
4973 0         0 # <<~HEREDOC
4974 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4975 0         0 $slash = 'm//';
4976             my $here_quote = $1;
4977             my $delimiter = $2;
4978 0 0       0  
4979 0         0 # get here document
4980 0         0 if ($here_script eq '') {
4981             $here_script = CORE::substr $_, pos $_;
4982 0 0       0 $here_script =~ s/.*?\n//oxm;
4983 0         0 }
4984 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4985 0         0 my $heredoc = $1;
4986 0         0 my $indent = $2;
4987 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4988             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4989             push @heredoc_delimiter, qq{\\s*$delimiter};
4990 0         0 }
4991             else {
4992 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4993             }
4994             $e_string .= qq{<<$delimiter};
4995             }
4996              
4997 0         0 # <<~`HEREDOC`
4998 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4999 0         0 $slash = 'm//';
5000             my $here_quote = $1;
5001             my $delimiter = $2;
5002 0 0       0  
5003 0         0 # get here document
5004 0         0 if ($here_script eq '') {
5005             $here_script = CORE::substr $_, pos $_;
5006 0 0       0 $here_script =~ s/.*?\n//oxm;
5007 0         0 }
5008 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
5009 0         0 my $heredoc = $1;
5010 0         0 my $indent = $2;
5011 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
5012             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
5013             push @heredoc_delimiter, qq{\\s*$delimiter};
5014 0         0 }
5015             else {
5016 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5017             }
5018             $e_string .= qq{<<`$delimiter`};
5019             }
5020              
5021 0         0 # <<'HEREDOC'
5022 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
5023 0         0 $slash = 'm//';
5024             my $here_quote = $1;
5025             my $delimiter = $2;
5026 0 0       0  
5027 0         0 # get here document
5028 0         0 if ($here_script eq '') {
5029             $here_script = CORE::substr $_, pos $_;
5030 0 0       0 $here_script =~ s/.*?\n//oxm;
5031 0         0 }
5032 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5033             push @heredoc, $1 . qq{\n$delimiter\n};
5034             push @heredoc_delimiter, $delimiter;
5035 0         0 }
5036             else {
5037 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5038             }
5039             $e_string .= $here_quote;
5040             }
5041              
5042 0         0 # <<\HEREDOC
5043 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5044 0         0 $slash = 'm//';
5045             my $here_quote = $1;
5046             my $delimiter = $2;
5047 0 0       0  
5048 0         0 # get here document
5049 0         0 if ($here_script eq '') {
5050             $here_script = CORE::substr $_, pos $_;
5051 0 0       0 $here_script =~ s/.*?\n//oxm;
5052 0         0 }
5053 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5054             push @heredoc, $1 . qq{\n$delimiter\n};
5055             push @heredoc_delimiter, $delimiter;
5056 0         0 }
5057             else {
5058 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5059             }
5060             $e_string .= $here_quote;
5061             }
5062              
5063 0         0 # <<"HEREDOC"
5064 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5065 0         0 $slash = 'm//';
5066             my $here_quote = $1;
5067             my $delimiter = $2;
5068 0 0       0  
5069 0         0 # get here document
5070 0         0 if ($here_script eq '') {
5071             $here_script = CORE::substr $_, pos $_;
5072 0 0       0 $here_script =~ s/.*?\n//oxm;
5073 0         0 }
5074 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5075             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5076             push @heredoc_delimiter, $delimiter;
5077 0         0 }
5078             else {
5079 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5080             }
5081             $e_string .= $here_quote;
5082             }
5083              
5084 0         0 # <
5085 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5086 0         0 $slash = 'm//';
5087             my $here_quote = $1;
5088             my $delimiter = $2;
5089 0 0       0  
5090 0         0 # get here document
5091 0         0 if ($here_script eq '') {
5092             $here_script = CORE::substr $_, pos $_;
5093 0 0       0 $here_script =~ s/.*?\n//oxm;
5094 0         0 }
5095 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5096             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5097             push @heredoc_delimiter, $delimiter;
5098 0         0 }
5099             else {
5100 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5101             }
5102             $e_string .= $here_quote;
5103             }
5104              
5105 0         0 # <<`HEREDOC`
5106 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5107 0         0 $slash = 'm//';
5108             my $here_quote = $1;
5109             my $delimiter = $2;
5110 0 0       0  
5111 0         0 # get here document
5112 0         0 if ($here_script eq '') {
5113             $here_script = CORE::substr $_, pos $_;
5114 0 0       0 $here_script =~ s/.*?\n//oxm;
5115 0         0 }
5116 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5117             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5118             push @heredoc_delimiter, $delimiter;
5119 0         0 }
5120             else {
5121 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5122             }
5123             $e_string .= $here_quote;
5124             }
5125              
5126             # any operator before div
5127             elsif ($string =~ /\G (
5128             -- | \+\+ |
5129 0         0 [\)\}\]]
  18         317  
5130              
5131             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
5132              
5133             # yada-yada or triple-dot operator
5134             elsif ($string =~ /\G (
5135 18         60 \.\.\.
  0         0  
5136              
5137             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
5138              
5139             # any operator before m//
5140             elsif ($string =~ /\G ((?>
5141              
5142             !~~ | !~ | != | ! |
5143             %= | % |
5144             &&= | && | &= | &\.= | &\. | & |
5145             -= | -> | - |
5146             :(?>\s*)= |
5147             : |
5148             <<>> |
5149             <<= | <=> | <= | < |
5150             == | => | =~ | = |
5151             >>= | >> | >= | > |
5152             \*\*= | \*\* | \*= | \* |
5153             \+= | \+ |
5154             \.\. | \.= | \. |
5155             \/\/= | \/\/ |
5156             \/= | \/ |
5157             \? |
5158             \\ |
5159             \^= | \^\.= | \^\. | \^ |
5160             \b x= |
5161             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
5162             ~~ | ~\. | ~ |
5163             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
5164             \b(?: print )\b |
5165              
5166 0         0 [,;\(\{\[]
  31         67  
5167              
5168             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
5169 31         106  
5170             # other any character
5171             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
5172              
5173 131         357 # system error
5174             else {
5175             die __FILE__, ": Oops, this shouldn't happen!\n";
5176             }
5177 0         0 }
5178              
5179             return $e_string;
5180             }
5181              
5182             #
5183             # character class
5184 17     1919 0 79 #
5185             sub character_class {
5186 1919 100       3423 my($char,$modifier) = @_;
5187 1919 100       2845  
5188 52         103 if ($char eq '.') {
5189             if ($modifier =~ /s/) {
5190             return '${Elatin3::dot_s}';
5191 17         37 }
5192             else {
5193             return '${Elatin3::dot}';
5194             }
5195 35         70 }
5196             else {
5197             return Elatin3::classic_character_class($char);
5198             }
5199             }
5200              
5201             #
5202             # escape capture ($1, $2, $3, ...)
5203             #
5204 1867     212 0 4030 sub e_capture {
5205              
5206             return join '', '${', $_[0], '}';
5207             }
5208              
5209             #
5210             # escape transliteration (tr/// or y///)
5211 212     3 0 781 #
5212 3         38 sub e_tr {
5213 3   50     8 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
5214             my $e_tr = '';
5215 3         7 $modifier ||= '';
5216              
5217             $slash = 'div';
5218 3         6  
5219             # quote character class 1
5220             $charclass = q_tr($charclass);
5221 3         6  
5222             # quote character class 2
5223             $charclass2 = q_tr($charclass2);
5224 3 50       8  
5225 3 0       12 # /b /B modifier
5226 0         0 if ($modifier =~ tr/bB//d) {
5227             if ($variable eq '') {
5228             $e_tr = qq{tr$charclass$e$charclass2$modifier};
5229 0         0 }
5230             else {
5231             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
5232             }
5233 0 100       0 }
5234 3         14 else {
5235             if ($variable eq '') {
5236             $e_tr = qq{Elatin3::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
5237 2         9 }
5238             else {
5239             $e_tr = qq{Elatin3::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
5240             }
5241             }
5242 1         6  
5243 3         5 # clear tr/// variable
5244             $tr_variable = '';
5245 3         5 $bind_operator = '';
5246              
5247             return $e_tr;
5248             }
5249              
5250             #
5251             # quote for escape transliteration (tr/// or y///)
5252 3     6 0 16 #
5253             sub q_tr {
5254             my($charclass) = @_;
5255 6 50       9  
    0          
    0          
    0          
    0          
    0          
5256 6         15 # quote character class
5257             if ($charclass !~ /'/oxms) {
5258             return e_q('', "'", "'", $charclass); # --> q' '
5259 6         10 }
5260             elsif ($charclass !~ /\//oxms) {
5261             return e_q('q', '/', '/', $charclass); # --> q/ /
5262 0         0 }
5263             elsif ($charclass !~ /\#/oxms) {
5264             return e_q('q', '#', '#', $charclass); # --> q# #
5265 0         0 }
5266             elsif ($charclass !~ /[\<\>]/oxms) {
5267             return e_q('q', '<', '>', $charclass); # --> q< >
5268 0         0 }
5269             elsif ($charclass !~ /[\(\)]/oxms) {
5270             return e_q('q', '(', ')', $charclass); # --> q( )
5271 0         0 }
5272             elsif ($charclass !~ /[\{\}]/oxms) {
5273             return e_q('q', '{', '}', $charclass); # --> q{ }
5274 0         0 }
5275 0 0       0 else {
5276 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5277             if ($charclass !~ /\Q$char\E/xms) {
5278             return e_q('q', $char, $char, $charclass);
5279             }
5280             }
5281 0         0 }
5282              
5283             return e_q('q', '{', '}', $charclass);
5284             }
5285              
5286             #
5287             # escape q string (q//, '')
5288 0     1264 0 0 #
5289             sub e_q {
5290 1264         3129 my($ope,$delimiter,$end_delimiter,$string) = @_;
5291              
5292 1264         1775 $slash = 'div';
5293              
5294             return join '', $ope, $delimiter, $string, $end_delimiter;
5295             }
5296              
5297             #
5298             # escape qq string (qq//, "", qx//, ``)
5299 1264     4052 0 17890 #
5300             sub e_qq {
5301 4052         9422 my($ope,$delimiter,$end_delimiter,$string) = @_;
5302              
5303 4052         5535 $slash = 'div';
5304 4052         4874  
5305             my $left_e = 0;
5306             my $right_e = 0;
5307 4052         4352  
5308             # split regexp
5309             my @char = $string =~ /\G((?>
5310             [^\\\$] |
5311             \\x\{ (?>[0-9A-Fa-f]+) \} |
5312             \\o\{ (?>[0-7]+) \} |
5313             \\N\{ (?>[^0-9\}][^\}]*) \} |
5314             \\ $q_char |
5315             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5316             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5317             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5318             \$ (?>\s* [0-9]+) |
5319             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5320             \$ \$ (?![\w\{]) |
5321             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5322             $q_char
5323 4052         134326 ))/oxmsg;
5324              
5325             for (my $i=0; $i <= $#char; $i++) {
5326 4052 50 33     13714  
    50 33        
    100          
    100          
    50          
5327 113799         388262 # "\L\u" --> "\u\L"
5328             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5329             @char[$i,$i+1] = @char[$i+1,$i];
5330             }
5331              
5332 0         0 # "\U\l" --> "\l\U"
5333             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5334             @char[$i,$i+1] = @char[$i+1,$i];
5335             }
5336              
5337 0         0 # octal escape sequence
5338             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5339             $char[$i] = Elatin3::octchr($1);
5340             }
5341              
5342 1         5 # hexadecimal escape sequence
5343             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5344             $char[$i] = Elatin3::hexchr($1);
5345             }
5346              
5347 1         4 # \N{CHARNAME} --> N{CHARNAME}
5348             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5349             $char[$i] = $1;
5350 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          
5351              
5352             if (0) {
5353             }
5354              
5355             # \F
5356             #
5357             # P.69 Table 2-6. Translation escapes
5358             # in Chapter 2: Bits and Pieces
5359             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5360             # (and so on)
5361 113799         904835  
5362 0 50       0 # \u \l \U \L \F \Q \E
5363 484         1170 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5364             if ($right_e < $left_e) {
5365             $char[$i] = '\\' . $char[$i];
5366             }
5367             }
5368             elsif ($char[$i] eq '\u') {
5369              
5370             # "STRING @{[ LIST EXPR ]} MORE STRING"
5371              
5372             # P.257 Other Tricks You Can Do with Hard References
5373             # in Chapter 8: References
5374             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5375              
5376             # P.353 Other Tricks You Can Do with Hard References
5377             # in Chapter 8: References
5378             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5379              
5380 0         0 # (and so on)
5381 0         0  
5382             $char[$i] = '@{[Elatin3::ucfirst qq<';
5383             $left_e++;
5384 0         0 }
5385 0         0 elsif ($char[$i] eq '\l') {
5386             $char[$i] = '@{[Elatin3::lcfirst qq<';
5387             $left_e++;
5388 0         0 }
5389 0         0 elsif ($char[$i] eq '\U') {
5390             $char[$i] = '@{[Elatin3::uc qq<';
5391             $left_e++;
5392 0         0 }
5393 0         0 elsif ($char[$i] eq '\L') {
5394             $char[$i] = '@{[Elatin3::lc qq<';
5395             $left_e++;
5396 0         0 }
5397 24         35 elsif ($char[$i] eq '\F') {
5398             $char[$i] = '@{[Elatin3::fc qq<';
5399             $left_e++;
5400 24         66 }
5401 0         0 elsif ($char[$i] eq '\Q') {
5402             $char[$i] = '@{[CORE::quotemeta qq<';
5403             $left_e++;
5404 0 50       0 }
5405 24         39 elsif ($char[$i] eq '\E') {
5406 24         34 if ($right_e < $left_e) {
5407             $char[$i] = '>]}';
5408             $right_e++;
5409 24         42 }
5410             else {
5411             $char[$i] = '';
5412             }
5413 0         0 }
5414 0 0       0 elsif ($char[$i] eq '\Q') {
5415 0         0 while (1) {
5416             if (++$i > $#char) {
5417 0 0       0 last;
5418 0         0 }
5419             if ($char[$i] eq '\E') {
5420             last;
5421             }
5422             }
5423             }
5424             elsif ($char[$i] eq '\E') {
5425             }
5426              
5427             # $0 --> $0
5428             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5429             }
5430             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5431             }
5432              
5433             # $$ --> $$
5434             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5435             }
5436              
5437             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5438 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5439             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5440             $char[$i] = e_capture($1);
5441 205         365 }
5442             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5443             $char[$i] = e_capture($1);
5444             }
5445              
5446 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5447             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5448             $char[$i] = e_capture($1.'->'.$2);
5449             }
5450              
5451 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5452             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5453             $char[$i] = e_capture($1.'->'.$2);
5454             }
5455              
5456 0         0 # $$foo
5457             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5458             $char[$i] = e_capture($1);
5459             }
5460              
5461 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
5462             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5463             $char[$i] = '@{[Elatin3::PREMATCH()]}';
5464             }
5465              
5466 44         130 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
5467             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5468             $char[$i] = '@{[Elatin3::MATCH()]}';
5469             }
5470              
5471 45         124 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
5472             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5473             $char[$i] = '@{[Elatin3::POSTMATCH()]}';
5474             }
5475              
5476             # ${ foo } --> ${ foo }
5477             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5478             }
5479              
5480 33         88 # ${ ... }
5481             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5482             $char[$i] = e_capture($1);
5483             }
5484             }
5485 0 50       0  
5486 4052         8576 # return string
5487             if ($left_e > $right_e) {
5488 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5489             }
5490             return join '', $ope, $delimiter, @char, $end_delimiter;
5491             }
5492              
5493             #
5494             # escape qw string (qw//)
5495 4052     16 0 34784 #
5496             sub e_qw {
5497 16         82 my($ope,$delimiter,$end_delimiter,$string) = @_;
5498              
5499             $slash = 'div';
5500 16         33  
  16         214  
5501 483 50       813 # choice again delimiter
    0          
    0          
    0          
    0          
5502 16         103 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5503             if (not $octet{$end_delimiter}) {
5504             return join '', $ope, $delimiter, $string, $end_delimiter;
5505 16         127 }
5506             elsif (not $octet{')'}) {
5507             return join '', $ope, '(', $string, ')';
5508 0         0 }
5509             elsif (not $octet{'}'}) {
5510             return join '', $ope, '{', $string, '}';
5511 0         0 }
5512             elsif (not $octet{']'}) {
5513             return join '', $ope, '[', $string, ']';
5514 0         0 }
5515             elsif (not $octet{'>'}) {
5516             return join '', $ope, '<', $string, '>';
5517 0         0 }
5518 0 0       0 else {
5519 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5520             if (not $octet{$char}) {
5521             return join '', $ope, $char, $string, $char;
5522             }
5523             }
5524             }
5525 0         0  
5526 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5527 0         0 my @string = CORE::split(/\s+/, $string);
5528 0         0 for my $string (@string) {
5529 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5530 0         0 for my $octet (@octet) {
5531             if ($octet =~ /\A (['\\]) \z/oxms) {
5532             $octet = '\\' . $1;
5533 0         0 }
5534             }
5535 0         0 $string = join '', @octet;
  0         0  
5536             }
5537             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5538             }
5539              
5540             #
5541             # escape here document (<<"HEREDOC", <
5542 0     93 0 0 #
5543             sub e_heredoc {
5544 93         259 my($string) = @_;
5545              
5546 93         164 $slash = 'm//';
5547              
5548 93         321 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5549 93         145  
5550             my $left_e = 0;
5551             my $right_e = 0;
5552 93         126  
5553             # split regexp
5554             my @char = $string =~ /\G((?>
5555             [^\\\$] |
5556             \\x\{ (?>[0-9A-Fa-f]+) \} |
5557             \\o\{ (?>[0-7]+) \} |
5558             \\N\{ (?>[^0-9\}][^\}]*) \} |
5559             \\ $q_char |
5560             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5561             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5562             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5563             \$ (?>\s* [0-9]+) |
5564             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5565             \$ \$ (?![\w\{]) |
5566             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5567             $q_char
5568 93         8380 ))/oxmsg;
5569              
5570             for (my $i=0; $i <= $#char; $i++) {
5571 93 50 33     411  
    50 33        
    100          
    100          
    50          
5572 3177         9420 # "\L\u" --> "\u\L"
5573             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5574             @char[$i,$i+1] = @char[$i+1,$i];
5575             }
5576              
5577 0         0 # "\U\l" --> "\l\U"
5578             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5579             @char[$i,$i+1] = @char[$i+1,$i];
5580             }
5581              
5582 0         0 # octal escape sequence
5583             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5584             $char[$i] = Elatin3::octchr($1);
5585             }
5586              
5587 1         3 # hexadecimal escape sequence
5588             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5589             $char[$i] = Elatin3::hexchr($1);
5590             }
5591              
5592 1         4 # \N{CHARNAME} --> N{CHARNAME}
5593             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5594             $char[$i] = $1;
5595 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          
5596              
5597             if (0) {
5598             }
5599 3177         25098  
5600 0 0       0 # \u \l \U \L \F \Q \E
5601 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5602             if ($right_e < $left_e) {
5603             $char[$i] = '\\' . $char[$i];
5604             }
5605 0         0 }
5606 0         0 elsif ($char[$i] eq '\u') {
5607             $char[$i] = '@{[Elatin3::ucfirst qq<';
5608             $left_e++;
5609 0         0 }
5610 0         0 elsif ($char[$i] eq '\l') {
5611             $char[$i] = '@{[Elatin3::lcfirst qq<';
5612             $left_e++;
5613 0         0 }
5614 0         0 elsif ($char[$i] eq '\U') {
5615             $char[$i] = '@{[Elatin3::uc qq<';
5616             $left_e++;
5617 0         0 }
5618 0         0 elsif ($char[$i] eq '\L') {
5619             $char[$i] = '@{[Elatin3::lc qq<';
5620             $left_e++;
5621 0         0 }
5622 0         0 elsif ($char[$i] eq '\F') {
5623             $char[$i] = '@{[Elatin3::fc qq<';
5624             $left_e++;
5625 0         0 }
5626 0         0 elsif ($char[$i] eq '\Q') {
5627             $char[$i] = '@{[CORE::quotemeta qq<';
5628             $left_e++;
5629 0 0       0 }
5630 0         0 elsif ($char[$i] eq '\E') {
5631 0         0 if ($right_e < $left_e) {
5632             $char[$i] = '>]}';
5633             $right_e++;
5634 0         0 }
5635             else {
5636             $char[$i] = '';
5637             }
5638 0         0 }
5639 0 0       0 elsif ($char[$i] eq '\Q') {
5640 0         0 while (1) {
5641             if (++$i > $#char) {
5642 0 0       0 last;
5643 0         0 }
5644             if ($char[$i] eq '\E') {
5645             last;
5646             }
5647             }
5648             }
5649             elsif ($char[$i] eq '\E') {
5650             }
5651              
5652             # $0 --> $0
5653             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5654             }
5655             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5656             }
5657              
5658             # $$ --> $$
5659             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5660             }
5661              
5662             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5663 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5664             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5665             $char[$i] = e_capture($1);
5666 0         0 }
5667             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5668             $char[$i] = e_capture($1);
5669             }
5670              
5671 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5672             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5673             $char[$i] = e_capture($1.'->'.$2);
5674             }
5675              
5676 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5677             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5678             $char[$i] = e_capture($1.'->'.$2);
5679             }
5680              
5681 0         0 # $$foo
5682             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5683             $char[$i] = e_capture($1);
5684             }
5685              
5686 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
5687             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5688             $char[$i] = '@{[Elatin3::PREMATCH()]}';
5689             }
5690              
5691 8         55 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
5692             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5693             $char[$i] = '@{[Elatin3::MATCH()]}';
5694             }
5695              
5696 8         76 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
5697             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5698             $char[$i] = '@{[Elatin3::POSTMATCH()]}';
5699             }
5700              
5701             # ${ foo } --> ${ foo }
5702             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5703             }
5704              
5705 6         37 # ${ ... }
5706             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5707             $char[$i] = e_capture($1);
5708             }
5709             }
5710 0 50       0  
5711 93         206 # return string
5712             if ($left_e > $right_e) {
5713 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5714             }
5715             return join '', @char;
5716             }
5717              
5718             #
5719             # escape regexp (m//, qr//)
5720 93     652 0 733 #
5721 652   100     2894 sub e_qr {
5722             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5723 652         2930 $modifier ||= '';
5724 652 50       1445  
5725 652         1609 $modifier =~ tr/p//d;
5726 0         0 if ($modifier =~ /([adlu])/oxms) {
5727 0 0       0 my $line = 0;
5728 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5729 0         0 if ($filename ne __FILE__) {
5730             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5731             last;
5732 0         0 }
5733             }
5734             die qq{Unsupported modifier "$1" used at line $line.\n};
5735 0         0 }
5736              
5737             $slash = 'div';
5738 652 100       1039  
    100          
5739 652         2074 # literal null string pattern
5740 8         13 if ($string eq '') {
5741 8         12 $modifier =~ tr/bB//d;
5742             $modifier =~ tr/i//d;
5743             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5744             }
5745              
5746             # /b /B modifier
5747             elsif ($modifier =~ tr/bB//d) {
5748 8 50       38  
5749 2         8 # choice again delimiter
5750 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5751 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5752 0         0 my %octet = map {$_ => 1} @char;
5753 0         0 if (not $octet{')'}) {
5754             $delimiter = '(';
5755             $end_delimiter = ')';
5756 0         0 }
5757 0         0 elsif (not $octet{'}'}) {
5758             $delimiter = '{';
5759             $end_delimiter = '}';
5760 0         0 }
5761 0         0 elsif (not $octet{']'}) {
5762             $delimiter = '[';
5763             $end_delimiter = ']';
5764 0         0 }
5765 0         0 elsif (not $octet{'>'}) {
5766             $delimiter = '<';
5767             $end_delimiter = '>';
5768 0         0 }
5769 0 0       0 else {
5770 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5771 0         0 if (not $octet{$char}) {
5772 0         0 $delimiter = $char;
5773             $end_delimiter = $char;
5774             last;
5775             }
5776             }
5777             }
5778 0 50 33     0 }
5779 2         10  
5780             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5781             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5782 0         0 }
5783             else {
5784             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5785             }
5786 2 100       11 }
5787 642         1483  
5788             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5789             my $metachar = qr/[\@\\|[\]{^]/oxms;
5790 642         2402  
5791             # split regexp
5792             my @char = $string =~ /\G((?>
5793             [^\\\$\@\[\(] |
5794             \\x (?>[0-9A-Fa-f]{1,2}) |
5795             \\ (?>[0-7]{2,3}) |
5796             \\c [\x40-\x5F] |
5797             \\x\{ (?>[0-9A-Fa-f]+) \} |
5798             \\o\{ (?>[0-7]+) \} |
5799             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5800             \\ $q_char |
5801             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5802             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5803             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5804             [\$\@] $qq_variable |
5805             \$ (?>\s* [0-9]+) |
5806             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5807             \$ \$ (?![\w\{]) |
5808             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5809             \[\^ |
5810             \[\: (?>[a-z]+) :\] |
5811             \[\:\^ (?>[a-z]+) :\] |
5812             \(\? |
5813             $q_char
5814             ))/oxmsg;
5815 642 50       69668  
5816 642         2748 # choice again delimiter
  0         0  
5817 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5818 0         0 my %octet = map {$_ => 1} @char;
5819 0         0 if (not $octet{')'}) {
5820             $delimiter = '(';
5821             $end_delimiter = ')';
5822 0         0 }
5823 0         0 elsif (not $octet{'}'}) {
5824             $delimiter = '{';
5825             $end_delimiter = '}';
5826 0         0 }
5827 0         0 elsif (not $octet{']'}) {
5828             $delimiter = '[';
5829             $end_delimiter = ']';
5830 0         0 }
5831 0         0 elsif (not $octet{'>'}) {
5832             $delimiter = '<';
5833             $end_delimiter = '>';
5834 0         0 }
5835 0 0       0 else {
5836 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5837 0         0 if (not $octet{$char}) {
5838 0         0 $delimiter = $char;
5839             $end_delimiter = $char;
5840             last;
5841             }
5842             }
5843             }
5844 0         0 }
5845 642         1043  
5846 642         955 my $left_e = 0;
5847             my $right_e = 0;
5848             for (my $i=0; $i <= $#char; $i++) {
5849 642 50 66     1648  
    50 66        
    100          
    100          
    100          
    100          
5850 1872         10708 # "\L\u" --> "\u\L"
5851             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5852             @char[$i,$i+1] = @char[$i+1,$i];
5853             }
5854              
5855 0         0 # "\U\l" --> "\l\U"
5856             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5857             @char[$i,$i+1] = @char[$i+1,$i];
5858             }
5859              
5860 0         0 # octal escape sequence
5861             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5862             $char[$i] = Elatin3::octchr($1);
5863             }
5864              
5865 1         3 # hexadecimal escape sequence
5866             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5867             $char[$i] = Elatin3::hexchr($1);
5868             }
5869              
5870             # \b{...} --> b\{...}
5871             # \B{...} --> B\{...}
5872             # \N{CHARNAME} --> N\{CHARNAME}
5873             # \p{PROPERTY} --> p\{PROPERTY}
5874 1         3 # \P{PROPERTY} --> P\{PROPERTY}
5875             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5876             $char[$i] = $1 . '\\' . $2;
5877             }
5878              
5879 6         19 # \p, \P, \X --> p, P, X
5880             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5881             $char[$i] = $1;
5882 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          
5883              
5884             if (0) {
5885             }
5886 1872         5953  
5887 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5888 6         91 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5889             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)) {
5890             $char[$i] .= join '', splice @char, $i+1, 3;
5891 0         0 }
5892             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)) {
5893             $char[$i] .= join '', splice @char, $i+1, 2;
5894 0         0 }
5895             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)) {
5896             $char[$i] .= join '', splice @char, $i+1, 1;
5897             }
5898             }
5899              
5900 0         0 # open character class [...]
5901             elsif ($char[$i] eq '[') {
5902             my $left = $i;
5903              
5904             # [] make die "Unmatched [] in regexp ...\n"
5905 328 100       481 # (and so on)
5906 328         764  
5907             if ($char[$i+1] eq ']') {
5908             $i++;
5909 3         7 }
5910 328 50       516  
5911 1379         2292 while (1) {
5912             if (++$i > $#char) {
5913 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5914 1379         2831 }
5915             if ($char[$i] eq ']') {
5916             my $right = $i;
5917 328 100       414  
5918 328         2094 # [...]
  30         65  
5919             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5920             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin3::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5921 90         144 }
5922             else {
5923             splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
5924 298         1239 }
5925 328         574  
5926             $i = $left;
5927             last;
5928             }
5929             }
5930             }
5931              
5932 328         919 # open character class [^...]
5933             elsif ($char[$i] eq '[^') {
5934             my $left = $i;
5935              
5936             # [^] make die "Unmatched [] in regexp ...\n"
5937 74 100       91 # (and so on)
5938 74         158  
5939             if ($char[$i+1] eq ']') {
5940             $i++;
5941 4         7 }
5942 74 50       85  
5943 272         413 while (1) {
5944             if (++$i > $#char) {
5945 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5946 272         414 }
5947             if ($char[$i] eq ']') {
5948             my $right = $i;
5949 74 100       82  
5950 74         341 # [^...]
  30         76  
5951             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5952             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin3::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5953 90         159 }
5954             else {
5955             splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5956 44         166 }
5957 74         136  
5958             $i = $left;
5959             last;
5960             }
5961             }
5962             }
5963              
5964 74         186 # rewrite character class or escape character
5965             elsif (my $char = character_class($char[$i],$modifier)) {
5966             $char[$i] = $char;
5967             }
5968              
5969 139 50       351 # /i modifier
5970 20         36 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
5971             if (CORE::length(Elatin3::fc($char[$i])) == 1) {
5972             $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
5973 20         33 }
5974             else {
5975             $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
5976             }
5977             }
5978              
5979 0 50       0 # \u \l \U \L \F \Q \E
5980 1         3 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5981             if ($right_e < $left_e) {
5982             $char[$i] = '\\' . $char[$i];
5983             }
5984 0         0 }
5985 0         0 elsif ($char[$i] eq '\u') {
5986             $char[$i] = '@{[Elatin3::ucfirst qq<';
5987             $left_e++;
5988 0         0 }
5989 0         0 elsif ($char[$i] eq '\l') {
5990             $char[$i] = '@{[Elatin3::lcfirst qq<';
5991             $left_e++;
5992 0         0 }
5993 1         4 elsif ($char[$i] eq '\U') {
5994             $char[$i] = '@{[Elatin3::uc qq<';
5995             $left_e++;
5996 1         4 }
5997 1         3 elsif ($char[$i] eq '\L') {
5998             $char[$i] = '@{[Elatin3::lc qq<';
5999             $left_e++;
6000 1         3 }
6001 18         27 elsif ($char[$i] eq '\F') {
6002             $char[$i] = '@{[Elatin3::fc qq<';
6003             $left_e++;
6004 18         41 }
6005 1         3 elsif ($char[$i] eq '\Q') {
6006             $char[$i] = '@{[CORE::quotemeta qq<';
6007             $left_e++;
6008 1 50       2 }
6009 21         39 elsif ($char[$i] eq '\E') {
6010 21         29 if ($right_e < $left_e) {
6011             $char[$i] = '>]}';
6012             $right_e++;
6013 21         45 }
6014             else {
6015             $char[$i] = '';
6016             }
6017 0         0 }
6018 0 0       0 elsif ($char[$i] eq '\Q') {
6019 0         0 while (1) {
6020             if (++$i > $#char) {
6021 0 0       0 last;
6022 0         0 }
6023             if ($char[$i] eq '\E') {
6024             last;
6025             }
6026             }
6027             }
6028             elsif ($char[$i] eq '\E') {
6029             }
6030              
6031 0 0       0 # $0 --> $0
6032 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6033             if ($ignorecase) {
6034             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6035             }
6036 0 0       0 }
6037 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6038             if ($ignorecase) {
6039             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6040             }
6041             }
6042              
6043             # $$ --> $$
6044             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6045             }
6046              
6047             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6048 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6049 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6050 0         0 $char[$i] = e_capture($1);
6051             if ($ignorecase) {
6052             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6053             }
6054 0         0 }
6055 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6056 0         0 $char[$i] = e_capture($1);
6057             if ($ignorecase) {
6058             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6059             }
6060             }
6061              
6062 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6063 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) {
6064 0         0 $char[$i] = e_capture($1.'->'.$2);
6065             if ($ignorecase) {
6066             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6067             }
6068             }
6069              
6070 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6071 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) {
6072 0         0 $char[$i] = e_capture($1.'->'.$2);
6073             if ($ignorecase) {
6074             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6075             }
6076             }
6077              
6078 0         0 # $$foo
6079 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6080 0         0 $char[$i] = e_capture($1);
6081             if ($ignorecase) {
6082             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6083             }
6084             }
6085              
6086 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
6087 8         25 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6088             if ($ignorecase) {
6089             $char[$i] = '@{[Elatin3::ignorecase(Elatin3::PREMATCH())]}';
6090 0         0 }
6091             else {
6092             $char[$i] = '@{[Elatin3::PREMATCH()]}';
6093             }
6094             }
6095              
6096 8 50       28 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
6097 8         21 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6098             if ($ignorecase) {
6099             $char[$i] = '@{[Elatin3::ignorecase(Elatin3::MATCH())]}';
6100 0         0 }
6101             else {
6102             $char[$i] = '@{[Elatin3::MATCH()]}';
6103             }
6104             }
6105              
6106 8 50       24 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
6107 6         17 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6108             if ($ignorecase) {
6109             $char[$i] = '@{[Elatin3::ignorecase(Elatin3::POSTMATCH())]}';
6110 0         0 }
6111             else {
6112             $char[$i] = '@{[Elatin3::POSTMATCH()]}';
6113             }
6114             }
6115              
6116 6 0       16 # ${ foo }
6117 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) {
6118             if ($ignorecase) {
6119             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6120             }
6121             }
6122              
6123 0         0 # ${ ... }
6124 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6125 0         0 $char[$i] = e_capture($1);
6126             if ($ignorecase) {
6127             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6128             }
6129             }
6130              
6131 0         0 # $scalar or @array
6132 21 100       49 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6133 21         120 $char[$i] = e_string($char[$i]);
6134             if ($ignorecase) {
6135             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6136             }
6137             }
6138              
6139 11 100 33     36 # quote character before ? + * {
    50          
6140             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6141             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6142 138         1066 }
6143 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6144 0         0 my $char = $char[$i-1];
6145             if ($char[$i] eq '{') {
6146             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
6147 0         0 }
6148             else {
6149             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
6150             }
6151 0         0 }
6152             else {
6153             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6154             }
6155             }
6156             }
6157 127         591  
6158 642 50       1156 # make regexp string
6159 642 0 0     1402 $modifier =~ tr/i//d;
6160 0         0 if ($left_e > $right_e) {
6161             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6162             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
6163 0         0 }
6164             else {
6165             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6166 0 50 33     0 }
6167 642         3493 }
6168             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6169             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
6170 0         0 }
6171             else {
6172             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6173             }
6174             }
6175              
6176             #
6177             # double quote stuff
6178 642     180 0 5558 #
6179             sub qq_stuff {
6180             my($delimiter,$end_delimiter,$stuff) = @_;
6181 180 100       256  
6182 180         360 # scalar variable or array variable
6183             if ($stuff =~ /\A [\$\@] /oxms) {
6184             return $stuff;
6185             }
6186 100         326  
  80         193  
6187 80         225 # quote by delimiter
6188 80 50       187 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
6189 80 50       126 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6190 80 50       116 next if $char eq $delimiter;
6191 80         126 next if $char eq $end_delimiter;
6192             if (not $octet{$char}) {
6193             return join '', 'qq', $char, $stuff, $char;
6194 80         307 }
6195             }
6196             return join '', 'qq', '<', $stuff, '>';
6197             }
6198              
6199             #
6200             # escape regexp (m'', qr'', and m''b, qr''b)
6201 0     10 0 0 #
6202 10   50     42 sub e_qr_q {
6203             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6204 10         46 $modifier ||= '';
6205 10 50       13  
6206 10         23 $modifier =~ tr/p//d;
6207 0         0 if ($modifier =~ /([adlu])/oxms) {
6208 0 0       0 my $line = 0;
6209 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6210 0         0 if ($filename ne __FILE__) {
6211             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6212             last;
6213 0         0 }
6214             }
6215             die qq{Unsupported modifier "$1" used at line $line.\n};
6216 0         0 }
6217              
6218             $slash = 'div';
6219 10 100       14  
    50          
6220 10         24 # literal null string pattern
6221 8         11 if ($string eq '') {
6222 8         9 $modifier =~ tr/bB//d;
6223             $modifier =~ tr/i//d;
6224             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6225             }
6226              
6227 8         37 # with /b /B modifier
6228             elsif ($modifier =~ tr/bB//d) {
6229             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6230             }
6231              
6232 0         0 # without /b /B modifier
6233             else {
6234             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6235             }
6236             }
6237              
6238             #
6239             # escape regexp (m'', qr'')
6240 2     2 0 8 #
6241             sub e_qr_qt {
6242 2 50       8 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6243              
6244             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6245 2         6  
6246             # split regexp
6247             my @char = $string =~ /\G((?>
6248             [^\\\[\$\@\/] |
6249             [\x00-\xFF] |
6250             \[\^ |
6251             \[\: (?>[a-z]+) \:\] |
6252             \[\:\^ (?>[a-z]+) \:\] |
6253             [\$\@\/] |
6254             \\ (?:$q_char) |
6255             (?:$q_char)
6256             ))/oxmsg;
6257 2         63  
6258 2 50 33     10 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
6259             for (my $i=0; $i <= $#char; $i++) {
6260             if (0) {
6261             }
6262 2         15  
6263 0         0 # open character class [...]
6264 0 0       0 elsif ($char[$i] eq '[') {
6265 0         0 my $left = $i;
6266             if ($char[$i+1] eq ']') {
6267 0         0 $i++;
6268 0 0       0 }
6269 0         0 while (1) {
6270             if (++$i > $#char) {
6271 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6272 0         0 }
6273             if ($char[$i] eq ']') {
6274             my $right = $i;
6275 0         0  
6276             # [...]
6277 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
6278 0         0  
6279             $i = $left;
6280             last;
6281             }
6282             }
6283             }
6284              
6285 0         0 # open character class [^...]
6286 0 0       0 elsif ($char[$i] eq '[^') {
6287 0         0 my $left = $i;
6288             if ($char[$i+1] eq ']') {
6289 0         0 $i++;
6290 0 0       0 }
6291 0         0 while (1) {
6292             if (++$i > $#char) {
6293 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6294 0         0 }
6295             if ($char[$i] eq ']') {
6296             my $right = $i;
6297 0         0  
6298             # [^...]
6299 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6300 0         0  
6301             $i = $left;
6302             last;
6303             }
6304             }
6305             }
6306              
6307 0         0 # escape $ @ / and \
6308             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6309             $char[$i] = '\\' . $char[$i];
6310             }
6311              
6312 0         0 # rewrite character class or escape character
6313             elsif (my $char = character_class($char[$i],$modifier)) {
6314             $char[$i] = $char;
6315             }
6316              
6317 0 0       0 # /i modifier
6318 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
6319             if (CORE::length(Elatin3::fc($char[$i])) == 1) {
6320             $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
6321 0         0 }
6322             else {
6323             $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
6324             }
6325             }
6326              
6327 0 0       0 # quote character before ? + * {
6328             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6329             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6330 0         0 }
6331             else {
6332             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6333             }
6334             }
6335 0         0 }
6336 2         7  
6337             $delimiter = '/';
6338 2         3 $end_delimiter = '/';
6339 2         3  
6340             $modifier =~ tr/i//d;
6341             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6342             }
6343              
6344             #
6345             # escape regexp (m''b, qr''b)
6346 2     0 0 15 #
6347             sub e_qr_qb {
6348             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6349 0         0  
6350             # split regexp
6351             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6352 0         0  
6353 0 0       0 # unescape character
    0          
6354             for (my $i=0; $i <= $#char; $i++) {
6355             if (0) {
6356             }
6357 0         0  
6358             # remain \\
6359             elsif ($char[$i] eq '\\\\') {
6360             }
6361              
6362 0         0 # escape $ @ / and \
6363             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6364             $char[$i] = '\\' . $char[$i];
6365             }
6366 0         0 }
6367 0         0  
6368 0         0 $delimiter = '/';
6369             $end_delimiter = '/';
6370             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6371             }
6372              
6373             #
6374             # escape regexp (s/here//)
6375 0     76 0 0 #
6376 76   100     222 sub e_s1 {
6377             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6378 76         337 $modifier ||= '';
6379 76 50       145  
6380 76         235 $modifier =~ tr/p//d;
6381 0         0 if ($modifier =~ /([adlu])/oxms) {
6382 0 0       0 my $line = 0;
6383 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6384 0         0 if ($filename ne __FILE__) {
6385             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6386             last;
6387 0         0 }
6388             }
6389             die qq{Unsupported modifier "$1" used at line $line.\n};
6390 0         0 }
6391              
6392             $slash = 'div';
6393 76 100       137  
    50          
6394 76         260 # literal null string pattern
6395 8         11 if ($string eq '') {
6396 8         8 $modifier =~ tr/bB//d;
6397             $modifier =~ tr/i//d;
6398             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6399             }
6400              
6401             # /b /B modifier
6402             elsif ($modifier =~ tr/bB//d) {
6403 8 0       53  
6404 0         0 # choice again delimiter
6405 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
6406 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
6407 0         0 my %octet = map {$_ => 1} @char;
6408 0         0 if (not $octet{')'}) {
6409             $delimiter = '(';
6410             $end_delimiter = ')';
6411 0         0 }
6412 0         0 elsif (not $octet{'}'}) {
6413             $delimiter = '{';
6414             $end_delimiter = '}';
6415 0         0 }
6416 0         0 elsif (not $octet{']'}) {
6417             $delimiter = '[';
6418             $end_delimiter = ']';
6419 0         0 }
6420 0         0 elsif (not $octet{'>'}) {
6421             $delimiter = '<';
6422             $end_delimiter = '>';
6423 0         0 }
6424 0 0       0 else {
6425 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6426 0         0 if (not $octet{$char}) {
6427 0         0 $delimiter = $char;
6428             $end_delimiter = $char;
6429             last;
6430             }
6431             }
6432             }
6433 0         0 }
6434 0         0  
6435             my $prematch = '';
6436             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6437 0 100       0 }
6438 68         196  
6439             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6440             my $metachar = qr/[\@\\|[\]{^]/oxms;
6441 68         304  
6442             # split regexp
6443             my @char = $string =~ /\G((?>
6444             [^\\\$\@\[\(] |
6445             \\ (?>[1-9][0-9]*) |
6446             \\g (?>\s*) (?>[1-9][0-9]*) |
6447             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6448             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6449             \\x (?>[0-9A-Fa-f]{1,2}) |
6450             \\ (?>[0-7]{2,3}) |
6451             \\c [\x40-\x5F] |
6452             \\x\{ (?>[0-9A-Fa-f]+) \} |
6453             \\o\{ (?>[0-7]+) \} |
6454             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6455             \\ $q_char |
6456             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6457             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6458             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6459             [\$\@] $qq_variable |
6460             \$ (?>\s* [0-9]+) |
6461             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6462             \$ \$ (?![\w\{]) |
6463             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6464             \[\^ |
6465             \[\: (?>[a-z]+) :\] |
6466             \[\:\^ (?>[a-z]+) :\] |
6467             \(\? |
6468             $q_char
6469             ))/oxmsg;
6470 68 50       16691  
6471 68         463 # choice again delimiter
  0         0  
6472 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
6473 0         0 my %octet = map {$_ => 1} @char;
6474 0         0 if (not $octet{')'}) {
6475             $delimiter = '(';
6476             $end_delimiter = ')';
6477 0         0 }
6478 0         0 elsif (not $octet{'}'}) {
6479             $delimiter = '{';
6480             $end_delimiter = '}';
6481 0         0 }
6482 0         0 elsif (not $octet{']'}) {
6483             $delimiter = '[';
6484             $end_delimiter = ']';
6485 0         0 }
6486 0         0 elsif (not $octet{'>'}) {
6487             $delimiter = '<';
6488             $end_delimiter = '>';
6489 0         0 }
6490 0 0       0 else {
6491 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6492 0         0 if (not $octet{$char}) {
6493 0         0 $delimiter = $char;
6494             $end_delimiter = $char;
6495             last;
6496             }
6497             }
6498             }
6499             }
6500 0         0  
  68         157  
6501             # count '('
6502 253         441 my $parens = grep { $_ eq '(' } @char;
6503 68         108  
6504 68         100 my $left_e = 0;
6505             my $right_e = 0;
6506             for (my $i=0; $i <= $#char; $i++) {
6507 68 50 33     208  
    50 33        
    100          
    100          
    50          
    50          
6508 195         1096 # "\L\u" --> "\u\L"
6509             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6510             @char[$i,$i+1] = @char[$i+1,$i];
6511             }
6512              
6513 0         0 # "\U\l" --> "\l\U"
6514             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6515             @char[$i,$i+1] = @char[$i+1,$i];
6516             }
6517              
6518 0         0 # octal escape sequence
6519             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6520             $char[$i] = Elatin3::octchr($1);
6521             }
6522              
6523 1         3 # hexadecimal escape sequence
6524             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6525             $char[$i] = Elatin3::hexchr($1);
6526             }
6527              
6528             # \b{...} --> b\{...}
6529             # \B{...} --> B\{...}
6530             # \N{CHARNAME} --> N\{CHARNAME}
6531             # \p{PROPERTY} --> p\{PROPERTY}
6532 1         4 # \P{PROPERTY} --> P\{PROPERTY}
6533             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6534             $char[$i] = $1 . '\\' . $2;
6535             }
6536              
6537 0         0 # \p, \P, \X --> p, P, X
6538             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6539             $char[$i] = $1;
6540 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          
6541              
6542             if (0) {
6543             }
6544 195         681  
6545 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6546 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6547             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)) {
6548             $char[$i] .= join '', splice @char, $i+1, 3;
6549 0         0 }
6550             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)) {
6551             $char[$i] .= join '', splice @char, $i+1, 2;
6552 0         0 }
6553             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)) {
6554             $char[$i] .= join '', splice @char, $i+1, 1;
6555             }
6556             }
6557              
6558 0         0 # open character class [...]
6559 13 50       21 elsif ($char[$i] eq '[') {
6560 13         43 my $left = $i;
6561             if ($char[$i+1] eq ']') {
6562 0         0 $i++;
6563 13 50       21 }
6564 58         95 while (1) {
6565             if (++$i > $#char) {
6566 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6567 58         133 }
6568             if ($char[$i] eq ']') {
6569             my $right = $i;
6570 13 50       28  
6571 13         90 # [...]
  0         0  
6572             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6573             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin3::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6574 0         0 }
6575             else {
6576             splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
6577 13         60 }
6578 13         30  
6579             $i = $left;
6580             last;
6581             }
6582             }
6583             }
6584              
6585 13         34 # open character class [^...]
6586 0 0       0 elsif ($char[$i] eq '[^') {
6587 0         0 my $left = $i;
6588             if ($char[$i+1] eq ']') {
6589 0         0 $i++;
6590 0 0       0 }
6591 0         0 while (1) {
6592             if (++$i > $#char) {
6593 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6594 0         0 }
6595             if ($char[$i] eq ']') {
6596             my $right = $i;
6597 0 0       0  
6598 0         0 # [^...]
  0         0  
6599             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6600             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin3::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6601 0         0 }
6602             else {
6603             splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6604 0         0 }
6605 0         0  
6606             $i = $left;
6607             last;
6608             }
6609             }
6610             }
6611              
6612 0         0 # rewrite character class or escape character
6613             elsif (my $char = character_class($char[$i],$modifier)) {
6614             $char[$i] = $char;
6615             }
6616              
6617 7 50       15 # /i modifier
6618 3         6 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
6619             if (CORE::length(Elatin3::fc($char[$i])) == 1) {
6620             $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
6621 3         7 }
6622             else {
6623             $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
6624             }
6625             }
6626              
6627 0 0       0 # \u \l \U \L \F \Q \E
6628 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6629             if ($right_e < $left_e) {
6630             $char[$i] = '\\' . $char[$i];
6631             }
6632 0         0 }
6633 0         0 elsif ($char[$i] eq '\u') {
6634             $char[$i] = '@{[Elatin3::ucfirst qq<';
6635             $left_e++;
6636 0         0 }
6637 0         0 elsif ($char[$i] eq '\l') {
6638             $char[$i] = '@{[Elatin3::lcfirst qq<';
6639             $left_e++;
6640 0         0 }
6641 0         0 elsif ($char[$i] eq '\U') {
6642             $char[$i] = '@{[Elatin3::uc qq<';
6643             $left_e++;
6644 0         0 }
6645 0         0 elsif ($char[$i] eq '\L') {
6646             $char[$i] = '@{[Elatin3::lc qq<';
6647             $left_e++;
6648 0         0 }
6649 0         0 elsif ($char[$i] eq '\F') {
6650             $char[$i] = '@{[Elatin3::fc qq<';
6651             $left_e++;
6652 0         0 }
6653 0         0 elsif ($char[$i] eq '\Q') {
6654             $char[$i] = '@{[CORE::quotemeta qq<';
6655             $left_e++;
6656 0 0       0 }
6657 0         0 elsif ($char[$i] eq '\E') {
6658 0         0 if ($right_e < $left_e) {
6659             $char[$i] = '>]}';
6660             $right_e++;
6661 0         0 }
6662             else {
6663             $char[$i] = '';
6664             }
6665 0         0 }
6666 0 0       0 elsif ($char[$i] eq '\Q') {
6667 0         0 while (1) {
6668             if (++$i > $#char) {
6669 0 0       0 last;
6670 0         0 }
6671             if ($char[$i] eq '\E') {
6672             last;
6673             }
6674             }
6675             }
6676             elsif ($char[$i] eq '\E') {
6677             }
6678              
6679             # \0 --> \0
6680             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6681             }
6682              
6683             # \g{N}, \g{-N}
6684              
6685             # P.108 Using Simple Patterns
6686             # in Chapter 7: In the World of Regular Expressions
6687             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6688              
6689             # P.221 Capturing
6690             # in Chapter 5: Pattern Matching
6691             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6692              
6693             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6694             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6695             }
6696              
6697             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6698             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6699             }
6700              
6701             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6702             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6703             }
6704              
6705             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6706             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6707             }
6708              
6709 0 0       0 # $0 --> $0
6710 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6711             if ($ignorecase) {
6712             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6713             }
6714 0 0       0 }
6715 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6716             if ($ignorecase) {
6717             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6718             }
6719             }
6720              
6721             # $$ --> $$
6722             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6723             }
6724              
6725             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6726 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6727 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6728 0         0 $char[$i] = e_capture($1);
6729             if ($ignorecase) {
6730             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6731             }
6732 0         0 }
6733 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6734 0         0 $char[$i] = e_capture($1);
6735             if ($ignorecase) {
6736             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6737             }
6738             }
6739              
6740 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6741 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) {
6742 0         0 $char[$i] = e_capture($1.'->'.$2);
6743             if ($ignorecase) {
6744             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6745             }
6746             }
6747              
6748 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6749 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) {
6750 0         0 $char[$i] = e_capture($1.'->'.$2);
6751             if ($ignorecase) {
6752             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6753             }
6754             }
6755              
6756 0         0 # $$foo
6757 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6758 0         0 $char[$i] = e_capture($1);
6759             if ($ignorecase) {
6760             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6761             }
6762             }
6763              
6764 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
6765 4         14 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6766             if ($ignorecase) {
6767             $char[$i] = '@{[Elatin3::ignorecase(Elatin3::PREMATCH())]}';
6768 0         0 }
6769             else {
6770             $char[$i] = '@{[Elatin3::PREMATCH()]}';
6771             }
6772             }
6773              
6774 4 50       16 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
6775 4         14 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6776             if ($ignorecase) {
6777             $char[$i] = '@{[Elatin3::ignorecase(Elatin3::MATCH())]}';
6778 0         0 }
6779             else {
6780             $char[$i] = '@{[Elatin3::MATCH()]}';
6781             }
6782             }
6783              
6784 4 50       13 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
6785 3         11 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6786             if ($ignorecase) {
6787             $char[$i] = '@{[Elatin3::ignorecase(Elatin3::POSTMATCH())]}';
6788 0         0 }
6789             else {
6790             $char[$i] = '@{[Elatin3::POSTMATCH()]}';
6791             }
6792             }
6793              
6794 3 0       13 # ${ foo }
6795 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) {
6796             if ($ignorecase) {
6797             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6798             }
6799             }
6800              
6801 0         0 # ${ ... }
6802 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6803 0         0 $char[$i] = e_capture($1);
6804             if ($ignorecase) {
6805             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6806             }
6807             }
6808              
6809 0         0 # $scalar or @array
6810 4 50       22 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6811 4         22 $char[$i] = e_string($char[$i]);
6812             if ($ignorecase) {
6813             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6814             }
6815             }
6816              
6817 0 50       0 # quote character before ? + * {
6818             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6819             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6820 13         64 }
6821             else {
6822             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6823             }
6824             }
6825             }
6826 13         63  
6827 68         153 # make regexp string
6828 68 50       115 my $prematch = '';
6829 68         291 $modifier =~ tr/i//d;
6830             if ($left_e > $right_e) {
6831 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6832             }
6833             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6834             }
6835              
6836             #
6837             # escape regexp (s'here'' or s'here''b)
6838 68     21 0 925 #
6839 21   100     48 sub e_s1_q {
6840             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6841 21         68 $modifier ||= '';
6842 21 50       26  
6843 21         40 $modifier =~ tr/p//d;
6844 0         0 if ($modifier =~ /([adlu])/oxms) {
6845 0 0       0 my $line = 0;
6846 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6847 0         0 if ($filename ne __FILE__) {
6848             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6849             last;
6850 0         0 }
6851             }
6852             die qq{Unsupported modifier "$1" used at line $line.\n};
6853 0         0 }
6854              
6855             $slash = 'div';
6856 21 100       30  
    50          
6857 21         56 # literal null string pattern
6858 8         12 if ($string eq '') {
6859 8         9 $modifier =~ tr/bB//d;
6860             $modifier =~ tr/i//d;
6861             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6862             }
6863              
6864 8         47 # with /b /B modifier
6865             elsif ($modifier =~ tr/bB//d) {
6866             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6867             }
6868              
6869 0         0 # without /b /B modifier
6870             else {
6871             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6872             }
6873             }
6874              
6875             #
6876             # escape regexp (s'here'')
6877 13     13 0 30 #
6878             sub e_s1_qt {
6879 13 50       36 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6880              
6881             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6882 13         24  
6883             # split regexp
6884             my @char = $string =~ /\G((?>
6885             [^\\\[\$\@\/] |
6886             [\x00-\xFF] |
6887             \[\^ |
6888             \[\: (?>[a-z]+) \:\] |
6889             \[\:\^ (?>[a-z]+) \:\] |
6890             [\$\@\/] |
6891             \\ (?:$q_char) |
6892             (?:$q_char)
6893             ))/oxmsg;
6894 13         185  
6895 13 50 33     41 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6896             for (my $i=0; $i <= $#char; $i++) {
6897             if (0) {
6898             }
6899 25         104  
6900 0         0 # open character class [...]
6901 0 0       0 elsif ($char[$i] eq '[') {
6902 0         0 my $left = $i;
6903             if ($char[$i+1] eq ']') {
6904 0         0 $i++;
6905 0 0       0 }
6906 0         0 while (1) {
6907             if (++$i > $#char) {
6908 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6909 0         0 }
6910             if ($char[$i] eq ']') {
6911             my $right = $i;
6912 0         0  
6913             # [...]
6914 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
6915 0         0  
6916             $i = $left;
6917             last;
6918             }
6919             }
6920             }
6921              
6922 0         0 # open character class [^...]
6923 0 0       0 elsif ($char[$i] eq '[^') {
6924 0         0 my $left = $i;
6925             if ($char[$i+1] eq ']') {
6926 0         0 $i++;
6927 0 0       0 }
6928 0         0 while (1) {
6929             if (++$i > $#char) {
6930 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6931 0         0 }
6932             if ($char[$i] eq ']') {
6933             my $right = $i;
6934 0         0  
6935             # [^...]
6936 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6937 0         0  
6938             $i = $left;
6939             last;
6940             }
6941             }
6942             }
6943              
6944 0         0 # escape $ @ / and \
6945             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6946             $char[$i] = '\\' . $char[$i];
6947             }
6948              
6949 0         0 # rewrite character class or escape character
6950             elsif (my $char = character_class($char[$i],$modifier)) {
6951             $char[$i] = $char;
6952             }
6953              
6954 6 0       12 # /i modifier
6955 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
6956             if (CORE::length(Elatin3::fc($char[$i])) == 1) {
6957             $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
6958 0         0 }
6959             else {
6960             $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
6961             }
6962             }
6963              
6964 0 0       0 # quote character before ? + * {
6965             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6966             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6967 0         0 }
6968             else {
6969             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6970             }
6971             }
6972 0         0 }
6973 13         21  
6974 13         21 $modifier =~ tr/i//d;
6975 13         15 $delimiter = '/';
6976 13         18 $end_delimiter = '/';
6977             my $prematch = '';
6978             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6979             }
6980              
6981             #
6982             # escape regexp (s'here''b)
6983 13     0 0 91 #
6984             sub e_s1_qb {
6985             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6986 0         0  
6987             # split regexp
6988             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6989 0         0  
6990 0 0       0 # unescape character
    0          
6991             for (my $i=0; $i <= $#char; $i++) {
6992             if (0) {
6993             }
6994 0         0  
6995             # remain \\
6996             elsif ($char[$i] eq '\\\\') {
6997             }
6998              
6999 0         0 # escape $ @ / and \
7000             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7001             $char[$i] = '\\' . $char[$i];
7002             }
7003 0         0 }
7004 0         0  
7005 0         0 $delimiter = '/';
7006 0         0 $end_delimiter = '/';
7007             my $prematch = '';
7008             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
7009             }
7010              
7011             #
7012             # escape regexp (s''here')
7013 0     16 0 0 #
7014             sub e_s2_q {
7015 16         32 my($ope,$delimiter,$end_delimiter,$string) = @_;
7016              
7017 16         21 $slash = 'div';
7018 16         100  
7019 16 100       43 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
7020             for (my $i=0; $i <= $#char; $i++) {
7021             if (0) {
7022             }
7023 9         29  
7024             # not escape \\
7025             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
7026             }
7027              
7028 0         0 # escape $ @ / and \
7029             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7030             $char[$i] = '\\' . $char[$i];
7031             }
7032 5         14 }
7033              
7034             return join '', $ope, $delimiter, @char, $end_delimiter;
7035             }
7036              
7037             #
7038             # escape regexp (s/here/and here/modifier)
7039 16     97 0 48 #
7040 97   100     760 sub e_sub {
7041             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
7042 97         432 $modifier ||= '';
7043 97 50       184  
7044 97         268 $modifier =~ tr/p//d;
7045 0         0 if ($modifier =~ /([adlu])/oxms) {
7046 0 0       0 my $line = 0;
7047 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7048 0         0 if ($filename ne __FILE__) {
7049             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7050             last;
7051 0         0 }
7052             }
7053             die qq{Unsupported modifier "$1" used at line $line.\n};
7054 0 100       0 }
7055 97         270  
7056 36         44 if ($variable eq '') {
7057             $variable = '$_';
7058             $bind_operator = ' =~ ';
7059 36         59 }
7060              
7061             $slash = 'div';
7062              
7063             # P.128 Start of match (or end of previous match): \G
7064             # P.130 Advanced Use of \G with Perl
7065             # in Chapter 3: Overview of Regular Expression Features and Flavors
7066             # P.312 Iterative Matching: Scalar Context, with /g
7067             # in Chapter 7: Perl
7068             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
7069              
7070             # P.181 Where You Left Off: The \G Assertion
7071             # in Chapter 5: Pattern Matching
7072             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7073              
7074             # P.220 Where You Left Off: The \G Assertion
7075             # in Chapter 5: Pattern Matching
7076 97         152 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7077 97         174  
7078             my $e_modifier = $modifier =~ tr/e//d;
7079 97         165 my $r_modifier = $modifier =~ tr/r//d;
7080 97 50       145  
7081 97         249 my $my = '';
7082 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
7083 0         0 $my = $variable;
7084             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
7085             $variable =~ s/ = .+ \z//oxms;
7086 0         0 }
7087 97         326  
7088             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
7089             $variable_basename =~ s/ \s+ \z//oxms;
7090 97         197  
7091 97 100       170 # quote replacement string
7092 97         228 my $e_replacement = '';
7093 17         26 if ($e_modifier >= 1) {
7094             $e_replacement = e_qq('', '', '', $replacement);
7095             $e_modifier--;
7096 17 100       25 }
7097 80         239 else {
7098             if ($delimiter2 eq "'") {
7099             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
7100 16         80 }
7101             else {
7102             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
7103             }
7104 64         169 }
7105              
7106             my $sub = '';
7107 97 100       167  
7108 97 100       199 # with /r
7109             if ($r_modifier) {
7110             if (0) {
7111             }
7112 8         21  
7113 0 50       0 # s///gr without multibyte anchoring
7114             elsif ($modifier =~ /g/oxms) {
7115             $sub = sprintf(
7116             # 1 2 3 4 5
7117             q,
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             '$Elatin3::re_r=CORE::eval $Elatin3::re_r; ' x $e_modifier, # 5
7126             );
7127             }
7128              
7129             # s///r
7130 4         15 else {
7131              
7132 4 50       5 my $prematch = q{$`};
7133              
7134             $sub = sprintf(
7135             # 1 2 3 4 5 6 7
7136             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Elatin3::re_r=%s; %s"%s$Elatin3::re_r$'" } : %s>,
7137              
7138             $variable, # 1
7139             ($delimiter1 eq "'") ? # 2
7140             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7141             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7142             $s_matched, # 3
7143             $e_replacement, # 4
7144             '$Elatin3::re_r=CORE::eval $Elatin3::re_r; ' x $e_modifier, # 5
7145             $prematch, # 6
7146             $variable, # 7
7147             );
7148             }
7149 4 50       12  
7150 8         24 # $var !~ s///r doesn't make sense
7151             if ($bind_operator =~ / !~ /oxms) {
7152             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
7153             }
7154             }
7155              
7156 0 100       0 # without /r
7157             else {
7158             if (0) {
7159             }
7160 89         223  
7161 0 100       0 # s///g without multibyte anchoring
    100          
7162             elsif ($modifier =~ /g/oxms) {
7163             $sub = sprintf(
7164             # 1 2 3 4 5 6 7 8
7165             q,
7166              
7167             $variable, # 1
7168             ($delimiter1 eq "'") ? # 2
7169             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7170             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7171             $s_matched, # 3
7172             $e_replacement, # 4
7173             '$Elatin3::re_r=CORE::eval $Elatin3::re_r; ' x $e_modifier, # 5
7174             $variable, # 6
7175             $variable, # 7
7176             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
7177             );
7178             }
7179              
7180             # s///
7181 22         86 else {
7182              
7183 67 100       100 my $prematch = q{$`};
    100          
7184              
7185             $sub = sprintf(
7186              
7187             ($bind_operator =~ / =~ /oxms) ?
7188              
7189             # 1 2 3 4 5 6 7 8
7190             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Elatin3::re_r=%s; %s%s="%s$Elatin3::re_r$'"; 1 } : undef> :
7191              
7192             # 1 2 3 4 5 6 7 8
7193             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Elatin3::re_r=%s; %s%s="%s$Elatin3::re_r$'"; undef }>,
7194              
7195             $variable, # 1
7196             $bind_operator, # 2
7197             ($delimiter1 eq "'") ? # 3
7198             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7199             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7200             $s_matched, # 4
7201             $e_replacement, # 5
7202             '$Elatin3::re_r=CORE::eval $Elatin3::re_r; ' x $e_modifier, # 6
7203             $variable, # 7
7204             $prematch, # 8
7205             );
7206             }
7207             }
7208 67 50       374  
7209 97         259 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
7210             if ($my ne '') {
7211             $sub = "($my, $sub)[1]";
7212             }
7213 0         0  
7214 97         167 # clear s/// variable
7215             $sub_variable = '';
7216 97         130 $bind_operator = '';
7217              
7218             return $sub;
7219             }
7220              
7221             #
7222             # escape regexp of split qr//
7223 97     74 0 736 #
7224 74   100     744 sub e_split {
7225             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7226 74         393 $modifier ||= '';
7227 74 50       128  
7228 74         519 $modifier =~ tr/p//d;
7229 0         0 if ($modifier =~ /([adlu])/oxms) {
7230 0 0       0 my $line = 0;
7231 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7232 0         0 if ($filename ne __FILE__) {
7233             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7234             last;
7235 0         0 }
7236             }
7237             die qq{Unsupported modifier "$1" used at line $line.\n};
7238 0         0 }
7239              
7240             $slash = 'div';
7241 74 50       149  
7242 74         182 # /b /B modifier
7243             if ($modifier =~ tr/bB//d) {
7244             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7245 0 50       0 }
7246 74         203  
7247             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7248             my $metachar = qr/[\@\\|[\]{^]/oxms;
7249 74         259  
7250             # split regexp
7251             my @char = $string =~ /\G((?>
7252             [^\\\$\@\[\(] |
7253             \\x (?>[0-9A-Fa-f]{1,2}) |
7254             \\ (?>[0-7]{2,3}) |
7255             \\c [\x40-\x5F] |
7256             \\x\{ (?>[0-9A-Fa-f]+) \} |
7257             \\o\{ (?>[0-7]+) \} |
7258             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7259             \\ $q_char |
7260             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7261             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7262             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7263             [\$\@] $qq_variable |
7264             \$ (?>\s* [0-9]+) |
7265             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7266             \$ \$ (?![\w\{]) |
7267             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7268             \[\^ |
7269             \[\: (?>[a-z]+) :\] |
7270             \[\:\^ (?>[a-z]+) :\] |
7271             \(\? |
7272             $q_char
7273 74         9942 ))/oxmsg;
7274 74         251  
7275 74         114 my $left_e = 0;
7276             my $right_e = 0;
7277             for (my $i=0; $i <= $#char; $i++) {
7278 74 50 33     388  
    50 33        
    100          
    100          
    50          
    50          
7279 249         1576 # "\L\u" --> "\u\L"
7280             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7281             @char[$i,$i+1] = @char[$i+1,$i];
7282             }
7283              
7284 0         0 # "\U\l" --> "\l\U"
7285             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7286             @char[$i,$i+1] = @char[$i+1,$i];
7287             }
7288              
7289 0         0 # octal escape sequence
7290             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7291             $char[$i] = Elatin3::octchr($1);
7292             }
7293              
7294 1         4 # hexadecimal escape sequence
7295             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7296             $char[$i] = Elatin3::hexchr($1);
7297             }
7298              
7299             # \b{...} --> b\{...}
7300             # \B{...} --> B\{...}
7301             # \N{CHARNAME} --> N\{CHARNAME}
7302             # \p{PROPERTY} --> p\{PROPERTY}
7303 1         2 # \P{PROPERTY} --> P\{PROPERTY}
7304             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7305             $char[$i] = $1 . '\\' . $2;
7306             }
7307              
7308 0         0 # \p, \P, \X --> p, P, X
7309             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7310             $char[$i] = $1;
7311 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          
7312              
7313             if (0) {
7314             }
7315 249         991  
7316 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
7317 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7318             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)) {
7319             $char[$i] .= join '', splice @char, $i+1, 3;
7320 0         0 }
7321             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)) {
7322             $char[$i] .= join '', splice @char, $i+1, 2;
7323 0         0 }
7324             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)) {
7325             $char[$i] .= join '', splice @char, $i+1, 1;
7326             }
7327             }
7328              
7329 0         0 # open character class [...]
7330 3 50       9 elsif ($char[$i] eq '[') {
7331 3         12 my $left = $i;
7332             if ($char[$i+1] eq ']') {
7333 0         0 $i++;
7334 3 50       6 }
7335 7         13 while (1) {
7336             if (++$i > $#char) {
7337 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7338 7         17 }
7339             if ($char[$i] eq ']') {
7340             my $right = $i;
7341 3 50       4  
7342 3         16 # [...]
  0         0  
7343             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7344             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin3::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7345 0         0 }
7346             else {
7347             splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
7348 3         20 }
7349 3         7  
7350             $i = $left;
7351             last;
7352             }
7353             }
7354             }
7355              
7356 3         7 # open character class [^...]
7357 0 0       0 elsif ($char[$i] eq '[^') {
7358 0         0 my $left = $i;
7359             if ($char[$i+1] eq ']') {
7360 0         0 $i++;
7361 0 0       0 }
7362 0         0 while (1) {
7363             if (++$i > $#char) {
7364 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7365 0         0 }
7366             if ($char[$i] eq ']') {
7367             my $right = $i;
7368 0 0       0  
7369 0         0 # [^...]
  0         0  
7370             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7371             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin3::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7372 0         0 }
7373             else {
7374             splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7375 0         0 }
7376 0         0  
7377             $i = $left;
7378             last;
7379             }
7380             }
7381             }
7382              
7383 0         0 # rewrite character class or escape character
7384             elsif (my $char = character_class($char[$i],$modifier)) {
7385             $char[$i] = $char;
7386             }
7387              
7388             # P.794 29.2.161. split
7389             # in Chapter 29: Functions
7390             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7391              
7392             # P.951 split
7393             # in Chapter 27: Functions
7394             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7395              
7396             # said "The //m modifier is assumed when you split on the pattern /^/",
7397             # but perl5.008 is not so. Therefore, this software adds //m.
7398             # (and so on)
7399              
7400 1         3 # split(m/^/) --> split(m/^/m)
7401             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7402             $modifier .= 'm';
7403             }
7404              
7405 7 0       22 # /i modifier
7406 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
7407             if (CORE::length(Elatin3::fc($char[$i])) == 1) {
7408             $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
7409 0         0 }
7410             else {
7411             $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
7412             }
7413             }
7414              
7415 0 0       0 # \u \l \U \L \F \Q \E
7416 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7417             if ($right_e < $left_e) {
7418             $char[$i] = '\\' . $char[$i];
7419             }
7420 0         0 }
7421 0         0 elsif ($char[$i] eq '\u') {
7422             $char[$i] = '@{[Elatin3::ucfirst qq<';
7423             $left_e++;
7424 0         0 }
7425 0         0 elsif ($char[$i] eq '\l') {
7426             $char[$i] = '@{[Elatin3::lcfirst qq<';
7427             $left_e++;
7428 0         0 }
7429 0         0 elsif ($char[$i] eq '\U') {
7430             $char[$i] = '@{[Elatin3::uc qq<';
7431             $left_e++;
7432 0         0 }
7433 0         0 elsif ($char[$i] eq '\L') {
7434             $char[$i] = '@{[Elatin3::lc qq<';
7435             $left_e++;
7436 0         0 }
7437 0         0 elsif ($char[$i] eq '\F') {
7438             $char[$i] = '@{[Elatin3::fc qq<';
7439             $left_e++;
7440 0         0 }
7441 0         0 elsif ($char[$i] eq '\Q') {
7442             $char[$i] = '@{[CORE::quotemeta qq<';
7443             $left_e++;
7444 0 0       0 }
7445 0         0 elsif ($char[$i] eq '\E') {
7446 0         0 if ($right_e < $left_e) {
7447             $char[$i] = '>]}';
7448             $right_e++;
7449 0         0 }
7450             else {
7451             $char[$i] = '';
7452             }
7453 0         0 }
7454 0 0       0 elsif ($char[$i] eq '\Q') {
7455 0         0 while (1) {
7456             if (++$i > $#char) {
7457 0 0       0 last;
7458 0         0 }
7459             if ($char[$i] eq '\E') {
7460             last;
7461             }
7462             }
7463             }
7464             elsif ($char[$i] eq '\E') {
7465             }
7466              
7467 0 0       0 # $0 --> $0
7468 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7469             if ($ignorecase) {
7470             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7471             }
7472 0 0       0 }
7473 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7474             if ($ignorecase) {
7475             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7476             }
7477             }
7478              
7479             # $$ --> $$
7480             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7481             }
7482              
7483             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7484 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7485 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7486 0         0 $char[$i] = e_capture($1);
7487             if ($ignorecase) {
7488             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7489             }
7490 0         0 }
7491 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7492 0         0 $char[$i] = e_capture($1);
7493             if ($ignorecase) {
7494             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7495             }
7496             }
7497              
7498 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7499 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) {
7500 0         0 $char[$i] = e_capture($1.'->'.$2);
7501             if ($ignorecase) {
7502             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7503             }
7504             }
7505              
7506 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7507 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) {
7508 0         0 $char[$i] = e_capture($1.'->'.$2);
7509             if ($ignorecase) {
7510             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7511             }
7512             }
7513              
7514 0         0 # $$foo
7515 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7516 0         0 $char[$i] = e_capture($1);
7517             if ($ignorecase) {
7518             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7519             }
7520             }
7521              
7522 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
7523 12         40 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7524             if ($ignorecase) {
7525             $char[$i] = '@{[Elatin3::ignorecase(Elatin3::PREMATCH())]}';
7526 0         0 }
7527             else {
7528             $char[$i] = '@{[Elatin3::PREMATCH()]}';
7529             }
7530             }
7531              
7532 12 50       56 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
7533 12         43 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7534             if ($ignorecase) {
7535             $char[$i] = '@{[Elatin3::ignorecase(Elatin3::MATCH())]}';
7536 0         0 }
7537             else {
7538             $char[$i] = '@{[Elatin3::MATCH()]}';
7539             }
7540             }
7541              
7542 12 50       57 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
7543 9         27 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7544             if ($ignorecase) {
7545             $char[$i] = '@{[Elatin3::ignorecase(Elatin3::POSTMATCH())]}';
7546 0         0 }
7547             else {
7548             $char[$i] = '@{[Elatin3::POSTMATCH()]}';
7549             }
7550             }
7551              
7552 9 0       41 # ${ foo }
7553 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) {
7554             if ($ignorecase) {
7555             $char[$i] = '@{[Elatin3::ignorecase(' . $1 . ')]}';
7556             }
7557             }
7558              
7559 0         0 # ${ ... }
7560 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7561 0         0 $char[$i] = e_capture($1);
7562             if ($ignorecase) {
7563             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7564             }
7565             }
7566              
7567 0         0 # $scalar or @array
7568 3 50       9 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7569 3         13 $char[$i] = e_string($char[$i]);
7570             if ($ignorecase) {
7571             $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7572             }
7573             }
7574              
7575 0 50       0 # quote character before ? + * {
7576             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7577             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7578 1         9 }
7579             else {
7580             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7581             }
7582             }
7583             }
7584 0         0  
7585 74 50       215 # make regexp string
7586 74         174 $modifier =~ tr/i//d;
7587             if ($left_e > $right_e) {
7588 0         0 return join '', 'Elatin3::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7589             }
7590             return join '', 'Elatin3::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7591             }
7592              
7593             #
7594             # escape regexp of split qr''
7595 74     0 0 925 #
7596 0   0       sub e_split_q {
7597             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7598 0           $modifier ||= '';
7599 0 0          
7600 0           $modifier =~ tr/p//d;
7601 0           if ($modifier =~ /([adlu])/oxms) {
7602 0 0         my $line = 0;
7603 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7604 0           if ($filename ne __FILE__) {
7605             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7606             last;
7607 0           }
7608             }
7609             die qq{Unsupported modifier "$1" used at line $line.\n};
7610 0           }
7611              
7612             $slash = 'div';
7613 0 0          
7614 0           # /b /B modifier
7615             if ($modifier =~ tr/bB//d) {
7616             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7617 0 0         }
7618              
7619             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7620 0            
7621             # split regexp
7622             my @char = $string =~ /\G((?>
7623             [^\\\[] |
7624             [\x00-\xFF] |
7625             \[\^ |
7626             \[\: (?>[a-z]+) \:\] |
7627             \[\:\^ (?>[a-z]+) \:\] |
7628             \\ (?:$q_char) |
7629             (?:$q_char)
7630             ))/oxmsg;
7631 0            
7632 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7633             for (my $i=0; $i <= $#char; $i++) {
7634             if (0) {
7635             }
7636 0            
7637 0           # open character class [...]
7638 0 0         elsif ($char[$i] eq '[') {
7639 0           my $left = $i;
7640             if ($char[$i+1] eq ']') {
7641 0           $i++;
7642 0 0         }
7643 0           while (1) {
7644             if (++$i > $#char) {
7645 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7646 0           }
7647             if ($char[$i] eq ']') {
7648             my $right = $i;
7649 0            
7650             # [...]
7651 0           splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
7652 0            
7653             $i = $left;
7654             last;
7655             }
7656             }
7657             }
7658              
7659 0           # open character class [^...]
7660 0 0         elsif ($char[$i] eq '[^') {
7661 0           my $left = $i;
7662             if ($char[$i+1] eq ']') {
7663 0           $i++;
7664 0 0         }
7665 0           while (1) {
7666             if (++$i > $#char) {
7667 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7668 0           }
7669             if ($char[$i] eq ']') {
7670             my $right = $i;
7671 0            
7672             # [^...]
7673 0           splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7674 0            
7675             $i = $left;
7676             last;
7677             }
7678             }
7679             }
7680              
7681 0           # rewrite character class or escape character
7682             elsif (my $char = character_class($char[$i],$modifier)) {
7683             $char[$i] = $char;
7684             }
7685              
7686 0           # split(m/^/) --> split(m/^/m)
7687             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7688             $modifier .= 'm';
7689             }
7690              
7691 0 0         # /i modifier
7692 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
7693             if (CORE::length(Elatin3::fc($char[$i])) == 1) {
7694             $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
7695 0           }
7696             else {
7697             $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
7698             }
7699             }
7700              
7701 0 0         # quote character before ? + * {
7702             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7703             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7704 0           }
7705             else {
7706             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7707             }
7708             }
7709 0           }
7710 0            
7711             $modifier =~ tr/i//d;
7712             return join '', 'Elatin3::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7713             }
7714              
7715             #
7716             # instead of Carp::carp
7717 0     0 0   #
7718 0           sub carp {
7719             my($package,$filename,$line) = caller(1);
7720             print STDERR "@_ at $filename line $line.\n";
7721             }
7722              
7723             #
7724             # instead of Carp::croak
7725 0     0 0   #
7726 0           sub croak {
7727 0           my($package,$filename,$line) = caller(1);
7728             print STDERR "@_ at $filename line $line.\n";
7729             die "\n";
7730             }
7731              
7732             #
7733             # instead of Carp::cluck
7734 0     0 0   #
7735 0           sub cluck {
7736 0           my $i = 0;
7737 0           my @cluck = ();
7738 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7739             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7740 0           $i++;
7741 0           }
7742 0           print STDERR CORE::reverse @cluck;
7743             print STDERR "\n";
7744             print STDERR @_;
7745             }
7746              
7747             #
7748             # instead of Carp::confess
7749 0     0 0   #
7750 0           sub confess {
7751 0           my $i = 0;
7752 0           my @confess = ();
7753 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7754             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7755 0           $i++;
7756 0           }
7757 0           print STDERR CORE::reverse @confess;
7758 0           print STDERR "\n";
7759             print STDERR @_;
7760             die "\n";
7761             }
7762              
7763             1;
7764              
7765             __END__