File Coverage

blib/lib/Elatin3.pm
Criterion Covered Total %
statement 83 3085 2.6
branch 4 2674 0.1
condition 1 373 0.2
subroutine 36 125 28.8
pod 7 74 9.4
total 131 6331 2.0


line stmt bran cond sub pod time code
1             package Elatin3;
2             ######################################################################
3             #
4             # Elatin3 - Run-time routines for Latin3.pm
5             #
6             # http://search.cpan.org/dist/Char-Latin3/
7             #
8             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 INABA Hitoshi
9             ######################################################################
10              
11 200     200   5363 use 5.00503; # Galapagos Consensus 1998 for primetools
  200         772  
  200         13213  
12             # use 5.008001; # Lancaster Consensus 2013 for toolchains
13              
14             # 12.3. Delaying use Until Runtime
15             # in Chapter 12. Packages, Libraries, and Modules
16             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
17             # (and so on)
18              
19             # Version numbers should be boring
20             # http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
21             # For the impatient, the disinterested or those who just want to follow
22             # a recipe, my advice for all modules is this:
23             # our $VERSION = "0.001"; # or "0.001_001" for a dev release
24             # $VERSION = eval $VERSION;
25              
26 200     200   17144 BEGIN { CORE::eval q{ use vars qw($VERSION) } }
  200     200   1557  
  200         362  
  200         45641  
27             $VERSION = '1.05';
28             $VERSION = CORE::eval $VERSION;
29              
30             BEGIN {
31 200 50   200   1532 if ($^X =~ / jperl /oxmsi) {
32 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
33             }
34 200         342 if (CORE::ord('A') == 193) {
35             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
36             }
37 200         34345 if (CORE::ord('A') != 0x41) {
38             die __FILE__, ": is not US-ASCII script (must be US-ASCII script).\n";
39             }
40             }
41              
42             BEGIN {
43              
44             # instead of utf8.pm
45 200     200   18161 CORE::eval q{
  200     200   1444  
  200     70   376  
  200         51392  
  70         14282  
  60         11698  
  57         10890  
  73         14771  
  70         12519  
  70         14380  
46             no warnings qw(redefine);
47             *utf8::upgrade = sub { CORE::length $_[0] };
48             *utf8::downgrade = sub { 1 };
49             *utf8::encode = sub { };
50             *utf8::decode = sub { 1 };
51             *utf8::is_utf8 = sub { };
52             *utf8::valid = sub { 1 };
53             };
54 200 50       133972 if ($@) {
55 0         0 *utf8::upgrade = sub { CORE::length $_[0] };
  0         0  
56 0         0 *utf8::downgrade = sub { 1 };
  0         0  
57 0         0 *utf8::encode = sub { };
  0         0  
58 0         0 *utf8::decode = sub { 1 };
  0         0  
59 0         0 *utf8::is_utf8 = sub { };
  0         0  
60 0         0 *utf8::valid = sub { 1 };
  0         0  
61             }
62             }
63              
64             # instead of Symbol.pm
65             BEGIN {
66 200     200   575 my $genpkg = "Symbol::";
67 200         10556 my $genseq = 0;
68              
69             sub gensym () {
70 0     0 0 0 my $name = "GEN" . $genseq++;
71              
72             # here, no strict qw(refs); if strict.pm exists
73              
74 0         0 my $ref = \*{$genpkg . $name};
  0         0  
75 0         0 delete $$genpkg{$name};
76 0         0 return $ref;
77             }
78              
79             sub qualify ($;$) {
80 0     0 0 0 my ($name) = @_;
81 0 0 0     0 if (!ref($name) && (Elatin3::index($name, '::') == -1) && (Elatin3::index($name, "'") == -1)) {
      0        
82 0         0 my $pkg;
83 0         0 my %global = map {$_ => 1} qw(ARGV ARGVOUT ENV INC SIG STDERR STDIN STDOUT DATA);
  0         0  
84              
85             # Global names: special character, "^xyz", or other.
86 0 0 0     0 if ($name =~ /^(([^a-z])|(\^[a-z_]+))\z/i || $global{$name}) {
87             # RGS 2001-11-05 : translate leading ^X to control-char
88 0         0 $name =~ s/^\^([a-z_])/'qq(\c'.$1.')'/eei;
  0         0  
89 0         0 $pkg = "main";
90             }
91             else {
92 0 0       0 $pkg = (@_ > 1) ? $_[1] : caller;
93             }
94 0         0 $name = $pkg . "::" . $name;
95             }
96 0         0 return $name;
97             }
98              
99             sub qualify_to_ref ($;$) {
100              
101             # here, no strict qw(refs); if strict.pm exists
102              
103 0 0   0 0 0 return \*{ qualify $_[0], @_ > 1 ? $_[1] : caller };
  0         0  
104             }
105             }
106              
107             # Column: local $@
108             # in Chapter 9. Osaete okitai Perl no kiso
109             # of ISBN 10: 4798119172 | ISBN 13: 978-4798119175 MODAN Perl NYUMON
110             # (and so on)
111              
112             # use strict; if strict.pm exists
113             BEGIN {
114 200 50   200   640 if (CORE::eval { local $@; CORE::require strict }) {
  200         391  
  200         2471  
115 200         45534 strict::->import;
116             }
117             }
118              
119             # P.714 29.2.39. flock
120             # in Chapter 29: Functions
121             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
122              
123             # P.863 flock
124             # in Chapter 27: Functions
125             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
126              
127             sub LOCK_SH() {1}
128             sub LOCK_EX() {2}
129             sub LOCK_UN() {8}
130             sub LOCK_NB() {4}
131              
132             # instead of Carp.pm
133             sub carp;
134             sub croak;
135             sub cluck;
136             sub confess;
137              
138             # 6.18. Matching Multiple-Byte Characters
139             # in Chapter 6. Pattern Matching
140             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
141             # (and so on)
142              
143             # regexp of character
144 200     200   20133 BEGIN { CORE::eval q{ use vars qw($your_char) } } $your_char = q{[\x00-\xFF]};
  200     200   1237  
  200         343  
  200         16738  
145 200     200   17727 BEGIN { CORE::eval q{ use vars qw($qq_char ) } } $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  200     200   1738  
  200         315  
  200         20794  
146 200     200   17336 BEGIN { CORE::eval q{ use vars qw($q_char ) } } $q_char = qr/$your_char/oxms;
  200     200   1258  
  200         459  
  200         18156  
147              
148             #
149             # Latin-3 character range per length
150             #
151             my %range_tr = ();
152              
153             #
154             # alias of encoding name
155             #
156 200     200   16214 BEGIN { CORE::eval q{ use vars qw($encoding_alias) } }
  200     200   2350  
  200         339  
  200         504727  
157              
158             #
159             # Latin-3 case conversion
160             #
161             my %lc = ();
162             @lc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
163             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
164             my %uc = ();
165             @uc{qw(a b c d e f g h i j k l m n o p q r s t u v w x y z)} =
166             qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
167             my %fc = ();
168             @fc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
169             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
170              
171             if (0) {
172             }
173              
174             elsif (__PACKAGE__ =~ / \b Elatin3 \z/oxms) {
175             %range_tr = (
176             1 => [ [0x00..0xFF],
177             ],
178             );
179             $encoding_alias = qr/ \b (?: iso[-_ ]?8859-3 | iec[- ]?8859-3 | latin-?3 ) \b /oxmsi;
180              
181             %lc = (%lc,
182             "\xA1" => "\xB1", # LATIN LETTER H WITH STROKE
183             "\xA6" => "\xB6", # LATIN LETTER H WITH CIRCUMFLEX
184             "\xAA" => "\xBA", # LATIN LETTER S WITH CEDILLA
185             "\xAB" => "\xBB", # LATIN LETTER G WITH BREVE
186             "\xAC" => "\xBC", # LATIN LETTER J WITH CIRCUMFLEX
187             "\xAF" => "\xBF", # LATIN LETTER Z WITH DOT ABOVE
188             "\xC0" => "\xE0", # LATIN LETTER A WITH GRAVE
189             "\xC1" => "\xE1", # LATIN LETTER A WITH ACUTE
190             "\xC2" => "\xE2", # LATIN LETTER A WITH CIRCUMFLEX
191             "\xC4" => "\xE4", # LATIN LETTER A WITH DIAERESIS
192             "\xC5" => "\xE5", # LATIN LETTER C WITH DOT ABOVE
193             "\xC6" => "\xE6", # LATIN LETTER C WITH CIRCUMFLEX
194             "\xC7" => "\xE7", # LATIN LETTER C WITH CEDILLA
195             "\xC8" => "\xE8", # LATIN LETTER E WITH GRAVE
196             "\xC9" => "\xE9", # LATIN LETTER E WITH ACUTE
197             "\xCA" => "\xEA", # LATIN LETTER E WITH CIRCUMFLEX
198             "\xCB" => "\xEB", # LATIN LETTER E WITH DIAERESIS
199             "\xCC" => "\xEC", # LATIN LETTER I WITH GRAVE
200             "\xCD" => "\xED", # LATIN LETTER I WITH ACUTE
201             "\xCE" => "\xEE", # LATIN LETTER I WITH CIRCUMFLEX
202             "\xCF" => "\xEF", # LATIN LETTER I WITH DIAERESIS
203             "\xD1" => "\xF1", # LATIN LETTER N WITH TILDE
204             "\xD2" => "\xF2", # LATIN LETTER O WITH GRAVE
205             "\xD3" => "\xF3", # LATIN LETTER O WITH ACUTE
206             "\xD4" => "\xF4", # LATIN LETTER O WITH CIRCUMFLEX
207             "\xD5" => "\xF5", # LATIN LETTER G WITH DOT ABOVE
208             "\xD6" => "\xF6", # LATIN LETTER O WITH DIAERESIS
209             "\xD8" => "\xF8", # LATIN LETTER G WITH CIRCUMFLEX
210             "\xD9" => "\xF9", # LATIN LETTER U WITH GRAVE
211             "\xDA" => "\xFA", # LATIN LETTER U WITH ACUTE
212             "\xDB" => "\xFB", # LATIN LETTER U WITH CIRCUMFLEX
213             "\xDC" => "\xFC", # LATIN LETTER U WITH DIAERESIS
214             "\xDD" => "\xFD", # LATIN LETTER U WITH BREVE
215             "\xDE" => "\xFE", # LATIN LETTER S WITH CIRCUMFLEX
216             );
217              
218             %uc = (%uc,
219             "\xB1" => "\xA1", # LATIN LETTER H WITH STROKE
220             "\xB6" => "\xA6", # LATIN LETTER H WITH CIRCUMFLEX
221             "\xBA" => "\xAA", # LATIN LETTER S WITH CEDILLA
222             "\xBB" => "\xAB", # LATIN LETTER G WITH BREVE
223             "\xBC" => "\xAC", # LATIN LETTER J WITH CIRCUMFLEX
224             "\xBF" => "\xAF", # LATIN LETTER Z WITH DOT ABOVE
225             "\xE0" => "\xC0", # LATIN LETTER A WITH GRAVE
226             "\xE1" => "\xC1", # LATIN LETTER A WITH ACUTE
227             "\xE2" => "\xC2", # LATIN LETTER A WITH CIRCUMFLEX
228             "\xE4" => "\xC4", # LATIN LETTER A WITH DIAERESIS
229             "\xE5" => "\xC5", # LATIN LETTER C WITH DOT ABOVE
230             "\xE6" => "\xC6", # LATIN LETTER C WITH CIRCUMFLEX
231             "\xE7" => "\xC7", # LATIN LETTER C WITH CEDILLA
232             "\xE8" => "\xC8", # LATIN LETTER E WITH GRAVE
233             "\xE9" => "\xC9", # LATIN LETTER E WITH ACUTE
234             "\xEA" => "\xCA", # LATIN LETTER E WITH CIRCUMFLEX
235             "\xEB" => "\xCB", # LATIN LETTER E WITH DIAERESIS
236             "\xEC" => "\xCC", # LATIN LETTER I WITH GRAVE
237             "\xED" => "\xCD", # LATIN LETTER I WITH ACUTE
238             "\xEE" => "\xCE", # LATIN LETTER I WITH CIRCUMFLEX
239             "\xEF" => "\xCF", # LATIN LETTER I WITH DIAERESIS
240             "\xF1" => "\xD1", # LATIN LETTER N WITH TILDE
241             "\xF2" => "\xD2", # LATIN LETTER O WITH GRAVE
242             "\xF3" => "\xD3", # LATIN LETTER O WITH ACUTE
243             "\xF4" => "\xD4", # LATIN LETTER O WITH CIRCUMFLEX
244             "\xF5" => "\xD5", # LATIN LETTER G WITH DOT ABOVE
245             "\xF6" => "\xD6", # LATIN LETTER O WITH DIAERESIS
246             "\xF8" => "\xD8", # LATIN LETTER G WITH CIRCUMFLEX
247             "\xF9" => "\xD9", # LATIN LETTER U WITH GRAVE
248             "\xFA" => "\xDA", # LATIN LETTER U WITH ACUTE
249             "\xFB" => "\xDB", # LATIN LETTER U WITH CIRCUMFLEX
250             "\xFC" => "\xDC", # LATIN LETTER U WITH DIAERESIS
251             "\xFD" => "\xDD", # LATIN LETTER U WITH BREVE
252             "\xFE" => "\xDE", # LATIN LETTER S WITH CIRCUMFLEX
253             );
254              
255             %fc = (%fc,
256             "\xA1" => "\xB1", # LATIN CAPITAL LETTER H WITH STROKE --> LATIN SMALL LETTER H WITH STROKE
257             "\xA6" => "\xB6", # LATIN CAPITAL LETTER H WITH CIRCUMFLEX --> LATIN SMALL LETTER H WITH CIRCUMFLEX
258              
259             # CaseFolding-6.1.0.txt
260             # Date: 2011-07-25, 21:21:56 GMT [MD]
261             #
262             # T: special case for uppercase I and dotted uppercase I
263             # - For non-Turkic languages, this mapping is normally not used.
264             # - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
265             # Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
266             # See the discussions of case mapping in the Unicode Standard for more information.
267              
268             #-------------------------------------------------------------------------------
269             "\xA9" => "\x69", # LATIN CAPITAL LETTER I WITH DOT ABOVE
270             # --> LATIN SMALL LETTER I (without COMBINING DOT ABOVE)
271             #-------------------------------------------------------------------------------
272              
273             "\xAA" => "\xBA", # LATIN CAPITAL LETTER S WITH CEDILLA --> LATIN SMALL LETTER S WITH CEDILLA
274             "\xAB" => "\xBB", # LATIN CAPITAL LETTER G WITH BREVE --> LATIN SMALL LETTER G WITH BREVE
275             "\xAC" => "\xBC", # LATIN CAPITAL LETTER J WITH CIRCUMFLEX --> LATIN SMALL LETTER J WITH CIRCUMFLEX
276             "\xAF" => "\xBF", # LATIN CAPITAL LETTER Z WITH DOT ABOVE --> LATIN SMALL LETTER Z WITH DOT ABOVE
277             "\xC0" => "\xE0", # LATIN CAPITAL LETTER A WITH GRAVE --> LATIN SMALL LETTER A WITH GRAVE
278             "\xC1" => "\xE1", # LATIN CAPITAL LETTER A WITH ACUTE --> LATIN SMALL LETTER A WITH ACUTE
279             "\xC2" => "\xE2", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX --> LATIN SMALL LETTER A WITH CIRCUMFLEX
280             "\xC4" => "\xE4", # LATIN CAPITAL LETTER A WITH DIAERESIS --> LATIN SMALL LETTER A WITH DIAERESIS
281             "\xC5" => "\xE5", # LATIN CAPITAL LETTER C WITH DOT ABOVE --> LATIN SMALL LETTER C WITH DOT ABOVE
282             "\xC6" => "\xE6", # LATIN CAPITAL LETTER C WITH CIRCUMFLEX --> LATIN SMALL LETTER C WITH CIRCUMFLEX
283             "\xC7" => "\xE7", # LATIN CAPITAL LETTER C WITH CEDILLA --> LATIN SMALL LETTER C WITH CEDILLA
284             "\xC8" => "\xE8", # LATIN CAPITAL LETTER E WITH GRAVE --> LATIN SMALL LETTER E WITH GRAVE
285             "\xC9" => "\xE9", # LATIN CAPITAL LETTER E WITH ACUTE --> LATIN SMALL LETTER E WITH ACUTE
286             "\xCA" => "\xEA", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX --> LATIN SMALL LETTER E WITH CIRCUMFLEX
287             "\xCB" => "\xEB", # LATIN CAPITAL LETTER E WITH DIAERESIS --> LATIN SMALL LETTER E WITH DIAERESIS
288             "\xCC" => "\xEC", # LATIN CAPITAL LETTER I WITH GRAVE --> LATIN SMALL LETTER I WITH GRAVE
289             "\xCD" => "\xED", # LATIN CAPITAL LETTER I WITH ACUTE --> LATIN SMALL LETTER I WITH ACUTE
290             "\xCE" => "\xEE", # LATIN CAPITAL LETTER I WITH CIRCUMFLEX --> LATIN SMALL LETTER I WITH CIRCUMFLEX
291             "\xCF" => "\xEF", # LATIN CAPITAL LETTER I WITH DIAERESIS --> LATIN SMALL LETTER I WITH DIAERESIS
292             "\xD1" => "\xF1", # LATIN CAPITAL LETTER N WITH TILDE --> LATIN SMALL LETTER N WITH TILDE
293             "\xD2" => "\xF2", # LATIN CAPITAL LETTER O WITH GRAVE --> LATIN SMALL LETTER O WITH GRAVE
294             "\xD3" => "\xF3", # LATIN CAPITAL LETTER O WITH ACUTE --> LATIN SMALL LETTER O WITH ACUTE
295             "\xD4" => "\xF4", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX --> LATIN SMALL LETTER O WITH CIRCUMFLEX
296             "\xD5" => "\xF5", # LATIN CAPITAL LETTER G WITH DOT ABOVE --> LATIN SMALL LETTER G WITH DOT ABOVE
297             "\xD6" => "\xF6", # LATIN CAPITAL LETTER O WITH DIAERESIS --> LATIN SMALL LETTER O WITH DIAERESIS
298             "\xD8" => "\xF8", # LATIN CAPITAL LETTER G WITH CIRCUMFLEX --> LATIN SMALL LETTER G WITH CIRCUMFLEX
299             "\xD9" => "\xF9", # LATIN CAPITAL LETTER U WITH GRAVE --> LATIN SMALL LETTER U WITH GRAVE
300             "\xDA" => "\xFA", # LATIN CAPITAL LETTER U WITH ACUTE --> LATIN SMALL LETTER U WITH ACUTE
301             "\xDB" => "\xFB", # LATIN CAPITAL LETTER U WITH CIRCUMFLEX --> LATIN SMALL LETTER U WITH CIRCUMFLEX
302             "\xDC" => "\xFC", # LATIN CAPITAL LETTER U WITH DIAERESIS --> LATIN SMALL LETTER U WITH DIAERESIS
303             "\xDD" => "\xFD", # LATIN CAPITAL LETTER U WITH BREVE --> LATIN SMALL LETTER U WITH BREVE
304             "\xDE" => "\xFE", # LATIN CAPITAL LETTER S WITH CIRCUMFLEX --> LATIN SMALL LETTER S WITH CIRCUMFLEX
305             "\xDF" => "\x73\x73", # LATIN SMALL LETTER SHARP S --> LATIN SMALL LETTER S, LATIN SMALL LETTER S
306             );
307             }
308              
309             else {
310             croak "Don't know my package name '@{[__PACKAGE__]}'";
311             }
312              
313             #
314             # @ARGV wildcard globbing
315             #
316             sub import {
317              
318 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
319 0         0 my @argv = ();
320 0         0 for (@ARGV) {
321              
322             # has space
323 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
324 0 0       0 if (my @glob = Elatin3::glob(qq{"$_"})) {
325 0         0 push @argv, @glob;
326             }
327             else {
328 0         0 push @argv, $_;
329             }
330             }
331              
332             # has wildcard metachar
333             elsif (/\A (?:$q_char)*? [*?] /oxms) {
334 0 0       0 if (my @glob = Elatin3::glob($_)) {
335 0         0 push @argv, @glob;
336             }
337             else {
338 0         0 push @argv, $_;
339             }
340             }
341              
342             # no wildcard globbing
343             else {
344 0         0 push @argv, $_;
345             }
346             }
347 0         0 @ARGV = @argv;
348             }
349              
350 0         0 *Char::ord = \&Latin3::ord;
351 0         0 *Char::ord_ = \&Latin3::ord_;
352 0         0 *Char::reverse = \&Latin3::reverse;
353 0         0 *Char::getc = \&Latin3::getc;
354 0         0 *Char::length = \&Latin3::length;
355 0         0 *Char::substr = \&Latin3::substr;
356 0         0 *Char::index = \&Latin3::index;
357 0         0 *Char::rindex = \&Latin3::rindex;
358 0         0 *Char::eval = \&Latin3::eval;
359 0         0 *Char::escape = \&Latin3::escape;
360 0         0 *Char::escape_token = \&Latin3::escape_token;
361 0         0 *Char::escape_script = \&Latin3::escape_script;
362             }
363              
364             # P.230 Care with Prototypes
365             # in Chapter 6: Subroutines
366             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
367             #
368             # If you aren't careful, you can get yourself into trouble with prototypes.
369             # But if you are careful, you can do a lot of neat things with them. This is
370             # all very powerful, of course, and should only be used in moderation to make
371             # the world a better place.
372              
373             # P.332 Care with Prototypes
374             # in Chapter 7: Subroutines
375             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
376             #
377             # If you aren't careful, you can get yourself into trouble with prototypes.
378             # But if you are careful, you can do a lot of neat things with them. This is
379             # all very powerful, of course, and should only be used in moderation to make
380             # the world a better place.
381              
382             #
383             # Prototypes of subroutines
384             #
385 0     0   0 sub unimport {}
386             sub Elatin3::split(;$$$);
387             sub Elatin3::tr($$$$;$);
388             sub Elatin3::chop(@);
389             sub Elatin3::index($$;$);
390             sub Elatin3::rindex($$;$);
391             sub Elatin3::lcfirst(@);
392             sub Elatin3::lcfirst_();
393             sub Elatin3::lc(@);
394             sub Elatin3::lc_();
395             sub Elatin3::ucfirst(@);
396             sub Elatin3::ucfirst_();
397             sub Elatin3::uc(@);
398             sub Elatin3::uc_();
399             sub Elatin3::fc(@);
400             sub Elatin3::fc_();
401             sub Elatin3::ignorecase;
402             sub Elatin3::classic_character_class;
403             sub Elatin3::capture;
404             sub Elatin3::chr(;$);
405             sub Elatin3::chr_();
406             sub Elatin3::glob($);
407             sub Elatin3::glob_();
408              
409             sub Latin3::ord(;$);
410             sub Latin3::ord_();
411             sub Latin3::reverse(@);
412             sub Latin3::getc(;*@);
413             sub Latin3::length(;$);
414             sub Latin3::substr($$;$$);
415             sub Latin3::index($$;$);
416             sub Latin3::rindex($$;$);
417             sub Latin3::escape(;$);
418              
419             #
420             # Regexp work
421             #
422 200     200   21174 BEGIN { CORE::eval q{ use vars qw(
  200     200   2001  
  200         386  
  200         104751  
423             $Latin3::re_a
424             $Latin3::re_t
425             $Latin3::re_n
426             $Latin3::re_r
427             ) } }
428              
429             #
430             # Character class
431             #
432 200     200   19133 BEGIN { CORE::eval q{ use vars qw(
  200     200   1315  
  200         410  
  200         3590721  
433             $dot
434             $dot_s
435             $eD
436             $eS
437             $eW
438             $eH
439             $eV
440             $eR
441             $eN
442             $not_alnum
443             $not_alpha
444             $not_ascii
445             $not_blank
446             $not_cntrl
447             $not_digit
448             $not_graph
449             $not_lower
450             $not_lower_i
451             $not_print
452             $not_punct
453             $not_space
454             $not_upper
455             $not_upper_i
456             $not_word
457             $not_xdigit
458             $eb
459             $eB
460             ) } }
461              
462             ${Elatin3::dot} = qr{(?>[^\x0A])};
463             ${Elatin3::dot_s} = qr{(?>[\x00-\xFF])};
464             ${Elatin3::eD} = qr{(?>[^0-9])};
465              
466             # Vertical tabs are now whitespace
467             # \s in a regex now matches a vertical tab in all circumstances.
468             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
469             # ${Elatin3::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
470             # ${Elatin3::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
471             ${Elatin3::eS} = qr{(?>[^\s])};
472              
473             ${Elatin3::eW} = qr{(?>[^0-9A-Z_a-z])};
474             ${Elatin3::eH} = qr{(?>[^\x09\x20])};
475             ${Elatin3::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
476             ${Elatin3::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
477             ${Elatin3::eN} = qr{(?>[^\x0A])};
478             ${Elatin3::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
479             ${Elatin3::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
480             ${Elatin3::not_ascii} = qr{(?>[^\x00-\x7F])};
481             ${Elatin3::not_blank} = qr{(?>[^\x09\x20])};
482             ${Elatin3::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
483             ${Elatin3::not_digit} = qr{(?>[^\x30-\x39])};
484             ${Elatin3::not_graph} = qr{(?>[^\x21-\x7F])};
485             ${Elatin3::not_lower} = qr{(?>[^\x61-\x7A])};
486             ${Elatin3::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
487             # ${Elatin3::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
488             ${Elatin3::not_print} = qr{(?>[^\x20-\x7F])};
489             ${Elatin3::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
490             ${Elatin3::not_space} = qr{(?>[^\s\x0B])};
491             ${Elatin3::not_upper} = qr{(?>[^\x41-\x5A])};
492             ${Elatin3::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
493             # ${Elatin3::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
494             ${Elatin3::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
495             ${Elatin3::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
496             ${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))};
497             ${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]))};
498              
499             # avoid: Name "Elatin3::foo" used only once: possible typo at here.
500             ${Elatin3::dot} = ${Elatin3::dot};
501             ${Elatin3::dot_s} = ${Elatin3::dot_s};
502             ${Elatin3::eD} = ${Elatin3::eD};
503             ${Elatin3::eS} = ${Elatin3::eS};
504             ${Elatin3::eW} = ${Elatin3::eW};
505             ${Elatin3::eH} = ${Elatin3::eH};
506             ${Elatin3::eV} = ${Elatin3::eV};
507             ${Elatin3::eR} = ${Elatin3::eR};
508             ${Elatin3::eN} = ${Elatin3::eN};
509             ${Elatin3::not_alnum} = ${Elatin3::not_alnum};
510             ${Elatin3::not_alpha} = ${Elatin3::not_alpha};
511             ${Elatin3::not_ascii} = ${Elatin3::not_ascii};
512             ${Elatin3::not_blank} = ${Elatin3::not_blank};
513             ${Elatin3::not_cntrl} = ${Elatin3::not_cntrl};
514             ${Elatin3::not_digit} = ${Elatin3::not_digit};
515             ${Elatin3::not_graph} = ${Elatin3::not_graph};
516             ${Elatin3::not_lower} = ${Elatin3::not_lower};
517             ${Elatin3::not_lower_i} = ${Elatin3::not_lower_i};
518             ${Elatin3::not_print} = ${Elatin3::not_print};
519             ${Elatin3::not_punct} = ${Elatin3::not_punct};
520             ${Elatin3::not_space} = ${Elatin3::not_space};
521             ${Elatin3::not_upper} = ${Elatin3::not_upper};
522             ${Elatin3::not_upper_i} = ${Elatin3::not_upper_i};
523             ${Elatin3::not_word} = ${Elatin3::not_word};
524             ${Elatin3::not_xdigit} = ${Elatin3::not_xdigit};
525             ${Elatin3::eb} = ${Elatin3::eb};
526             ${Elatin3::eB} = ${Elatin3::eB};
527              
528             #
529             # Latin-3 split
530             #
531             sub Elatin3::split(;$$$) {
532              
533             # P.794 29.2.161. split
534             # in Chapter 29: Functions
535             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
536              
537             # P.951 split
538             # in Chapter 27: Functions
539             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
540              
541 0     0 0 0 my $pattern = $_[0];
542 0         0 my $string = $_[1];
543 0         0 my $limit = $_[2];
544              
545             # if $pattern is also omitted or is the literal space, " "
546 0 0       0 if (not defined $pattern) {
547 0         0 $pattern = ' ';
548             }
549              
550             # if $string is omitted, the function splits the $_ string
551 0 0       0 if (not defined $string) {
552 0 0       0 if (defined $_) {
553 0         0 $string = $_;
554             }
555             else {
556 0         0 $string = '';
557             }
558             }
559              
560 0         0 my @split = ();
561              
562             # when string is empty
563 0 0       0 if ($string eq '') {
    0          
564              
565             # resulting list value in list context
566 0 0       0 if (wantarray) {
567 0         0 return @split;
568             }
569              
570             # count of substrings in scalar context
571             else {
572 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
573 0         0 @_ = @split;
574 0         0 return scalar @_;
575             }
576             }
577              
578             # split's first argument is more consistently interpreted
579             #
580             # After some changes earlier in v5.17, split's behavior has been simplified:
581             # if the PATTERN argument evaluates to a string containing one space, it is
582             # treated the way that a literal string containing one space once was.
583             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
584              
585             # if $pattern is also omitted or is the literal space, " ", the function splits
586             # on whitespace, /\s+/, after skipping any leading whitespace
587             # (and so on)
588              
589             elsif ($pattern eq ' ') {
590 0 0       0 if (not defined $limit) {
591 0         0 return CORE::split(' ', $string);
592             }
593             else {
594 0         0 return CORE::split(' ', $string, $limit);
595             }
596             }
597              
598             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
599 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
600              
601             # a pattern capable of matching either the null string or something longer than the
602             # null string will split the value of $string into separate characters wherever it
603             # matches the null string between characters
604             # (and so on)
605              
606 0 0       0 if ('' =~ / \A $pattern \z /xms) {
607 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
608 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
609              
610             # P.1024 Appendix W.10 Multibyte Processing
611             # of ISBN 1-56592-224-7 CJKV Information Processing
612             # (and so on)
613              
614             # the //m modifier is assumed when you split on the pattern /^/
615             # (and so on)
616              
617             # V
618 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
619              
620             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
621             # is included in the resulting list, interspersed with the fields that are ordinarily returned
622             # (and so on)
623              
624 0         0 local $@;
625 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
626 0         0 push @split, CORE::eval('$' . $digit);
627             }
628             }
629             }
630              
631             else {
632 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
633              
634             # V
635 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
636 0         0 local $@;
637 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
638 0         0 push @split, CORE::eval('$' . $digit);
639             }
640             }
641             }
642             }
643              
644             elsif ($limit > 0) {
645 0 0       0 if ('' =~ / \A $pattern \z /xms) {
646 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
647 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
648              
649             # V
650 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
651 0         0 local $@;
652 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
653 0         0 push @split, CORE::eval('$' . $digit);
654             }
655             }
656             }
657             }
658             else {
659 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
660 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
661              
662             # V
663 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
664 0         0 local $@;
665 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
666 0         0 push @split, CORE::eval('$' . $digit);
667             }
668             }
669             }
670             }
671             }
672              
673 0 0       0 if (CORE::length($string) > 0) {
674 0         0 push @split, $string;
675             }
676              
677             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
678 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
679 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
680 0         0 pop @split;
681             }
682             }
683              
684             # resulting list value in list context
685 0 0       0 if (wantarray) {
686 0         0 return @split;
687             }
688              
689             # count of substrings in scalar context
690             else {
691 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
692 0         0 @_ = @split;
693 0         0 return scalar @_;
694             }
695             }
696              
697             #
698             # get last subexpression offsets
699             #
700             sub _last_subexpression_offsets {
701 0     0   0 my $pattern = $_[0];
702              
703             # remove comment
704 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
705              
706 0         0 my $modifier = '';
707 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
708 0         0 $modifier = $1;
709 0         0 $modifier =~ s/-[A-Za-z]*//;
710             }
711              
712             # with /x modifier
713 0         0 my @char = ();
714 0 0       0 if ($modifier =~ /x/oxms) {
715 0         0 @char = $pattern =~ /\G((?>
716             [^\\\#\[\(] |
717             \\ $q_char |
718             \# (?>[^\n]*) $ |
719             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
720             \(\? |
721             $q_char
722             ))/oxmsg;
723             }
724              
725             # without /x modifier
726             else {
727 0         0 @char = $pattern =~ /\G((?>
728             [^\\\[\(] |
729             \\ $q_char |
730             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
731             \(\? |
732             $q_char
733             ))/oxmsg;
734             }
735              
736 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
737             }
738              
739             #
740             # Latin-3 transliteration (tr///)
741             #
742             sub Elatin3::tr($$$$;$) {
743              
744 0     0 0 0 my $bind_operator = $_[1];
745 0         0 my $searchlist = $_[2];
746 0         0 my $replacementlist = $_[3];
747 0   0     0 my $modifier = $_[4] || '';
748              
749 0 0       0 if ($modifier =~ /r/oxms) {
750 0 0       0 if ($bind_operator =~ / !~ /oxms) {
751 0         0 croak "Using !~ with tr///r doesn't make sense";
752             }
753             }
754              
755 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
756 0         0 my @searchlist = _charlist_tr($searchlist);
757 0         0 my @replacementlist = _charlist_tr($replacementlist);
758              
759 0         0 my %tr = ();
760 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
761 0 0       0 if (not exists $tr{$searchlist[$i]}) {
762 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
763 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
764             }
765             elsif ($modifier =~ /d/oxms) {
766 0         0 $tr{$searchlist[$i]} = '';
767             }
768             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
769 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
770             }
771             else {
772 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
773             }
774             }
775             }
776              
777 0         0 my $tr = 0;
778 0         0 my $replaced = '';
779 0 0       0 if ($modifier =~ /c/oxms) {
780 0         0 while (defined(my $char = shift @char)) {
781 0 0       0 if (not exists $tr{$char}) {
782 0 0       0 if (defined $replacementlist[0]) {
783 0         0 $replaced .= $replacementlist[0];
784             }
785 0         0 $tr++;
786 0 0       0 if ($modifier =~ /s/oxms) {
787 0   0     0 while (@char and (not exists $tr{$char[0]})) {
788 0         0 shift @char;
789 0         0 $tr++;
790             }
791             }
792             }
793             else {
794 0         0 $replaced .= $char;
795             }
796             }
797             }
798             else {
799 0         0 while (defined(my $char = shift @char)) {
800 0 0       0 if (exists $tr{$char}) {
801 0         0 $replaced .= $tr{$char};
802 0         0 $tr++;
803 0 0       0 if ($modifier =~ /s/oxms) {
804 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
805 0         0 shift @char;
806 0         0 $tr++;
807             }
808             }
809             }
810             else {
811 0         0 $replaced .= $char;
812             }
813             }
814             }
815              
816 0 0       0 if ($modifier =~ /r/oxms) {
817 0         0 return $replaced;
818             }
819             else {
820 0         0 $_[0] = $replaced;
821 0 0       0 if ($bind_operator =~ / !~ /oxms) {
822 0         0 return not $tr;
823             }
824             else {
825 0         0 return $tr;
826             }
827             }
828             }
829              
830             #
831             # Latin-3 chop
832             #
833             sub Elatin3::chop(@) {
834              
835 0     0 0 0 my $chop;
836 0 0       0 if (@_ == 0) {
837 0         0 my @char = /\G (?>$q_char) /oxmsg;
838 0         0 $chop = pop @char;
839 0         0 $_ = join '', @char;
840             }
841             else {
842 0         0 for (@_) {
843 0         0 my @char = /\G (?>$q_char) /oxmsg;
844 0         0 $chop = pop @char;
845 0         0 $_ = join '', @char;
846             }
847             }
848 0         0 return $chop;
849             }
850              
851             #
852             # Latin-3 index by octet
853             #
854             sub Elatin3::index($$;$) {
855              
856 0     0 1 0 my($str,$substr,$position) = @_;
857 0   0     0 $position ||= 0;
858 0         0 my $pos = 0;
859              
860 0         0 while ($pos < CORE::length($str)) {
861 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
862 0 0       0 if ($pos >= $position) {
863 0         0 return $pos;
864             }
865             }
866 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
867 0         0 $pos += CORE::length($1);
868             }
869             else {
870 0         0 $pos += 1;
871             }
872             }
873 0         0 return -1;
874             }
875              
876             #
877             # Latin-3 reverse index
878             #
879             sub Elatin3::rindex($$;$) {
880              
881 0     0 0 0 my($str,$substr,$position) = @_;
882 0   0     0 $position ||= CORE::length($str) - 1;
883 0         0 my $pos = 0;
884 0         0 my $rindex = -1;
885              
886 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
887 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
888 0         0 $rindex = $pos;
889             }
890 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
891 0         0 $pos += CORE::length($1);
892             }
893             else {
894 0         0 $pos += 1;
895             }
896             }
897 0         0 return $rindex;
898             }
899              
900             #
901             # Latin-3 lower case first with parameter
902             #
903             sub Elatin3::lcfirst(@) {
904 0 0   0 0 0 if (@_) {
905 0         0 my $s = shift @_;
906 0 0 0     0 if (@_ and wantarray) {
907 0         0 return Elatin3::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
908             }
909             else {
910 0         0 return Elatin3::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
911             }
912             }
913             else {
914 0         0 return Elatin3::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
915             }
916             }
917              
918             #
919             # Latin-3 lower case first without parameter
920             #
921             sub Elatin3::lcfirst_() {
922 0     0 0 0 return Elatin3::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
923             }
924              
925             #
926             # Latin-3 lower case with parameter
927             #
928             sub Elatin3::lc(@) {
929 0 0   0 0 0 if (@_) {
930 0         0 my $s = shift @_;
931 0 0 0     0 if (@_ and wantarray) {
932 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
933             }
934             else {
935 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
936             }
937             }
938             else {
939 0         0 return Elatin3::lc_();
940             }
941             }
942              
943             #
944             # Latin-3 lower case without parameter
945             #
946             sub Elatin3::lc_() {
947 0     0 0 0 my $s = $_;
948 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
949             }
950              
951             #
952             # Latin-3 upper case first with parameter
953             #
954             sub Elatin3::ucfirst(@) {
955 0 0   0 0 0 if (@_) {
956 0         0 my $s = shift @_;
957 0 0 0     0 if (@_ and wantarray) {
958 0         0 return Elatin3::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
959             }
960             else {
961 0         0 return Elatin3::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
962             }
963             }
964             else {
965 0         0 return Elatin3::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
966             }
967             }
968              
969             #
970             # Latin-3 upper case first without parameter
971             #
972             sub Elatin3::ucfirst_() {
973 0     0 0 0 return Elatin3::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
974             }
975              
976             #
977             # Latin-3 upper case with parameter
978             #
979             sub Elatin3::uc(@) {
980 0 0   0 0 0 if (@_) {
981 0         0 my $s = shift @_;
982 0 0 0     0 if (@_ and wantarray) {
983 0 0       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
984             }
985             else {
986 0 0       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
987             }
988             }
989             else {
990 0         0 return Elatin3::uc_();
991             }
992             }
993              
994             #
995             # Latin-3 upper case without parameter
996             #
997             sub Elatin3::uc_() {
998 0     0 0 0 my $s = $_;
999 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1000             }
1001              
1002             #
1003             # Latin-3 fold case with parameter
1004             #
1005             sub Elatin3::fc(@) {
1006 0 0   0 0 0 if (@_) {
1007 0         0 my $s = shift @_;
1008 0 0 0     0 if (@_ and wantarray) {
1009 0 0       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1010             }
1011             else {
1012 0 0       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
1013             }
1014             }
1015             else {
1016 0         0 return Elatin3::fc_();
1017             }
1018             }
1019              
1020             #
1021             # Latin-3 fold case without parameter
1022             #
1023             sub Elatin3::fc_() {
1024 0     0 0 0 my $s = $_;
1025 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1026             }
1027              
1028             #
1029             # Latin-3 regexp capture
1030             #
1031             {
1032             sub Elatin3::capture {
1033 0     0 1 0 return $_[0];
1034             }
1035             }
1036              
1037             #
1038             # Latin-3 regexp ignore case modifier
1039             #
1040             sub Elatin3::ignorecase {
1041              
1042 0     0 0 0 my @string = @_;
1043 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1044              
1045             # ignore case of $scalar or @array
1046 0         0 for my $string (@string) {
1047              
1048             # split regexp
1049 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1050              
1051             # unescape character
1052 0         0 for (my $i=0; $i <= $#char; $i++) {
1053 0 0       0 next if not defined $char[$i];
1054              
1055             # open character class [...]
1056 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1057 0         0 my $left = $i;
1058              
1059             # [] make die "unmatched [] in regexp ...\n"
1060              
1061 0 0       0 if ($char[$i+1] eq ']') {
1062 0         0 $i++;
1063             }
1064              
1065 0         0 while (1) {
1066 0 0       0 if (++$i > $#char) {
1067 0         0 croak "Unmatched [] in regexp";
1068             }
1069 0 0       0 if ($char[$i] eq ']') {
1070 0         0 my $right = $i;
1071 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1072              
1073             # escape character
1074 0         0 for my $char (@charlist) {
1075 0 0       0 if (0) {
1076             }
1077              
1078 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1079 0         0 $char = '\\' . $char;
1080             }
1081             }
1082              
1083             # [...]
1084 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1085              
1086 0         0 $i = $left;
1087 0         0 last;
1088             }
1089             }
1090             }
1091              
1092             # open character class [^...]
1093             elsif ($char[$i] eq '[^') {
1094 0         0 my $left = $i;
1095              
1096             # [^] make die "unmatched [] in regexp ...\n"
1097              
1098 0 0       0 if ($char[$i+1] eq ']') {
1099 0         0 $i++;
1100             }
1101              
1102 0         0 while (1) {
1103 0 0       0 if (++$i > $#char) {
1104 0         0 croak "Unmatched [] in regexp";
1105             }
1106 0 0       0 if ($char[$i] eq ']') {
1107 0         0 my $right = $i;
1108 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1109              
1110             # escape character
1111 0         0 for my $char (@charlist) {
1112 0 0       0 if (0) {
1113             }
1114              
1115 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1116 0         0 $char = '\\' . $char;
1117             }
1118             }
1119              
1120             # [^...]
1121 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1122              
1123 0         0 $i = $left;
1124 0         0 last;
1125             }
1126             }
1127             }
1128              
1129             # rewrite classic character class or escape character
1130             elsif (my $char = classic_character_class($char[$i])) {
1131 0         0 $char[$i] = $char;
1132             }
1133              
1134             # with /i modifier
1135             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1136 0         0 my $uc = Elatin3::uc($char[$i]);
1137 0         0 my $fc = Elatin3::fc($char[$i]);
1138 0 0       0 if ($uc ne $fc) {
1139 0 0       0 if (CORE::length($fc) == 1) {
1140 0         0 $char[$i] = '[' . $uc . $fc . ']';
1141             }
1142             else {
1143 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1144             }
1145             }
1146             }
1147             }
1148              
1149             # characterize
1150 0         0 for (my $i=0; $i <= $#char; $i++) {
1151 0 0       0 next if not defined $char[$i];
1152              
1153 0 0       0 if (0) {
1154             }
1155              
1156             # quote character before ? + * {
1157 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1158 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1159 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1160             }
1161             }
1162             }
1163              
1164 0         0 $string = join '', @char;
1165             }
1166              
1167             # make regexp string
1168 0         0 return @string;
1169             }
1170              
1171             #
1172             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1173             #
1174             sub Elatin3::classic_character_class {
1175 0     0 0 0 my($char) = @_;
1176              
1177             return {
1178 0   0     0 '\D' => '${Elatin3::eD}',
1179             '\S' => '${Elatin3::eS}',
1180             '\W' => '${Elatin3::eW}',
1181             '\d' => '[0-9]',
1182              
1183             # Before Perl 5.6, \s only matched the five whitespace characters
1184             # tab, newline, form-feed, carriage return, and the space character
1185             # itself, which, taken together, is the character class [\t\n\f\r ].
1186              
1187             # Vertical tabs are now whitespace
1188             # \s in a regex now matches a vertical tab in all circumstances.
1189             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1190             # \t \n \v \f \r space
1191             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1192             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1193             '\s' => '\s',
1194              
1195             '\w' => '[0-9A-Z_a-z]',
1196             '\C' => '[\x00-\xFF]',
1197             '\X' => 'X',
1198              
1199             # \h \v \H \V
1200              
1201             # P.114 Character Class Shortcuts
1202             # in Chapter 7: In the World of Regular Expressions
1203             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1204              
1205             # P.357 13.2.3 Whitespace
1206             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1207             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1208             #
1209             # 0x00009 CHARACTER TABULATION h s
1210             # 0x0000a LINE FEED (LF) vs
1211             # 0x0000b LINE TABULATION v
1212             # 0x0000c FORM FEED (FF) vs
1213             # 0x0000d CARRIAGE RETURN (CR) vs
1214             # 0x00020 SPACE h s
1215              
1216             # P.196 Table 5-9. Alphanumeric regex metasymbols
1217             # in Chapter 5. Pattern Matching
1218             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1219              
1220             # (and so on)
1221              
1222             '\H' => '${Elatin3::eH}',
1223             '\V' => '${Elatin3::eV}',
1224             '\h' => '[\x09\x20]',
1225             '\v' => '[\x0A\x0B\x0C\x0D]',
1226             '\R' => '${Elatin3::eR}',
1227              
1228             # \N
1229             #
1230             # http://perldoc.perl.org/perlre.html
1231             # Character Classes and other Special Escapes
1232             # Any character but \n (experimental). Not affected by /s modifier
1233              
1234             '\N' => '${Elatin3::eN}',
1235              
1236             # \b \B
1237              
1238             # P.180 Boundaries: The \b and \B Assertions
1239             # in Chapter 5: Pattern Matching
1240             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1241              
1242             # P.219 Boundaries: The \b and \B Assertions
1243             # in Chapter 5: Pattern Matching
1244             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1245              
1246             # \b really means (?:(?<=\w)(?!\w)|(?
1247             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1248             '\b' => '${Elatin3::eb}',
1249              
1250             # \B really means (?:(?<=\w)(?=\w)|(?
1251             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1252             '\B' => '${Elatin3::eB}',
1253              
1254             }->{$char} || '';
1255             }
1256              
1257             #
1258             # prepare Latin-3 characters per length
1259             #
1260              
1261             # 1 octet characters
1262             my @chars1 = ();
1263             sub chars1 {
1264 0 0   0 0 0 if (@chars1) {
1265 0         0 return @chars1;
1266             }
1267 0 0       0 if (exists $range_tr{1}) {
1268 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1269 0         0 while (my @range = splice(@ranges,0,1)) {
1270 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1271 0         0 push @chars1, pack 'C', $oct0;
1272             }
1273             }
1274             }
1275 0         0 return @chars1;
1276             }
1277              
1278             # 2 octets characters
1279             my @chars2 = ();
1280             sub chars2 {
1281 0 0   0 0 0 if (@chars2) {
1282 0         0 return @chars2;
1283             }
1284 0 0       0 if (exists $range_tr{2}) {
1285 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1286 0         0 while (my @range = splice(@ranges,0,2)) {
1287 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1288 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1289 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1290             }
1291             }
1292             }
1293             }
1294 0         0 return @chars2;
1295             }
1296              
1297             # 3 octets characters
1298             my @chars3 = ();
1299             sub chars3 {
1300 0 0   0 0 0 if (@chars3) {
1301 0         0 return @chars3;
1302             }
1303 0 0       0 if (exists $range_tr{3}) {
1304 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1305 0         0 while (my @range = splice(@ranges,0,3)) {
1306 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1307 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1308 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1309 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1310             }
1311             }
1312             }
1313             }
1314             }
1315 0         0 return @chars3;
1316             }
1317              
1318             # 4 octets characters
1319             my @chars4 = ();
1320             sub chars4 {
1321 0 0   0 0 0 if (@chars4) {
1322 0         0 return @chars4;
1323             }
1324 0 0       0 if (exists $range_tr{4}) {
1325 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1326 0         0 while (my @range = splice(@ranges,0,4)) {
1327 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1328 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1329 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1330 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1331 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1332             }
1333             }
1334             }
1335             }
1336             }
1337             }
1338 0         0 return @chars4;
1339             }
1340              
1341             #
1342             # Latin-3 open character list for tr
1343             #
1344             sub _charlist_tr {
1345              
1346 0     0   0 local $_ = shift @_;
1347              
1348             # unescape character
1349 0         0 my @char = ();
1350 0         0 while (not /\G \z/oxmsgc) {
1351 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1352 0         0 push @char, '\-';
1353             }
1354             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1355 0         0 push @char, CORE::chr(oct $1);
1356             }
1357             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1358 0         0 push @char, CORE::chr(hex $1);
1359             }
1360             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1361 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1362             }
1363             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1364 0         0 push @char, {
1365             '\0' => "\0",
1366             '\n' => "\n",
1367             '\r' => "\r",
1368             '\t' => "\t",
1369             '\f' => "\f",
1370             '\b' => "\x08", # \b means backspace in character class
1371             '\a' => "\a",
1372             '\e' => "\e",
1373             }->{$1};
1374             }
1375             elsif (/\G \\ ($q_char) /oxmsgc) {
1376 0         0 push @char, $1;
1377             }
1378             elsif (/\G ($q_char) /oxmsgc) {
1379 0         0 push @char, $1;
1380             }
1381             }
1382              
1383             # join separated multiple-octet
1384 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1385              
1386             # unescape '-'
1387 0         0 my @i = ();
1388 0         0 for my $i (0 .. $#char) {
1389 0 0       0 if ($char[$i] eq '\-') {
    0          
1390 0         0 $char[$i] = '-';
1391             }
1392             elsif ($char[$i] eq '-') {
1393 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1394 0         0 push @i, $i;
1395             }
1396             }
1397             }
1398              
1399             # open character list (reverse for splice)
1400 0         0 for my $i (CORE::reverse @i) {
1401 0         0 my @range = ();
1402              
1403             # range error
1404 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1405 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1406             }
1407              
1408             # range of multiple-octet code
1409 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1410 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1411 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1412             }
1413             elsif (CORE::length($char[$i+1]) == 2) {
1414 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1415 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1416             }
1417             elsif (CORE::length($char[$i+1]) == 3) {
1418 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1419 0         0 push @range, chars2();
1420 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1421             }
1422             elsif (CORE::length($char[$i+1]) == 4) {
1423 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1424 0         0 push @range, chars2();
1425 0         0 push @range, chars3();
1426 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1427             }
1428             else {
1429 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1430             }
1431             }
1432             elsif (CORE::length($char[$i-1]) == 2) {
1433 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1434 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1435             }
1436             elsif (CORE::length($char[$i+1]) == 3) {
1437 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1438 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1439             }
1440             elsif (CORE::length($char[$i+1]) == 4) {
1441 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1442 0         0 push @range, chars3();
1443 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1444             }
1445             else {
1446 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1447             }
1448             }
1449             elsif (CORE::length($char[$i-1]) == 3) {
1450 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1451 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1452             }
1453             elsif (CORE::length($char[$i+1]) == 4) {
1454 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1455 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1456             }
1457             else {
1458 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1459             }
1460             }
1461             elsif (CORE::length($char[$i-1]) == 4) {
1462 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1463 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1464             }
1465             else {
1466 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1467             }
1468             }
1469             else {
1470 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1471             }
1472              
1473 0         0 splice @char, $i-1, 3, @range;
1474             }
1475              
1476 0         0 return @char;
1477             }
1478              
1479             #
1480             # Latin-3 open character class
1481             #
1482             sub _cc {
1483 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1484 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1485             }
1486             elsif (scalar(@_) == 1) {
1487 0         0 return sprintf('\x%02X',$_[0]);
1488             }
1489             elsif (scalar(@_) == 2) {
1490 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1491 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1492             }
1493             elsif ($_[0] == $_[1]) {
1494 0         0 return sprintf('\x%02X',$_[0]);
1495             }
1496             elsif (($_[0]+1) == $_[1]) {
1497 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1498             }
1499             else {
1500 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1501             }
1502             }
1503             else {
1504 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1505             }
1506             }
1507              
1508             #
1509             # Latin-3 octet range
1510             #
1511             sub _octets {
1512 0     0   0 my $length = shift @_;
1513              
1514 0 0       0 if ($length == 1) {
1515 0         0 my($a1) = unpack 'C', $_[0];
1516 0         0 my($z1) = unpack 'C', $_[1];
1517              
1518 0 0       0 if ($a1 > $z1) {
1519 0         0 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1520             }
1521              
1522 0 0       0 if ($a1 == $z1) {
    0          
1523 0         0 return sprintf('\x%02X',$a1);
1524             }
1525             elsif (($a1+1) == $z1) {
1526 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1527             }
1528             else {
1529 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1530             }
1531             }
1532             else {
1533 0         0 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1534             }
1535             }
1536              
1537             #
1538             # Latin-3 range regexp
1539             #
1540             sub _range_regexp {
1541 0     0   0 my($length,$first,$last) = @_;
1542              
1543 0         0 my @range_regexp = ();
1544 0 0       0 if (not exists $range_tr{$length}) {
1545 0         0 return @range_regexp;
1546             }
1547              
1548 0         0 my @ranges = @{ $range_tr{$length} };
  0         0  
1549 0         0 while (my @range = splice(@ranges,0,$length)) {
1550 0         0 my $min = '';
1551 0         0 my $max = '';
1552 0         0 for (my $i=0; $i < $length; $i++) {
1553 0         0 $min .= pack 'C', $range[$i][0];
1554 0         0 $max .= pack 'C', $range[$i][-1];
1555             }
1556              
1557             # min___max
1558             # FIRST_____________LAST
1559             # (nothing)
1560              
1561 0 0 0     0 if ($max lt $first) {
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
1562             }
1563              
1564             # **********
1565             # min_________max
1566             # FIRST_____________LAST
1567             # **********
1568              
1569             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1570 0         0 push @range_regexp, _octets($length,$first,$max,$min,$max);
1571             }
1572              
1573             # **********************
1574             # min________________max
1575             # FIRST_____________LAST
1576             # **********************
1577              
1578             elsif (($min eq $first) and ($max eq $last)) {
1579 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1580             }
1581              
1582             # *********
1583             # min___max
1584             # FIRST_____________LAST
1585             # *********
1586              
1587             elsif (($first le $min) and ($max le $last)) {
1588 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1589             }
1590              
1591             # **********************
1592             # min__________________________max
1593             # FIRST_____________LAST
1594             # **********************
1595              
1596             elsif (($min le $first) and ($last le $max)) {
1597 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1598             }
1599              
1600             # *********
1601             # min________max
1602             # FIRST_____________LAST
1603             # *********
1604              
1605             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1606 0         0 push @range_regexp, _octets($length,$min,$last,$min,$max);
1607             }
1608              
1609             # min___max
1610             # FIRST_____________LAST
1611             # (nothing)
1612              
1613             elsif ($last lt $min) {
1614             }
1615              
1616             else {
1617 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1618             }
1619             }
1620              
1621 0         0 return @range_regexp;
1622             }
1623              
1624             #
1625             # Latin-3 open character list for qr and not qr
1626             #
1627             sub _charlist {
1628              
1629 0     0   0 my $modifier = pop @_;
1630 0         0 my @char = @_;
1631              
1632 0 0       0 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1633              
1634             # unescape character
1635 0         0 for (my $i=0; $i <= $#char; $i++) {
1636              
1637             # escape - to ...
1638 0 0 0     0 if ($char[$i] eq '-') {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1639 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1640 0         0 $char[$i] = '...';
1641             }
1642             }
1643              
1644             # octal escape sequence
1645             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1646 0         0 $char[$i] = octchr($1);
1647             }
1648              
1649             # hexadecimal escape sequence
1650             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1651 0         0 $char[$i] = hexchr($1);
1652             }
1653              
1654             # \b{...} --> b\{...}
1655             # \B{...} --> B\{...}
1656             # \N{CHARNAME} --> N\{CHARNAME}
1657             # \p{PROPERTY} --> p\{PROPERTY}
1658             # \P{PROPERTY} --> P\{PROPERTY}
1659             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1660 0         0 $char[$i] = $1 . '\\' . $2;
1661             }
1662              
1663             # \p, \P, \X --> p, P, X
1664             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1665 0         0 $char[$i] = $1;
1666             }
1667              
1668             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1669 0         0 $char[$i] = CORE::chr oct $1;
1670             }
1671             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1672 0         0 $char[$i] = CORE::chr hex $1;
1673             }
1674             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1675 0         0 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1676             }
1677             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1678 0         0 $char[$i] = {
1679             '\0' => "\0",
1680             '\n' => "\n",
1681             '\r' => "\r",
1682             '\t' => "\t",
1683             '\f' => "\f",
1684             '\b' => "\x08", # \b means backspace in character class
1685             '\a' => "\a",
1686             '\e' => "\e",
1687             '\d' => '[0-9]',
1688              
1689             # Vertical tabs are now whitespace
1690             # \s in a regex now matches a vertical tab in all circumstances.
1691             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1692             # \t \n \v \f \r space
1693             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1694             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1695             '\s' => '\s',
1696              
1697             '\w' => '[0-9A-Z_a-z]',
1698             '\D' => '${Elatin3::eD}',
1699             '\S' => '${Elatin3::eS}',
1700             '\W' => '${Elatin3::eW}',
1701              
1702             '\H' => '${Elatin3::eH}',
1703             '\V' => '${Elatin3::eV}',
1704             '\h' => '[\x09\x20]',
1705             '\v' => '[\x0A\x0B\x0C\x0D]',
1706             '\R' => '${Elatin3::eR}',
1707              
1708             }->{$1};
1709             }
1710              
1711             # POSIX-style character classes
1712             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1713 0         0 $char[$i] = {
1714              
1715             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1716             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1717             '[:^lower:]' => '${Elatin3::not_lower_i}',
1718             '[:^upper:]' => '${Elatin3::not_upper_i}',
1719              
1720             }->{$1};
1721             }
1722             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1723 0         0 $char[$i] = {
1724              
1725             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1726             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1727             '[:ascii:]' => '[\x00-\x7F]',
1728             '[:blank:]' => '[\x09\x20]',
1729             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1730             '[:digit:]' => '[\x30-\x39]',
1731             '[:graph:]' => '[\x21-\x7F]',
1732             '[:lower:]' => '[\x61-\x7A]',
1733             '[:print:]' => '[\x20-\x7F]',
1734             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1735              
1736             # P.174 POSIX-Style Character Classes
1737             # in Chapter 5: Pattern Matching
1738             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1739              
1740             # P.311 11.2.4 Character Classes and other Special Escapes
1741             # in Chapter 11: perlre: Perl regular expressions
1742             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1743              
1744             # P.210 POSIX-Style Character Classes
1745             # in Chapter 5: Pattern Matching
1746             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1747              
1748             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1749              
1750             '[:upper:]' => '[\x41-\x5A]',
1751             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1752             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1753             '[:^alnum:]' => '${Elatin3::not_alnum}',
1754             '[:^alpha:]' => '${Elatin3::not_alpha}',
1755             '[:^ascii:]' => '${Elatin3::not_ascii}',
1756             '[:^blank:]' => '${Elatin3::not_blank}',
1757             '[:^cntrl:]' => '${Elatin3::not_cntrl}',
1758             '[:^digit:]' => '${Elatin3::not_digit}',
1759             '[:^graph:]' => '${Elatin3::not_graph}',
1760             '[:^lower:]' => '${Elatin3::not_lower}',
1761             '[:^print:]' => '${Elatin3::not_print}',
1762             '[:^punct:]' => '${Elatin3::not_punct}',
1763             '[:^space:]' => '${Elatin3::not_space}',
1764             '[:^upper:]' => '${Elatin3::not_upper}',
1765             '[:^word:]' => '${Elatin3::not_word}',
1766             '[:^xdigit:]' => '${Elatin3::not_xdigit}',
1767              
1768             }->{$1};
1769             }
1770             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1771 0         0 $char[$i] = $1;
1772             }
1773             }
1774              
1775             # open character list
1776 0         0 my @singleoctet = ();
1777 0         0 my @multipleoctet = ();
1778 0         0 for (my $i=0; $i <= $#char; ) {
1779              
1780             # escaped -
1781 0 0 0     0 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    0          
    0          
    0          
    0          
    0          
1782 0         0 $i += 1;
1783 0         0 next;
1784             }
1785              
1786             # make range regexp
1787             elsif ($char[$i] eq '...') {
1788              
1789             # range error
1790 0 0       0 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    0          
1791 0         0 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1792             }
1793             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1794 0 0       0 if ($char[$i-1] gt $char[$i+1]) {
1795 0         0 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1796             }
1797             }
1798              
1799             # make range regexp per length
1800 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1801 0         0 my @regexp = ();
1802              
1803             # is first and last
1804 0 0 0     0 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1805 0         0 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1806             }
1807              
1808             # is first
1809             elsif ($length == CORE::length($char[$i-1])) {
1810 0         0 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1811             }
1812              
1813             # is inside in first and last
1814             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1815 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1816             }
1817              
1818             # is last
1819             elsif ($length == CORE::length($char[$i+1])) {
1820 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1821             }
1822              
1823             else {
1824 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1825             }
1826              
1827 0 0       0 if ($length == 1) {
1828 0         0 push @singleoctet, @regexp;
1829             }
1830             else {
1831 0         0 push @multipleoctet, @regexp;
1832             }
1833             }
1834              
1835 0         0 $i += 2;
1836             }
1837              
1838             # with /i modifier
1839             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1840 0 0       0 if ($modifier =~ /i/oxms) {
1841 0         0 my $uc = Elatin3::uc($char[$i]);
1842 0         0 my $fc = Elatin3::fc($char[$i]);
1843 0 0       0 if ($uc ne $fc) {
1844 0 0       0 if (CORE::length($fc) == 1) {
1845 0         0 push @singleoctet, $uc, $fc;
1846             }
1847             else {
1848 0         0 push @singleoctet, $uc;
1849 0         0 push @multipleoctet, $fc;
1850             }
1851             }
1852             else {
1853 0         0 push @singleoctet, $char[$i];
1854             }
1855             }
1856             else {
1857 0         0 push @singleoctet, $char[$i];
1858             }
1859 0         0 $i += 1;
1860             }
1861              
1862             # single character of single octet code
1863             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1864 0         0 push @singleoctet, "\t", "\x20";
1865 0         0 $i += 1;
1866             }
1867             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1868 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1869 0         0 $i += 1;
1870             }
1871             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1872 0         0 push @singleoctet, $char[$i];
1873 0         0 $i += 1;
1874             }
1875              
1876             # single character of multiple-octet code
1877             else {
1878 0         0 push @multipleoctet, $char[$i];
1879 0         0 $i += 1;
1880             }
1881             }
1882              
1883             # quote metachar
1884 0         0 for (@singleoctet) {
1885 0 0       0 if ($_ eq '...') {
    0          
    0          
    0          
    0          
1886 0         0 $_ = '-';
1887             }
1888             elsif (/\A \n \z/oxms) {
1889 0         0 $_ = '\n';
1890             }
1891             elsif (/\A \r \z/oxms) {
1892 0         0 $_ = '\r';
1893             }
1894             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1895 0         0 $_ = sprintf('\x%02X', CORE::ord $1);
1896             }
1897             elsif (/\A [\x00-\xFF] \z/oxms) {
1898 0         0 $_ = quotemeta $_;
1899             }
1900             }
1901              
1902             # return character list
1903 0         0 return \@singleoctet, \@multipleoctet;
1904             }
1905              
1906             #
1907             # Latin-3 octal escape sequence
1908             #
1909             sub octchr {
1910 0     0 0 0 my($octdigit) = @_;
1911              
1912 0         0 my @binary = ();
1913 0         0 for my $octal (split(//,$octdigit)) {
1914 0         0 push @binary, {
1915             '0' => '000',
1916             '1' => '001',
1917             '2' => '010',
1918             '3' => '011',
1919             '4' => '100',
1920             '5' => '101',
1921             '6' => '110',
1922             '7' => '111',
1923             }->{$octal};
1924             }
1925 0         0 my $binary = join '', @binary;
1926              
1927 0         0 my $octchr = {
1928             # 1234567
1929             1 => pack('B*', "0000000$binary"),
1930             2 => pack('B*', "000000$binary"),
1931             3 => pack('B*', "00000$binary"),
1932             4 => pack('B*', "0000$binary"),
1933             5 => pack('B*', "000$binary"),
1934             6 => pack('B*', "00$binary"),
1935             7 => pack('B*', "0$binary"),
1936             0 => pack('B*', "$binary"),
1937              
1938             }->{CORE::length($binary) % 8};
1939              
1940 0         0 return $octchr;
1941             }
1942              
1943             #
1944             # Latin-3 hexadecimal escape sequence
1945             #
1946             sub hexchr {
1947 0     0 0 0 my($hexdigit) = @_;
1948              
1949 0         0 my $hexchr = {
1950             1 => pack('H*', "0$hexdigit"),
1951             0 => pack('H*', "$hexdigit"),
1952              
1953             }->{CORE::length($_[0]) % 2};
1954              
1955 0         0 return $hexchr;
1956             }
1957              
1958             #
1959             # Latin-3 open character list for qr
1960             #
1961             sub charlist_qr {
1962              
1963 0     0 0 0 my $modifier = pop @_;
1964 0         0 my @char = @_;
1965              
1966 0         0 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1967 0         0 my @singleoctet = @$singleoctet;
1968 0         0 my @multipleoctet = @$multipleoctet;
1969              
1970             # return character list
1971 0 0       0 if (scalar(@singleoctet) >= 1) {
1972              
1973             # with /i modifier
1974 0 0       0 if ($modifier =~ m/i/oxms) {
1975 0         0 my %singleoctet_ignorecase = ();
1976 0         0 for (@singleoctet) {
1977 0   0     0 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1978 0         0 for my $ord (hex($1) .. hex($2)) {
1979 0         0 my $char = CORE::chr($ord);
1980 0         0 my $uc = Elatin3::uc($char);
1981 0         0 my $fc = Elatin3::fc($char);
1982 0 0       0 if ($uc eq $fc) {
1983 0         0 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1984             }
1985             else {
1986 0 0       0 if (CORE::length($fc) == 1) {
1987 0         0 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1988 0         0 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1989             }
1990             else {
1991 0         0 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1992 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1993             }
1994             }
1995             }
1996             }
1997 0 0       0 if ($_ ne '') {
1998 0         0 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1999             }
2000             }
2001 0         0 my $i = 0;
2002 0         0 my @singleoctet_ignorecase = ();
2003 0         0 for my $ord (0 .. 255) {
2004 0 0       0 if (exists $singleoctet_ignorecase{$ord}) {
2005 0         0 push @{$singleoctet_ignorecase[$i]}, $ord;
  0         0  
2006             }
2007             else {
2008 0         0 $i++;
2009             }
2010             }
2011 0         0 @singleoctet = ();
2012 0         0 for my $range (@singleoctet_ignorecase) {
2013 0 0       0 if (ref $range) {
2014 0 0       0 if (scalar(@{$range}) == 1) {
  0 0       0  
  0         0  
2015 0         0 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2016             }
2017             elsif (scalar(@{$range}) == 2) {
2018 0         0 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2019             }
2020             else {
2021 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2022             }
2023             }
2024             }
2025             }
2026              
2027 0         0 my $not_anchor = '';
2028              
2029 0         0 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2030             }
2031 0 0       0 if (scalar(@multipleoctet) >= 2) {
2032 0         0 return '(?:' . join('|', @multipleoctet) . ')';
2033             }
2034             else {
2035 0         0 return $multipleoctet[0];
2036             }
2037             }
2038              
2039             #
2040             # Latin-3 open character list for not qr
2041             #
2042             sub charlist_not_qr {
2043              
2044 0     0 0 0 my $modifier = pop @_;
2045 0         0 my @char = @_;
2046              
2047 0         0 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2048 0         0 my @singleoctet = @$singleoctet;
2049 0         0 my @multipleoctet = @$multipleoctet;
2050              
2051             # with /i modifier
2052 0 0       0 if ($modifier =~ m/i/oxms) {
2053 0         0 my %singleoctet_ignorecase = ();
2054 0         0 for (@singleoctet) {
2055 0   0     0 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2056 0         0 for my $ord (hex($1) .. hex($2)) {
2057 0         0 my $char = CORE::chr($ord);
2058 0         0 my $uc = Elatin3::uc($char);
2059 0         0 my $fc = Elatin3::fc($char);
2060 0 0       0 if ($uc eq $fc) {
2061 0         0 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2062             }
2063             else {
2064 0 0       0 if (CORE::length($fc) == 1) {
2065 0         0 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2066 0         0 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2067             }
2068             else {
2069 0         0 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2070 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2071             }
2072             }
2073             }
2074             }
2075 0 0       0 if ($_ ne '') {
2076 0         0 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2077             }
2078             }
2079 0         0 my $i = 0;
2080 0         0 my @singleoctet_ignorecase = ();
2081 0         0 for my $ord (0 .. 255) {
2082 0 0       0 if (exists $singleoctet_ignorecase{$ord}) {
2083 0         0 push @{$singleoctet_ignorecase[$i]}, $ord;
  0         0  
2084             }
2085             else {
2086 0         0 $i++;
2087             }
2088             }
2089 0         0 @singleoctet = ();
2090 0         0 for my $range (@singleoctet_ignorecase) {
2091 0 0       0 if (ref $range) {
2092 0 0       0 if (scalar(@{$range}) == 1) {
  0 0       0  
  0         0  
2093 0         0 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2094             }
2095             elsif (scalar(@{$range}) == 2) {
2096 0         0 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2097             }
2098             else {
2099 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2100             }
2101             }
2102             }
2103             }
2104              
2105             # return character list
2106 0 0       0 if (scalar(@multipleoctet) >= 1) {
2107 0 0       0 if (scalar(@singleoctet) >= 1) {
2108              
2109             # any character other than multiple-octet and single octet character class
2110 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2111             }
2112             else {
2113              
2114             # any character other than multiple-octet character class
2115 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2116             }
2117             }
2118             else {
2119 0 0       0 if (scalar(@singleoctet) >= 1) {
2120              
2121             # any character other than single octet character class
2122 0         0 return '(?:[^' . join('', @singleoctet) . '])';
2123             }
2124             else {
2125              
2126             # any character
2127 0         0 return "(?:$your_char)";
2128             }
2129             }
2130             }
2131              
2132             #
2133             # open file in read mode
2134             #
2135             sub _open_r {
2136 200     200   647 my(undef,$file) = @_;
2137 200         825 $file =~ s#\A (\s) #./$1#oxms;
2138 200   33     17994 return CORE::eval(q{open($_[0],'<',$_[1])}) ||
2139             open($_[0],"< $file\0");
2140             }
2141              
2142             #
2143             # open file in write mode
2144             #
2145             sub _open_w {
2146 0     0   0 my(undef,$file) = @_;
2147 0         0 $file =~ s#\A (\s) #./$1#oxms;
2148 0   0     0 return CORE::eval(q{open($_[0],'>',$_[1])}) ||
2149             open($_[0],"> $file\0");
2150             }
2151              
2152             #
2153             # open file in append mode
2154             #
2155             sub _open_a {
2156 0     0   0 my(undef,$file) = @_;
2157 0         0 $file =~ s#\A (\s) #./$1#oxms;
2158 0   0     0 return CORE::eval(q{open($_[0],'>>',$_[1])}) ||
2159             open($_[0],">> $file\0");
2160             }
2161              
2162             #
2163             # safe system
2164             #
2165             sub _systemx {
2166              
2167             # P.707 29.2.33. exec
2168             # in Chapter 29: Functions
2169             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2170             #
2171             # Be aware that in older releases of Perl, 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 in the case of exec, or
2174             # misordererd output in the case of system. This situation was largely remedied
2175             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2176              
2177             # P.855 exec
2178             # in Chapter 27: Functions
2179             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2180             #
2181             # In very old release of Perl (before v5.6), exec (and system) did not flush
2182             # your output buffer, so you needed to enable command buffering by setting $|
2183             # on one or more filehandles to avoid lost output with exec or misordered
2184             # output with system.
2185              
2186 200     200   911 $| = 1;
2187              
2188             # P.565 23.1.2. Cleaning Up Your Environment
2189             # in Chapter 23: Security
2190             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2191              
2192             # P.656 Cleaning Up Your Environment
2193             # in Chapter 20: Security
2194             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2195              
2196             # local $ENV{'PATH'} = '.';
2197 200         2078 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2198              
2199             # P.707 29.2.33. exec
2200             # in Chapter 29: Functions
2201             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2202             #
2203             # As we mentioned earlier, exec treats a discrete list of arguments as an
2204             # indication that it should bypass shell processing. However, there is one
2205             # place where you might still get tripped up. The exec call (and system, too)
2206             # will not distinguish between a single scalar argument and an array containing
2207             # only one element.
2208             #
2209             # @args = ("echo surprise"); # just one element in list
2210             # exec @args # still subject to shell escapes
2211             # or die "exec: $!"; # because @args == 1
2212             #
2213             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2214             # first argument as the pathname, which forces the rest of the arguments to be
2215             # interpreted as a list, even if there is only one of them:
2216             #
2217             # exec { $args[0] } @args # safe even with one-argument list
2218             # or die "can't exec @args: $!";
2219              
2220             # P.855 exec
2221             # in Chapter 27: Functions
2222             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2223             #
2224             # As we mentioned earlier, exec treats a discrete list of arguments as a
2225             # directive to bypass shell processing. However, there is one place where
2226             # you might still get tripped up. The exec call (and system, too) cannot
2227             # distinguish between a single scalar argument and an array containing
2228             # only one element.
2229             #
2230             # @args = ("echo surprise"); # just one element in list
2231             # exec @args # still subject to shell escapes
2232             # || die "exec: $!"; # because @args == 1
2233             #
2234             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2235             # argument as the pathname, which forces the rest of the arguments to be
2236             # interpreted as a list, even if there is only one of them:
2237             #
2238             # exec { $args[0] } @args # safe even with one-argument list
2239             # || die "can't exec @args: $!";
2240              
2241 200         422 return CORE::system { $_[0] } @_; # safe even with one-argument list
  200         25523703  
2242             }
2243              
2244             #
2245             # Latin-3 order to character (with parameter)
2246             #
2247             sub Elatin3::chr(;$) {
2248              
2249 0 0   0 0   my $c = @_ ? $_[0] : $_;
2250              
2251 0 0         if ($c == 0x00) {
2252 0           return "\x00";
2253             }
2254             else {
2255 0           my @chr = ();
2256 0           while ($c > 0) {
2257 0           unshift @chr, ($c % 0x100);
2258 0           $c = int($c / 0x100);
2259             }
2260 0           return pack 'C*', @chr;
2261             }
2262             }
2263              
2264             #
2265             # Latin-3 order to character (without parameter)
2266             #
2267             sub Elatin3::chr_() {
2268              
2269 0     0 0   my $c = $_;
2270              
2271 0 0         if ($c == 0x00) {
2272 0           return "\x00";
2273             }
2274             else {
2275 0           my @chr = ();
2276 0           while ($c > 0) {
2277 0           unshift @chr, ($c % 0x100);
2278 0           $c = int($c / 0x100);
2279             }
2280 0           return pack 'C*', @chr;
2281             }
2282             }
2283              
2284             #
2285             # Latin-3 path globbing (with parameter)
2286             #
2287             sub Elatin3::glob($) {
2288              
2289 0 0   0 0   if (wantarray) {
2290 0           my @glob = _DOS_like_glob(@_);
2291 0           for my $glob (@glob) {
2292 0           $glob =~ s{ \A (?:\./)+ }{}oxms;
2293             }
2294 0           return @glob;
2295             }
2296             else {
2297 0           my $glob = _DOS_like_glob(@_);
2298 0           $glob =~ s{ \A (?:\./)+ }{}oxms;
2299 0           return $glob;
2300             }
2301             }
2302              
2303             #
2304             # Latin-3 path globbing (without parameter)
2305             #
2306             sub Elatin3::glob_() {
2307              
2308 0 0   0 0   if (wantarray) {
2309 0           my @glob = _DOS_like_glob();
2310 0           for my $glob (@glob) {
2311 0           $glob =~ s{ \A (?:\./)+ }{}oxms;
2312             }
2313 0           return @glob;
2314             }
2315             else {
2316 0           my $glob = _DOS_like_glob();
2317 0           $glob =~ s{ \A (?:\./)+ }{}oxms;
2318 0           return $glob;
2319             }
2320             }
2321              
2322             #
2323             # Latin-3 path globbing via File::DosGlob 1.10
2324             #
2325             # Often I confuse "_dosglob" and "_doglob".
2326             # So, I renamed "_dosglob" to "_DOS_like_glob".
2327             #
2328             my %iter;
2329             my %entries;
2330             sub _DOS_like_glob {
2331              
2332             # context (keyed by second cxix argument provided by core)
2333 0     0     my($expr,$cxix) = @_;
2334              
2335             # glob without args defaults to $_
2336 0 0         $expr = $_ if not defined $expr;
2337              
2338             # represents the current user's home directory
2339             #
2340             # 7.3. Expanding Tildes in Filenames
2341             # in Chapter 7. File Access
2342             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2343             #
2344             # and File::HomeDir, File::HomeDir::Windows module
2345              
2346             # DOS-like system
2347 0 0         if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2348 0           $expr =~ s{ \A ~ (?= [^/\\] ) }
2349 0           { my_home_MSWin32() }oxmse;
2350             }
2351              
2352             # UNIX-like system
2353             else {
2354 0           $expr =~ s{ \A ~ ( (?:[^/])* ) }
2355 0 0 0       { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2356             }
2357              
2358             # assume global context if not provided one
2359 0 0         $cxix = '_G_' if not defined $cxix;
2360 0 0         $iter{$cxix} = 0 if not exists $iter{$cxix};
2361              
2362             # if we're just beginning, do it all first
2363 0 0         if ($iter{$cxix} == 0) {
2364 0           $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2365             }
2366              
2367             # chuck it all out, quick or slow
2368 0 0         if (wantarray) {
2369 0           delete $iter{$cxix};
2370 0           return @{delete $entries{$cxix}};
  0            
2371             }
2372             else {
2373 0 0         if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
  0            
2374 0           return shift @{$entries{$cxix}};
  0            
2375             }
2376             else {
2377             # return undef for EOL
2378 0           delete $iter{$cxix};
2379 0           delete $entries{$cxix};
2380 0           return undef;
2381             }
2382             }
2383             }
2384              
2385             #
2386             # Latin-3 path globbing subroutine
2387             #
2388             sub _do_glob {
2389              
2390 0     0     my($cond,@expr) = @_;
2391 0           my @glob = ();
2392 0           my $fix_drive_relative_paths = 0;
2393              
2394             OUTER:
2395 0           for my $expr (@expr) {
2396 0 0         next OUTER if not defined $expr;
2397 0 0         next OUTER if $expr eq '';
2398              
2399 0           my @matched = ();
2400 0           my @globdir = ();
2401 0           my $head = '.';
2402 0           my $pathsep = '/';
2403 0           my $tail;
2404              
2405             # if argument is within quotes strip em and do no globbing
2406 0 0         if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2407 0           $expr = $1;
2408 0 0         if ($cond eq 'd') {
2409 0 0         if (-d $expr) {
2410 0           push @glob, $expr;
2411             }
2412             }
2413             else {
2414 0 0         if (-e $expr) {
2415 0           push @glob, $expr;
2416             }
2417             }
2418 0           next OUTER;
2419             }
2420              
2421             # wildcards with a drive prefix such as h:*.pm must be changed
2422             # to h:./*.pm to expand correctly
2423 0 0         if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2424 0 0         if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2425 0           $fix_drive_relative_paths = 1;
2426             }
2427             }
2428              
2429 0 0         if (($head, $tail) = _parse_path($expr,$pathsep)) {
2430 0 0         if ($tail eq '') {
2431 0           push @glob, $expr;
2432 0           next OUTER;
2433             }
2434 0 0         if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
2435 0 0         if (@globdir = _do_glob('d', $head)) {
2436 0           push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
  0            
2437 0           next OUTER;
2438             }
2439             }
2440 0 0 0       if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2441 0           $head .= $pathsep;
2442             }
2443 0           $expr = $tail;
2444             }
2445              
2446             # If file component has no wildcards, we can avoid opendir
2447 0 0         if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2448 0 0         if ($head eq '.') {
2449 0           $head = '';
2450             }
2451 0 0 0       if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2452 0           $head .= $pathsep;
2453             }
2454 0           $head .= $expr;
2455 0 0         if ($cond eq 'd') {
2456 0 0         if (-d $head) {
2457 0           push @glob, $head;
2458             }
2459             }
2460             else {
2461 0 0         if (-e $head) {
2462 0           push @glob, $head;
2463             }
2464             }
2465 0           next OUTER;
2466             }
2467 0 0         opendir(*DIR, $head) or next OUTER;
2468 0           my @leaf = readdir DIR;
2469 0           closedir DIR;
2470              
2471 0 0         if ($head eq '.') {
2472 0           $head = '';
2473             }
2474 0 0 0       if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2475 0           $head .= $pathsep;
2476             }
2477              
2478 0           my $pattern = '';
2479 0           while ($expr =~ / \G ($q_char) /oxgc) {
2480 0           my $char = $1;
2481              
2482             # 6.9. Matching Shell Globs as Regular Expressions
2483             # in Chapter 6. Pattern Matching
2484             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2485             # (and so on)
2486              
2487 0 0         if ($char eq '*') {
    0          
    0          
2488 0           $pattern .= "(?:$your_char)*",
2489             }
2490             elsif ($char eq '?') {
2491 0           $pattern .= "(?:$your_char)?", # DOS style
2492             # $pattern .= "(?:$your_char)", # UNIX style
2493             }
2494             elsif ((my $fc = Elatin3::fc($char)) ne $char) {
2495 0           $pattern .= $fc;
2496             }
2497             else {
2498 0           $pattern .= quotemeta $char;
2499             }
2500             }
2501 0     0     my $matchsub = sub { Elatin3::fc($_[0]) =~ /\A $pattern \z/xms };
  0            
2502              
2503             # if ($@) {
2504             # print STDERR "$0: $@\n";
2505             # next OUTER;
2506             # }
2507              
2508             INNER:
2509 0           for my $leaf (@leaf) {
2510 0 0 0       if ($leaf eq '.' or $leaf eq '..') {
2511 0           next INNER;
2512             }
2513 0 0 0       if ($cond eq 'd' and not -d "$head$leaf") {
2514 0           next INNER;
2515             }
2516              
2517 0 0         if (&$matchsub($leaf)) {
2518 0           push @matched, "$head$leaf";
2519 0           next INNER;
2520             }
2521              
2522             # [DOS compatibility special case]
2523             # Failed, add a trailing dot and try again, but only...
2524              
2525 0 0 0       if (Elatin3::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
      0        
2526             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2527             Elatin3::index($pattern,'\\.') != -1 # pattern has a dot.
2528             ) {
2529 0 0         if (&$matchsub("$leaf.")) {
2530 0           push @matched, "$head$leaf";
2531 0           next INNER;
2532             }
2533             }
2534             }
2535 0 0         if (@matched) {
2536 0           push @glob, @matched;
2537             }
2538             }
2539 0 0         if ($fix_drive_relative_paths) {
2540 0           for my $glob (@glob) {
2541 0           $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2542             }
2543             }
2544 0           return @glob;
2545             }
2546              
2547             #
2548             # Latin-3 parse line
2549             #
2550             sub _parse_line {
2551              
2552 0     0     my($line) = @_;
2553              
2554 0           $line .= ' ';
2555 0           my @piece = ();
2556 0           while ($line =~ /
2557             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2558             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2559             /oxmsg
2560             ) {
2561 0 0         push @piece, defined($1) ? $1 : $2;
2562             }
2563 0           return @piece;
2564             }
2565              
2566             #
2567             # Latin-3 parse path
2568             #
2569             sub _parse_path {
2570              
2571 0     0     my($path,$pathsep) = @_;
2572              
2573 0           $path .= '/';
2574 0           my @subpath = ();
2575 0           while ($path =~ /
2576             ((?: [^\/\\] )+?) [\/\\]
2577             /oxmsg
2578             ) {
2579 0           push @subpath, $1;
2580             }
2581              
2582 0           my $tail = pop @subpath;
2583 0           my $head = join $pathsep, @subpath;
2584 0           return $head, $tail;
2585             }
2586              
2587             #
2588             # via File::HomeDir::Windows 1.00
2589             #
2590             sub my_home_MSWin32 {
2591              
2592             # A lot of unix people and unix-derived tools rely on
2593             # the ability to overload HOME. We will support it too
2594             # so that they can replace raw HOME calls with File::HomeDir.
2595 0 0 0 0 0   if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
    0 0        
    0 0        
      0        
      0        
2596 0           return $ENV{'HOME'};
2597             }
2598              
2599             # Do we have a user profile?
2600             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2601 0           return $ENV{'USERPROFILE'};
2602             }
2603              
2604             # Some Windows use something like $ENV{'HOME'}
2605             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2606 0           return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2607             }
2608              
2609 0           return undef;
2610             }
2611              
2612             #
2613             # via File::HomeDir::Unix 1.00
2614             #
2615             sub my_home {
2616 0     0 0   my $home;
2617              
2618 0 0 0       if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
    0 0        
2619 0           $home = $ENV{'HOME'};
2620             }
2621              
2622             # This is from the original code, but I'm guessing
2623             # it means "login directory" and exists on some Unixes.
2624             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2625 0           $home = $ENV{'LOGDIR'};
2626             }
2627              
2628             ### More-desperate methods
2629              
2630             # Light desperation on any (Unixish) platform
2631             else {
2632 0           $home = CORE::eval q{ (getpwuid($<))[7] };
2633             }
2634              
2635             # On Unix in general, a non-existant home means "no home"
2636             # For example, "nobody"-like users might use /nonexistant
2637 0 0 0       if (defined $home and ! -d($home)) {
2638 0           $home = undef;
2639             }
2640 0           return $home;
2641             }
2642              
2643             #
2644             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2645             #
2646             sub Elatin3::PREMATCH {
2647 0     0 0   return $`;
2648             }
2649              
2650             #
2651             # ${^MATCH}, $MATCH, $& the string that matched
2652             #
2653             sub Elatin3::MATCH {
2654 0     0 0   return $&;
2655             }
2656              
2657             #
2658             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2659             #
2660             sub Elatin3::POSTMATCH {
2661 0     0 0   return $';
2662             }
2663              
2664             #
2665             # Latin-3 character to order (with parameter)
2666             #
2667             sub Latin3::ord(;$) {
2668              
2669 0 0   0 1   local $_ = shift if @_;
2670              
2671 0 0         if (/\A ($q_char) /oxms) {
2672 0           my @ord = unpack 'C*', $1;
2673 0           my $ord = 0;
2674 0           while (my $o = shift @ord) {
2675 0           $ord = $ord * 0x100 + $o;
2676             }
2677 0           return $ord;
2678             }
2679             else {
2680 0           return CORE::ord $_;
2681             }
2682             }
2683              
2684             #
2685             # Latin-3 character to order (without parameter)
2686             #
2687             sub Latin3::ord_() {
2688              
2689 0 0   0 0   if (/\A ($q_char) /oxms) {
2690 0           my @ord = unpack 'C*', $1;
2691 0           my $ord = 0;
2692 0           while (my $o = shift @ord) {
2693 0           $ord = $ord * 0x100 + $o;
2694             }
2695 0           return $ord;
2696             }
2697             else {
2698 0           return CORE::ord $_;
2699             }
2700             }
2701              
2702             #
2703             # Latin-3 reverse
2704             #
2705             sub Latin3::reverse(@) {
2706              
2707 0 0   0 0   if (wantarray) {
2708 0           return CORE::reverse @_;
2709             }
2710             else {
2711              
2712             # One of us once cornered Larry in an elevator and asked him what
2713             # problem he was solving with this, but he looked as far off into
2714             # the distance as he could in an elevator and said, "It seemed like
2715             # a good idea at the time."
2716              
2717 0           return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2718             }
2719             }
2720              
2721             #
2722             # Latin-3 getc (with parameter, without parameter)
2723             #
2724             sub Latin3::getc(;*@) {
2725              
2726 0     0 0   my($package) = caller;
2727 0 0         my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2728 0 0 0       croak 'Too many arguments for Latin3::getc' if @_ and not wantarray;
2729              
2730 0           my @length = sort { $a <=> $b } keys %range_tr;
  0            
2731 0           my $getc = '';
2732 0           for my $length ($length[0] .. $length[-1]) {
2733 0           $getc .= CORE::getc($fh);
2734 0 0         if (exists $range_tr{CORE::length($getc)}) {
2735 0 0         if ($getc =~ /\A ${Elatin3::dot_s} \z/oxms) {
2736 0 0         return wantarray ? ($getc,@_) : $getc;
2737             }
2738             }
2739             }
2740 0 0         return wantarray ? ($getc,@_) : $getc;
2741             }
2742              
2743             #
2744             # Latin-3 length by character
2745             #
2746             sub Latin3::length(;$) {
2747              
2748 0 0   0 1   local $_ = shift if @_;
2749              
2750 0           local @_ = /\G ($q_char) /oxmsg;
2751 0           return scalar @_;
2752             }
2753              
2754             #
2755             # Latin-3 substr by character
2756             #
2757             BEGIN {
2758              
2759             # P.232 The lvalue Attribute
2760             # in Chapter 6: Subroutines
2761             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2762              
2763             # P.336 The lvalue Attribute
2764             # in Chapter 7: Subroutines
2765             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2766              
2767             # P.144 8.4 Lvalue subroutines
2768             # in Chapter 8: perlsub: Perl subroutines
2769             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
2770              
2771 200 50 0 200 1 160772 CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
  0 0   0      
  0 0          
  0 0          
  0 0          
  0 0          
  0 0          
  0 0          
  0 0          
  0 0          
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
2772             # vv----------------------*******
2773             sub Latin3::substr($$;$$) %s {
2774              
2775             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2776              
2777             # If the substring is beyond either end of the string, substr() returns the undefined
2778             # value and produces a warning. When used as an lvalue, specifying a substring that
2779             # is entirely outside the string raises an exception.
2780             # http://perldoc.perl.org/functions/substr.html
2781              
2782             # A return with no argument returns the scalar value undef in scalar context,
2783             # an empty list () in list context, and (naturally) nothing at all in void
2784             # context.
2785              
2786             my $offset = $_[1];
2787             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2788             return;
2789             }
2790              
2791             # substr($string,$offset,$length,$replacement)
2792             if (@_ == 4) {
2793             my(undef,undef,$length,$replacement) = @_;
2794             my $substr = join '', splice(@char, $offset, $length, $replacement);
2795             $_[0] = join '', @char;
2796              
2797             # return $substr; this doesn't work, don't say "return"
2798             $substr;
2799             }
2800              
2801             # substr($string,$offset,$length)
2802             elsif (@_ == 3) {
2803             my(undef,undef,$length) = @_;
2804             my $octet_offset = 0;
2805             my $octet_length = 0;
2806             if ($offset == 0) {
2807             $octet_offset = 0;
2808             }
2809             elsif ($offset > 0) {
2810             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2811             }
2812             else {
2813             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2814             }
2815             if ($length == 0) {
2816             $octet_length = 0;
2817             }
2818             elsif ($length > 0) {
2819             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2820             }
2821             else {
2822             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2823             }
2824             CORE::substr($_[0], $octet_offset, $octet_length);
2825             }
2826              
2827             # substr($string,$offset)
2828             else {
2829             my $octet_offset = 0;
2830             if ($offset == 0) {
2831             $octet_offset = 0;
2832             }
2833             elsif ($offset > 0) {
2834             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2835             }
2836             else {
2837             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2838             }
2839             CORE::substr($_[0], $octet_offset);
2840             }
2841             }
2842             END
2843             }
2844              
2845             #
2846             # Latin-3 index by character
2847             #
2848             sub Latin3::index($$;$) {
2849              
2850 0     0 1   my $index;
2851 0 0         if (@_ == 3) {
2852 0           $index = Elatin3::index($_[0], $_[1], CORE::length(Latin3::substr($_[0], 0, $_[2])));
2853             }
2854             else {
2855 0           $index = Elatin3::index($_[0], $_[1]);
2856             }
2857              
2858 0 0         if ($index == -1) {
2859 0           return -1;
2860             }
2861             else {
2862 0           return Latin3::length(CORE::substr $_[0], 0, $index);
2863             }
2864             }
2865              
2866             #
2867             # Latin-3 rindex by character
2868             #
2869             sub Latin3::rindex($$;$) {
2870              
2871 0     0 1   my $rindex;
2872 0 0         if (@_ == 3) {
2873 0           $rindex = Elatin3::rindex($_[0], $_[1], CORE::length(Latin3::substr($_[0], 0, $_[2])));
2874             }
2875             else {
2876 0           $rindex = Elatin3::rindex($_[0], $_[1]);
2877             }
2878              
2879 0 0         if ($rindex == -1) {
2880 0           return -1;
2881             }
2882             else {
2883 0           return Latin3::length(CORE::substr $_[0], 0, $rindex);
2884             }
2885             }
2886              
2887             # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
2888             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2889 200     200   19664 BEGIN { CORE::eval q{ use vars qw($slash) } } $slash = 'm//';
  200     200   2208  
  200         486  
  200         19123  
2890              
2891             # ord() to ord() or Latin3::ord()
2892 200     200   29534 BEGIN { CORE::eval q{ use vars qw($function_ord) } } $function_ord = 'ord';
  200     200   2093  
  200         442  
  200         15640  
2893              
2894             # ord to ord or Latin3::ord_
2895 200     200   14951 BEGIN { CORE::eval q{ use vars qw($function_ord_) } } $function_ord_ = 'ord';
  200     200   1197  
  200         508  
  200         19973  
2896              
2897             # reverse to reverse or Latin3::reverse
2898 200     200   14553 BEGIN { CORE::eval q{ use vars qw($function_reverse) } } $function_reverse = 'reverse';
  200     200   1493  
  200         381  
  200         14691  
2899              
2900             # getc to getc or Latin3::getc
2901 200     200   14856 BEGIN { CORE::eval q{ use vars qw($function_getc) } } $function_getc = 'getc';
  200     200   2486  
  200         383  
  200         20252  
2902              
2903             # P.1023 Appendix W.9 Multibyte Anchoring
2904             # of ISBN 1-56592-224-7 CJKV Information Processing
2905              
2906             my $anchor = '';
2907              
2908 200     200   14724 BEGIN { CORE::eval q{ use vars qw($nest) } }
  200     200   1261  
  200         407  
  200         13325243  
2909              
2910             # regexp of nested parens in qqXX
2911              
2912             # P.340 Matching Nested Constructs with Embedded Code
2913             # in Chapter 7: Perl
2914             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2915              
2916             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2917             [^\\()] |
2918             \( (?{$nest++}) |
2919             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2920             \\ [^c] |
2921             \\c[\x40-\x5F] |
2922             [\x00-\xFF]
2923             }xms;
2924              
2925             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2926             [^\\{}] |
2927             \{ (?{$nest++}) |
2928             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2929             \\ [^c] |
2930             \\c[\x40-\x5F] |
2931             [\x00-\xFF]
2932             }xms;
2933              
2934             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2935             [^\\\[\]] |
2936             \[ (?{$nest++}) |
2937             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2938             \\ [^c] |
2939             \\c[\x40-\x5F] |
2940             [\x00-\xFF]
2941             }xms;
2942              
2943             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2944             [^\\<>] |
2945             \< (?{$nest++}) |
2946             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2947             \\ [^c] |
2948             \\c[\x40-\x5F] |
2949             [\x00-\xFF]
2950             }xms;
2951              
2952             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2953             (?: ::)? (?:
2954             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2955             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2956             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2957             ))
2958             }xms;
2959              
2960             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2961             (?: ::)? (?:
2962             (?>[0-9]+) |
2963             [^a-zA-Z_0-9\[\]] |
2964             ^[A-Z] |
2965             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2966             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2967             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2968             ))
2969             }xms;
2970              
2971             my $qq_substr = qr{(?> Char::substr | Latin3::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2972             }xms;
2973              
2974             # regexp of nested parens in qXX
2975             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2976             [^()] |
2977             \( (?{$nest++}) |
2978             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2979             [\x00-\xFF]
2980             }xms;
2981              
2982             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2983             [^\{\}] |
2984             \{ (?{$nest++}) |
2985             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2986             [\x00-\xFF]
2987             }xms;
2988              
2989             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2990             [^\[\]] |
2991             \[ (?{$nest++}) |
2992             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2993             [\x00-\xFF]
2994             }xms;
2995              
2996             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2997             [^<>] |
2998             \< (?{$nest++}) |
2999             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
3000             [\x00-\xFF]
3001             }xms;
3002              
3003             my $matched = '';
3004             my $s_matched = '';
3005              
3006             my $tr_variable = ''; # variable of tr///
3007             my $sub_variable = ''; # variable of s///
3008             my $bind_operator = ''; # =~ or !~
3009              
3010             my @heredoc = (); # here document
3011             my @heredoc_delimiter = ();
3012             my $here_script = ''; # here script
3013              
3014             #
3015             # escape Latin-3 script
3016             #
3017             sub Latin3::escape(;$) {
3018 0 0   0 0   local($_) = $_[0] if @_;
3019              
3020             # P.359 The Study Function
3021             # in Chapter 7: Perl
3022             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3023              
3024 0           study $_; # Yes, I studied study yesterday.
3025              
3026             # while all script
3027              
3028             # 6.14. Matching from Where the Last Pattern Left Off
3029             # in Chapter 6. Pattern Matching
3030             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3031             # (and so on)
3032              
3033             # one member of Tag-team
3034             #
3035             # P.128 Start of match (or end of previous match): \G
3036             # P.130 Advanced Use of \G with Perl
3037             # in Chapter 3: Overview of Regular Expression Features and Flavors
3038             # P.255 Use leading anchors
3039             # P.256 Expose ^ and \G at the front expressions
3040             # in Chapter 6: Crafting an Efficient Expression
3041             # P.315 "Tag-team" matching with /gc
3042             # in Chapter 7: Perl
3043             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3044              
3045 0           my $e_script = '';
3046 0           while (not /\G \z/oxgc) { # member
3047 0           $e_script .= Latin3::escape_token();
3048             }
3049              
3050 0           return $e_script;
3051             }
3052              
3053             #
3054             # escape Latin-3 token of script
3055             #
3056             sub Latin3::escape_token {
3057              
3058             # \n output here document
3059              
3060 0     0 0   my $ignore_modules = join('|', qw(
3061             utf8
3062             bytes
3063             charnames
3064             I18N::Japanese
3065             I18N::Collate
3066             I18N::JExt
3067             File::DosGlob
3068             Wild
3069             Wildcard
3070             Japanese
3071             ));
3072              
3073             # another member of Tag-team
3074             #
3075             # P.315 "Tag-team" matching with /gc
3076             # in Chapter 7: Perl
3077             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3078              
3079 0 0 0       if (/\G ( \n ) /oxgc) { # another member (and so on)
    0 0        
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    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          
3080 0           my $heredoc = '';
3081 0 0         if (scalar(@heredoc_delimiter) >= 1) {
3082 0           $slash = 'm//';
3083              
3084 0           $heredoc = join '', @heredoc;
3085 0           @heredoc = ();
3086              
3087             # skip here document
3088 0           for my $heredoc_delimiter (@heredoc_delimiter) {
3089 0           /\G .*? \n $heredoc_delimiter \n/xmsgc;
3090             }
3091 0           @heredoc_delimiter = ();
3092              
3093 0           $here_script = '';
3094             }
3095 0           return "\n" . $heredoc;
3096             }
3097              
3098             # ignore space, comment
3099 0           elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3100              
3101             # if (, elsif (, unless (, while (, until (, given (, and when (
3102              
3103             # given, when
3104              
3105             # P.225 The given Statement
3106             # in Chapter 15: Smart Matching and given-when
3107             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3108              
3109             # P.133 The given Statement
3110             # in Chapter 4: Statements and Declarations
3111             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3112              
3113             elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3114 0           $slash = 'm//';
3115 0           return $1;
3116             }
3117              
3118             # scalar variable ($scalar = ...) =~ tr///;
3119             # scalar variable ($scalar = ...) =~ s///;
3120              
3121             # state
3122              
3123             # P.68 Persistent, Private Variables
3124             # in Chapter 4: Subroutines
3125             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3126              
3127             # P.160 Persistent Lexically Scoped Variables: state
3128             # in Chapter 4: Statements and Declarations
3129             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3130              
3131             # (and so on)
3132              
3133             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3134 0           my $e_string = e_string($1);
3135              
3136 0 0         if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
    0          
3137 0           $tr_variable = $e_string . e_string($1);
3138 0           $bind_operator = $2;
3139 0           $slash = 'm//';
3140 0           return '';
3141             }
3142             elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3143 0           $sub_variable = $e_string . e_string($1);
3144 0           $bind_operator = $2;
3145 0           $slash = 'm//';
3146 0           return '';
3147             }
3148             else {
3149 0           $slash = 'div';
3150 0           return $e_string;
3151             }
3152             }
3153              
3154             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
3155             elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3156 0           $slash = 'div';
3157 0           return q{Elatin3::PREMATCH()};
3158             }
3159              
3160             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
3161             elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3162 0           $slash = 'div';
3163 0           return q{Elatin3::MATCH()};
3164             }
3165              
3166             # $', ${'} --> $', ${'}
3167             elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3168 0           $slash = 'div';
3169 0           return $1;
3170             }
3171              
3172             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
3173             elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3174 0           $slash = 'div';
3175 0           return q{Elatin3::POSTMATCH()};
3176             }
3177              
3178             # scalar variable $scalar =~ tr///;
3179             # scalar variable $scalar =~ s///;
3180             # substr() =~ tr///;
3181             # substr() =~ s///;
3182             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3183 0           my $scalar = e_string($1);
3184              
3185 0 0         if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
    0          
3186 0           $tr_variable = $scalar;
3187 0           $bind_operator = $1;
3188 0           $slash = 'm//';
3189 0           return '';
3190             }
3191             elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3192 0           $sub_variable = $scalar;
3193 0           $bind_operator = $1;
3194 0           $slash = 'm//';
3195 0           return '';
3196             }
3197             else {
3198 0           $slash = 'div';
3199 0           return $scalar;
3200             }
3201             }
3202              
3203             # end of statement
3204             elsif (/\G ( [,;] ) /oxgc) {
3205 0           $slash = 'm//';
3206              
3207             # clear tr/// variable
3208 0           $tr_variable = '';
3209              
3210             # clear s/// variable
3211 0           $sub_variable = '';
3212              
3213 0           $bind_operator = '';
3214              
3215 0           return $1;
3216             }
3217              
3218             # bareword
3219             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3220 0           return $1;
3221             }
3222              
3223             # $0 --> $0
3224             elsif (/\G ( \$ 0 ) /oxmsgc) {
3225 0           $slash = 'div';
3226 0           return $1;
3227             }
3228             elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3229 0           $slash = 'div';
3230 0           return $1;
3231             }
3232              
3233             # $$ --> $$
3234             elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3235 0           $slash = 'div';
3236 0           return $1;
3237             }
3238              
3239             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3240             # $1, $2, $3 --> $1, $2, $3 otherwise
3241             elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3242 0           $slash = 'div';
3243 0           return e_capture($1);
3244             }
3245             elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3246 0           $slash = 'div';
3247 0           return e_capture($1);
3248             }
3249              
3250             # $$foo[ ... ] --> $ $foo->[ ... ]
3251             elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3252 0           $slash = 'div';
3253 0           return e_capture($1.'->'.$2);
3254             }
3255              
3256             # $$foo{ ... } --> $ $foo->{ ... }
3257             elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3258 0           $slash = 'div';
3259 0           return e_capture($1.'->'.$2);
3260             }
3261              
3262             # $$foo
3263             elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3264 0           $slash = 'div';
3265 0           return e_capture($1);
3266             }
3267              
3268             # ${ foo }
3269             elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3270 0           $slash = 'div';
3271 0           return '${' . $1 . '}';
3272             }
3273              
3274             # ${ ... }
3275             elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3276 0           $slash = 'div';
3277 0           return e_capture($1);
3278             }
3279              
3280             # variable or function
3281             # $ @ % & * $ #
3282             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) {
3283 0           $slash = 'div';
3284 0           return $1;
3285             }
3286             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3287             # $ @ # \ ' " / ? ( ) [ ] < >
3288             elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3289 0           $slash = 'div';
3290 0           return $1;
3291             }
3292              
3293             # while ()
3294             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3295 0           return $1;
3296             }
3297              
3298             # while () --- glob
3299              
3300             # avoid "Error: Runtime exception" of perl version 5.005_03
3301              
3302             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3303 0           return 'while ($_ = Elatin3::glob("' . $1 . '"))';
3304             }
3305              
3306             # while (glob)
3307             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3308 0           return 'while ($_ = Elatin3::glob_)';
3309             }
3310              
3311             # while (glob(WILDCARD))
3312             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3313 0           return 'while ($_ = Elatin3::glob';
3314             }
3315              
3316             # doit if, doit unless, doit while, doit until, doit for, doit when
3317 0           elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
  0            
3318              
3319             # subroutines of package Elatin3
3320 0           elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  0            
3321 0           elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0            
3322 0           elsif (/\G \b Latin3::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0            
3323 0           elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  0            
3324 0           elsif (/\G \b Latin3::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Latin3::escape'; }
  0            
3325 0           elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  0            
3326 0           elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::chop'; }
  0            
3327 0           elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0            
3328 0           elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0            
3329 0           elsif (/\G \b Latin3::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin3::index'; }
  0            
3330 0           elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::index'; }
  0            
3331 0           elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0            
3332 0           elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0            
3333 0           elsif (/\G \b Latin3::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin3::rindex'; }
  0            
3334 0           elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::rindex'; }
  0            
3335 0           elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::lc'; }
  0            
3336 0           elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::lcfirst'; }
  0            
3337 0           elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::uc'; }
  0            
3338 0           elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::ucfirst'; }
  0            
3339 0           elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::fc'; }
  0            
3340              
3341             # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
3342 0           elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0            
3343 0           elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0            
3344 0           elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0            
3345 0           elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0            
3346 0           elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0            
3347 0           elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0            
3348 0           elsif (/\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0            
3349              
3350 0           elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0            
3351 0           elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0            
3352 0           elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0            
3353 0           elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0            
3354 0           elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0            
3355 0           elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0            
3356 0           elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0            
3357              
3358             elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
3359 0           { $slash = 'm//'; return "-s $1"; }
  0            
3360 0           elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0            
3361 0           elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
  0            
3362 0           elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  0            
3363              
3364 0           elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  0            
3365 0           elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  0            
3366 0           elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::chr'; }
  0            
3367 0           elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0            
3368 0           elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0            
3369 0           elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::glob'; }
  0            
3370 0           elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::lc_'; }
  0            
3371 0           elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::lcfirst_'; }
  0            
3372 0           elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::uc_'; }
  0            
3373 0           elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::ucfirst_'; }
  0            
3374 0           elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::fc_'; }
  0            
3375 0           elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0            
3376              
3377 0           elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0            
3378 0           elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0            
3379 0           elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::chr_'; }
  0            
3380 0           elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0            
3381 0           elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0            
3382 0           elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::glob_'; }
  0            
3383 0           elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
  0            
3384 0           elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
  0            
3385             # split
3386             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3387 0           $slash = 'm//';
3388              
3389 0           my $e = '';
3390 0           while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3391 0           $e .= $1;
3392             }
3393              
3394             # end of split
3395 0 0         if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Elatin3::split' . $e; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3396              
3397             # split scalar value
3398 0           elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Elatin3::split' . $e . e_string($1); }
3399              
3400             # split literal space
3401 0           elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Elatin3::split' . $e . qq {qq$1 $2}; }
3402 0           elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3403 0           elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3404 0           elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3405 0           elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3406 0           elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3407 0           elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Elatin3::split' . $e . qq {q$1 $2}; }
3408 0           elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3409 0           elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3410 0           elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3411 0           elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3412 0           elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3413 0           elsif (/\G ' [ ] ' /oxgc) { return 'Elatin3::split' . $e . qq {' '}; }
3414 0           elsif (/\G " [ ] " /oxgc) { return 'Elatin3::split' . $e . qq {" "}; }
3415              
3416             # split qq//
3417             elsif (/\G \b (qq) \b /oxgc) {
3418 0 0         if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
  0            
3419             else {
3420 0           while (not /\G \z/oxgc) {
3421 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
3422 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3423 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3424 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3425 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3426 0           elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3427 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3428             }
3429 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3430             }
3431             }
3432              
3433             # split qr//
3434             elsif (/\G \b (qr) \b /oxgc) {
3435 0 0         if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
  0            
3436             else {
3437 0           while (not /\G \z/oxgc) {
3438 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
3439 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3440 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3441 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3442 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3443 0           elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3444 0           elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3445 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3446             }
3447 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3448             }
3449             }
3450              
3451             # split q//
3452             elsif (/\G \b (q) \b /oxgc) {
3453 0 0         if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
  0            
3454             else {
3455 0           while (not /\G \z/oxgc) {
3456 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
3457 0           elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3458 0           elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3459 0           elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3460 0           elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3461 0           elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3462 0           elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3463             }
3464 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3465             }
3466             }
3467              
3468             # split m//
3469             elsif (/\G \b (m) \b /oxgc) {
3470 0 0         if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
  0            
3471             else {
3472 0           while (not /\G \z/oxgc) {
3473 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
3474 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3475 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3476 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3477 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3478 0           elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3479 0           elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3480 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3481             }
3482 0           die __FILE__, ": Search pattern not terminated\n";
3483             }
3484             }
3485              
3486             # split ''
3487             elsif (/\G (\') /oxgc) {
3488 0           my $q_string = '';
3489 0           while (not /\G \z/oxgc) {
3490 0 0         if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0          
    0          
    0          
3491 0           elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3492 0           elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3493 0           elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3494             }
3495 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3496             }
3497              
3498             # split ""
3499             elsif (/\G (\") /oxgc) {
3500 0           my $qq_string = '';
3501 0           while (not /\G \z/oxgc) {
3502 0 0         if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0          
    0          
    0          
3503 0           elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3504 0           elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3505 0           elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3506             }
3507 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3508             }
3509              
3510             # split //
3511             elsif (/\G (\/) /oxgc) {
3512 0           my $regexp = '';
3513 0           while (not /\G \z/oxgc) {
3514 0 0         if (/\G (\\\\) /oxgc) { $regexp .= $1; }
  0 0          
    0          
    0          
3515 0           elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3516 0           elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3517 0           elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3518             }
3519 0           die __FILE__, ": Search pattern not terminated\n";
3520             }
3521             }
3522              
3523             # tr/// or y///
3524              
3525             # about [cdsrbB]* (/B modifier)
3526             #
3527             # P.559 appendix C
3528             # of ISBN 4-89052-384-7 Programming perl
3529             # (Japanese title is: Perl puroguramingu)
3530              
3531             elsif (/\G \b ( tr | y ) \b /oxgc) {
3532 0           my $ope = $1;
3533              
3534             # $1 $2 $3 $4 $5 $6
3535 0 0         if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3536 0           my @tr = ($tr_variable,$2);
3537 0           return e_tr(@tr,'',$4,$6);
3538             }
3539             else {
3540 0           my $e = '';
3541 0           while (not /\G \z/oxgc) {
3542 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3543             elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3544 0           my @tr = ($tr_variable,$2);
3545 0           while (not /\G \z/oxgc) {
3546 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3547 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3548 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3549 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3550 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3551 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3552             }
3553 0           die __FILE__, ": Transliteration replacement not terminated\n";
3554             }
3555             elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3556 0           my @tr = ($tr_variable,$2);
3557 0           while (not /\G \z/oxgc) {
3558 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3559 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3560 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3561 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3562 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3563 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3564             }
3565 0           die __FILE__, ": Transliteration replacement not terminated\n";
3566             }
3567             elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3568 0           my @tr = ($tr_variable,$2);
3569 0           while (not /\G \z/oxgc) {
3570 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3571 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3572 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3573 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3574 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3575 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3576             }
3577 0           die __FILE__, ": Transliteration replacement not terminated\n";
3578             }
3579             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3580 0           my @tr = ($tr_variable,$2);
3581 0           while (not /\G \z/oxgc) {
3582 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3583 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3584 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3585 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3586 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3587 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3588             }
3589 0           die __FILE__, ": Transliteration replacement not terminated\n";
3590             }
3591             # $1 $2 $3 $4 $5 $6
3592             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3593 0           my @tr = ($tr_variable,$2);
3594 0           return e_tr(@tr,'',$4,$6);
3595             }
3596             }
3597 0           die __FILE__, ": Transliteration pattern not terminated\n";
3598             }
3599             }
3600              
3601             # qq//
3602             elsif (/\G \b (qq) \b /oxgc) {
3603 0           my $ope = $1;
3604              
3605             # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3606 0 0         if (/\G (\#) /oxgc) { # qq# #
3607 0           my $qq_string = '';
3608 0           while (not /\G \z/oxgc) {
3609 0 0         if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0          
    0          
    0          
3610 0           elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3611 0           elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3612 0           elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3613             }
3614 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3615             }
3616              
3617             else {
3618 0           my $e = '';
3619 0           while (not /\G \z/oxgc) {
3620 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3621              
3622             # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3623             elsif (/\G (\() /oxgc) { # qq ( )
3624 0           my $qq_string = '';
3625 0           local $nest = 1;
3626 0           while (not /\G \z/oxgc) {
3627 0 0         if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0          
    0          
    0          
    0          
3628 0           elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3629 0           elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0            
3630             elsif (/\G (\)) /oxgc) {
3631 0 0         if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
  0            
3632 0           else { $qq_string .= $1; }
3633             }
3634 0           elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3635             }
3636 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3637             }
3638              
3639             # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3640             elsif (/\G (\{) /oxgc) { # qq { }
3641 0           my $qq_string = '';
3642 0           local $nest = 1;
3643 0           while (not /\G \z/oxgc) {
3644 0 0         if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0          
    0          
    0          
    0          
3645 0           elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3646 0           elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  0            
3647             elsif (/\G (\}) /oxgc) {
3648 0 0         if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
  0            
3649 0           else { $qq_string .= $1; }
3650             }
3651 0           elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3652             }
3653 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3654             }
3655              
3656             # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3657             elsif (/\G (\[) /oxgc) { # qq [ ]
3658 0           my $qq_string = '';
3659 0           local $nest = 1;
3660 0           while (not /\G \z/oxgc) {
3661 0 0         if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0          
    0          
    0          
    0          
3662 0           elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3663 0           elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0            
3664             elsif (/\G (\]) /oxgc) {
3665 0 0         if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
  0            
3666 0           else { $qq_string .= $1; }
3667             }
3668 0           elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3669             }
3670 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3671             }
3672              
3673             # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3674             elsif (/\G (\<) /oxgc) { # qq < >
3675 0           my $qq_string = '';
3676 0           local $nest = 1;
3677 0           while (not /\G \z/oxgc) {
3678 0 0         if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0          
    0          
    0          
    0          
3679 0           elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3680 0           elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  0            
3681             elsif (/\G (\>) /oxgc) {
3682 0 0         if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
  0            
3683 0           else { $qq_string .= $1; }
3684             }
3685 0           elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3686             }
3687 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3688             }
3689              
3690             # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3691             elsif (/\G (\S) /oxgc) { # qq * *
3692 0           my $delimiter = $1;
3693 0           my $qq_string = '';
3694 0           while (not /\G \z/oxgc) {
3695 0 0         if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0          
    0          
    0          
3696 0           elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3697 0           elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3698 0           elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3699             }
3700 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3701             }
3702             }
3703 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3704             }
3705             }
3706              
3707             # qr//
3708             elsif (/\G \b (qr) \b /oxgc) {
3709 0           my $ope = $1;
3710 0 0         if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3711 0           return e_qr($ope,$1,$3,$2,$4);
3712             }
3713             else {
3714 0           my $e = '';
3715 0           while (not /\G \z/oxgc) {
3716 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
3717 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3718 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3719 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3720 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3721 0           elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3722 0           elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3723 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3724             }
3725 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3726             }
3727             }
3728              
3729             # qw//
3730             elsif (/\G \b (qw) \b /oxgc) {
3731 0           my $ope = $1;
3732 0 0         if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3733 0           return e_qw($ope,$1,$3,$2);
3734             }
3735             else {
3736 0           my $e = '';
3737 0           while (not /\G \z/oxgc) {
3738 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3739              
3740 0           elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3741 0           elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3742              
3743 0           elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3744 0           elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3745              
3746 0           elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3747 0           elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3748              
3749 0           elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3750 0           elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3751              
3752 0           elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3753 0           elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3754             }
3755 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3756             }
3757             }
3758              
3759             # qx//
3760             elsif (/\G \b (qx) \b /oxgc) {
3761 0           my $ope = $1;
3762 0 0         if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3763 0           return e_qq($ope,$1,$3,$2);
3764             }
3765             else {
3766 0           my $e = '';
3767 0           while (not /\G \z/oxgc) {
3768 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
3769 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3770 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3771 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3772 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3773 0           elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3774 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3775             }
3776 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3777             }
3778             }
3779              
3780             # q//
3781             elsif (/\G \b (q) \b /oxgc) {
3782 0           my $ope = $1;
3783              
3784             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3785              
3786             # avoid "Error: Runtime exception" of perl version 5.005_03
3787             # (and so on)
3788              
3789 0 0         if (/\G (\#) /oxgc) { # q# #
3790 0           my $q_string = '';
3791 0           while (not /\G \z/oxgc) {
3792 0 0         if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0          
    0          
    0          
3793 0           elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3794 0           elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3795 0           elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3796             }
3797 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3798             }
3799              
3800             else {
3801 0           my $e = '';
3802 0           while (not /\G \z/oxgc) {
3803 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3804              
3805             # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3806             elsif (/\G (\() /oxgc) { # q ( )
3807 0           my $q_string = '';
3808 0           local $nest = 1;
3809 0           while (not /\G \z/oxgc) {
3810 0 0         if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3811 0           elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
3812 0           elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3813 0           elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0            
3814             elsif (/\G (\)) /oxgc) {
3815 0 0         if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
  0            
3816 0           else { $q_string .= $1; }
3817             }
3818 0           elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3819             }
3820 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3821             }
3822              
3823             # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3824             elsif (/\G (\{) /oxgc) { # q { }
3825 0           my $q_string = '';
3826 0           local $nest = 1;
3827 0           while (not /\G \z/oxgc) {
3828 0 0         if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3829 0           elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
3830 0           elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3831 0           elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  0            
3832             elsif (/\G (\}) /oxgc) {
3833 0 0         if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
  0            
3834 0           else { $q_string .= $1; }
3835             }
3836 0           elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3837             }
3838 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3839             }
3840              
3841             # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3842             elsif (/\G (\[) /oxgc) { # q [ ]
3843 0           my $q_string = '';
3844 0           local $nest = 1;
3845 0           while (not /\G \z/oxgc) {
3846 0 0         if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3847 0           elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
3848 0           elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3849 0           elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0            
3850             elsif (/\G (\]) /oxgc) {
3851 0 0         if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
  0            
3852 0           else { $q_string .= $1; }
3853             }
3854 0           elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3855             }
3856 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3857             }
3858              
3859             # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3860             elsif (/\G (\<) /oxgc) { # q < >
3861 0           my $q_string = '';
3862 0           local $nest = 1;
3863 0           while (not /\G \z/oxgc) {
3864 0 0         if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0          
    0          
    0          
    0          
    0          
3865 0           elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
3866 0           elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3867 0           elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  0            
3868             elsif (/\G (\>) /oxgc) {
3869 0 0         if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
  0            
3870 0           else { $q_string .= $1; }
3871             }
3872 0           elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3873             }
3874 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3875             }
3876              
3877             # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3878             elsif (/\G (\S) /oxgc) { # q * *
3879 0           my $delimiter = $1;
3880 0           my $q_string = '';
3881 0           while (not /\G \z/oxgc) {
3882 0 0         if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0          
    0          
    0          
3883 0           elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3884 0           elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3885 0           elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3886             }
3887 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3888             }
3889             }
3890 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3891             }
3892             }
3893              
3894             # m//
3895             elsif (/\G \b (m) \b /oxgc) {
3896 0           my $ope = $1;
3897 0 0         if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3898 0           return e_qr($ope,$1,$3,$2,$4);
3899             }
3900             else {
3901 0           my $e = '';
3902 0           while (not /\G \z/oxgc) {
3903 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3904 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3905 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3906 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3907 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3908 0           elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3909 0           elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3910 0           elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3911 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3912             }
3913 0           die __FILE__, ": Search pattern not terminated\n";
3914             }
3915             }
3916              
3917             # s///
3918              
3919             # about [cegimosxpradlunbB]* (/cg modifier)
3920             #
3921             # P.67 Pattern-Matching Operators
3922             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3923              
3924             elsif (/\G \b (s) \b /oxgc) {
3925 0           my $ope = $1;
3926              
3927             # $1 $2 $3 $4 $5 $6
3928 0 0         if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3929 0           return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3930             }
3931             else {
3932 0           my $e = '';
3933 0           while (not /\G \z/oxgc) {
3934 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3935             elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3936 0           my @s = ($1,$2,$3);
3937 0           while (not /\G \z/oxgc) {
3938 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3939             # $1 $2 $3 $4
3940 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3941 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3942 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3943 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3944 0           elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3945 0           elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3946 0           elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3947 0           elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3948 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3949             }
3950 0           die __FILE__, ": Substitution replacement not terminated\n";
3951             }
3952             elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3953 0           my @s = ($1,$2,$3);
3954 0           while (not /\G \z/oxgc) {
3955 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3956             # $1 $2 $3 $4
3957 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3958 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3960 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3961 0           elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3962 0           elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3963 0           elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3964 0           elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3965 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3966             }
3967 0           die __FILE__, ": Substitution replacement not terminated\n";
3968             }
3969             elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3970 0           my @s = ($1,$2,$3);
3971 0           while (not /\G \z/oxgc) {
3972 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
3973             # $1 $2 $3 $4
3974 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3975 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3976 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3977 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3978 0           elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3979 0           elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3980 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3981             }
3982 0           die __FILE__, ": Substitution replacement not terminated\n";
3983             }
3984             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3985 0           my @s = ($1,$2,$3);
3986 0           while (not /\G \z/oxgc) {
3987 0 0         if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3988             # $1 $2 $3 $4
3989 0           elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3990 0           elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3991 0           elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3992 0           elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3993 0           elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3994 0           elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3995 0           elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3996 0           elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3997 0           elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3998             }
3999 0           die __FILE__, ": Substitution replacement not terminated\n";
4000             }
4001             # $1 $2 $3 $4 $5 $6
4002             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
4003 0           return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4004             }
4005             # $1 $2 $3 $4 $5 $6
4006             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4007 0           return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
4008             }
4009             # $1 $2 $3 $4 $5 $6
4010             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4011 0           return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4012             }
4013             # $1 $2 $3 $4 $5 $6
4014             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
4015 0           return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4016             }
4017             }
4018 0           die __FILE__, ": Substitution pattern not terminated\n";
4019             }
4020             }
4021              
4022             # require ignore module
4023 0           elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
4024 0           elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
4025 0           elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4026              
4027             # use strict; --> use strict; no strict qw(refs);
4028 0           elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4029 0           elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4030 0           elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4031              
4032             # use 5.12.0; --> use 5.12.0; no strict qw(refs);
4033             elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4034 0 0 0       if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
      0        
4035 0           return "use $1; no strict qw(refs);";
4036             }
4037             else {
4038 0           return "use $1;";
4039             }
4040             }
4041             elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4042 0 0 0       if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
      0        
4043 0           return "use $1; no strict qw(refs);";
4044             }
4045             else {
4046 0           return "use $1;";
4047             }
4048             }
4049              
4050             # ignore use module
4051 0           elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4052 0           elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4053 0           elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4054              
4055             # ignore no module
4056 0           elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4057 0           elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4058 0           elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4059              
4060             # use else
4061 0           elsif (/\G \b use \b /oxmsgc) { return "use"; }
4062              
4063             # use else
4064 0           elsif (/\G \b no \b /oxmsgc) { return "no"; }
4065              
4066             # ''
4067             elsif (/\G (?
4068 0           my $q_string = '';
4069 0           while (not /\G \z/oxgc) {
4070 0 0         if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0          
    0          
    0          
4071 0           elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4072 0           elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4073 0           elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4074             }
4075 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4076             }
4077              
4078             # ""
4079             elsif (/\G (\") /oxgc) {
4080 0           my $qq_string = '';
4081 0           while (not /\G \z/oxgc) {
4082 0 0         if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0          
    0          
    0          
4083 0           elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4084 0           elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4085 0           elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4086             }
4087 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4088             }
4089              
4090             # ``
4091             elsif (/\G (\`) /oxgc) {
4092 0           my $qx_string = '';
4093 0           while (not /\G \z/oxgc) {
4094 0 0         if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
  0 0          
    0          
    0          
4095 0           elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4096 0           elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4097 0           elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4098             }
4099 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4100             }
4101              
4102             # // --- not divide operator (num / num), not defined-or
4103             elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4104 0           my $regexp = '';
4105 0           while (not /\G \z/oxgc) {
4106 0 0         if (/\G (\\\\) /oxgc) { $regexp .= $1; }
  0 0          
    0          
    0          
4107 0           elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4108 0           elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4109 0           elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4110             }
4111 0           die __FILE__, ": Search pattern not terminated\n";
4112             }
4113              
4114             # ?? --- not conditional operator (condition ? then : else)
4115             elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4116 0           my $regexp = '';
4117 0           while (not /\G \z/oxgc) {
4118 0 0         if (/\G (\\\\) /oxgc) { $regexp .= $1; }
  0 0          
    0          
    0          
4119 0           elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4120 0           elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4121 0           elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4122             }
4123 0           die __FILE__, ": Search pattern not terminated\n";
4124             }
4125              
4126             # <<>> (a safer ARGV)
4127 0           elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
  0            
4128              
4129             # << (bit shift) --- not here document
4130 0           elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
  0            
4131              
4132             # <<'HEREDOC'
4133             elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4134 0           $slash = 'm//';
4135 0           my $here_quote = $1;
4136 0           my $delimiter = $2;
4137              
4138             # get here document
4139 0 0         if ($here_script eq '') {
4140 0           $here_script = CORE::substr $_, pos $_;
4141 0           $here_script =~ s/.*?\n//oxm;
4142             }
4143 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4144 0           push @heredoc, $1 . qq{\n$delimiter\n};
4145 0           push @heredoc_delimiter, $delimiter;
4146             }
4147             else {
4148 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4149             }
4150 0           return $here_quote;
4151             }
4152              
4153             # <<\HEREDOC
4154              
4155             # P.66 2.6.6. "Here" Documents
4156             # in Chapter 2: Bits and Pieces
4157             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4158              
4159             # P.73 "Here" Documents
4160             # in Chapter 2: Bits and Pieces
4161             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4162              
4163             elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4164 0           $slash = 'm//';
4165 0           my $here_quote = $1;
4166 0           my $delimiter = $2;
4167              
4168             # get here document
4169 0 0         if ($here_script eq '') {
4170 0           $here_script = CORE::substr $_, pos $_;
4171 0           $here_script =~ s/.*?\n//oxm;
4172             }
4173 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4174 0           push @heredoc, $1 . qq{\n$delimiter\n};
4175 0           push @heredoc_delimiter, $delimiter;
4176             }
4177             else {
4178 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4179             }
4180 0           return $here_quote;
4181             }
4182              
4183             # <<"HEREDOC"
4184             elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4185 0           $slash = 'm//';
4186 0           my $here_quote = $1;
4187 0           my $delimiter = $2;
4188              
4189             # get here document
4190 0 0         if ($here_script eq '') {
4191 0           $here_script = CORE::substr $_, pos $_;
4192 0           $here_script =~ s/.*?\n//oxm;
4193             }
4194 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4195 0           push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4196 0           push @heredoc_delimiter, $delimiter;
4197             }
4198             else {
4199 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4200             }
4201 0           return $here_quote;
4202             }
4203              
4204             # <
4205             elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4206 0           $slash = 'm//';
4207 0           my $here_quote = $1;
4208 0           my $delimiter = $2;
4209              
4210             # get here document
4211 0 0         if ($here_script eq '') {
4212 0           $here_script = CORE::substr $_, pos $_;
4213 0           $here_script =~ s/.*?\n//oxm;
4214             }
4215 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4216 0           push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4217 0           push @heredoc_delimiter, $delimiter;
4218             }
4219             else {
4220 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4221             }
4222 0           return $here_quote;
4223             }
4224              
4225             # <<`HEREDOC`
4226             elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4227 0           $slash = 'm//';
4228 0           my $here_quote = $1;
4229 0           my $delimiter = $2;
4230              
4231             # get here document
4232 0 0         if ($here_script eq '') {
4233 0           $here_script = CORE::substr $_, pos $_;
4234 0           $here_script =~ s/.*?\n//oxm;
4235             }
4236 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4237 0           push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4238 0           push @heredoc_delimiter, $delimiter;
4239             }
4240             else {
4241 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4242             }
4243 0           return $here_quote;
4244             }
4245              
4246             # <<= <=> <= < operator
4247             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4248 0           return $1;
4249             }
4250              
4251             #
4252             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4253 0           return $1;
4254             }
4255              
4256             # --- glob
4257              
4258             # avoid "Error: Runtime exception" of perl version 5.005_03
4259              
4260             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4261 0           return 'Elatin3::glob("' . $1 . '")';
4262             }
4263              
4264             # __DATA__
4265 0           elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4266              
4267             # __END__
4268 0           elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4269              
4270             # \cD Control-D
4271              
4272             # P.68 2.6.8. Other Literal Tokens
4273             # in Chapter 2: Bits and Pieces
4274             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4275              
4276             # P.76 Other Literal Tokens
4277             # in Chapter 2: Bits and Pieces
4278             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4279              
4280 0           elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4281              
4282             # \cZ Control-Z
4283 0           elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4284              
4285             # any operator before div
4286             elsif (/\G (
4287             -- | \+\+ |
4288             [\)\}\]]
4289              
4290 0           ) /oxgc) { $slash = 'div'; return $1; }
  0            
4291              
4292             # yada-yada or triple-dot operator
4293             elsif (/\G (
4294             \.\.\.
4295              
4296 0           ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
  0            
4297              
4298             # any operator before m//
4299              
4300             # //, //= (defined-or)
4301              
4302             # P.164 Logical Operators
4303             # in Chapter 10: More Control Structures
4304             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4305              
4306             # P.119 C-Style Logical (Short-Circuit) Operators
4307             # in Chapter 3: Unary and Binary Operators
4308             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4309              
4310             # (and so on)
4311              
4312             # ~~
4313              
4314             # P.221 The Smart Match Operator
4315             # in Chapter 15: Smart Matching and given-when
4316             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4317              
4318             # P.112 Smartmatch Operator
4319             # in Chapter 3: Unary and Binary Operators
4320             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4321              
4322             # (and so on)
4323              
4324             elsif (/\G ((?>
4325              
4326             !~~ | !~ | != | ! |
4327             %= | % |
4328             &&= | && | &= | &\.= | &\. | & |
4329             -= | -> | - |
4330             :(?>\s*)= |
4331             : |
4332             <<>> |
4333             <<= | <=> | <= | < |
4334             == | => | =~ | = |
4335             >>= | >> | >= | > |
4336             \*\*= | \*\* | \*= | \* |
4337             \+= | \+ |
4338             \.\. | \.= | \. |
4339             \/\/= | \/\/ |
4340             \/= | \/ |
4341             \? |
4342             \\ |
4343             \^= | \^\.= | \^\. | \^ |
4344             \b x= |
4345             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4346             ~~ | ~\. | ~ |
4347             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4348             \b(?: print )\b |
4349              
4350             [,;\(\{\[]
4351              
4352 0           )) /oxgc) { $slash = 'm//'; return $1; }
  0            
4353              
4354             # other any character
4355 0           elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
  0            
4356              
4357             # system error
4358             else {
4359 0           die __FILE__, ": Oops, this shouldn't happen!\n";
4360             }
4361             }
4362              
4363             # escape Latin-3 string
4364             sub e_string {
4365 0     0 0   my($string) = @_;
4366 0           my $e_string = '';
4367              
4368 0           local $slash = 'm//';
4369              
4370             # P.1024 Appendix W.10 Multibyte Processing
4371             # of ISBN 1-56592-224-7 CJKV Information Processing
4372             # (and so on)
4373              
4374 0           my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4375              
4376             # without { ... }
4377 0 0 0       if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4378 0 0         if ($string !~ /<
4379 0           return $string;
4380             }
4381             }
4382              
4383             E_STRING_LOOP:
4384 0           while ($string !~ /\G \z/oxgc) {
4385 0 0         if (0) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
4386             }
4387              
4388             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Elatin3::PREMATCH()]}
4389 0           elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4390 0           $e_string .= q{Elatin3::PREMATCH()};
4391 0           $slash = 'div';
4392             }
4393              
4394             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Elatin3::MATCH()]}
4395             elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4396 0           $e_string .= q{Elatin3::MATCH()};
4397 0           $slash = 'div';
4398             }
4399              
4400             # $', ${'} --> $', ${'}
4401             elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4402 0           $e_string .= $1;
4403 0           $slash = 'div';
4404             }
4405              
4406             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Elatin3::POSTMATCH()]}
4407             elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4408 0           $e_string .= q{Elatin3::POSTMATCH()};
4409 0           $slash = 'div';
4410             }
4411              
4412             # bareword
4413             elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4414 0           $e_string .= $1;
4415 0           $slash = 'div';
4416             }
4417              
4418             # $0 --> $0
4419             elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4420 0           $e_string .= $1;
4421 0           $slash = 'div';
4422             }
4423             elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4424 0           $e_string .= $1;
4425 0           $slash = 'div';
4426             }
4427              
4428             # $$ --> $$
4429             elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4430 0           $e_string .= $1;
4431 0           $slash = 'div';
4432             }
4433              
4434             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4435             # $1, $2, $3 --> $1, $2, $3 otherwise
4436             elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4437 0           $e_string .= e_capture($1);
4438 0           $slash = 'div';
4439             }
4440             elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4441 0           $e_string .= e_capture($1);
4442 0           $slash = 'div';
4443             }
4444              
4445             # $$foo[ ... ] --> $ $foo->[ ... ]
4446             elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4447 0           $e_string .= e_capture($1.'->'.$2);
4448 0           $slash = 'div';
4449             }
4450              
4451             # $$foo{ ... } --> $ $foo->{ ... }
4452             elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4453 0           $e_string .= e_capture($1.'->'.$2);
4454 0           $slash = 'div';
4455             }
4456              
4457             # $$foo
4458             elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4459 0           $e_string .= e_capture($1);
4460 0           $slash = 'div';
4461             }
4462              
4463             # ${ foo }
4464             elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4465 0           $e_string .= '${' . $1 . '}';
4466 0           $slash = 'div';
4467             }
4468              
4469             # ${ ... }
4470             elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4471 0           $e_string .= e_capture($1);
4472 0           $slash = 'div';
4473             }
4474              
4475             # variable or function
4476             # $ @ % & * $ #
4477             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) {
4478 0           $e_string .= $1;
4479 0           $slash = 'div';
4480             }
4481             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4482             # $ @ # \ ' " / ? ( ) [ ] < >
4483             elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4484 0           $e_string .= $1;
4485 0           $slash = 'div';
4486             }
4487              
4488             # subroutines of package Elatin3
4489 0           elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0            
4490 0           elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0            
4491 0           elsif ($string =~ /\G \b Latin3::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0            
4492 0           elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0            
4493 0           elsif ($string =~ /\G \b Latin3::eval \b /oxgc) { $e_string .= 'eval Latin3::escape'; $slash = 'm//'; }
  0            
4494 0           elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0            
4495 0           elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Elatin3::chop'; $slash = 'm//'; }
  0            
4496 0           elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0            
4497 0           elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0            
4498 0           elsif ($string =~ /\G \b Latin3::index \b /oxgc) { $e_string .= 'Latin3::index'; $slash = 'm//'; }
  0            
4499 0           elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Elatin3::index'; $slash = 'm//'; }
  0            
4500 0           elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0            
4501 0           elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0            
4502 0           elsif ($string =~ /\G \b Latin3::rindex \b /oxgc) { $e_string .= 'Latin3::rindex'; $slash = 'm//'; }
  0            
4503 0           elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Elatin3::rindex'; $slash = 'm//'; }
  0            
4504 0           elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::lc'; $slash = 'm//'; }
  0            
4505 0           elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::lcfirst'; $slash = 'm//'; }
  0            
4506 0           elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::uc'; $slash = 'm//'; }
  0            
4507 0           elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::ucfirst'; $slash = 'm//'; }
  0            
4508 0           elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::fc'; $slash = 'm//'; }
  0            
4509              
4510             # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
4511 0           elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0            
4512 0           elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0            
4513 0           elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0            
4514 0           elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0            
4515 0           elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0            
4516 0           elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0            
4517 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            
4518              
4519 0           elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0            
4520 0           elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0            
4521 0           elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0            
4522 0           elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0            
4523 0           elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0            
4524 0           elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0            
4525 0           elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0            
4526              
4527             elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
4528 0           { $e_string .= "-s $1"; $slash = 'm//'; }
  0            
4529 0           elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0            
4530 0           elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
  0            
4531 0           elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0            
4532              
4533 0           elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0            
4534 0           elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0            
4535 0           elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::chr'; $slash = 'm//'; }
  0            
4536 0           elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0            
4537 0           elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0            
4538 0           elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::glob'; $slash = 'm//'; }
  0            
4539 0           elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Elatin3::lc_'; $slash = 'm//'; }
  0            
4540 0           elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Elatin3::lcfirst_'; $slash = 'm//'; }
  0            
4541 0           elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Elatin3::uc_'; $slash = 'm//'; }
  0            
4542 0           elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Elatin3::ucfirst_'; $slash = 'm//'; }
  0            
4543 0           elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Elatin3::fc_'; $slash = 'm//'; }
  0            
4544 0           elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0            
4545              
4546 0           elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0            
4547 0           elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0            
4548 0           elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Elatin3::chr_'; $slash = 'm//'; }
  0            
4549 0           elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0            
4550 0           elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0            
4551 0           elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Elatin3::glob_'; $slash = 'm//'; }
  0            
4552 0           elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
  0            
4553 0           elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
  0            
4554             # split
4555             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4556 0           $slash = 'm//';
4557              
4558 0           my $e = '';
4559 0           while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4560 0           $e .= $1;
4561             }
4562              
4563             # end of split
4564 0 0         if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Elatin3::split' . $e; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
4565              
4566             # split scalar value
4567 0           elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Elatin3::split' . $e . e_string($1); next E_STRING_LOOP; }
  0            
4568              
4569             # split literal space
4570 0           elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0            
4571 0           elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0            
4572 0           elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0            
4573 0           elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0            
4574 0           elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0            
4575 0           elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0            
4576 0           elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0            
4577 0           elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0            
4578 0           elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0            
4579 0           elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0            
4580 0           elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0            
4581 0           elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0            
4582 0           elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {' '}; next E_STRING_LOOP; }
  0            
4583 0           elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {" "}; next E_STRING_LOOP; }
  0            
4584              
4585             # split qq//
4586             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4587 0 0         if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
  0            
  0            
4588             else {
4589 0           while ($string !~ /\G \z/oxgc) {
4590 0 0         if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
4591 0           elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq ( ) --> qr ( )
  0            
4592 0           elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq { } --> qr { }
  0            
4593 0           elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq [ ] --> qr [ ]
  0            
4594 0           elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq < > --> qr < >
  0            
4595 0           elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
  0            
4596 0           elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq * * --> qr * *
  0            
4597             }
4598 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4599             }
4600             }
4601              
4602             # split qr//
4603             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4604 0 0         if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
  0            
  0            
4605             else {
4606 0           while ($string !~ /\G \z/oxgc) {
4607 0 0         if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
4608 0           elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ( )
  0            
4609 0           elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr { }
  0            
4610 0           elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr [ ]
  0            
4611 0           elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr < >
  0            
4612 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            
4613 0           elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
  0            
4614 0           elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr * *
  0            
4615             }
4616 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4617             }
4618             }
4619              
4620             # split q//
4621             elsif ($string =~ /\G \b (q) \b /oxgc) {
4622 0 0         if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
  0            
  0            
4623             else {
4624 0           while ($string !~ /\G \z/oxgc) {
4625 0 0         if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
4626 0           elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q ( ) --> qr ( )
  0            
4627 0           elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q { } --> qr { }
  0            
4628 0           elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q [ ] --> qr [ ]
  0            
4629 0           elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q < > --> qr < >
  0            
4630 0           elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
  0            
4631 0           elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q * * --> qr * *
  0            
4632             }
4633 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4634             }
4635             }
4636              
4637             # split m//
4638             elsif ($string =~ /\G \b (m) \b /oxgc) {
4639 0 0         if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # m# # --> qr # #
  0            
  0            
4640             else {
4641 0           while ($string !~ /\G \z/oxgc) {
4642 0 0         if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
4643 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            
4644 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            
4645 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            
4646 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            
4647 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            
4648 0           elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
  0            
4649 0           elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m * * --> qr * *
  0            
4650             }
4651 0           die __FILE__, ": Search pattern not terminated\n";
4652             }
4653             }
4654              
4655             # split ''
4656             elsif ($string =~ /\G (\') /oxgc) {
4657 0           my $q_string = '';
4658 0           while ($string !~ /\G \z/oxgc) {
4659 0 0         if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0          
    0          
    0          
4660 0           elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4661 0           elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
  0            
4662 0           elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4663             }
4664 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4665             }
4666              
4667             # split ""
4668             elsif ($string =~ /\G (\") /oxgc) {
4669 0           my $qq_string = '';
4670 0           while ($string !~ /\G \z/oxgc) {
4671 0 0         if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0          
    0          
    0          
4672 0           elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4673 0           elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
  0            
4674 0           elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4675             }
4676 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4677             }
4678              
4679             # split //
4680             elsif ($string =~ /\G (\/) /oxgc) {
4681 0           my $regexp = '';
4682 0           while ($string !~ /\G \z/oxgc) {
4683 0 0         if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0 0          
    0          
    0          
4684 0           elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4685 0           elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
  0            
4686 0           elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4687             }
4688 0           die __FILE__, ": Search pattern not terminated\n";
4689             }
4690             }
4691              
4692             # qq//
4693             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4694 0           my $ope = $1;
4695 0 0         if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4696 0           $e_string .= e_qq($ope,$1,$3,$2);
4697             }
4698             else {
4699 0           my $e = '';
4700 0           while ($string !~ /\G \z/oxgc) {
4701 0 0         if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
4702 0           elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0            
4703 0           elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0            
4704 0           elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0            
4705 0           elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
  0            
4706 0           elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
  0            
4707             }
4708 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4709             }
4710             }
4711              
4712             # qx//
4713             elsif ($string =~ /\G \b (qx) \b /oxgc) {
4714 0           my $ope = $1;
4715 0 0         if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4716 0           $e_string .= e_qq($ope,$1,$3,$2);
4717             }
4718             else {
4719 0           my $e = '';
4720 0           while ($string !~ /\G \z/oxgc) {
4721 0 0         if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
    0          
4722 0           elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0            
4723 0           elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0            
4724 0           elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0            
4725 0           elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0            
4726 0           elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
  0            
4727 0           elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
  0            
4728             }
4729 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4730             }
4731             }
4732              
4733             # q//
4734             elsif ($string =~ /\G \b (q) \b /oxgc) {
4735 0           my $ope = $1;
4736 0 0         if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4737 0           $e_string .= e_q($ope,$1,$3,$2);
4738             }
4739             else {
4740 0           my $e = '';
4741 0           while ($string !~ /\G \z/oxgc) {
4742 0 0         if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0          
    0          
    0          
    0          
    0          
4743 0           elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0            
4744 0           elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0            
4745 0           elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0            
4746 0           elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
  0            
4747 0           elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q * *
  0            
4748             }
4749 0           die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4750             }
4751             }
4752              
4753             # ''
4754 0           elsif ($string =~ /\G (?
4755              
4756             # ""
4757 0           elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4758              
4759             # ``
4760 0           elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4761              
4762             # <<>> (a safer ARGV)
4763 0           elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4764              
4765             # <<= <=> <= < operator
4766 0           elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4767              
4768             #
4769 0           elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4770              
4771             # --- glob
4772             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4773 0           $e_string .= 'Elatin3::glob("' . $1 . '")';
4774             }
4775              
4776             # << (bit shift) --- not here document
4777 0           elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; $e_string .= $1; }
  0            
4778              
4779             # <<'HEREDOC'
4780             elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4781 0           $slash = 'm//';
4782 0           my $here_quote = $1;
4783 0           my $delimiter = $2;
4784              
4785             # get here document
4786 0 0         if ($here_script eq '') {
4787 0           $here_script = CORE::substr $_, pos $_;
4788 0           $here_script =~ s/.*?\n//oxm;
4789             }
4790 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4791 0           push @heredoc, $1 . qq{\n$delimiter\n};
4792 0           push @heredoc_delimiter, $delimiter;
4793             }
4794             else {
4795 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4796             }
4797 0           $e_string .= $here_quote;
4798             }
4799              
4800             # <<\HEREDOC
4801             elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4802 0           $slash = 'm//';
4803 0           my $here_quote = $1;
4804 0           my $delimiter = $2;
4805              
4806             # get here document
4807 0 0         if ($here_script eq '') {
4808 0           $here_script = CORE::substr $_, pos $_;
4809 0           $here_script =~ s/.*?\n//oxm;
4810             }
4811 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4812 0           push @heredoc, $1 . qq{\n$delimiter\n};
4813 0           push @heredoc_delimiter, $delimiter;
4814             }
4815             else {
4816 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4817             }
4818 0           $e_string .= $here_quote;
4819             }
4820              
4821             # <<"HEREDOC"
4822             elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4823 0           $slash = 'm//';
4824 0           my $here_quote = $1;
4825 0           my $delimiter = $2;
4826              
4827             # get here document
4828 0 0         if ($here_script eq '') {
4829 0           $here_script = CORE::substr $_, pos $_;
4830 0           $here_script =~ s/.*?\n//oxm;
4831             }
4832 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4833 0           push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4834 0           push @heredoc_delimiter, $delimiter;
4835             }
4836             else {
4837 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4838             }
4839 0           $e_string .= $here_quote;
4840             }
4841              
4842             # <
4843             elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4844 0           $slash = 'm//';
4845 0           my $here_quote = $1;
4846 0           my $delimiter = $2;
4847              
4848             # get here document
4849 0 0         if ($here_script eq '') {
4850 0           $here_script = CORE::substr $_, pos $_;
4851 0           $here_script =~ s/.*?\n//oxm;
4852             }
4853 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4854 0           push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4855 0           push @heredoc_delimiter, $delimiter;
4856             }
4857             else {
4858 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4859             }
4860 0           $e_string .= $here_quote;
4861             }
4862              
4863             # <<`HEREDOC`
4864             elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4865 0           $slash = 'm//';
4866 0           my $here_quote = $1;
4867 0           my $delimiter = $2;
4868              
4869             # get here document
4870 0 0         if ($here_script eq '') {
4871 0           $here_script = CORE::substr $_, pos $_;
4872 0           $here_script =~ s/.*?\n//oxm;
4873             }
4874 0 0         if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4875 0           push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4876 0           push @heredoc_delimiter, $delimiter;
4877             }
4878             else {
4879 0           die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4880             }
4881 0           $e_string .= $here_quote;
4882             }
4883              
4884             # any operator before div
4885             elsif ($string =~ /\G (
4886             -- | \+\+ |
4887             [\)\}\]]
4888              
4889 0           ) /oxgc) { $slash = 'div'; $e_string .= $1; }
  0            
4890              
4891             # yada-yada or triple-dot operator
4892             elsif ($string =~ /\G (
4893             \.\.\.
4894              
4895 0           ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
  0            
4896              
4897             # any operator before m//
4898             elsif ($string =~ /\G ((?>
4899              
4900             !~~ | !~ | != | ! |
4901             %= | % |
4902             &&= | && | &= | &\.= | &\. | & |
4903             -= | -> | - |
4904             :(?>\s*)= |
4905             : |
4906             <<>> |
4907             <<= | <=> | <= | < |
4908             == | => | =~ | = |
4909             >>= | >> | >= | > |
4910             \*\*= | \*\* | \*= | \* |
4911             \+= | \+ |
4912             \.\. | \.= | \. |
4913             \/\/= | \/\/ |
4914             \/= | \/ |
4915             \? |
4916             \\ |
4917             \^= | \^\.= | \^\. | \^ |
4918             \b x= |
4919             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4920             ~~ | ~\. | ~ |
4921             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4922             \b(?: print )\b |
4923              
4924             [,;\(\{\[]
4925              
4926 0           )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
  0            
4927              
4928             # other any character
4929 0           elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
4930              
4931             # system error
4932             else {
4933 0           die __FILE__, ": Oops, this shouldn't happen!\n";
4934             }
4935             }
4936              
4937 0           return $e_string;
4938             }
4939              
4940             #
4941             # character class
4942             #
4943             sub character_class {
4944 0     0 0   my($char,$modifier) = @_;
4945              
4946 0 0         if ($char eq '.') {
4947 0 0         if ($modifier =~ /s/) {
4948 0           return '${Elatin3::dot_s}';
4949             }
4950             else {
4951 0           return '${Elatin3::dot}';
4952             }
4953             }
4954             else {
4955 0           return Elatin3::classic_character_class($char);
4956             }
4957             }
4958              
4959             #
4960             # escape capture ($1, $2, $3, ...)
4961             #
4962             sub e_capture {
4963              
4964 0     0 0   return join '', '${', $_[0], '}';
4965             }
4966              
4967             #
4968             # escape transliteration (tr/// or y///)
4969             #
4970             sub e_tr {
4971 0     0 0   my($variable,$charclass,$e,$charclass2,$modifier) = @_;
4972 0           my $e_tr = '';
4973 0   0       $modifier ||= '';
4974              
4975 0           $slash = 'div';
4976              
4977             # quote character class 1
4978 0           $charclass = q_tr($charclass);
4979              
4980             # quote character class 2
4981 0           $charclass2 = q_tr($charclass2);
4982              
4983             # /b /B modifier
4984 0 0         if ($modifier =~ tr/bB//d) {
4985 0 0         if ($variable eq '') {
4986 0           $e_tr = qq{tr$charclass$e$charclass2$modifier};
4987             }
4988             else {
4989 0           $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
4990             }
4991             }
4992             else {
4993 0 0         if ($variable eq '') {
4994 0           $e_tr = qq{Elatin3::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
4995             }
4996             else {
4997 0           $e_tr = qq{Elatin3::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
4998             }
4999             }
5000              
5001             # clear tr/// variable
5002 0           $tr_variable = '';
5003 0           $bind_operator = '';
5004              
5005 0           return $e_tr;
5006             }
5007              
5008             #
5009             # quote for escape transliteration (tr/// or y///)
5010             #
5011             sub q_tr {
5012 0     0 0   my($charclass) = @_;
5013              
5014             # quote character class
5015 0 0         if ($charclass !~ /'/oxms) {
    0          
    0          
    0          
    0          
    0          
5016 0           return e_q('', "'", "'", $charclass); # --> q' '
5017             }
5018             elsif ($charclass !~ /\//oxms) {
5019 0           return e_q('q', '/', '/', $charclass); # --> q/ /
5020             }
5021             elsif ($charclass !~ /\#/oxms) {
5022 0           return e_q('q', '#', '#', $charclass); # --> q# #
5023             }
5024             elsif ($charclass !~ /[\<\>]/oxms) {
5025 0           return e_q('q', '<', '>', $charclass); # --> q< >
5026             }
5027             elsif ($charclass !~ /[\(\)]/oxms) {
5028 0           return e_q('q', '(', ')', $charclass); # --> q( )
5029             }
5030             elsif ($charclass !~ /[\{\}]/oxms) {
5031 0           return e_q('q', '{', '}', $charclass); # --> q{ }
5032             }
5033             else {
5034 0           for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5035 0 0         if ($charclass !~ /\Q$char\E/xms) {
5036 0           return e_q('q', $char, $char, $charclass);
5037             }
5038             }
5039             }
5040              
5041 0           return e_q('q', '{', '}', $charclass);
5042             }
5043              
5044             #
5045             # escape q string (q//, '')
5046             #
5047             sub e_q {
5048 0     0 0   my($ope,$delimiter,$end_delimiter,$string) = @_;
5049              
5050 0           $slash = 'div';
5051              
5052 0           return join '', $ope, $delimiter, $string, $end_delimiter;
5053             }
5054              
5055             #
5056             # escape qq string (qq//, "", qx//, ``)
5057             #
5058             sub e_qq {
5059 0     0 0   my($ope,$delimiter,$end_delimiter,$string) = @_;
5060              
5061 0           $slash = 'div';
5062              
5063 0           my $left_e = 0;
5064 0           my $right_e = 0;
5065              
5066             # split regexp
5067 0           my @char = $string =~ /\G((?>
5068             [^\\\$] |
5069             \\x\{ (?>[0-9A-Fa-f]+) \} |
5070             \\o\{ (?>[0-7]+) \} |
5071             \\N\{ (?>[^0-9\}][^\}]*) \} |
5072             \\ $q_char |
5073             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5074             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5075             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5076             \$ (?>\s* [0-9]+) |
5077             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5078             \$ \$ (?![\w\{]) |
5079             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5080             $q_char
5081             ))/oxmsg;
5082              
5083 0           for (my $i=0; $i <= $#char; $i++) {
5084              
5085             # "\L\u" --> "\u\L"
5086 0 0 0       if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    0 0        
    0          
    0          
    0          
5087 0           @char[$i,$i+1] = @char[$i+1,$i];
5088             }
5089              
5090             # "\U\l" --> "\l\U"
5091             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5092 0           @char[$i,$i+1] = @char[$i+1,$i];
5093             }
5094              
5095             # octal escape sequence
5096             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5097 0           $char[$i] = Elatin3::octchr($1);
5098             }
5099              
5100             # hexadecimal escape sequence
5101             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5102 0           $char[$i] = Elatin3::hexchr($1);
5103             }
5104              
5105             # \N{CHARNAME} --> N{CHARNAME}
5106             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5107 0           $char[$i] = $1;
5108             }
5109              
5110 0 0         if (0) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5111             }
5112              
5113             # \F
5114             #
5115             # P.69 Table 2-6. Translation escapes
5116             # in Chapter 2: Bits and Pieces
5117             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5118             # (and so on)
5119              
5120             # \u \l \U \L \F \Q \E
5121 0           elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5122 0 0         if ($right_e < $left_e) {
5123 0           $char[$i] = '\\' . $char[$i];
5124             }
5125             }
5126             elsif ($char[$i] eq '\u') {
5127              
5128             # "STRING @{[ LIST EXPR ]} MORE STRING"
5129              
5130             # P.257 Other Tricks You Can Do with Hard References
5131             # in Chapter 8: References
5132             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5133              
5134             # P.353 Other Tricks You Can Do with Hard References
5135             # in Chapter 8: References
5136             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5137              
5138             # (and so on)
5139              
5140 0           $char[$i] = '@{[Elatin3::ucfirst qq<';
5141 0           $left_e++;
5142             }
5143             elsif ($char[$i] eq '\l') {
5144 0           $char[$i] = '@{[Elatin3::lcfirst qq<';
5145 0           $left_e++;
5146             }
5147             elsif ($char[$i] eq '\U') {
5148 0           $char[$i] = '@{[Elatin3::uc qq<';
5149 0           $left_e++;
5150             }
5151             elsif ($char[$i] eq '\L') {
5152 0           $char[$i] = '@{[Elatin3::lc qq<';
5153 0           $left_e++;
5154             }
5155             elsif ($char[$i] eq '\F') {
5156 0           $char[$i] = '@{[Elatin3::fc qq<';
5157 0           $left_e++;
5158             }
5159             elsif ($char[$i] eq '\Q') {
5160 0           $char[$i] = '@{[CORE::quotemeta qq<';
5161 0           $left_e++;
5162             }
5163             elsif ($char[$i] eq '\E') {
5164 0 0         if ($right_e < $left_e) {
5165 0           $char[$i] = '>]}';
5166 0           $right_e++;
5167             }
5168             else {
5169 0           $char[$i] = '';
5170             }
5171             }
5172             elsif ($char[$i] eq '\Q') {
5173 0           while (1) {
5174 0 0         if (++$i > $#char) {
5175 0           last;
5176             }
5177 0 0         if ($char[$i] eq '\E') {
5178 0           last;
5179             }
5180             }
5181             }
5182             elsif ($char[$i] eq '\E') {
5183             }
5184              
5185             # $0 --> $0
5186             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5187             }
5188             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5189             }
5190              
5191             # $$ --> $$
5192             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5193             }
5194              
5195             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5196             # $1, $2, $3 --> $1, $2, $3 otherwise
5197             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5198 0           $char[$i] = e_capture($1);
5199             }
5200             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5201 0           $char[$i] = e_capture($1);
5202             }
5203              
5204             # $$foo[ ... ] --> $ $foo->[ ... ]
5205             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5206 0           $char[$i] = e_capture($1.'->'.$2);
5207             }
5208              
5209             # $$foo{ ... } --> $ $foo->{ ... }
5210             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5211 0           $char[$i] = e_capture($1.'->'.$2);
5212             }
5213              
5214             # $$foo
5215             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5216 0           $char[$i] = e_capture($1);
5217             }
5218              
5219             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
5220             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5221 0           $char[$i] = '@{[Elatin3::PREMATCH()]}';
5222             }
5223              
5224             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
5225             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5226 0           $char[$i] = '@{[Elatin3::MATCH()]}';
5227             }
5228              
5229             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
5230             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5231 0           $char[$i] = '@{[Elatin3::POSTMATCH()]}';
5232             }
5233              
5234             # ${ foo } --> ${ foo }
5235             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5236             }
5237              
5238             # ${ ... }
5239             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5240 0           $char[$i] = e_capture($1);
5241             }
5242             }
5243              
5244             # return string
5245 0 0         if ($left_e > $right_e) {
5246 0           return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5247             }
5248 0           return join '', $ope, $delimiter, @char, $end_delimiter;
5249             }
5250              
5251             #
5252             # escape qw string (qw//)
5253             #
5254             sub e_qw {
5255 0     0 0   my($ope,$delimiter,$end_delimiter,$string) = @_;
5256              
5257 0           $slash = 'div';
5258              
5259             # choice again delimiter
5260 0           my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
  0            
5261 0 0         if (not $octet{$end_delimiter}) {
    0          
    0          
    0          
    0          
5262 0           return join '', $ope, $delimiter, $string, $end_delimiter;
5263             }
5264             elsif (not $octet{')'}) {
5265 0           return join '', $ope, '(', $string, ')';
5266             }
5267             elsif (not $octet{'}'}) {
5268 0           return join '', $ope, '{', $string, '}';
5269             }
5270             elsif (not $octet{']'}) {
5271 0           return join '', $ope, '[', $string, ']';
5272             }
5273             elsif (not $octet{'>'}) {
5274 0           return join '', $ope, '<', $string, '>';
5275             }
5276             else {
5277 0           for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5278 0 0         if (not $octet{$char}) {
5279 0           return join '', $ope, $char, $string, $char;
5280             }
5281             }
5282             }
5283              
5284             # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5285 0           my @string = CORE::split(/\s+/, $string);
5286 0           for my $string (@string) {
5287 0           my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5288 0           for my $octet (@octet) {
5289 0 0         if ($octet =~ /\A (['\\]) \z/oxms) {
5290 0           $octet = '\\' . $1;
5291             }
5292             }
5293 0           $string = join '', @octet;
5294             }
5295 0           return join '', '(', (join ', ', map { "'$_'" } @string), ')';
  0            
5296             }
5297              
5298             #
5299             # escape here document (<<"HEREDOC", <
5300             #
5301             sub e_heredoc {
5302 0     0 0   my($string) = @_;
5303              
5304 0           $slash = 'm//';
5305              
5306 0           my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5307              
5308 0           my $left_e = 0;
5309 0           my $right_e = 0;
5310              
5311             # split regexp
5312 0           my @char = $string =~ /\G((?>
5313             [^\\\$] |
5314             \\x\{ (?>[0-9A-Fa-f]+) \} |
5315             \\o\{ (?>[0-7]+) \} |
5316             \\N\{ (?>[^0-9\}][^\}]*) \} |
5317             \\ $q_char |
5318             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5319             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5320             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5321             \$ (?>\s* [0-9]+) |
5322             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5323             \$ \$ (?![\w\{]) |
5324             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5325             $q_char
5326             ))/oxmsg;
5327              
5328 0           for (my $i=0; $i <= $#char; $i++) {
5329              
5330             # "\L\u" --> "\u\L"
5331 0 0 0       if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    0 0        
    0          
    0          
    0          
5332 0           @char[$i,$i+1] = @char[$i+1,$i];
5333             }
5334              
5335             # "\U\l" --> "\l\U"
5336             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5337 0           @char[$i,$i+1] = @char[$i+1,$i];
5338             }
5339              
5340             # octal escape sequence
5341             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5342 0           $char[$i] = Elatin3::octchr($1);
5343             }
5344              
5345             # hexadecimal escape sequence
5346             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5347 0           $char[$i] = Elatin3::hexchr($1);
5348             }
5349              
5350             # \N{CHARNAME} --> N{CHARNAME}
5351             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5352 0           $char[$i] = $1;
5353             }
5354              
5355 0 0         if (0) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
5356             }
5357              
5358             # \u \l \U \L \F \Q \E
5359 0           elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5360 0 0         if ($right_e < $left_e) {
5361 0           $char[$i] = '\\' . $char[$i];
5362             }
5363             }
5364             elsif ($char[$i] eq '\u') {
5365 0           $char[$i] = '@{[Elatin3::ucfirst qq<';
5366 0           $left_e++;
5367             }
5368             elsif ($char[$i] eq '\l') {
5369 0           $char[$i] = '@{[Elatin3::lcfirst qq<';
5370 0           $left_e++;
5371             }
5372             elsif ($char[$i] eq '\U') {
5373 0           $char[$i] = '@{[Elatin3::uc qq<';
5374 0           $left_e++;
5375             }
5376             elsif ($char[$i] eq '\L') {
5377 0           $char[$i] = '@{[Elatin3::lc qq<';
5378 0           $left_e++;
5379             }
5380             elsif ($char[$i] eq '\F') {
5381 0           $char[$i] = '@{[Elatin3::fc qq<';
5382 0           $left_e++;
5383             }
5384             elsif ($char[$i] eq '\Q') {
5385 0           $char[$i] = '@{[CORE::quotemeta qq<';
5386 0           $left_e++;
5387             }
5388             elsif ($char[$i] eq '\E') {
5389 0 0         if ($right_e < $left_e) {
5390 0           $char[$i] = '>]}';
5391 0           $right_e++;
5392             }
5393             else {
5394 0           $char[$i] = '';
5395             }
5396             }
5397             elsif ($char[$i] eq '\Q') {
5398 0           while (1) {
5399 0 0         if (++$i > $#char) {
5400 0           last;
5401             }
5402 0 0         if ($char[$i] eq '\E') {
5403 0           last;
5404             }
5405             }
5406             }
5407             elsif ($char[$i] eq '\E') {
5408             }
5409              
5410             # $0 --> $0
5411             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5412             }
5413             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5414             }
5415              
5416             # $$ --> $$
5417             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5418             }
5419              
5420             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5421             # $1, $2, $3 --> $1, $2, $3 otherwise
5422             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5423 0           $char[$i] = e_capture($1);
5424             }
5425             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5426 0           $char[$i] = e_capture($1);
5427             }
5428              
5429             # $$foo[ ... ] --> $ $foo->[ ... ]
5430             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5431 0           $char[$i] = e_capture($1.'->'.$2);
5432             }
5433              
5434             # $$foo{ ... } --> $ $foo->{ ... }
5435             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5436 0           $char[$i] = e_capture($1.'->'.$2);
5437             }
5438              
5439             # $$foo
5440             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5441 0           $char[$i] = e_capture($1);
5442             }
5443              
5444             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
5445             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5446 0           $char[$i] = '@{[Elatin3::PREMATCH()]}';
5447             }
5448              
5449             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
5450             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5451 0           $char[$i] = '@{[Elatin3::MATCH()]}';
5452             }
5453              
5454             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
5455             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5456 0           $char[$i] = '@{[Elatin3::POSTMATCH()]}';
5457             }
5458              
5459             # ${ foo } --> ${ foo }
5460             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5461             }
5462              
5463             # ${ ... }
5464             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5465 0           $char[$i] = e_capture($1);
5466             }
5467             }
5468              
5469             # return string
5470 0 0         if ($left_e > $right_e) {
5471 0           return join '', @char, '>]}' x ($left_e - $right_e);
5472             }
5473 0           return join '', @char;
5474             }
5475              
5476             #
5477             # escape regexp (m//, qr//)
5478             #
5479             sub e_qr {
5480 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5481 0   0       $modifier ||= '';
5482              
5483 0           $modifier =~ tr/p//d;
5484 0 0         if ($modifier =~ /([adlu])/oxms) {
5485 0           my $line = 0;
5486 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5487 0 0         if ($filename ne __FILE__) {
5488 0           $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5489 0           last;
5490             }
5491             }
5492 0           die qq{Unsupported modifier "$1" used at line $line.\n};
5493             }
5494              
5495 0           $slash = 'div';
5496              
5497             # literal null string pattern
5498 0 0         if ($string eq '') {
    0          
5499 0           $modifier =~ tr/bB//d;
5500 0           $modifier =~ tr/i//d;
5501 0           return join '', $ope, $delimiter, $end_delimiter, $modifier;
5502             }
5503              
5504             # /b /B modifier
5505             elsif ($modifier =~ tr/bB//d) {
5506              
5507             # choice again delimiter
5508 0 0         if ($delimiter =~ / [\@:] /oxms) {
5509 0           my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5510 0           my %octet = map {$_ => 1} @char;
  0            
5511 0 0         if (not $octet{')'}) {
    0          
    0          
    0          
5512 0           $delimiter = '(';
5513 0           $end_delimiter = ')';
5514             }
5515             elsif (not $octet{'}'}) {
5516 0           $delimiter = '{';
5517 0           $end_delimiter = '}';
5518             }
5519             elsif (not $octet{']'}) {
5520 0           $delimiter = '[';
5521 0           $end_delimiter = ']';
5522             }
5523             elsif (not $octet{'>'}) {
5524 0           $delimiter = '<';
5525 0           $end_delimiter = '>';
5526             }
5527             else {
5528 0           for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5529 0 0         if (not $octet{$char}) {
5530 0           $delimiter = $char;
5531 0           $end_delimiter = $char;
5532 0           last;
5533             }
5534             }
5535             }
5536             }
5537              
5538 0 0 0       if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5539 0           return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5540             }
5541             else {
5542 0           return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5543             }
5544             }
5545              
5546 0 0         my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5547 0           my $metachar = qr/[\@\\|[\]{^]/oxms;
5548              
5549             # split regexp
5550 0           my @char = $string =~ /\G((?>
5551             [^\\\$\@\[\(] |
5552             \\x (?>[0-9A-Fa-f]{1,2}) |
5553             \\ (?>[0-7]{2,3}) |
5554             \\c [\x40-\x5F] |
5555             \\x\{ (?>[0-9A-Fa-f]+) \} |
5556             \\o\{ (?>[0-7]+) \} |
5557             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5558             \\ $q_char |
5559             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5560             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5561             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5562             [\$\@] $qq_variable |
5563             \$ (?>\s* [0-9]+) |
5564             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5565             \$ \$ (?![\w\{]) |
5566             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5567             \[\^ |
5568             \[\: (?>[a-z]+) :\] |
5569             \[\:\^ (?>[a-z]+) :\] |
5570             \(\? |
5571             $q_char
5572             ))/oxmsg;
5573              
5574             # choice again delimiter
5575 0 0         if ($delimiter =~ / [\@:] /oxms) {
5576 0           my %octet = map {$_ => 1} @char;
  0            
5577 0 0         if (not $octet{')'}) {
    0          
    0          
    0          
5578 0           $delimiter = '(';
5579 0           $end_delimiter = ')';
5580             }
5581             elsif (not $octet{'}'}) {
5582 0           $delimiter = '{';
5583 0           $end_delimiter = '}';
5584             }
5585             elsif (not $octet{']'}) {
5586 0           $delimiter = '[';
5587 0           $end_delimiter = ']';
5588             }
5589             elsif (not $octet{'>'}) {
5590 0           $delimiter = '<';
5591 0           $end_delimiter = '>';
5592             }
5593             else {
5594 0           for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5595 0 0         if (not $octet{$char}) {
5596 0           $delimiter = $char;
5597 0           $end_delimiter = $char;
5598 0           last;
5599             }
5600             }
5601             }
5602             }
5603              
5604 0           my $left_e = 0;
5605 0           my $right_e = 0;
5606 0           for (my $i=0; $i <= $#char; $i++) {
5607              
5608             # "\L\u" --> "\u\L"
5609 0 0 0       if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    0 0        
    0          
    0          
    0          
    0          
5610 0           @char[$i,$i+1] = @char[$i+1,$i];
5611             }
5612              
5613             # "\U\l" --> "\l\U"
5614             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5615 0           @char[$i,$i+1] = @char[$i+1,$i];
5616             }
5617              
5618             # octal escape sequence
5619             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5620 0           $char[$i] = Elatin3::octchr($1);
5621             }
5622              
5623             # hexadecimal escape sequence
5624             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5625 0           $char[$i] = Elatin3::hexchr($1);
5626             }
5627              
5628             # \b{...} --> b\{...}
5629             # \B{...} --> B\{...}
5630             # \N{CHARNAME} --> N\{CHARNAME}
5631             # \p{PROPERTY} --> p\{PROPERTY}
5632             # \P{PROPERTY} --> P\{PROPERTY}
5633             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5634 0           $char[$i] = $1 . '\\' . $2;
5635             }
5636              
5637             # \p, \P, \X --> p, P, X
5638             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5639 0           $char[$i] = $1;
5640             }
5641              
5642 0 0 0       if (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          
5643             }
5644              
5645             # join separated multiple-octet
5646 0           elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5647 0 0 0       if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
    0 0        
    0 0        
      0        
      0        
      0        
5648 0           $char[$i] .= join '', splice @char, $i+1, 3;
5649             }
5650             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)) {
5651 0           $char[$i] .= join '', splice @char, $i+1, 2;
5652             }
5653             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)) {
5654 0           $char[$i] .= join '', splice @char, $i+1, 1;
5655             }
5656             }
5657              
5658             # open character class [...]
5659             elsif ($char[$i] eq '[') {
5660 0           my $left = $i;
5661              
5662             # [] make die "Unmatched [] in regexp ...\n"
5663             # (and so on)
5664              
5665 0 0         if ($char[$i+1] eq ']') {
5666 0           $i++;
5667             }
5668              
5669 0           while (1) {
5670 0 0         if (++$i > $#char) {
5671 0           die __FILE__, ": Unmatched [] in regexp\n";
5672             }
5673 0 0         if ($char[$i] eq ']') {
5674 0           my $right = $i;
5675              
5676             # [...]
5677 0 0         if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5678 0           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);
  0            
5679             }
5680             else {
5681 0           splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
5682             }
5683              
5684 0           $i = $left;
5685 0           last;
5686             }
5687             }
5688             }
5689              
5690             # open character class [^...]
5691             elsif ($char[$i] eq '[^') {
5692 0           my $left = $i;
5693              
5694             # [^] make die "Unmatched [] in regexp ...\n"
5695             # (and so on)
5696              
5697 0 0         if ($char[$i+1] eq ']') {
5698 0           $i++;
5699             }
5700              
5701 0           while (1) {
5702 0 0         if (++$i > $#char) {
5703 0           die __FILE__, ": Unmatched [] in regexp\n";
5704             }
5705 0 0         if ($char[$i] eq ']') {
5706 0           my $right = $i;
5707              
5708             # [^...]
5709 0 0         if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5710 0           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);
  0            
5711             }
5712             else {
5713 0           splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5714             }
5715              
5716 0           $i = $left;
5717 0           last;
5718             }
5719             }
5720             }
5721              
5722             # rewrite character class or escape character
5723             elsif (my $char = character_class($char[$i],$modifier)) {
5724 0           $char[$i] = $char;
5725             }
5726              
5727             # /i modifier
5728             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
5729 0 0         if (CORE::length(Elatin3::fc($char[$i])) == 1) {
5730 0           $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
5731             }
5732             else {
5733 0           $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
5734             }
5735             }
5736              
5737             # \u \l \U \L \F \Q \E
5738             elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5739 0 0         if ($right_e < $left_e) {
5740 0           $char[$i] = '\\' . $char[$i];
5741             }
5742             }
5743             elsif ($char[$i] eq '\u') {
5744 0           $char[$i] = '@{[Elatin3::ucfirst qq<';
5745 0           $left_e++;
5746             }
5747             elsif ($char[$i] eq '\l') {
5748 0           $char[$i] = '@{[Elatin3::lcfirst qq<';
5749 0           $left_e++;
5750             }
5751             elsif ($char[$i] eq '\U') {
5752 0           $char[$i] = '@{[Elatin3::uc qq<';
5753 0           $left_e++;
5754             }
5755             elsif ($char[$i] eq '\L') {
5756 0           $char[$i] = '@{[Elatin3::lc qq<';
5757 0           $left_e++;
5758             }
5759             elsif ($char[$i] eq '\F') {
5760 0           $char[$i] = '@{[Elatin3::fc qq<';
5761 0           $left_e++;
5762             }
5763             elsif ($char[$i] eq '\Q') {
5764 0           $char[$i] = '@{[CORE::quotemeta qq<';
5765 0           $left_e++;
5766             }
5767             elsif ($char[$i] eq '\E') {
5768 0 0         if ($right_e < $left_e) {
5769 0           $char[$i] = '>]}';
5770 0           $right_e++;
5771             }
5772             else {
5773 0           $char[$i] = '';
5774             }
5775             }
5776             elsif ($char[$i] eq '\Q') {
5777 0           while (1) {
5778 0 0         if (++$i > $#char) {
5779 0           last;
5780             }
5781 0 0         if ($char[$i] eq '\E') {
5782 0           last;
5783             }
5784             }
5785             }
5786             elsif ($char[$i] eq '\E') {
5787             }
5788              
5789             # $0 --> $0
5790             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5791 0 0         if ($ignorecase) {
5792 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5793             }
5794             }
5795             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5796 0 0         if ($ignorecase) {
5797 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5798             }
5799             }
5800              
5801             # $$ --> $$
5802             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5803             }
5804              
5805             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5806             # $1, $2, $3 --> $1, $2, $3 otherwise
5807             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5808 0           $char[$i] = e_capture($1);
5809 0 0         if ($ignorecase) {
5810 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5811             }
5812             }
5813             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5814 0           $char[$i] = e_capture($1);
5815 0 0         if ($ignorecase) {
5816 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5817             }
5818             }
5819              
5820             # $$foo[ ... ] --> $ $foo->[ ... ]
5821             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5822 0           $char[$i] = e_capture($1.'->'.$2);
5823 0 0         if ($ignorecase) {
5824 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5825             }
5826             }
5827              
5828             # $$foo{ ... } --> $ $foo->{ ... }
5829             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5830 0           $char[$i] = e_capture($1.'->'.$2);
5831 0 0         if ($ignorecase) {
5832 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5833             }
5834             }
5835              
5836             # $$foo
5837             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5838 0           $char[$i] = e_capture($1);
5839 0 0         if ($ignorecase) {
5840 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5841             }
5842             }
5843              
5844             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
5845             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5846 0 0         if ($ignorecase) {
5847 0           $char[$i] = '@{[Elatin3::ignorecase(Elatin3::PREMATCH())]}';
5848             }
5849             else {
5850 0           $char[$i] = '@{[Elatin3::PREMATCH()]}';
5851             }
5852             }
5853              
5854             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
5855             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5856 0 0         if ($ignorecase) {
5857 0           $char[$i] = '@{[Elatin3::ignorecase(Elatin3::MATCH())]}';
5858             }
5859             else {
5860 0           $char[$i] = '@{[Elatin3::MATCH()]}';
5861             }
5862             }
5863              
5864             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
5865             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5866 0 0         if ($ignorecase) {
5867 0           $char[$i] = '@{[Elatin3::ignorecase(Elatin3::POSTMATCH())]}';
5868             }
5869             else {
5870 0           $char[$i] = '@{[Elatin3::POSTMATCH()]}';
5871             }
5872             }
5873              
5874             # ${ foo }
5875             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
5876 0 0         if ($ignorecase) {
5877 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5878             }
5879             }
5880              
5881             # ${ ... }
5882             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5883 0           $char[$i] = e_capture($1);
5884 0 0         if ($ignorecase) {
5885 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5886             }
5887             }
5888              
5889             # $scalar or @array
5890             elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
5891 0           $char[$i] = e_string($char[$i]);
5892 0 0         if ($ignorecase) {
5893 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5894             }
5895             }
5896              
5897             # quote character before ? + * {
5898             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
5899 0 0 0       if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
    0          
5900             }
5901             elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5902 0           my $char = $char[$i-1];
5903 0 0         if ($char[$i] eq '{') {
5904 0           die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
5905             }
5906             else {
5907 0           die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
5908             }
5909             }
5910             else {
5911 0           $char[$i-1] = '(?:' . $char[$i-1] . ')';
5912             }
5913             }
5914             }
5915              
5916             # make regexp string
5917 0           $modifier =~ tr/i//d;
5918 0 0         if ($left_e > $right_e) {
5919 0 0 0       if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5920 0           return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
5921             }
5922             else {
5923 0           return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
5924             }
5925             }
5926 0 0 0       if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5927 0           return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
5928             }
5929             else {
5930 0           return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5931             }
5932             }
5933              
5934             #
5935             # double quote stuff
5936             #
5937             sub qq_stuff {
5938 0     0 0   my($delimiter,$end_delimiter,$stuff) = @_;
5939              
5940             # scalar variable or array variable
5941 0 0         if ($stuff =~ /\A [\$\@] /oxms) {
5942 0           return $stuff;
5943             }
5944              
5945             # quote by delimiter
5946 0           my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
  0            
5947 0           for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5948 0 0         next if $char eq $delimiter;
5949 0 0         next if $char eq $end_delimiter;
5950 0 0         if (not $octet{$char}) {
5951 0           return join '', 'qq', $char, $stuff, $char;
5952             }
5953             }
5954 0           return join '', 'qq', '<', $stuff, '>';
5955             }
5956              
5957             #
5958             # escape regexp (m'', qr'', and m''b, qr''b)
5959             #
5960             sub e_qr_q {
5961 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5962 0   0       $modifier ||= '';
5963              
5964 0           $modifier =~ tr/p//d;
5965 0 0         if ($modifier =~ /([adlu])/oxms) {
5966 0           my $line = 0;
5967 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5968 0 0         if ($filename ne __FILE__) {
5969 0           $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5970 0           last;
5971             }
5972             }
5973 0           die qq{Unsupported modifier "$1" used at line $line.\n};
5974             }
5975              
5976 0           $slash = 'div';
5977              
5978             # literal null string pattern
5979 0 0         if ($string eq '') {
    0          
5980 0           $modifier =~ tr/bB//d;
5981 0           $modifier =~ tr/i//d;
5982 0           return join '', $ope, $delimiter, $end_delimiter, $modifier;
5983             }
5984              
5985             # with /b /B modifier
5986             elsif ($modifier =~ tr/bB//d) {
5987 0           return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
5988             }
5989              
5990             # without /b /B modifier
5991             else {
5992 0           return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
5993             }
5994             }
5995              
5996             #
5997             # escape regexp (m'', qr'')
5998             #
5999             sub e_qr_qt {
6000 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6001              
6002 0 0         my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6003              
6004             # split regexp
6005 0           my @char = $string =~ /\G((?>
6006             [^\\\[\$\@\/] |
6007             [\x00-\xFF] |
6008             \[\^ |
6009             \[\: (?>[a-z]+) \:\] |
6010             \[\:\^ (?>[a-z]+) \:\] |
6011             [\$\@\/] |
6012             \\ (?:$q_char) |
6013             (?:$q_char)
6014             ))/oxmsg;
6015              
6016             # unescape character
6017 0           for (my $i=0; $i <= $#char; $i++) {
6018 0 0 0       if (0) {
    0 0        
    0 0        
    0          
    0          
    0          
6019             }
6020              
6021             # open character class [...]
6022 0           elsif ($char[$i] eq '[') {
6023 0           my $left = $i;
6024 0 0         if ($char[$i+1] eq ']') {
6025 0           $i++;
6026             }
6027 0           while (1) {
6028 0 0         if (++$i > $#char) {
6029 0           die __FILE__, ": Unmatched [] in regexp\n";
6030             }
6031 0 0         if ($char[$i] eq ']') {
6032 0           my $right = $i;
6033              
6034             # [...]
6035 0           splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
6036              
6037 0           $i = $left;
6038 0           last;
6039             }
6040             }
6041             }
6042              
6043             # open character class [^...]
6044             elsif ($char[$i] eq '[^') {
6045 0           my $left = $i;
6046 0 0         if ($char[$i+1] eq ']') {
6047 0           $i++;
6048             }
6049 0           while (1) {
6050 0 0         if (++$i > $#char) {
6051 0           die __FILE__, ": Unmatched [] in regexp\n";
6052             }
6053 0 0         if ($char[$i] eq ']') {
6054 0           my $right = $i;
6055              
6056             # [^...]
6057 0           splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6058              
6059 0           $i = $left;
6060 0           last;
6061             }
6062             }
6063             }
6064              
6065             # escape $ @ / and \
6066             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6067 0           $char[$i] = '\\' . $char[$i];
6068             }
6069              
6070             # rewrite character class or escape character
6071             elsif (my $char = character_class($char[$i],$modifier)) {
6072 0           $char[$i] = $char;
6073             }
6074              
6075             # /i modifier
6076             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
6077 0 0         if (CORE::length(Elatin3::fc($char[$i])) == 1) {
6078 0           $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
6079             }
6080             else {
6081 0           $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
6082             }
6083             }
6084              
6085             # quote character before ? + * {
6086             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6087 0 0         if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6088             }
6089             else {
6090 0           $char[$i-1] = '(?:' . $char[$i-1] . ')';
6091             }
6092             }
6093             }
6094              
6095 0           $delimiter = '/';
6096 0           $end_delimiter = '/';
6097              
6098 0           $modifier =~ tr/i//d;
6099 0           return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6100             }
6101              
6102             #
6103             # escape regexp (m''b, qr''b)
6104             #
6105             sub e_qr_qb {
6106 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6107              
6108             # split regexp
6109 0           my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6110              
6111             # unescape character
6112 0           for (my $i=0; $i <= $#char; $i++) {
6113 0 0         if (0) {
    0          
6114             }
6115              
6116             # remain \\
6117 0           elsif ($char[$i] eq '\\\\') {
6118             }
6119              
6120             # escape $ @ / and \
6121             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6122 0           $char[$i] = '\\' . $char[$i];
6123             }
6124             }
6125              
6126 0           $delimiter = '/';
6127 0           $end_delimiter = '/';
6128 0           return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6129             }
6130              
6131             #
6132             # escape regexp (s/here//)
6133             #
6134             sub e_s1 {
6135 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6136 0   0       $modifier ||= '';
6137              
6138 0           $modifier =~ tr/p//d;
6139 0 0         if ($modifier =~ /([adlu])/oxms) {
6140 0           my $line = 0;
6141 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6142 0 0         if ($filename ne __FILE__) {
6143 0           $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6144 0           last;
6145             }
6146             }
6147 0           die qq{Unsupported modifier "$1" used at line $line.\n};
6148             }
6149              
6150 0           $slash = 'div';
6151              
6152             # literal null string pattern
6153 0 0         if ($string eq '') {
    0          
6154 0           $modifier =~ tr/bB//d;
6155 0           $modifier =~ tr/i//d;
6156 0           return join '', $ope, $delimiter, $end_delimiter, $modifier;
6157             }
6158              
6159             # /b /B modifier
6160             elsif ($modifier =~ tr/bB//d) {
6161              
6162             # choice again delimiter
6163 0 0         if ($delimiter =~ / [\@:] /oxms) {
6164 0           my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
6165 0           my %octet = map {$_ => 1} @char;
  0            
6166 0 0         if (not $octet{')'}) {
    0          
    0          
    0          
6167 0           $delimiter = '(';
6168 0           $end_delimiter = ')';
6169             }
6170             elsif (not $octet{'}'}) {
6171 0           $delimiter = '{';
6172 0           $end_delimiter = '}';
6173             }
6174             elsif (not $octet{']'}) {
6175 0           $delimiter = '[';
6176 0           $end_delimiter = ']';
6177             }
6178             elsif (not $octet{'>'}) {
6179 0           $delimiter = '<';
6180 0           $end_delimiter = '>';
6181             }
6182             else {
6183 0           for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6184 0 0         if (not $octet{$char}) {
6185 0           $delimiter = $char;
6186 0           $end_delimiter = $char;
6187 0           last;
6188             }
6189             }
6190             }
6191             }
6192              
6193 0           my $prematch = '';
6194 0           return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6195             }
6196              
6197 0 0         my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6198 0           my $metachar = qr/[\@\\|[\]{^]/oxms;
6199              
6200             # split regexp
6201 0           my @char = $string =~ /\G((?>
6202             [^\\\$\@\[\(] |
6203             \\ (?>[1-9][0-9]*) |
6204             \\g (?>\s*) (?>[1-9][0-9]*) |
6205             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6206             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6207             \\x (?>[0-9A-Fa-f]{1,2}) |
6208             \\ (?>[0-7]{2,3}) |
6209             \\c [\x40-\x5F] |
6210             \\x\{ (?>[0-9A-Fa-f]+) \} |
6211             \\o\{ (?>[0-7]+) \} |
6212             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6213             \\ $q_char |
6214             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6215             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6216             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6217             [\$\@] $qq_variable |
6218             \$ (?>\s* [0-9]+) |
6219             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6220             \$ \$ (?![\w\{]) |
6221             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6222             \[\^ |
6223             \[\: (?>[a-z]+) :\] |
6224             \[\:\^ (?>[a-z]+) :\] |
6225             \(\? |
6226             $q_char
6227             ))/oxmsg;
6228              
6229             # choice again delimiter
6230 0 0         if ($delimiter =~ / [\@:] /oxms) {
6231 0           my %octet = map {$_ => 1} @char;
  0            
6232 0 0         if (not $octet{')'}) {
    0          
    0          
    0          
6233 0           $delimiter = '(';
6234 0           $end_delimiter = ')';
6235             }
6236             elsif (not $octet{'}'}) {
6237 0           $delimiter = '{';
6238 0           $end_delimiter = '}';
6239             }
6240             elsif (not $octet{']'}) {
6241 0           $delimiter = '[';
6242 0           $end_delimiter = ']';
6243             }
6244             elsif (not $octet{'>'}) {
6245 0           $delimiter = '<';
6246 0           $end_delimiter = '>';
6247             }
6248             else {
6249 0           for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6250 0 0         if (not $octet{$char}) {
6251 0           $delimiter = $char;
6252 0           $end_delimiter = $char;
6253 0           last;
6254             }
6255             }
6256             }
6257             }
6258              
6259             # count '('
6260 0           my $parens = grep { $_ eq '(' } @char;
  0            
6261              
6262 0           my $left_e = 0;
6263 0           my $right_e = 0;
6264 0           for (my $i=0; $i <= $#char; $i++) {
6265              
6266             # "\L\u" --> "\u\L"
6267 0 0 0       if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    0 0        
    0          
    0          
    0          
    0          
6268 0           @char[$i,$i+1] = @char[$i+1,$i];
6269             }
6270              
6271             # "\U\l" --> "\l\U"
6272             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6273 0           @char[$i,$i+1] = @char[$i+1,$i];
6274             }
6275              
6276             # octal escape sequence
6277             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6278 0           $char[$i] = Elatin3::octchr($1);
6279             }
6280              
6281             # hexadecimal escape sequence
6282             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6283 0           $char[$i] = Elatin3::hexchr($1);
6284             }
6285              
6286             # \b{...} --> b\{...}
6287             # \B{...} --> B\{...}
6288             # \N{CHARNAME} --> N\{CHARNAME}
6289             # \p{PROPERTY} --> p\{PROPERTY}
6290             # \P{PROPERTY} --> P\{PROPERTY}
6291             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6292 0           $char[$i] = $1 . '\\' . $2;
6293             }
6294              
6295             # \p, \P, \X --> p, P, X
6296             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6297 0           $char[$i] = $1;
6298             }
6299              
6300 0 0 0       if (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          
6301             }
6302              
6303             # join separated multiple-octet
6304 0           elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6305 0 0 0       if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
    0 0        
    0 0        
      0        
      0        
      0        
6306 0           $char[$i] .= join '', splice @char, $i+1, 3;
6307             }
6308             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)) {
6309 0           $char[$i] .= join '', splice @char, $i+1, 2;
6310             }
6311             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)) {
6312 0           $char[$i] .= join '', splice @char, $i+1, 1;
6313             }
6314             }
6315              
6316             # open character class [...]
6317             elsif ($char[$i] eq '[') {
6318 0           my $left = $i;
6319 0 0         if ($char[$i+1] eq ']') {
6320 0           $i++;
6321             }
6322 0           while (1) {
6323 0 0         if (++$i > $#char) {
6324 0           die __FILE__, ": Unmatched [] in regexp\n";
6325             }
6326 0 0         if ($char[$i] eq ']') {
6327 0           my $right = $i;
6328              
6329             # [...]
6330 0 0         if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6331 0           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);
  0            
6332             }
6333             else {
6334 0           splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
6335             }
6336              
6337 0           $i = $left;
6338 0           last;
6339             }
6340             }
6341             }
6342              
6343             # open character class [^...]
6344             elsif ($char[$i] eq '[^') {
6345 0           my $left = $i;
6346 0 0         if ($char[$i+1] eq ']') {
6347 0           $i++;
6348             }
6349 0           while (1) {
6350 0 0         if (++$i > $#char) {
6351 0           die __FILE__, ": Unmatched [] in regexp\n";
6352             }
6353 0 0         if ($char[$i] eq ']') {
6354 0           my $right = $i;
6355              
6356             # [^...]
6357 0 0         if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6358 0           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);
  0            
6359             }
6360             else {
6361 0           splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6362             }
6363              
6364 0           $i = $left;
6365 0           last;
6366             }
6367             }
6368             }
6369              
6370             # rewrite character class or escape character
6371             elsif (my $char = character_class($char[$i],$modifier)) {
6372 0           $char[$i] = $char;
6373             }
6374              
6375             # /i modifier
6376             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
6377 0 0         if (CORE::length(Elatin3::fc($char[$i])) == 1) {
6378 0           $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
6379             }
6380             else {
6381 0           $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
6382             }
6383             }
6384              
6385             # \u \l \U \L \F \Q \E
6386             elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6387 0 0         if ($right_e < $left_e) {
6388 0           $char[$i] = '\\' . $char[$i];
6389             }
6390             }
6391             elsif ($char[$i] eq '\u') {
6392 0           $char[$i] = '@{[Elatin3::ucfirst qq<';
6393 0           $left_e++;
6394             }
6395             elsif ($char[$i] eq '\l') {
6396 0           $char[$i] = '@{[Elatin3::lcfirst qq<';
6397 0           $left_e++;
6398             }
6399             elsif ($char[$i] eq '\U') {
6400 0           $char[$i] = '@{[Elatin3::uc qq<';
6401 0           $left_e++;
6402             }
6403             elsif ($char[$i] eq '\L') {
6404 0           $char[$i] = '@{[Elatin3::lc qq<';
6405 0           $left_e++;
6406             }
6407             elsif ($char[$i] eq '\F') {
6408 0           $char[$i] = '@{[Elatin3::fc qq<';
6409 0           $left_e++;
6410             }
6411             elsif ($char[$i] eq '\Q') {
6412 0           $char[$i] = '@{[CORE::quotemeta qq<';
6413 0           $left_e++;
6414             }
6415             elsif ($char[$i] eq '\E') {
6416 0 0         if ($right_e < $left_e) {
6417 0           $char[$i] = '>]}';
6418 0           $right_e++;
6419             }
6420             else {
6421 0           $char[$i] = '';
6422             }
6423             }
6424             elsif ($char[$i] eq '\Q') {
6425 0           while (1) {
6426 0 0         if (++$i > $#char) {
6427 0           last;
6428             }
6429 0 0         if ($char[$i] eq '\E') {
6430 0           last;
6431             }
6432             }
6433             }
6434             elsif ($char[$i] eq '\E') {
6435             }
6436              
6437             # \0 --> \0
6438             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6439             }
6440              
6441             # \g{N}, \g{-N}
6442              
6443             # P.108 Using Simple Patterns
6444             # in Chapter 7: In the World of Regular Expressions
6445             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6446              
6447             # P.221 Capturing
6448             # in Chapter 5: Pattern Matching
6449             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6450              
6451             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6452             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6453             }
6454              
6455             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6456             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6457             }
6458              
6459             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6460             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6461             }
6462              
6463             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6464             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6465             }
6466              
6467             # $0 --> $0
6468             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6469 0 0         if ($ignorecase) {
6470 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6471             }
6472             }
6473             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6474 0 0         if ($ignorecase) {
6475 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6476             }
6477             }
6478              
6479             # $$ --> $$
6480             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6481             }
6482              
6483             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6484             # $1, $2, $3 --> $1, $2, $3 otherwise
6485             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6486 0           $char[$i] = e_capture($1);
6487 0 0         if ($ignorecase) {
6488 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6489             }
6490             }
6491             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6492 0           $char[$i] = e_capture($1);
6493 0 0         if ($ignorecase) {
6494 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6495             }
6496             }
6497              
6498             # $$foo[ ... ] --> $ $foo->[ ... ]
6499             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
6500 0           $char[$i] = e_capture($1.'->'.$2);
6501 0 0         if ($ignorecase) {
6502 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6503             }
6504             }
6505              
6506             # $$foo{ ... } --> $ $foo->{ ... }
6507             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
6508 0           $char[$i] = e_capture($1.'->'.$2);
6509 0 0         if ($ignorecase) {
6510 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6511             }
6512             }
6513              
6514             # $$foo
6515             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6516 0           $char[$i] = e_capture($1);
6517 0 0         if ($ignorecase) {
6518 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6519             }
6520             }
6521              
6522             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
6523             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6524 0 0         if ($ignorecase) {
6525 0           $char[$i] = '@{[Elatin3::ignorecase(Elatin3::PREMATCH())]}';
6526             }
6527             else {
6528 0           $char[$i] = '@{[Elatin3::PREMATCH()]}';
6529             }
6530             }
6531              
6532             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
6533             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6534 0 0         if ($ignorecase) {
6535 0           $char[$i] = '@{[Elatin3::ignorecase(Elatin3::MATCH())]}';
6536             }
6537             else {
6538 0           $char[$i] = '@{[Elatin3::MATCH()]}';
6539             }
6540             }
6541              
6542             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
6543             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6544 0 0         if ($ignorecase) {
6545 0           $char[$i] = '@{[Elatin3::ignorecase(Elatin3::POSTMATCH())]}';
6546             }
6547             else {
6548 0           $char[$i] = '@{[Elatin3::POSTMATCH()]}';
6549             }
6550             }
6551              
6552             # ${ foo }
6553             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
6554 0 0         if ($ignorecase) {
6555 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6556             }
6557             }
6558              
6559             # ${ ... }
6560             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6561 0           $char[$i] = e_capture($1);
6562 0 0         if ($ignorecase) {
6563 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6564             }
6565             }
6566              
6567             # $scalar or @array
6568             elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6569 0           $char[$i] = e_string($char[$i]);
6570 0 0         if ($ignorecase) {
6571 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6572             }
6573             }
6574              
6575             # quote character before ? + * {
6576             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6577 0 0         if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6578             }
6579             else {
6580 0           $char[$i-1] = '(?:' . $char[$i-1] . ')';
6581             }
6582             }
6583             }
6584              
6585             # make regexp string
6586 0           my $prematch = '';
6587 0           $modifier =~ tr/i//d;
6588 0 0         if ($left_e > $right_e) {
6589 0           return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6590             }
6591 0           return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6592             }
6593              
6594             #
6595             # escape regexp (s'here'' or s'here''b)
6596             #
6597             sub e_s1_q {
6598 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6599 0   0       $modifier ||= '';
6600              
6601 0           $modifier =~ tr/p//d;
6602 0 0         if ($modifier =~ /([adlu])/oxms) {
6603 0           my $line = 0;
6604 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6605 0 0         if ($filename ne __FILE__) {
6606 0           $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6607 0           last;
6608             }
6609             }
6610 0           die qq{Unsupported modifier "$1" used at line $line.\n};
6611             }
6612              
6613 0           $slash = 'div';
6614              
6615             # literal null string pattern
6616 0 0         if ($string eq '') {
    0          
6617 0           $modifier =~ tr/bB//d;
6618 0           $modifier =~ tr/i//d;
6619 0           return join '', $ope, $delimiter, $end_delimiter, $modifier;
6620             }
6621              
6622             # with /b /B modifier
6623             elsif ($modifier =~ tr/bB//d) {
6624 0           return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6625             }
6626              
6627             # without /b /B modifier
6628             else {
6629 0           return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6630             }
6631             }
6632              
6633             #
6634             # escape regexp (s'here'')
6635             #
6636             sub e_s1_qt {
6637 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6638              
6639 0 0         my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6640              
6641             # split regexp
6642 0           my @char = $string =~ /\G((?>
6643             [^\\\[\$\@\/] |
6644             [\x00-\xFF] |
6645             \[\^ |
6646             \[\: (?>[a-z]+) \:\] |
6647             \[\:\^ (?>[a-z]+) \:\] |
6648             [\$\@\/] |
6649             \\ (?:$q_char) |
6650             (?:$q_char)
6651             ))/oxmsg;
6652              
6653             # unescape character
6654 0           for (my $i=0; $i <= $#char; $i++) {
6655 0 0 0       if (0) {
    0 0        
    0 0        
    0          
    0          
    0          
6656             }
6657              
6658             # open character class [...]
6659 0           elsif ($char[$i] eq '[') {
6660 0           my $left = $i;
6661 0 0         if ($char[$i+1] eq ']') {
6662 0           $i++;
6663             }
6664 0           while (1) {
6665 0 0         if (++$i > $#char) {
6666 0           die __FILE__, ": Unmatched [] in regexp\n";
6667             }
6668 0 0         if ($char[$i] eq ']') {
6669 0           my $right = $i;
6670              
6671             # [...]
6672 0           splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
6673              
6674 0           $i = $left;
6675 0           last;
6676             }
6677             }
6678             }
6679              
6680             # open character class [^...]
6681             elsif ($char[$i] eq '[^') {
6682 0           my $left = $i;
6683 0 0         if ($char[$i+1] eq ']') {
6684 0           $i++;
6685             }
6686 0           while (1) {
6687 0 0         if (++$i > $#char) {
6688 0           die __FILE__, ": Unmatched [] in regexp\n";
6689             }
6690 0 0         if ($char[$i] eq ']') {
6691 0           my $right = $i;
6692              
6693             # [^...]
6694 0           splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6695              
6696 0           $i = $left;
6697 0           last;
6698             }
6699             }
6700             }
6701              
6702             # escape $ @ / and \
6703             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6704 0           $char[$i] = '\\' . $char[$i];
6705             }
6706              
6707             # rewrite character class or escape character
6708             elsif (my $char = character_class($char[$i],$modifier)) {
6709 0           $char[$i] = $char;
6710             }
6711              
6712             # /i modifier
6713             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
6714 0 0         if (CORE::length(Elatin3::fc($char[$i])) == 1) {
6715 0           $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
6716             }
6717             else {
6718 0           $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
6719             }
6720             }
6721              
6722             # quote character before ? + * {
6723             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6724 0 0         if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6725             }
6726             else {
6727 0           $char[$i-1] = '(?:' . $char[$i-1] . ')';
6728             }
6729             }
6730             }
6731              
6732 0           $modifier =~ tr/i//d;
6733 0           $delimiter = '/';
6734 0           $end_delimiter = '/';
6735 0           my $prematch = '';
6736 0           return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6737             }
6738              
6739             #
6740             # escape regexp (s'here''b)
6741             #
6742             sub e_s1_qb {
6743 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6744              
6745             # split regexp
6746 0           my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6747              
6748             # unescape character
6749 0           for (my $i=0; $i <= $#char; $i++) {
6750 0 0         if (0) {
    0          
6751             }
6752              
6753             # remain \\
6754 0           elsif ($char[$i] eq '\\\\') {
6755             }
6756              
6757             # escape $ @ / and \
6758             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6759 0           $char[$i] = '\\' . $char[$i];
6760             }
6761             }
6762              
6763 0           $delimiter = '/';
6764 0           $end_delimiter = '/';
6765 0           my $prematch = '';
6766 0           return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6767             }
6768              
6769             #
6770             # escape regexp (s''here')
6771             #
6772             sub e_s2_q {
6773 0     0 0   my($ope,$delimiter,$end_delimiter,$string) = @_;
6774              
6775 0           $slash = 'div';
6776              
6777 0           my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
6778 0           for (my $i=0; $i <= $#char; $i++) {
6779 0 0         if (0) {
    0          
6780             }
6781              
6782             # not escape \\
6783 0           elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
6784             }
6785              
6786             # escape $ @ / and \
6787             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6788 0           $char[$i] = '\\' . $char[$i];
6789             }
6790             }
6791              
6792 0           return join '', $ope, $delimiter, @char, $end_delimiter;
6793             }
6794              
6795             #
6796             # escape regexp (s/here/and here/modifier)
6797             #
6798             sub e_sub {
6799 0     0 0   my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
6800 0   0       $modifier ||= '';
6801              
6802 0           $modifier =~ tr/p//d;
6803 0 0         if ($modifier =~ /([adlu])/oxms) {
6804 0           my $line = 0;
6805 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6806 0 0         if ($filename ne __FILE__) {
6807 0           $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6808 0           last;
6809             }
6810             }
6811 0           die qq{Unsupported modifier "$1" used at line $line.\n};
6812             }
6813              
6814 0 0         if ($variable eq '') {
6815 0           $variable = '$_';
6816 0           $bind_operator = ' =~ ';
6817             }
6818              
6819 0           $slash = 'div';
6820              
6821             # P.128 Start of match (or end of previous match): \G
6822             # P.130 Advanced Use of \G with Perl
6823             # in Chapter 3: Overview of Regular Expression Features and Flavors
6824             # P.312 Iterative Matching: Scalar Context, with /g
6825             # in Chapter 7: Perl
6826             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
6827              
6828             # P.181 Where You Left Off: The \G Assertion
6829             # in Chapter 5: Pattern Matching
6830             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6831              
6832             # P.220 Where You Left Off: The \G Assertion
6833             # in Chapter 5: Pattern Matching
6834             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6835              
6836 0           my $e_modifier = $modifier =~ tr/e//d;
6837 0           my $r_modifier = $modifier =~ tr/r//d;
6838              
6839 0           my $my = '';
6840 0 0         if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
6841 0           $my = $variable;
6842 0           $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
6843 0           $variable =~ s/ = .+ \z//oxms;
6844             }
6845              
6846 0           (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
6847 0           $variable_basename =~ s/ \s+ \z//oxms;
6848              
6849             # quote replacement string
6850 0           my $e_replacement = '';
6851 0 0         if ($e_modifier >= 1) {
6852 0           $e_replacement = e_qq('', '', '', $replacement);
6853 0           $e_modifier--;
6854             }
6855             else {
6856 0 0         if ($delimiter2 eq "'") {
6857 0           $e_replacement = e_s2_q('qq', '/', '/', $replacement);
6858             }
6859             else {
6860 0           $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
6861             }
6862             }
6863              
6864 0           my $sub = '';
6865              
6866             # with /r
6867 0 0         if ($r_modifier) {
6868 0 0         if (0) {
6869             }
6870              
6871             # s///gr without multibyte anchoring
6872 0           elsif ($modifier =~ /g/oxms) {
6873 0 0         $sub = sprintf(
6874             # 1 2 3 4 5
6875             q,
6876              
6877             $variable, # 1
6878             ($delimiter1 eq "'") ? # 2
6879             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6880             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6881             $s_matched, # 3
6882             $e_replacement, # 4
6883             '$Latin3::re_r=CORE::eval $Latin3::re_r; ' x $e_modifier, # 5
6884             );
6885             }
6886              
6887             # s///r
6888             else {
6889              
6890 0           my $prematch = q{$`};
6891              
6892 0 0         $sub = sprintf(
6893             # 1 2 3 4 5 6 7
6894             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Latin3::re_r=%s; %s"%s$Latin3::re_r$'" } : %s>,
6895              
6896             $variable, # 1
6897             ($delimiter1 eq "'") ? # 2
6898             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6899             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6900             $s_matched, # 3
6901             $e_replacement, # 4
6902             '$Latin3::re_r=CORE::eval $Latin3::re_r; ' x $e_modifier, # 5
6903             $prematch, # 6
6904             $variable, # 7
6905             );
6906             }
6907              
6908             # $var !~ s///r doesn't make sense
6909 0 0         if ($bind_operator =~ / !~ /oxms) {
6910 0           $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
6911             }
6912             }
6913              
6914             # without /r
6915             else {
6916 0 0         if (0) {
6917             }
6918              
6919             # s///g without multibyte anchoring
6920 0           elsif ($modifier =~ /g/oxms) {
6921 0 0         $sub = sprintf(
    0          
6922             # 1 2 3 4 5 6 7 8
6923             q,
6924              
6925             $variable, # 1
6926             ($delimiter1 eq "'") ? # 2
6927             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6928             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6929             $s_matched, # 3
6930             $e_replacement, # 4
6931             '$Latin3::re_r=CORE::eval $Latin3::re_r; ' x $e_modifier, # 5
6932             $variable, # 6
6933             $variable, # 7
6934             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
6935             );
6936             }
6937              
6938             # s///
6939             else {
6940              
6941 0           my $prematch = q{$`};
6942              
6943 0 0         $sub = sprintf(
    0          
6944              
6945             ($bind_operator =~ / =~ /oxms) ?
6946              
6947             # 1 2 3 4 5 6 7 8
6948             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Latin3::re_r=%s; %s%s="%s$Latin3::re_r$'"; 1 } : undef> :
6949              
6950             # 1 2 3 4 5 6 7 8
6951             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Latin3::re_r=%s; %s%s="%s$Latin3::re_r$'"; undef }>,
6952              
6953             $variable, # 1
6954             $bind_operator, # 2
6955             ($delimiter1 eq "'") ? # 3
6956             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6957             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6958             $s_matched, # 4
6959             $e_replacement, # 5
6960             '$Latin3::re_r=CORE::eval $Latin3::re_r; ' x $e_modifier, # 6
6961             $variable, # 7
6962             $prematch, # 8
6963             );
6964             }
6965             }
6966              
6967             # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
6968 0 0         if ($my ne '') {
6969 0           $sub = "($my, $sub)[1]";
6970             }
6971              
6972             # clear s/// variable
6973 0           $sub_variable = '';
6974 0           $bind_operator = '';
6975              
6976 0           return $sub;
6977             }
6978              
6979             #
6980             # escape regexp of split qr//
6981             #
6982             sub e_split {
6983 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6984 0   0       $modifier ||= '';
6985              
6986 0           $modifier =~ tr/p//d;
6987 0 0         if ($modifier =~ /([adlu])/oxms) {
6988 0           my $line = 0;
6989 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6990 0 0         if ($filename ne __FILE__) {
6991 0           $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6992 0           last;
6993             }
6994             }
6995 0           die qq{Unsupported modifier "$1" used at line $line.\n};
6996             }
6997              
6998 0           $slash = 'div';
6999              
7000             # /b /B modifier
7001 0 0         if ($modifier =~ tr/bB//d) {
7002 0           return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7003             }
7004              
7005 0 0         my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7006 0           my $metachar = qr/[\@\\|[\]{^]/oxms;
7007              
7008             # split regexp
7009 0           my @char = $string =~ /\G((?>
7010             [^\\\$\@\[\(] |
7011             \\x (?>[0-9A-Fa-f]{1,2}) |
7012             \\ (?>[0-7]{2,3}) |
7013             \\c [\x40-\x5F] |
7014             \\x\{ (?>[0-9A-Fa-f]+) \} |
7015             \\o\{ (?>[0-7]+) \} |
7016             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7017             \\ $q_char |
7018             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7019             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7020             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7021             [\$\@] $qq_variable |
7022             \$ (?>\s* [0-9]+) |
7023             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7024             \$ \$ (?![\w\{]) |
7025             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7026             \[\^ |
7027             \[\: (?>[a-z]+) :\] |
7028             \[\:\^ (?>[a-z]+) :\] |
7029             \(\? |
7030             $q_char
7031             ))/oxmsg;
7032              
7033 0           my $left_e = 0;
7034 0           my $right_e = 0;
7035 0           for (my $i=0; $i <= $#char; $i++) {
7036              
7037             # "\L\u" --> "\u\L"
7038 0 0 0       if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    0 0        
    0          
    0          
    0          
    0          
7039 0           @char[$i,$i+1] = @char[$i+1,$i];
7040             }
7041              
7042             # "\U\l" --> "\l\U"
7043             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7044 0           @char[$i,$i+1] = @char[$i+1,$i];
7045             }
7046              
7047             # octal escape sequence
7048             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7049 0           $char[$i] = Elatin3::octchr($1);
7050             }
7051              
7052             # hexadecimal escape sequence
7053             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7054 0           $char[$i] = Elatin3::hexchr($1);
7055             }
7056              
7057             # \b{...} --> b\{...}
7058             # \B{...} --> B\{...}
7059             # \N{CHARNAME} --> N\{CHARNAME}
7060             # \p{PROPERTY} --> p\{PROPERTY}
7061             # \P{PROPERTY} --> P\{PROPERTY}
7062             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7063 0           $char[$i] = $1 . '\\' . $2;
7064             }
7065              
7066             # \p, \P, \X --> p, P, X
7067             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7068 0           $char[$i] = $1;
7069             }
7070              
7071 0 0 0       if (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          
7072             }
7073              
7074             # join separated multiple-octet
7075 0           elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7076 0 0 0       if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
    0 0        
    0 0        
      0        
      0        
      0        
7077 0           $char[$i] .= join '', splice @char, $i+1, 3;
7078             }
7079             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)) {
7080 0           $char[$i] .= join '', splice @char, $i+1, 2;
7081             }
7082             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)) {
7083 0           $char[$i] .= join '', splice @char, $i+1, 1;
7084             }
7085             }
7086              
7087             # open character class [...]
7088             elsif ($char[$i] eq '[') {
7089 0           my $left = $i;
7090 0 0         if ($char[$i+1] eq ']') {
7091 0           $i++;
7092             }
7093 0           while (1) {
7094 0 0         if (++$i > $#char) {
7095 0           die __FILE__, ": Unmatched [] in regexp\n";
7096             }
7097 0 0         if ($char[$i] eq ']') {
7098 0           my $right = $i;
7099              
7100             # [...]
7101 0 0         if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7102 0           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);
  0            
7103             }
7104             else {
7105 0           splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
7106             }
7107              
7108 0           $i = $left;
7109 0           last;
7110             }
7111             }
7112             }
7113              
7114             # open character class [^...]
7115             elsif ($char[$i] eq '[^') {
7116 0           my $left = $i;
7117 0 0         if ($char[$i+1] eq ']') {
7118 0           $i++;
7119             }
7120 0           while (1) {
7121 0 0         if (++$i > $#char) {
7122 0           die __FILE__, ": Unmatched [] in regexp\n";
7123             }
7124 0 0         if ($char[$i] eq ']') {
7125 0           my $right = $i;
7126              
7127             # [^...]
7128 0 0         if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7129 0           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);
  0            
7130             }
7131             else {
7132 0           splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7133             }
7134              
7135 0           $i = $left;
7136 0           last;
7137             }
7138             }
7139             }
7140              
7141             # rewrite character class or escape character
7142             elsif (my $char = character_class($char[$i],$modifier)) {
7143 0           $char[$i] = $char;
7144             }
7145              
7146             # P.794 29.2.161. split
7147             # in Chapter 29: Functions
7148             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7149              
7150             # P.951 split
7151             # in Chapter 27: Functions
7152             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7153              
7154             # said "The //m modifier is assumed when you split on the pattern /^/",
7155             # but perl5.008 is not so. Therefore, this software adds //m.
7156             # (and so on)
7157              
7158             # split(m/^/) --> split(m/^/m)
7159             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7160 0           $modifier .= 'm';
7161             }
7162              
7163             # /i modifier
7164             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
7165 0 0         if (CORE::length(Elatin3::fc($char[$i])) == 1) {
7166 0           $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
7167             }
7168             else {
7169 0           $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
7170             }
7171             }
7172              
7173             # \u \l \U \L \F \Q \E
7174             elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7175 0 0         if ($right_e < $left_e) {
7176 0           $char[$i] = '\\' . $char[$i];
7177             }
7178             }
7179             elsif ($char[$i] eq '\u') {
7180 0           $char[$i] = '@{[Elatin3::ucfirst qq<';
7181 0           $left_e++;
7182             }
7183             elsif ($char[$i] eq '\l') {
7184 0           $char[$i] = '@{[Elatin3::lcfirst qq<';
7185 0           $left_e++;
7186             }
7187             elsif ($char[$i] eq '\U') {
7188 0           $char[$i] = '@{[Elatin3::uc qq<';
7189 0           $left_e++;
7190             }
7191             elsif ($char[$i] eq '\L') {
7192 0           $char[$i] = '@{[Elatin3::lc qq<';
7193 0           $left_e++;
7194             }
7195             elsif ($char[$i] eq '\F') {
7196 0           $char[$i] = '@{[Elatin3::fc qq<';
7197 0           $left_e++;
7198             }
7199             elsif ($char[$i] eq '\Q') {
7200 0           $char[$i] = '@{[CORE::quotemeta qq<';
7201 0           $left_e++;
7202             }
7203             elsif ($char[$i] eq '\E') {
7204 0 0         if ($right_e < $left_e) {
7205 0           $char[$i] = '>]}';
7206 0           $right_e++;
7207             }
7208             else {
7209 0           $char[$i] = '';
7210             }
7211             }
7212             elsif ($char[$i] eq '\Q') {
7213 0           while (1) {
7214 0 0         if (++$i > $#char) {
7215 0           last;
7216             }
7217 0 0         if ($char[$i] eq '\E') {
7218 0           last;
7219             }
7220             }
7221             }
7222             elsif ($char[$i] eq '\E') {
7223             }
7224              
7225             # $0 --> $0
7226             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7227 0 0         if ($ignorecase) {
7228 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7229             }
7230             }
7231             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7232 0 0         if ($ignorecase) {
7233 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7234             }
7235             }
7236              
7237             # $$ --> $$
7238             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7239             }
7240              
7241             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7242             # $1, $2, $3 --> $1, $2, $3 otherwise
7243             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7244 0           $char[$i] = e_capture($1);
7245 0 0         if ($ignorecase) {
7246 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7247             }
7248             }
7249             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7250 0           $char[$i] = e_capture($1);
7251 0 0         if ($ignorecase) {
7252 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7253             }
7254             }
7255              
7256             # $$foo[ ... ] --> $ $foo->[ ... ]
7257             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7258 0           $char[$i] = e_capture($1.'->'.$2);
7259 0 0         if ($ignorecase) {
7260 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7261             }
7262             }
7263              
7264             # $$foo{ ... } --> $ $foo->{ ... }
7265             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
7266 0           $char[$i] = e_capture($1.'->'.$2);
7267 0 0         if ($ignorecase) {
7268 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7269             }
7270             }
7271              
7272             # $$foo
7273             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7274 0           $char[$i] = e_capture($1);
7275 0 0         if ($ignorecase) {
7276 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7277             }
7278             }
7279              
7280             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin3::PREMATCH()
7281             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7282 0 0         if ($ignorecase) {
7283 0           $char[$i] = '@{[Elatin3::ignorecase(Elatin3::PREMATCH())]}';
7284             }
7285             else {
7286 0           $char[$i] = '@{[Elatin3::PREMATCH()]}';
7287             }
7288             }
7289              
7290             # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin3::MATCH()
7291             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7292 0 0         if ($ignorecase) {
7293 0           $char[$i] = '@{[Elatin3::ignorecase(Elatin3::MATCH())]}';
7294             }
7295             else {
7296 0           $char[$i] = '@{[Elatin3::MATCH()]}';
7297             }
7298             }
7299              
7300             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
7301             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7302 0 0         if ($ignorecase) {
7303 0           $char[$i] = '@{[Elatin3::ignorecase(Elatin3::POSTMATCH())]}';
7304             }
7305             else {
7306 0           $char[$i] = '@{[Elatin3::POSTMATCH()]}';
7307             }
7308             }
7309              
7310             # ${ foo }
7311             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
7312 0 0         if ($ignorecase) {
7313 0           $char[$i] = '@{[Elatin3::ignorecase(' . $1 . ')]}';
7314             }
7315             }
7316              
7317             # ${ ... }
7318             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7319 0           $char[$i] = e_capture($1);
7320 0 0         if ($ignorecase) {
7321 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7322             }
7323             }
7324              
7325             # $scalar or @array
7326             elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7327 0           $char[$i] = e_string($char[$i]);
7328 0 0         if ($ignorecase) {
7329 0           $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7330             }
7331             }
7332              
7333             # quote character before ? + * {
7334             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7335 0 0         if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7336             }
7337             else {
7338 0           $char[$i-1] = '(?:' . $char[$i-1] . ')';
7339             }
7340             }
7341             }
7342              
7343             # make regexp string
7344 0           $modifier =~ tr/i//d;
7345 0 0         if ($left_e > $right_e) {
7346 0           return join '', 'Elatin3::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7347             }
7348 0           return join '', 'Elatin3::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7349             }
7350              
7351             #
7352             # escape regexp of split qr''
7353             #
7354             sub e_split_q {
7355 0     0 0   my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7356 0   0       $modifier ||= '';
7357              
7358 0           $modifier =~ tr/p//d;
7359 0 0         if ($modifier =~ /([adlu])/oxms) {
7360 0           my $line = 0;
7361 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7362 0 0         if ($filename ne __FILE__) {
7363 0           $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7364 0           last;
7365             }
7366             }
7367 0           die qq{Unsupported modifier "$1" used at line $line.\n};
7368             }
7369              
7370 0           $slash = 'div';
7371              
7372             # /b /B modifier
7373 0 0         if ($modifier =~ tr/bB//d) {
7374 0           return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7375             }
7376              
7377 0 0         my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7378              
7379             # split regexp
7380 0           my @char = $string =~ /\G((?>
7381             [^\\\[] |
7382             [\x00-\xFF] |
7383             \[\^ |
7384             \[\: (?>[a-z]+) \:\] |
7385             \[\:\^ (?>[a-z]+) \:\] |
7386             \\ (?:$q_char) |
7387             (?:$q_char)
7388             ))/oxmsg;
7389              
7390             # unescape character
7391 0           for (my $i=0; $i <= $#char; $i++) {
7392 0 0 0       if (0) {
    0 0        
    0 0        
    0 0        
    0          
    0          
7393             }
7394              
7395             # open character class [...]
7396 0           elsif ($char[$i] eq '[') {
7397 0           my $left = $i;
7398 0 0         if ($char[$i+1] eq ']') {
7399 0           $i++;
7400             }
7401 0           while (1) {
7402 0 0         if (++$i > $#char) {
7403 0           die __FILE__, ": Unmatched [] in regexp\n";
7404             }
7405 0 0         if ($char[$i] eq ']') {
7406 0           my $right = $i;
7407              
7408             # [...]
7409 0           splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
7410              
7411 0           $i = $left;
7412 0           last;
7413             }
7414             }
7415             }
7416              
7417             # open character class [^...]
7418             elsif ($char[$i] eq '[^') {
7419 0           my $left = $i;
7420 0 0         if ($char[$i+1] eq ']') {
7421 0           $i++;
7422             }
7423 0           while (1) {
7424 0 0         if (++$i > $#char) {
7425 0           die __FILE__, ": Unmatched [] in regexp\n";
7426             }
7427 0 0         if ($char[$i] eq ']') {
7428 0           my $right = $i;
7429              
7430             # [^...]
7431 0           splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7432              
7433 0           $i = $left;
7434 0           last;
7435             }
7436             }
7437             }
7438              
7439             # rewrite character class or escape character
7440             elsif (my $char = character_class($char[$i],$modifier)) {
7441 0           $char[$i] = $char;
7442             }
7443              
7444             # split(m/^/) --> split(m/^/m)
7445             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7446 0           $modifier .= 'm';
7447             }
7448              
7449             # /i modifier
7450             elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin3::uc($char[$i]) ne Elatin3::fc($char[$i]))) {
7451 0 0         if (CORE::length(Elatin3::fc($char[$i])) == 1) {
7452 0           $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
7453             }
7454             else {
7455 0           $char[$i] = '(?:' . Elatin3::uc($char[$i]) . '|' . Elatin3::fc($char[$i]) . ')';
7456             }
7457             }
7458              
7459             # quote character before ? + * {
7460             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7461 0 0         if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7462             }
7463             else {
7464 0           $char[$i-1] = '(?:' . $char[$i-1] . ')';
7465             }
7466             }
7467             }
7468              
7469 0           $modifier =~ tr/i//d;
7470 0           return join '', 'Elatin3::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7471             }
7472              
7473             #
7474             # instead of Carp::carp
7475             #
7476             sub carp {
7477 0     0 0   my($package,$filename,$line) = caller(1);
7478 0           print STDERR "@_ at $filename line $line.\n";
7479             }
7480              
7481             #
7482             # instead of Carp::croak
7483             #
7484             sub croak {
7485 0     0 0   my($package,$filename,$line) = caller(1);
7486 0           print STDERR "@_ at $filename line $line.\n";
7487 0           die "\n";
7488             }
7489              
7490             #
7491             # instead of Carp::cluck
7492             #
7493             sub cluck {
7494 0     0 0   my $i = 0;
7495 0           my @cluck = ();
7496 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7497 0           push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7498 0           $i++;
7499             }
7500 0           print STDERR CORE::reverse @cluck;
7501 0           print STDERR "\n";
7502 0           carp @_;
7503             }
7504              
7505             #
7506             # instead of Carp::confess
7507             #
7508             sub confess {
7509 0     0 0   my $i = 0;
7510 0           my @confess = ();
7511 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7512 0           push @confess, "[$i] $filename($line) $package::$subroutine\n";
7513 0           $i++;
7514             }
7515 0           print STDERR CORE::reverse @confess;
7516 0           print STDERR "\n";
7517 0           croak @_;
7518             }
7519              
7520             1;
7521              
7522             __END__