File Coverage

blib/lib/Elatin3.pm
Criterion Covered Total %
statement 865 3080 28.0
branch 944 2674 35.3
condition 99 373 26.5
subroutine 67 125 53.6
pod 7 74 9.4
total 1982 6326 31.3


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, 2016 INABA Hitoshi
9             ######################################################################
10              
11 200     200   3479 use 5.00503; # Galapagos Consensus 1998 for primetools
  200         649  
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   13055 BEGIN { CORE::eval q{ use vars qw($VERSION) } }
  200     200   1069  
  200         403  
  200         28853  
27             $VERSION = '1.08';
28             $VERSION = CORE::eval $VERSION;
29              
30             BEGIN {
31 200 50   200   1228 if ($^X =~ / jperl /oxmsi) {
32 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
33             }
34 200         293 if (CORE::ord('A') == 193) {
35             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
36             }
37 200         25729 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   12891 CORE::eval q{
  200     200   1017  
  200     69   304  
  200         23365  
  55         5040  
  42         3787  
  44         3977  
  59         5249  
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       100278 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 { };
58 0         0 *utf8::decode = sub { 1 };
  0         0  
59 0         0 *utf8::is_utf8 = sub { };
60 0         0 *utf8::valid = sub { 1 };
  0         0  
61             }
62             }
63              
64             # instead of Symbol.pm
65 0         0 BEGIN {
66 200     200   493 my $genpkg = "Symbol::";
67 200         9077 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   378 if (CORE::eval { local $@; CORE::require strict }) {
  200         301  
  200         1903  
115 200         22080 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   13569 BEGIN { CORE::eval q{ use vars qw($your_char) } } $your_char = q{[\x00-\xFF]};
  200     200   992  
  200         271  
  200         11182  
145 200     200   11897 BEGIN { CORE::eval q{ use vars qw($qq_char ) } } $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  200     200   984  
  200         278  
  200         12621  
146 200     200   11434 BEGIN { CORE::eval q{ use vars qw($q_char ) } } $q_char = qr/$your_char/oxms;
  200     200   888  
  200         279  
  200         13738  
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   11778 BEGIN { CORE::eval q{ use vars qw($encoding_alias) } }
  200     200   926  
  200         271  
  200         342936  
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     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   14364 BEGIN { CORE::eval q{ use vars qw(
  200     200   1151  
  200         306  
  200         72557  
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   14715 BEGIN { CORE::eval q{ use vars qw(
  200     200   1047  
  200         296  
  200         2481052  
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 174 50   174 0 306 if (@_) {
981 174         230 my $s = shift @_;
982 174 50 33     395 if (@_ and wantarray) {
983 0 0       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
984             }
985             else {
986 174 100       650 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         740  
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 197 50   197 0 290 if (@_) {
1007 197         202 my $s = shift @_;
1008 197 50 33     408 if (@_ and wantarray) {
1009 0 0       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1010             }
1011             else {
1012 197 100       576 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         1504  
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 1862     1862 0 1811 my($char) = @_;
1176              
1177             return {
1178             '\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 1862   100     80250 }->{$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             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 0         0 }->{$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 182     182   277 my $length = shift @_;
1513              
1514 182 50       358 if ($length == 1) {
1515 182         574 my($a1) = unpack 'C', $_[0];
1516 182         299 my($z1) = unpack 'C', $_[1];
1517              
1518 182 50       386 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 182 50       481 if ($a1 == $z1) {
    50          
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 182         1364 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 182     182   282 my($length,$first,$last) = @_;
1542              
1543 182         236 my @range_regexp = ();
1544 182 50       499 if (not exists $range_tr{$length}) {
1545 0         0 return @range_regexp;
1546             }
1547              
1548 182         179 my @ranges = @{ $range_tr{$length} };
  182         410  
1549 182         674 while (my @range = splice(@ranges,0,$length)) {
1550 182         218 my $min = '';
1551 182         178 my $max = '';
1552 182         440 for (my $i=0; $i < $length; $i++) {
1553 182         746 $min .= pack 'C', $range[$i][0];
1554 182         515 $max .= pack 'C', $range[$i][-1];
1555             }
1556              
1557             # min___max
1558             # FIRST_____________LAST
1559             # (nothing)
1560              
1561 182 50 33     2490 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    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 182         470 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 182         380 return @range_regexp;
1622             }
1623              
1624             #
1625             # Latin-3 open character list for qr and not qr
1626             #
1627             sub _charlist {
1628              
1629 358     358   505 my $modifier = pop @_;
1630 358         825 my @char = @_;
1631              
1632 358 100       813 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1633              
1634             # unescape character
1635 358         1087 for (my $i=0; $i <= $#char; $i++) {
1636              
1637             # escape - to ...
1638 1125 100 100     10505 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1639 206 100 100     1030 if ((0 < $i) and ($i < $#char)) {
1640 182         413 $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 22         122 $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             $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 25         488 }->{$1};
1709             }
1710              
1711             # POSIX-style character classes
1712             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1713             $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 8         75 }->{$1};
1721             }
1722             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1723             $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 70         1468 }->{$1};
1769             }
1770             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1771 7         36 $char[$i] = $1;
1772             }
1773             }
1774              
1775             # open character list
1776 358         542 my @singleoctet = ();
1777 358         453 my @multipleoctet = ();
1778 358         882 for (my $i=0; $i <= $#char; ) {
1779              
1780             # escaped -
1781 943 100 100     5087 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1782 182         182 $i += 1;
1783 182         351 next;
1784             }
1785              
1786             # make range regexp
1787             elsif ($char[$i] eq '...') {
1788              
1789             # range error
1790 182 50       815 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
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 182 50       471 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 182         570 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1801 182         241 my @regexp = ();
1802              
1803             # is first and last
1804 182 50 33     843 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1805 182         513 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 182 50       411 if ($length == 1) {
1828 182         402 push @singleoctet, @regexp;
1829             }
1830             else {
1831 0         0 push @multipleoctet, @regexp;
1832             }
1833             }
1834              
1835 182         426 $i += 2;
1836             }
1837              
1838             # with /i modifier
1839             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1840 493 100       755 if ($modifier =~ /i/oxms) {
1841 24         56 my $uc = Elatin3::uc($char[$i]);
1842 24         62 my $fc = Elatin3::fc($char[$i]);
1843 24 100       47 if ($uc ne $fc) {
1844 12 50       29 if (CORE::length($fc) == 1) {
1845 12         31 push @singleoctet, $uc, $fc;
1846             }
1847             else {
1848 0         0 push @singleoctet, $uc;
1849 0         0 push @multipleoctet, $fc;
1850             }
1851             }
1852             else {
1853 12         26 push @singleoctet, $char[$i];
1854             }
1855             }
1856             else {
1857 469         706 push @singleoctet, $char[$i];
1858             }
1859 493         862 $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 2         6 push @singleoctet, $char[$i];
1873 2         8 $i += 1;
1874             }
1875              
1876             # single character of multiple-octet code
1877             else {
1878 84         131 push @multipleoctet, $char[$i];
1879 84         164 $i += 1;
1880             }
1881             }
1882              
1883             # quote metachar
1884 358         711 for (@singleoctet) {
1885 689 50       3549 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1886 0         0 $_ = '-';
1887             }
1888             elsif (/\A \n \z/oxms) {
1889 8         21 $_ = '\n';
1890             }
1891             elsif (/\A \r \z/oxms) {
1892 8         19 $_ = '\r';
1893             }
1894             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1895 60         215 $_ = sprintf('\x%02X', CORE::ord $1);
1896             }
1897             elsif (/\A [\x00-\xFF] \z/oxms) {
1898 429         575 $_ = quotemeta $_;
1899             }
1900             }
1901              
1902             # return character list
1903 358         1122 return \@singleoctet, \@multipleoctet;
1904             }
1905              
1906             #
1907             # Latin-3 octal escape sequence
1908             #
1909             sub octchr {
1910 5     5 0 15 my($octdigit) = @_;
1911              
1912 5         9 my @binary = ();
1913 5         26 for my $octal (split(//,$octdigit)) {
1914             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 50         224 }->{$octal};
1924             }
1925 5         18 my $binary = join '', @binary;
1926              
1927             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 5         100 }->{CORE::length($binary) % 8};
1939              
1940 5         23 return $octchr;
1941             }
1942              
1943             #
1944             # Latin-3 hexadecimal escape sequence
1945             #
1946             sub hexchr {
1947 5     5 0 15 my($hexdigit) = @_;
1948              
1949             my $hexchr = {
1950             1 => pack('H*', "0$hexdigit"),
1951             0 => pack('H*', "$hexdigit"),
1952              
1953 5         56 }->{CORE::length($_[0]) % 2};
1954              
1955 5         19 return $hexchr;
1956             }
1957              
1958             #
1959             # Latin-3 open character list for qr
1960             #
1961             sub charlist_qr {
1962              
1963 314     314 0 569 my $modifier = pop @_;
1964 314         742 my @char = @_;
1965              
1966 314         1002 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1967 314         658 my @singleoctet = @$singleoctet;
1968 314         485 my @multipleoctet = @$multipleoctet;
1969              
1970             # return character list
1971 314 100       833 if (scalar(@singleoctet) >= 1) {
1972              
1973             # with /i modifier
1974 236 100       521 if ($modifier =~ m/i/oxms) {
1975 22         39 my %singleoctet_ignorecase = ();
1976 22         36 for (@singleoctet) {
1977 46   100     270 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1978 46         177 for my $ord (hex($1) .. hex($2)) {
1979 66         95 my $char = CORE::chr($ord);
1980 66         101 my $uc = Elatin3::uc($char);
1981 66         119 my $fc = Elatin3::fc($char);
1982 66 100       111 if ($uc eq $fc) {
1983 12         116 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1984             }
1985             else {
1986 54 50       89 if (CORE::length($fc) == 1) {
1987 54         138 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1988 54         254 $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 46 50       96 if ($_ ne '') {
1998 0         0 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1999             }
2000             }
2001 22         27 my $i = 0;
2002 22         31 my @singleoctet_ignorecase = ();
2003 22         46 for my $ord (0 .. 255) {
2004 5632 100       5991 if (exists $singleoctet_ignorecase{$ord}) {
2005 96         76 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         231  
2006             }
2007             else {
2008 5536         4537 $i++;
2009             }
2010             }
2011 22         59 @singleoctet = ();
2012 22         61 for my $range (@singleoctet_ignorecase) {
2013 3648 100       6569 if (ref $range) {
2014 56 100       48 if (scalar(@{$range}) == 1) {
  56 50       123  
2015 36         36 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         177  
2016             }
2017 20         35 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 20         23 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         55  
  20         116  
2022             }
2023             }
2024             }
2025             }
2026              
2027 236         342 my $not_anchor = '';
2028              
2029 236         656 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2030             }
2031 314 100       624 if (scalar(@multipleoctet) >= 2) {
2032 6         32 return '(?:' . join('|', @multipleoctet) . ')';
2033             }
2034             else {
2035 308         1343 return $multipleoctet[0];
2036             }
2037             }
2038              
2039             #
2040             # Latin-3 open character list for not qr
2041             #
2042             sub charlist_not_qr {
2043              
2044 44     44 0 81 my $modifier = pop @_;
2045 44         106 my @char = @_;
2046              
2047 44         128 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2048 44         92 my @singleoctet = @$singleoctet;
2049 44         62 my @multipleoctet = @$multipleoctet;
2050              
2051             # with /i modifier
2052 44 100       105 if ($modifier =~ m/i/oxms) {
2053 10         20 my %singleoctet_ignorecase = ();
2054 10         23 for (@singleoctet) {
2055 10   66     67 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2056 10         58 for my $ord (hex($1) .. hex($2)) {
2057 30         55 my $char = CORE::chr($ord);
2058 30         70 my $uc = Elatin3::uc($char);
2059 30         60 my $fc = Elatin3::fc($char);
2060 30 50       59 if ($uc eq $fc) {
2061 0         0 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2062             }
2063             else {
2064 30 50       49 if (CORE::length($fc) == 1) {
2065 30         97 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2066 30         264 $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 10 50       30 if ($_ ne '') {
2076 0         0 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2077             }
2078             }
2079 10         14 my $i = 0;
2080 10         16 my @singleoctet_ignorecase = ();
2081 10         22 for my $ord (0 .. 255) {
2082 2560 100       3290 if (exists $singleoctet_ignorecase{$ord}) {
2083 60         47 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         201  
2084             }
2085             else {
2086 2500         2460 $i++;
2087             }
2088             }
2089 10         28 @singleoctet = ();
2090 10         31 for my $range (@singleoctet_ignorecase) {
2091 960 100       2071 if (ref $range) {
2092 20 50       17 if (scalar(@{$range}) == 1) {
  20 50       46  
2093 0         0 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2094             }
2095 20         38 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 20         22 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         30  
  20         141  
2100             }
2101             }
2102             }
2103             }
2104              
2105             # return character list
2106 44 50       189 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 44 50       82 if (scalar(@singleoctet) >= 1) {
2120              
2121             # any character other than single octet character class
2122 44         280 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 400     400   997 my(undef,$file) = @_;
2137 400         2730 $file =~ s#\A (\s) #./$1#oxms;
2138 400   33     33444 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   813 $| = 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         1839 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         371 return CORE::system { $_[0] } @_; # safe even with one-argument list
  200         17077710  
2242             }
2243              
2244             #
2245             # Latin-3 order to character (with parameter)
2246             #
2247             sub Elatin3::chr(;$) {
2248              
2249 0 0   0 0 0 my $c = @_ ? $_[0] : $_;
2250              
2251 0 0       0 if ($c == 0x00) {
2252 0         0 return "\x00";
2253             }
2254             else {
2255 0         0 my @chr = ();
2256 0         0 while ($c > 0) {
2257 0         0 unshift @chr, ($c % 0x100);
2258 0         0 $c = int($c / 0x100);
2259             }
2260 0         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 0 my $c = $_;
2270              
2271 0 0       0 if ($c == 0x00) {
2272 0         0 return "\x00";
2273             }
2274             else {
2275 0         0 my @chr = ();
2276 0         0 while ($c > 0) {
2277 0         0 unshift @chr, ($c % 0x100);
2278 0         0 $c = int($c / 0x100);
2279             }
2280 0         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 0 if (wantarray) {
2290 0         0 my @glob = _DOS_like_glob(@_);
2291 0         0 for my $glob (@glob) {
2292 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2293             }
2294 0         0 return @glob;
2295             }
2296             else {
2297 0         0 my $glob = _DOS_like_glob(@_);
2298 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2299 0         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 0 if (wantarray) {
2309 0         0 my @glob = _DOS_like_glob();
2310 0         0 for my $glob (@glob) {
2311 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2312             }
2313 0         0 return @glob;
2314             }
2315             else {
2316 0         0 my $glob = _DOS_like_glob();
2317 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2318 0         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   0 my($expr,$cxix) = @_;
2334              
2335             # glob without args defaults to $_
2336 0 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       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2348 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
2349 0         0 { my_home_MSWin32() }oxmse;
2350             }
2351              
2352             # UNIX-like system
2353             else {
2354 0         0 $expr =~ s{ \A ~ ( (?:[^/])* ) }
2355 0 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       0 $cxix = '_G_' if not defined $cxix;
2360 0 0       0 $iter{$cxix} = 0 if not exists $iter{$cxix};
2361              
2362             # if we're just beginning, do it all first
2363 0 0       0 if ($iter{$cxix} == 0) {
2364 0         0 $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2365             }
2366              
2367             # chuck it all out, quick or slow
2368 0 0       0 if (wantarray) {
2369 0         0 delete $iter{$cxix};
2370 0         0 return @{delete $entries{$cxix}};
  0         0  
2371             }
2372             else {
2373 0 0       0 if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
  0         0  
2374 0         0 return shift @{$entries{$cxix}};
  0         0  
2375             }
2376             else {
2377             # return undef for EOL
2378 0         0 delete $iter{$cxix};
2379 0         0 delete $entries{$cxix};
2380 0         0 return undef;
2381             }
2382             }
2383             }
2384              
2385             #
2386             # Latin-3 path globbing subroutine
2387             #
2388             sub _do_glob {
2389              
2390 0     0   0 my($cond,@expr) = @_;
2391 0         0 my @glob = ();
2392 0         0 my $fix_drive_relative_paths = 0;
2393              
2394             OUTER:
2395 0         0 for my $expr (@expr) {
2396 0 0       0 next OUTER if not defined $expr;
2397 0 0       0 next OUTER if $expr eq '';
2398              
2399 0         0 my @matched = ();
2400 0         0 my @globdir = ();
2401 0         0 my $head = '.';
2402 0         0 my $pathsep = '/';
2403 0         0 my $tail;
2404              
2405             # if argument is within quotes strip em and do no globbing
2406 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2407 0         0 $expr = $1;
2408 0 0       0 if ($cond eq 'd') {
2409 0 0       0 if (-d $expr) {
2410 0         0 push @glob, $expr;
2411             }
2412             }
2413             else {
2414 0 0       0 if (-e $expr) {
2415 0         0 push @glob, $expr;
2416             }
2417             }
2418 0         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       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2424 0 0       0 if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2425 0         0 $fix_drive_relative_paths = 1;
2426             }
2427             }
2428              
2429 0 0       0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2430 0 0       0 if ($tail eq '') {
2431 0         0 push @glob, $expr;
2432 0         0 next OUTER;
2433             }
2434 0 0       0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
2435 0 0       0 if (@globdir = _do_glob('d', $head)) {
2436 0         0 push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
  0         0  
2437 0         0 next OUTER;
2438             }
2439             }
2440 0 0 0     0 if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2441 0         0 $head .= $pathsep;
2442             }
2443 0         0 $expr = $tail;
2444             }
2445              
2446             # If file component has no wildcards, we can avoid opendir
2447 0 0       0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2448 0 0       0 if ($head eq '.') {
2449 0         0 $head = '';
2450             }
2451 0 0 0     0 if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2452 0         0 $head .= $pathsep;
2453             }
2454 0         0 $head .= $expr;
2455 0 0       0 if ($cond eq 'd') {
2456 0 0       0 if (-d $head) {
2457 0         0 push @glob, $head;
2458             }
2459             }
2460             else {
2461 0 0       0 if (-e $head) {
2462 0         0 push @glob, $head;
2463             }
2464             }
2465 0         0 next OUTER;
2466             }
2467 0 0       0 opendir(*DIR, $head) or next OUTER;
2468 0         0 my @leaf = readdir DIR;
2469 0         0 closedir DIR;
2470              
2471 0 0       0 if ($head eq '.') {
2472 0         0 $head = '';
2473             }
2474 0 0 0     0 if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2475 0         0 $head .= $pathsep;
2476             }
2477              
2478 0         0 my $pattern = '';
2479 0         0 while ($expr =~ / \G ($q_char) /oxgc) {
2480 0         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       0 if ($char eq '*') {
    0          
    0          
2488 0         0 $pattern .= "(?:$your_char)*",
2489             }
2490             elsif ($char eq '?') {
2491 0         0 $pattern .= "(?:$your_char)?", # DOS style
2492             # $pattern .= "(?:$your_char)", # UNIX style
2493             }
2494             elsif ((my $fc = Elatin3::fc($char)) ne $char) {
2495 0         0 $pattern .= $fc;
2496             }
2497             else {
2498 0         0 $pattern .= quotemeta $char;
2499             }
2500             }
2501 0     0   0 my $matchsub = sub { Elatin3::fc($_[0]) =~ /\A $pattern \z/xms };
  0         0  
2502              
2503             # if ($@) {
2504             # print STDERR "$0: $@\n";
2505             # next OUTER;
2506             # }
2507              
2508             INNER:
2509 0         0 for my $leaf (@leaf) {
2510 0 0 0     0 if ($leaf eq '.' or $leaf eq '..') {
2511 0         0 next INNER;
2512             }
2513 0 0 0     0 if ($cond eq 'd' and not -d "$head$leaf") {
2514 0         0 next INNER;
2515             }
2516              
2517 0 0       0 if (&$matchsub($leaf)) {
2518 0         0 push @matched, "$head$leaf";
2519 0         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     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       0 if (&$matchsub("$leaf.")) {
2530 0         0 push @matched, "$head$leaf";
2531 0         0 next INNER;
2532             }
2533             }
2534             }
2535 0 0       0 if (@matched) {
2536 0         0 push @glob, @matched;
2537             }
2538             }
2539 0 0       0 if ($fix_drive_relative_paths) {
2540 0         0 for my $glob (@glob) {
2541 0         0 $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2542             }
2543             }
2544 0         0 return @glob;
2545             }
2546              
2547             #
2548             # Latin-3 parse line
2549             #
2550             sub _parse_line {
2551              
2552 0     0   0 my($line) = @_;
2553              
2554 0         0 $line .= ' ';
2555 0         0 my @piece = ();
2556 0         0 while ($line =~ /
2557             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2558             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2559             /oxmsg
2560             ) {
2561 0 0       0 push @piece, defined($1) ? $1 : $2;
2562             }
2563 0         0 return @piece;
2564             }
2565              
2566             #
2567             # Latin-3 parse path
2568             #
2569             sub _parse_path {
2570              
2571 0     0   0 my($path,$pathsep) = @_;
2572              
2573 0         0 $path .= '/';
2574 0         0 my @subpath = ();
2575 0         0 while ($path =~ /
2576             ((?: [^\/\\] )+?) [\/\\]
2577             /oxmsg
2578             ) {
2579 0         0 push @subpath, $1;
2580             }
2581              
2582 0         0 my $tail = pop @subpath;
2583 0         0 my $head = join $pathsep, @subpath;
2584 0         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 0 if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
    0 0        
    0 0        
      0        
      0        
2596 0         0 return $ENV{'HOME'};
2597             }
2598              
2599             # Do we have a user profile?
2600             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2601 0         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         0 return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2607             }
2608              
2609 0         0 return undef;
2610             }
2611              
2612             #
2613             # via File::HomeDir::Unix 1.00
2614             #
2615             sub my_home {
2616 0     0 0 0 my $home;
2617              
2618 0 0 0     0 if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
    0 0        
2619 0         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         0 $home = $ENV{'LOGDIR'};
2626             }
2627              
2628             ### More-desperate methods
2629              
2630             # Light desperation on any (Unixish) platform
2631             else {
2632 0         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     0 if (defined $home and ! -d($home)) {
2638 0         0 $home = undef;
2639             }
2640 0         0 return $home;
2641             }
2642              
2643             #
2644             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2645             #
2646             sub Elatin3::PREMATCH {
2647 0     0 0 0 return $`;
2648             }
2649              
2650             #
2651             # ${^MATCH}, $MATCH, $& the string that matched
2652             #
2653             sub Elatin3::MATCH {
2654 0     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 0 return $';
2662             }
2663              
2664             #
2665             # Latin-3 character to order (with parameter)
2666             #
2667             sub Latin3::ord(;$) {
2668              
2669 0 0   0 1 0 local $_ = shift if @_;
2670              
2671 0 0       0 if (/\A ($q_char) /oxms) {
2672 0         0 my @ord = unpack 'C*', $1;
2673 0         0 my $ord = 0;
2674 0         0 while (my $o = shift @ord) {
2675 0         0 $ord = $ord * 0x100 + $o;
2676             }
2677 0         0 return $ord;
2678             }
2679             else {
2680 0         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 0 if (/\A ($q_char) /oxms) {
2690 0         0 my @ord = unpack 'C*', $1;
2691 0         0 my $ord = 0;
2692 0         0 while (my $o = shift @ord) {
2693 0         0 $ord = $ord * 0x100 + $o;
2694             }
2695 0         0 return $ord;
2696             }
2697             else {
2698 0         0 return CORE::ord $_;
2699             }
2700             }
2701              
2702             #
2703             # Latin-3 reverse
2704             #
2705             sub Latin3::reverse(@) {
2706              
2707 0 0   0 0 0 if (wantarray) {
2708 0         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         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 0 my($package) = caller;
2727 0 0       0 my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2728 0 0 0     0 croak 'Too many arguments for Latin3::getc' if @_ and not wantarray;
2729              
2730 0         0 my @length = sort { $a <=> $b } keys %range_tr;
  0         0  
2731 0         0 my $getc = '';
2732 0         0 for my $length ($length[0] .. $length[-1]) {
2733 0         0 $getc .= CORE::getc($fh);
2734 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2735 0 0       0 if ($getc =~ /\A ${Elatin3::dot_s} \z/oxms) {
2736 0 0       0 return wantarray ? ($getc,@_) : $getc;
2737             }
2738             }
2739             }
2740 0 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 0 local $_ = shift if @_;
2749              
2750 0         0 local @_ = /\G ($q_char) /oxmsg;
2751 0         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 115871 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         0  
  0         0  
  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 0 my $index;
2851 0 0       0 if (@_ == 3) {
2852 0         0 $index = Elatin3::index($_[0], $_[1], CORE::length(Latin3::substr($_[0], 0, $_[2])));
2853             }
2854             else {
2855 0         0 $index = Elatin3::index($_[0], $_[1]);
2856             }
2857              
2858 0 0       0 if ($index == -1) {
2859 0         0 return -1;
2860             }
2861             else {
2862 0         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 0 my $rindex;
2872 0 0       0 if (@_ == 3) {
2873 0         0 $rindex = Elatin3::rindex($_[0], $_[1], CORE::length(Latin3::substr($_[0], 0, $_[2])));
2874             }
2875             else {
2876 0         0 $rindex = Elatin3::rindex($_[0], $_[1]);
2877             }
2878              
2879 0 0       0 if ($rindex == -1) {
2880 0         0 return -1;
2881             }
2882             else {
2883 0         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   15836 BEGIN { CORE::eval q{ use vars qw($slash) } } $slash = 'm//';
  200     200   1653  
  200         339  
  200         13136  
2890              
2891             # ord() to ord() or Latin3::ord()
2892 200     200   11873 BEGIN { CORE::eval q{ use vars qw($function_ord) } } $function_ord = 'ord';
  200     200   1032  
  200         362  
  200         15372  
2893              
2894             # ord to ord or Latin3::ord_
2895 200     200   11888 BEGIN { CORE::eval q{ use vars qw($function_ord_) } } $function_ord_ = 'ord';
  200     200   1073  
  200         335  
  200         10657  
2896              
2897             # reverse to reverse or Latin3::reverse
2898 200     200   14908 BEGIN { CORE::eval q{ use vars qw($function_reverse) } } $function_reverse = 'reverse';
  200     200   970  
  200         351  
  200         11008  
2899              
2900             # getc to getc or Latin3::getc
2901 200     200   10404 BEGIN { CORE::eval q{ use vars qw($function_getc) } } $function_getc = 'getc';
  200     200   927  
  200         611  
  200         11190  
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   11293 BEGIN { CORE::eval q{ use vars qw($nest) } }
  200     200   945  
  200         370  
  200         8574493  
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 200 50   200 0 683 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 200         361 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 200         329 my $e_script = '';
3046 200         897 while (not /\G \z/oxgc) { # member
3047 71860         90610 $e_script .= Latin3::escape_token();
3048             }
3049              
3050 200         2250 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 71860     71860 0 61954 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 71860 100 100     3979005 if (/\G ( \n ) /oxgc) { # another member (and so on)
    100 66        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
3080 12082         10448 my $heredoc = '';
3081 12082 100       20855 if (scalar(@heredoc_delimiter) >= 1) {
3082 150         161 $slash = 'm//';
3083              
3084 150         254 $heredoc = join '', @heredoc;
3085 150         233 @heredoc = ();
3086              
3087             # skip here document
3088 150         243 for my $heredoc_delimiter (@heredoc_delimiter) {
3089 150         1092 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3090             }
3091 150         215 @heredoc_delimiter = ();
3092              
3093 150         174 $here_script = '';
3094             }
3095 12082         35410 return "\n" . $heredoc;
3096             }
3097              
3098             # ignore space, comment
3099 17259         51020 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 1373         1756 $slash = 'm//';
3115 1373         4266 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 85         202 my $e_string = e_string($1);
3135              
3136 85 50       2272 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
    50          
3137 0         0 $tr_variable = $e_string . e_string($1);
3138 0         0 $bind_operator = $2;
3139 0         0 $slash = 'm//';
3140 0         0 return '';
3141             }
3142             elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3143 0         0 $sub_variable = $e_string . e_string($1);
3144 0         0 $bind_operator = $2;
3145 0         0 $slash = 'm//';
3146 0         0 return '';
3147             }
3148             else {
3149 85         126 $slash = 'div';
3150 85         323 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 4         9 $slash = 'div';
3157 4         16 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 28         43 $slash = 'div';
3163 28         86 return q{Elatin3::MATCH()};
3164             }
3165              
3166             # $', ${'} --> $', ${'}
3167             elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3168 1         2 $slash = 'div';
3169 1         6 return $1;
3170             }
3171              
3172             # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin3::POSTMATCH()
3173             elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3174 3         5 $slash = 'div';
3175 3         11 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 1604         3116 my $scalar = e_string($1);
3184              
3185 1604 100       7103 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
    100          
3186 1         2 $tr_variable = $scalar;
3187 1         2 $bind_operator = $1;
3188 1         2 $slash = 'm//';
3189 1         11 return '';
3190             }
3191             elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3192 61         109 $sub_variable = $scalar;
3193 61         127 $bind_operator = $1;
3194 61         77 $slash = 'm//';
3195 61         200 return '';
3196             }
3197             else {
3198 1542         1774 $slash = 'div';
3199 1542         4381 return $scalar;
3200             }
3201             }
3202              
3203             # end of statement
3204             elsif (/\G ( [,;] ) /oxgc) {
3205 4563         5036 $slash = 'm//';
3206              
3207             # clear tr/// variable
3208 4563         4186 $tr_variable = '';
3209              
3210             # clear s/// variable
3211 4563         3843 $sub_variable = '';
3212              
3213 4563         3708 $bind_operator = '';
3214              
3215 4563         17019 return $1;
3216             }
3217              
3218             # bareword
3219             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3220 0         0 return $1;
3221             }
3222              
3223             # $0 --> $0
3224             elsif (/\G ( \$ 0 ) /oxmsgc) {
3225 2         5 $slash = 'div';
3226 2         9 return $1;
3227             }
3228             elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3229 0         0 $slash = 'div';
3230 0         0 return $1;
3231             }
3232              
3233             # $$ --> $$
3234             elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3235 1         3 $slash = 'div';
3236 1         7 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 4         5 $slash = 'div';
3243 4         5 return e_capture($1);
3244             }
3245             elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3246 0         0 $slash = 'div';
3247 0         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         0 $slash = 'div';
3253 0         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         0 $slash = 'div';
3259 0         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         0 $slash = 'div';
3265 0         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         0 $slash = 'div';
3271 0         0 return '${' . $1 . '}';
3272             }
3273              
3274             # ${ ... }
3275             elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3276 0         0 $slash = 'div';
3277 0         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 42         63 $slash = 'div';
3284 42         154 return $1;
3285             }
3286             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3287             # $ @ # \ ' " / ? ( ) [ ] < >
3288             elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3289 60         123 $slash = 'div';
3290 60         328 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         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         0 return 'while ($_ = Elatin3::glob("' . $1 . '"))';
3304             }
3305              
3306             # while (glob)
3307             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3308 0         0 return 'while ($_ = Elatin3::glob_)';
3309             }
3310              
3311             # while (glob(WILDCARD))
3312             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3313 0         0 return 'while ($_ = Elatin3::glob';
3314             }
3315              
3316             # doit if, doit unless, doit while, doit until, doit for, doit when
3317 241         514 elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
  241         1002  
3318              
3319             # subroutines of package Elatin3
3320 19         35 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  19         96  
3321 0         0 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3322 13         18 elsif (/\G \b Latin3::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  13         37  
3323 0         0 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  0         0  
3324 114         149 elsif (/\G \b Latin3::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Latin3::escape'; }
  114         341  
3325 2         6 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         9  
3326 0         0 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::chop'; }
  0         0  
3327 2         5 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  2         7  
3328 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3329 0         0 elsif (/\G \b Latin3::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin3::index'; }
  0         0  
3330 0         0 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::index'; }
  0         0  
3331 2         6 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  2         10  
3332 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3333 0         0 elsif (/\G \b Latin3::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin3::rindex'; }
  0         0  
3334 0         0 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::rindex'; }
  0         0  
3335 1         27 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::lc'; }
  1         9  
3336 0         0 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::lcfirst'; }
  0         0  
3337 1         2 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::uc'; }
  1         3  
3338 0         0 elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::ucfirst'; }
  0         0  
3339 6         5 elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::fc'; }
  6         14  
3340              
3341             # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
3342 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3343 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3344 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3345 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3346 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3347 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3348 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3349              
3350 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3351 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3352 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3353 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3354 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3355 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3356 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3357              
3358             elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
3359 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3360 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3361 0         0 elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
  0         0  
3362 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  0         0  
3363              
3364 2         6 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  2         10  
3365 2         4 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         9  
3366 36         57 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::chr'; }
  36         109  
3367 2         6 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  2         9  
3368 8         12 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  8         26  
3369 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin3::glob'; }
  0         0  
3370 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::lc_'; }
  0         0  
3371 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::lcfirst_'; }
  0         0  
3372 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::uc_'; }
  0         0  
3373 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::ucfirst_'; }
  0         0  
3374 0         0 elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::fc_'; }
  0         0  
3375 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3376              
3377 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3378 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3379 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::chr_'; }
  0         0  
3380 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3381 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3382 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin3::glob_'; }
  0         0  
3383 0         0 elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
  0         0  
3384 8         26 elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
  8         37  
3385             # split
3386             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3387 87         176 $slash = 'm//';
3388              
3389 87         128 my $e = '';
3390 87         405 while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3391 85         405 $e .= $1;
3392             }
3393              
3394             # end of split
3395 87 100       8409 if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Elatin3::split' . $e; }
  2 100       10  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3396              
3397             # split scalar value
3398 1         5 elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Elatin3::split' . $e . e_string($1); }
3399              
3400             # split literal space
3401 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Elatin3::split' . $e . qq {qq$1 $2}; }
3402 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3403 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3404 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3405 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3406 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin3::split' . $e . qq{$1qq$2 $3}; }
3407 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Elatin3::split' . $e . qq {q$1 $2}; }
3408 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3409 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3410 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3411 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3412 0         0 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin3::split' . $e . qq {$1q$2 $3}; }
3413 10         66 elsif (/\G ' [ ] ' /oxgc) { return 'Elatin3::split' . $e . qq {' '}; }
3414 0         0 elsif (/\G " [ ] " /oxgc) { return 'Elatin3::split' . $e . qq {" "}; }
3415              
3416             # split qq//
3417             elsif (/\G \b (qq) \b /oxgc) {
3418 0 0       0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
  0         0  
3419             else {
3420 0         0 while (not /\G \z/oxgc) {
3421 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3422 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3423 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3424 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3425 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3426 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3427 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3428             }
3429 0         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 12 50       536 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
  0         0  
3436             else {
3437 12         67 while (not /\G \z/oxgc) {
3438 12 50       3701 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    50          
    50          
    50          
3439 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3440 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3441 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3442 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3443 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3444 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3445 12         67 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3446             }
3447 0         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       0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
  0         0  
3454             else {
3455 0         0 while (not /\G \z/oxgc) {
3456 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3457 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3458 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3459 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3460 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3461 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3462 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3463             }
3464 0         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 18 50       596 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
  0         0  
3471             else {
3472 18         80 while (not /\G \z/oxgc) {
3473 18 50       4785 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    50          
    50          
    50          
3474 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3475 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3476 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3477 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3478 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3479 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3480 18         154 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3481             }
3482 0         0 die __FILE__, ": Search pattern not terminated\n";
3483             }
3484             }
3485              
3486             # split ''
3487             elsif (/\G (\') /oxgc) {
3488 0         0 my $q_string = '';
3489 0         0 while (not /\G \z/oxgc) {
3490 0 0       0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
3491 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3492 0         0 elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3493 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3494             }
3495 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3496             }
3497              
3498             # split ""
3499             elsif (/\G (\") /oxgc) {
3500 0         0 my $qq_string = '';
3501 0         0 while (not /\G \z/oxgc) {
3502 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
3503 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3504 0         0 elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3505 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3506             }
3507 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3508             }
3509              
3510             # split //
3511             elsif (/\G (\/) /oxgc) {
3512 44         82 my $regexp = '';
3513 44         174 while (not /\G \z/oxgc) {
3514 381 50       1714 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
  0 50       0  
    100          
    50          
3515 0         0 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3516 44         244 elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3517 337         699 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3518             }
3519 0         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 3         9 my $ope = $1;
3533              
3534             # $1 $2 $3 $4 $5 $6
3535 3 50       61 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3536 0         0 my @tr = ($tr_variable,$2);
3537 0         0 return e_tr(@tr,'',$4,$6);
3538             }
3539             else {
3540 3         5 my $e = '';
3541 3         16 while (not /\G \z/oxgc) {
3542 3 50       216 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    50          
3543             elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3544 0         0 my @tr = ($tr_variable,$2);
3545 0         0 while (not /\G \z/oxgc) {
3546 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3547 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3548 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3549 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3550 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3551 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3552             }
3553 0         0 die __FILE__, ": Transliteration replacement not terminated\n";
3554             }
3555             elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3556 0         0 my @tr = ($tr_variable,$2);
3557 0         0 while (not /\G \z/oxgc) {
3558 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3559 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3560 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3561 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3562 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3563 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3564             }
3565 0         0 die __FILE__, ": Transliteration replacement not terminated\n";
3566             }
3567             elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3568 0         0 my @tr = ($tr_variable,$2);
3569 0         0 while (not /\G \z/oxgc) {
3570 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3571 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3572 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3573 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3574 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3575 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3576             }
3577 0         0 die __FILE__, ": Transliteration replacement not terminated\n";
3578             }
3579             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3580 0         0 my @tr = ($tr_variable,$2);
3581 0         0 while (not /\G \z/oxgc) {
3582 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3583 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3584 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3585 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3586 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3587 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3588             }
3589 0         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 3         12 my @tr = ($tr_variable,$2);
3594 3         12 return e_tr(@tr,'',$4,$6);
3595             }
3596             }
3597 0         0 die __FILE__, ": Transliteration pattern not terminated\n";
3598             }
3599             }
3600              
3601             # qq//
3602             elsif (/\G \b (qq) \b /oxgc) {
3603 2130         4020 my $ope = $1;
3604              
3605             # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3606 2130 50       3516 if (/\G (\#) /oxgc) { # qq# #
3607 0         0 my $qq_string = '';
3608 0         0 while (not /\G \z/oxgc) {
3609 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
3610 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3611 0         0 elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3612 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3613             }
3614 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3615             }
3616              
3617             else {
3618 2130         2200 my $e = '';
3619 2130         6007 while (not /\G \z/oxgc) {
3620 2130 50       8402 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    100          
    50          
    50          
    0          
3621              
3622             # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3623             elsif (/\G (\() /oxgc) { # qq ( )
3624 0         0 my $qq_string = '';
3625 0         0 local $nest = 1;
3626 0         0 while (not /\G \z/oxgc) {
3627 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
    0          
3628 0         0 elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3629 0         0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3630             elsif (/\G (\)) /oxgc) {
3631 0 0       0 if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
  0         0  
3632 0         0 else { $qq_string .= $1; }
3633             }
3634 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3635             }
3636 0         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 2100         2031 my $qq_string = '';
3642 2100         2652 local $nest = 1;
3643 2100         4291 while (not /\G \z/oxgc) {
3644 82644 100       281122 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  722 50       1579  
    100          
    100          
    50          
3645 0         0 elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3646 1103         1251 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  1103         1912  
3647             elsif (/\G (\}) /oxgc) {
3648 3203 100       4330 if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
  2100         4191  
3649 1103         2367 else { $qq_string .= $1; }
3650             }
3651 77616         152086 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3652             }
3653 0         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         0 my $qq_string = '';
3659 0         0 local $nest = 1;
3660 0         0 while (not /\G \z/oxgc) {
3661 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
    0          
3662 0         0 elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3663 0         0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3664             elsif (/\G (\]) /oxgc) {
3665 0 0       0 if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
  0         0  
3666 0         0 else { $qq_string .= $1; }
3667             }
3668 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3669             }
3670 0         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 30         47 my $qq_string = '';
3676 30         51 local $nest = 1;
3677 30         97 while (not /\G \z/oxgc) {
3678 1166 100       4405 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  22 50       52  
    50          
    100          
    50          
3679 0         0 elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3680 0         0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3681             elsif (/\G (\>) /oxgc) {
3682 30 50       75 if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
  30         76  
3683 0         0 else { $qq_string .= $1; }
3684             }
3685 1114         2149 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3686             }
3687 0         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         0 my $delimiter = $1;
3693 0         0 my $qq_string = '';
3694 0         0 while (not /\G \z/oxgc) {
3695 0 0       0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
3696 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3697 0         0 elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3698 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3699             }
3700 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3701             }
3702             }
3703 0         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         0 my $ope = $1;
3710 0 0       0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3711 0         0 return e_qr($ope,$1,$3,$2,$4);
3712             }
3713             else {
3714 0         0 my $e = '';
3715 0         0 while (not /\G \z/oxgc) {
3716 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3717 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3718 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3719 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3720 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3721 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3722 0         0 elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3723 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3724             }
3725 0         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 16         55 my $ope = $1;
3732 16 50       83 if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3733 0         0 return e_qw($ope,$1,$3,$2);
3734             }
3735             else {
3736 16         107 my $e = '';
3737 16         83 while (not /\G \z/oxgc) {
3738 16 50       150 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3739              
3740 16         70 elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3741 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3742              
3743 0         0 elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3744 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3745              
3746 0         0 elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3747 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3748              
3749 0         0 elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3750 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3751              
3752 0         0 elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3753 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3754             }
3755 0         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         0 my $ope = $1;
3762 0 0       0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3763 0         0 return e_qq($ope,$1,$3,$2);
3764             }
3765             else {
3766 0         0 my $e = '';
3767 0         0 while (not /\G \z/oxgc) {
3768 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3769 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3770 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3771 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3772 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3773 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3774 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3775             }
3776 0         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 245         719 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 245 50       814 if (/\G (\#) /oxgc) { # q# #
3790 0         0 my $q_string = '';
3791 0         0 while (not /\G \z/oxgc) {
3792 0 0       0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
3793 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3794 0         0 elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3795 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3796             }
3797 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3798             }
3799              
3800             else {
3801 245         456 my $e = '';
3802 245         954 while (not /\G \z/oxgc) {
3803 245 50       1841 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    100          
    50          
    100          
    50          
3804              
3805             # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3806             elsif (/\G (\() /oxgc) { # q ( )
3807 0         0 my $q_string = '';
3808 0         0 local $nest = 1;
3809 0         0 while (not /\G \z/oxgc) {
3810 0 0       0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3811 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
3812 0         0 elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3813 0         0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3814             elsif (/\G (\)) /oxgc) {
3815 0 0       0 if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
  0         0  
3816 0         0 else { $q_string .= $1; }
3817             }
3818 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3819             }
3820 0         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 239         411 my $q_string = '';
3826 239         479 local $nest = 1;
3827 239         918 while (not /\G \z/oxgc) {
3828 3637 50       19605 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 50       0  
    50          
    100          
    100          
    50          
3829 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
3830 0         0 elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3831 107         145 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  107         220  
3832             elsif (/\G (\}) /oxgc) {
3833 346 100       777 if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
  239         890  
3834 107         253 else { $q_string .= $1; }
3835             }
3836 3184         7585 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3837             }
3838 0         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         0 my $q_string = '';
3844 0         0 local $nest = 1;
3845 0         0 while (not /\G \z/oxgc) {
3846 0 0       0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
3847 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
3848 0         0 elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3849 0         0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3850             elsif (/\G (\]) /oxgc) {
3851 0 0       0 if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
  0         0  
3852 0         0 else { $q_string .= $1; }
3853             }
3854 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3855             }
3856 0         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 5         15 my $q_string = '';
3862 5         13 local $nest = 1;
3863 5         91 while (not /\G \z/oxgc) {
3864 88 50       598 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 50       0  
    50          
    50          
    100          
    50          
3865 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
3866 0         0 elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3867 0         0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3868             elsif (/\G (\>) /oxgc) {
3869 5 50       24 if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
  5         21  
3870 0         0 else { $q_string .= $1; }
3871             }
3872 83         237 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3873             }
3874 0         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 1         4 my $delimiter = $1;
3880 1         2 my $q_string = '';
3881 1         5 while (not /\G \z/oxgc) {
3882 14 50       76 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  0 50       0  
    100          
    50          
3883 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3884 1         3 elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3885 13         22 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3886             }
3887 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3888             }
3889             }
3890 0         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 209         426 my $ope = $1;
3897 209 50       2017 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3898 0         0 return e_qr($ope,$1,$3,$2,$4);
3899             }
3900             else {
3901 209         293 my $e = '';
3902 209         584 while (not /\G \z/oxgc) {
3903 209 50       13243 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3904 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3905 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3906 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3907 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3908 0         0 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3909 10         37 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3910 0         0 elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3911 199         619 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3912             }
3913 0         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 97         301 my $ope = $1;
3926              
3927             # $1 $2 $3 $4 $5 $6
3928 97 100       2215 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3929 1         10 return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3930             }
3931             else {
3932 96         134 my $e = '';
3933 96         333 while (not /\G \z/oxgc) {
3934 96 50       13059 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 50       0  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3935             elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3936 0         0 my @s = ($1,$2,$3);
3937 0         0 while (not /\G \z/oxgc) {
3938 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3939             # $1 $2 $3 $4
3940 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3941 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3942 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3943 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3944 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3945 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3946 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3947 0         0 elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3948 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3949             }
3950 0         0 die __FILE__, ": Substitution replacement not terminated\n";
3951             }
3952             elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3953 0         0 my @s = ($1,$2,$3);
3954 0         0 while (not /\G \z/oxgc) {
3955 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3956             # $1 $2 $3 $4
3957 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3958 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3960 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3961 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3962 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3963 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3964 0         0 elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3965 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3966             }
3967 0         0 die __FILE__, ": Substitution replacement not terminated\n";
3968             }
3969             elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3970 0         0 my @s = ($1,$2,$3);
3971 0         0 while (not /\G \z/oxgc) {
3972 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3973             # $1 $2 $3 $4
3974 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3975 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3976 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3977 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3978 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3979 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3980 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3981             }
3982 0         0 die __FILE__, ": Substitution replacement not terminated\n";
3983             }
3984             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3985 0         0 my @s = ($1,$2,$3);
3986 0         0 while (not /\G \z/oxgc) {
3987 0 0       0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3988             # $1 $2 $3 $4
3989 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3990 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3991 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3992 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3993 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3994 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3995 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3996 0         0 elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3997 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3998             }
3999 0         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 21         70 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         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         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 75         323 return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
4016             }
4017             }
4018 0         0 die __FILE__, ": Substitution pattern not terminated\n";
4019             }
4020             }
4021              
4022             # require ignore module
4023 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
4024 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
4025 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4026              
4027             # use strict; --> use strict; no strict qw(refs);
4028 36         328 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4029 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4030 0         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 2 50 33     26 if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
      33        
4035 0         0 return "use $1; no strict qw(refs);";
4036             }
4037             else {
4038 2         10 return "use $1;";
4039             }
4040             }
4041             elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4042 0 0 0     0 if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
      0        
4043 0         0 return "use $1; no strict qw(refs);";
4044             }
4045             else {
4046 0         0 return "use $1;";
4047             }
4048             }
4049              
4050             # ignore use module
4051 2         23 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4052 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4053 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4054              
4055             # ignore no module
4056 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4057 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4058 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4059              
4060             # use else
4061 0         0 elsif (/\G \b use \b /oxmsgc) { return "use"; }
4062              
4063             # use else
4064 2         9 elsif (/\G \b no \b /oxmsgc) { return "no"; }
4065              
4066             # ''
4067             elsif (/\G (?
4068 841         1332 my $q_string = '';
4069 841         2302 while (not /\G \z/oxgc) {
4070 8209 100       28662 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
  4 100       14  
    100          
    50          
4071 48         78 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4072 841         1966 elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4073 7316         14438 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4074             }
4075 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4076             }
4077              
4078             # ""
4079             elsif (/\G (\") /oxgc) {
4080 1749         2528 my $qq_string = '';
4081 1749         4587 while (not /\G \z/oxgc) {
4082 34334 100       110920 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  67 100       208  
    100          
    50          
4083 12         27 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4084 1749         4301 elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4085 32506         68177 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4086             }
4087 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4088             }
4089              
4090             # ``
4091             elsif (/\G (\`) /oxgc) {
4092 1         2 my $qx_string = '';
4093 1         3 while (not /\G \z/oxgc) {
4094 19 50       78 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
  0 50       0  
    100          
    50          
4095 0         0 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4096 1         2 elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4097 18         27 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4098             }
4099 0         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 452         799 my $regexp = '';
4105 452         1355 while (not /\G \z/oxgc) {
4106 4490 50       16944 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
  0 50       0  
    100          
    50          
4107 0         0 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4108 452         1320 elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4109 4038         8599 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4110             }
4111 0         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         0 my $regexp = '';
4117 0         0 while (not /\G \z/oxgc) {
4118 0 0       0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
  0 0       0  
    0          
    0          
4119 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4120 0         0 elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4121 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4122             }
4123 0         0 die __FILE__, ": Search pattern not terminated\n";
4124             }
4125              
4126             # <<>> (a safer ARGV)
4127 0         0 elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
  0         0  
4128              
4129             # << (bit shift) --- not here document
4130 0         0 elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
  0         0  
4131              
4132             # <<'HEREDOC'
4133             elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4134 72         108 $slash = 'm//';
4135 72         155 my $here_quote = $1;
4136 72         115 my $delimiter = $2;
4137              
4138             # get here document
4139 72 50       146 if ($here_script eq '') {
4140 72         398 $here_script = CORE::substr $_, pos $_;
4141 72         412 $here_script =~ s/.*?\n//oxm;
4142             }
4143 72 50       607 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4144 72         235 push @heredoc, $1 . qq{\n$delimiter\n};
4145 72         113 push @heredoc_delimiter, $delimiter;
4146             }
4147             else {
4148 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4149             }
4150 72         303 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         0 $slash = 'm//';
4165 0         0 my $here_quote = $1;
4166 0         0 my $delimiter = $2;
4167              
4168             # get here document
4169 0 0       0 if ($here_script eq '') {
4170 0         0 $here_script = CORE::substr $_, pos $_;
4171 0         0 $here_script =~ s/.*?\n//oxm;
4172             }
4173 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4174 0         0 push @heredoc, $1 . qq{\n$delimiter\n};
4175 0         0 push @heredoc_delimiter, $delimiter;
4176             }
4177             else {
4178 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4179             }
4180 0         0 return $here_quote;
4181             }
4182              
4183             # <<"HEREDOC"
4184             elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4185 36         60 $slash = 'm//';
4186 36         90 my $here_quote = $1;
4187 36         432 my $delimiter = $2;
4188              
4189             # get here document
4190 36 50       94 if ($here_script eq '') {
4191 36         211 $here_script = CORE::substr $_, pos $_;
4192 36         193 $here_script =~ s/.*?\n//oxm;
4193             }
4194 36 50       777 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4195 36         87 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4196 36         148 push @heredoc_delimiter, $delimiter;
4197             }
4198             else {
4199 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4200             }
4201 36         168 return $here_quote;
4202             }
4203              
4204             # <
4205             elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4206 42         74 $slash = 'm//';
4207 42         83 my $here_quote = $1;
4208 42         74 my $delimiter = $2;
4209              
4210             # get here document
4211 42 50       103 if ($here_script eq '') {
4212 42         292 $here_script = CORE::substr $_, pos $_;
4213 42         308 $here_script =~ s/.*?\n//oxm;
4214             }
4215 42 50       606 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4216 42         123 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4217 42         86 push @heredoc_delimiter, $delimiter;
4218             }
4219             else {
4220 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4221             }
4222 42         170 return $here_quote;
4223             }
4224              
4225             # <<`HEREDOC`
4226             elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4227 0         0 $slash = 'm//';
4228 0         0 my $here_quote = $1;
4229 0         0 my $delimiter = $2;
4230              
4231             # get here document
4232 0 0       0 if ($here_script eq '') {
4233 0         0 $here_script = CORE::substr $_, pos $_;
4234 0         0 $here_script =~ s/.*?\n//oxm;
4235             }
4236 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4237 0         0 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4238 0         0 push @heredoc_delimiter, $delimiter;
4239             }
4240             else {
4241 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4242             }
4243 0         0 return $here_quote;
4244             }
4245              
4246             # <<= <=> <= < operator
4247             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4248 11         72 return $1;
4249             }
4250              
4251             #
4252             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4253 0         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         0 return 'Elatin3::glob("' . $1 . '")';
4262             }
4263              
4264             # __DATA__
4265 0         0 elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4266              
4267             # __END__
4268 200         1505 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         0 elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4281              
4282             # \cZ Control-Z
4283 0         0 elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4284              
4285             # any operator before div
4286             elsif (/\G (
4287             -- | \+\+ |
4288             [\)\}\]]
4289              
4290 4824         5980 ) /oxgc) { $slash = 'div'; return $1; }
  4824         21252  
4291              
4292             # yada-yada or triple-dot operator
4293             elsif (/\G (
4294             \.\.\.
4295              
4296 7         9 ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
  7         23  
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 8486         10315 )) /oxgc) { $slash = 'm//'; return $1; }
  8486         37282  
4353              
4354             # other any character
4355 14740         17381 elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
  14740         66378  
4356              
4357             # system error
4358             else {
4359 0         0 die __FILE__, ": Oops, this shouldn't happen!\n";
4360             }
4361             }
4362              
4363             # escape Latin-3 string
4364             sub e_string {
4365 1718     1718 0 3347 my($string) = @_;
4366 1718         1874 my $e_string = '';
4367              
4368 1718         2227 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 1718         16943 my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4375              
4376             # without { ... }
4377 1718 100 66     8278 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4378 1701 50       3712 if ($string !~ /<
4379 1701         4263 return $string;
4380             }
4381             }
4382              
4383             E_STRING_LOOP:
4384 17         69 while ($string !~ /\G \z/oxgc) {
4385 190 50       15219 if (0) {
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
4386             }
4387              
4388             # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Elatin3::PREMATCH()]}
4389 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4390 0         0 $e_string .= q{Elatin3::PREMATCH()};
4391 0         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         0 $e_string .= q{Elatin3::MATCH()};
4397 0         0 $slash = 'div';
4398             }
4399              
4400             # $', ${'} --> $', ${'}
4401             elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4402 0         0 $e_string .= $1;
4403 0         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         0 $e_string .= q{Elatin3::POSTMATCH()};
4409 0         0 $slash = 'div';
4410             }
4411              
4412             # bareword
4413             elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4414 0         0 $e_string .= $1;
4415 0         0 $slash = 'div';
4416             }
4417              
4418             # $0 --> $0
4419             elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4420 0         0 $e_string .= $1;
4421 0         0 $slash = 'div';
4422             }
4423             elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4424 0         0 $e_string .= $1;
4425 0         0 $slash = 'div';
4426             }
4427              
4428             # $$ --> $$
4429             elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4430 0         0 $e_string .= $1;
4431 0         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         0 $e_string .= e_capture($1);
4438 0         0 $slash = 'div';
4439             }
4440             elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4441 0         0 $e_string .= e_capture($1);
4442 0         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         0 $e_string .= e_capture($1.'->'.$2);
4448 0         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         0 $e_string .= e_capture($1.'->'.$2);
4454 0         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         0 $e_string .= e_capture($1);
4460 0         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         0 $e_string .= '${' . $1 . '}';
4466 0         0 $slash = 'div';
4467             }
4468              
4469             # ${ ... }
4470             elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4471 3         11 $e_string .= e_capture($1);
4472 3         20 $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 7         16 $e_string .= $1;
4479 7         23 $slash = 'div';
4480             }
4481             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4482             # $ @ # \ ' " / ? ( ) [ ] < >
4483             elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4484 0         0 $e_string .= $1;
4485 0         0 $slash = 'div';
4486             }
4487              
4488             # subroutines of package Elatin3
4489 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4490 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4491 0         0 elsif ($string =~ /\G \b Latin3::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4492 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4493 0         0 elsif ($string =~ /\G \b Latin3::eval \b /oxgc) { $e_string .= 'eval Latin3::escape'; $slash = 'm//'; }
  0         0  
4494 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4495 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Elatin3::chop'; $slash = 'm//'; }
  0         0  
4496 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4497 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4498 0         0 elsif ($string =~ /\G \b Latin3::index \b /oxgc) { $e_string .= 'Latin3::index'; $slash = 'm//'; }
  0         0  
4499 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Elatin3::index'; $slash = 'm//'; }
  0         0  
4500 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4501 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4502 0         0 elsif ($string =~ /\G \b Latin3::rindex \b /oxgc) { $e_string .= 'Latin3::rindex'; $slash = 'm//'; }
  0         0  
4503 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Elatin3::rindex'; $slash = 'm//'; }
  0         0  
4504 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::lc'; $slash = 'm//'; }
  0         0  
4505 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::lcfirst'; $slash = 'm//'; }
  0         0  
4506 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::uc'; $slash = 'm//'; }
  0         0  
4507 0         0 elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::ucfirst'; $slash = 'm//'; }
  0         0  
4508 0         0 elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::fc'; $slash = 'm//'; }
  0         0  
4509              
4510             # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
4511 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4512 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4513 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4514 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4515 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4516 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4517 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4518              
4519 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4520 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4521 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4522 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4523 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4524 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4525 0         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         0  
4526              
4527             elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
4528 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4529 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4530 0         0 elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
  0         0  
4531 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4532              
4533 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4534 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4535 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::chr'; $slash = 'm//'; }
  0         0  
4536 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4537 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4538 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin3::glob'; $slash = 'm//'; }
  0         0  
4539 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Elatin3::lc_'; $slash = 'm//'; }
  0         0  
4540 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Elatin3::lcfirst_'; $slash = 'm//'; }
  0         0  
4541 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Elatin3::uc_'; $slash = 'm//'; }
  0         0  
4542 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Elatin3::ucfirst_'; $slash = 'm//'; }
  0         0  
4543 0         0 elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Elatin3::fc_'; $slash = 'm//'; }
  0         0  
4544 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4545              
4546 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4547 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4548 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Elatin3::chr_'; $slash = 'm//'; }
  0         0  
4549 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4550 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4551 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Elatin3::glob_'; $slash = 'm//'; }
  0         0  
4552 0         0 elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
  0         0  
4553 0         0 elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
  0         0  
4554             # split
4555             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4556 0         0 $slash = 'm//';
4557              
4558 0         0 my $e = '';
4559 0         0 while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4560 0         0 $e .= $1;
4561             }
4562              
4563             # end of split
4564 0 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          
    0          
4565              
4566             # split scalar value
4567 0         0 elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Elatin3::split' . $e . e_string($1); next E_STRING_LOOP; }
  0         0  
4568              
4569             # split literal space
4570 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4571 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4572 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4573 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4574 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4575 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4576 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4577 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4578 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4579 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4580 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4581 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4582 0         0 elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {' '}; next E_STRING_LOOP; }
  0         0  
4583 0         0 elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Elatin3::split' . $e . qq {" "}; next E_STRING_LOOP; }
  0         0  
4584              
4585             # split qq//
4586             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4587 0 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  
  0         0  
4588             else {
4589 0         0 while ($string !~ /\G \z/oxgc) {
4590 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4591 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq ( ) --> qr ( )
  0         0  
4592 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq { } --> qr { }
  0         0  
4593 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq [ ] --> qr [ ]
  0         0  
4594 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq < > --> qr < >
  0         0  
4595 0         0 elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
  0         0  
4596 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq * * --> qr * *
  0         0  
4597             }
4598 0         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       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  
  0         0  
4605             else {
4606 0         0 while ($string !~ /\G \z/oxgc) {
4607 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4608 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ( )
  0         0  
4609 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr { }
  0         0  
4610 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr [ ]
  0         0  
4611 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr < >
  0         0  
4612 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ' '
  0         0  
4613 0         0 elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
  0         0  
4614 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr * *
  0         0  
4615             }
4616 0         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       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  
  0         0  
4623             else {
4624 0         0 while ($string !~ /\G \z/oxgc) {
4625 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4626 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q ( ) --> qr ( )
  0         0  
4627 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q { } --> qr { }
  0         0  
4628 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q [ ] --> qr [ ]
  0         0  
4629 0         0 elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q < > --> qr < >
  0         0  
4630 0         0 elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
  0         0  
4631 0         0 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q * * --> qr * *
  0         0  
4632             }
4633 0         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       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  
  0         0  
4640             else {
4641 0         0 while ($string !~ /\G \z/oxgc) {
4642 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4643 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ( ) --> qr ( )
  0         0  
4644 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m { } --> qr { }
  0         0  
4645 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m [ ] --> qr [ ]
  0         0  
4646 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m < > --> qr < >
  0         0  
4647 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ' ' --> qr ' '
  0         0  
4648 0         0 elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
  0         0  
4649 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m * * --> qr * *
  0         0  
4650             }
4651 0         0 die __FILE__, ": Search pattern not terminated\n";
4652             }
4653             }
4654              
4655             # split ''
4656             elsif ($string =~ /\G (\') /oxgc) {
4657 0         0 my $q_string = '';
4658 0         0 while ($string !~ /\G \z/oxgc) {
4659 0 0       0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0 0       0  
    0          
    0          
4660 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4661 0         0 elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
  0         0  
4662 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4663             }
4664 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4665             }
4666              
4667             # split ""
4668             elsif ($string =~ /\G (\") /oxgc) {
4669 0         0 my $qq_string = '';
4670 0         0 while ($string !~ /\G \z/oxgc) {
4671 0 0       0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0 0       0  
    0          
    0          
4672 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4673 0         0 elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
  0         0  
4674 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4675             }
4676 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4677             }
4678              
4679             # split //
4680             elsif ($string =~ /\G (\/) /oxgc) {
4681 0         0 my $regexp = '';
4682 0         0 while ($string !~ /\G \z/oxgc) {
4683 0 0       0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0 0       0  
    0          
    0          
4684 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4685 0         0 elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
  0         0  
4686 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4687             }
4688 0         0 die __FILE__, ": Search pattern not terminated\n";
4689             }
4690             }
4691              
4692             # qq//
4693             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4694 0         0 my $ope = $1;
4695 0 0       0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4696 0         0 $e_string .= e_qq($ope,$1,$3,$2);
4697             }
4698             else {
4699 0         0 my $e = '';
4700 0         0 while ($string !~ /\G \z/oxgc) {
4701 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
4702 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4703 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4704 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4705 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
  0         0  
4706 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
  0         0  
4707             }
4708 0         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         0 my $ope = $1;
4715 0 0       0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4716 0         0 $e_string .= e_qq($ope,$1,$3,$2);
4717             }
4718             else {
4719 0         0 my $e = '';
4720 0         0 while ($string !~ /\G \z/oxgc) {
4721 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4722 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4723 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4724 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4725 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4726 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
  0         0  
4727 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
  0         0  
4728             }
4729 0         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         0 my $ope = $1;
4736 0 0       0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4737 0         0 $e_string .= e_q($ope,$1,$3,$2);
4738             }
4739             else {
4740 0         0 my $e = '';
4741 0         0 while ($string !~ /\G \z/oxgc) {
4742 0 0       0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0 0       0  
    0          
    0          
    0          
    0          
4743 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4744 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4745 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4746 0         0 elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
  0         0  
4747 0         0 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q * *
  0         0  
4748             }
4749 0         0 die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4750             }
4751             }
4752              
4753             # ''
4754 0         0 elsif ($string =~ /\G (?
4755              
4756             # ""
4757 0         0 elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4758              
4759             # ``
4760 0         0 elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4761              
4762             # <<>> (a safer ARGV)
4763 0         0 elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4764              
4765             # <<= <=> <= < operator
4766 0         0 elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4767              
4768             #
4769 0         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         0 $e_string .= 'Elatin3::glob("' . $1 . '")';
4774             }
4775              
4776             # << (bit shift) --- not here document
4777 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; $e_string .= $1; }
  0         0  
4778              
4779             # <<'HEREDOC'
4780             elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4781 0         0 $slash = 'm//';
4782 0         0 my $here_quote = $1;
4783 0         0 my $delimiter = $2;
4784              
4785             # get here document
4786 0 0       0 if ($here_script eq '') {
4787 0         0 $here_script = CORE::substr $_, pos $_;
4788 0         0 $here_script =~ s/.*?\n//oxm;
4789             }
4790 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4791 0         0 push @heredoc, $1 . qq{\n$delimiter\n};
4792 0         0 push @heredoc_delimiter, $delimiter;
4793             }
4794             else {
4795 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4796             }
4797 0         0 $e_string .= $here_quote;
4798             }
4799              
4800             # <<\HEREDOC
4801             elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4802 0         0 $slash = 'm//';
4803 0         0 my $here_quote = $1;
4804 0         0 my $delimiter = $2;
4805              
4806             # get here document
4807 0 0       0 if ($here_script eq '') {
4808 0         0 $here_script = CORE::substr $_, pos $_;
4809 0         0 $here_script =~ s/.*?\n//oxm;
4810             }
4811 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4812 0         0 push @heredoc, $1 . qq{\n$delimiter\n};
4813 0         0 push @heredoc_delimiter, $delimiter;
4814             }
4815             else {
4816 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4817             }
4818 0         0 $e_string .= $here_quote;
4819             }
4820              
4821             # <<"HEREDOC"
4822             elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4823 0         0 $slash = 'm//';
4824 0         0 my $here_quote = $1;
4825 0         0 my $delimiter = $2;
4826              
4827             # get here document
4828 0 0       0 if ($here_script eq '') {
4829 0         0 $here_script = CORE::substr $_, pos $_;
4830 0         0 $here_script =~ s/.*?\n//oxm;
4831             }
4832 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4833 0         0 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4834 0         0 push @heredoc_delimiter, $delimiter;
4835             }
4836             else {
4837 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4838             }
4839 0         0 $e_string .= $here_quote;
4840             }
4841              
4842             # <
4843             elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4844 0         0 $slash = 'm//';
4845 0         0 my $here_quote = $1;
4846 0         0 my $delimiter = $2;
4847              
4848             # get here document
4849 0 0       0 if ($here_script eq '') {
4850 0         0 $here_script = CORE::substr $_, pos $_;
4851 0         0 $here_script =~ s/.*?\n//oxm;
4852             }
4853 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4854 0         0 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4855 0         0 push @heredoc_delimiter, $delimiter;
4856             }
4857             else {
4858 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4859             }
4860 0         0 $e_string .= $here_quote;
4861             }
4862              
4863             # <<`HEREDOC`
4864             elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4865 0         0 $slash = 'm//';
4866 0         0 my $here_quote = $1;
4867 0         0 my $delimiter = $2;
4868              
4869             # get here document
4870 0 0       0 if ($here_script eq '') {
4871 0         0 $here_script = CORE::substr $_, pos $_;
4872 0         0 $here_script =~ s/.*?\n//oxm;
4873             }
4874 0 0       0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4875 0         0 push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4876 0         0 push @heredoc_delimiter, $delimiter;
4877             }
4878             else {
4879 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4880             }
4881 0         0 $e_string .= $here_quote;
4882             }
4883              
4884             # any operator before div
4885             elsif ($string =~ /\G (
4886             -- | \+\+ |
4887             [\)\}\]]
4888              
4889 18         33 ) /oxgc) { $slash = 'div'; $e_string .= $1; }
  18         65  
4890              
4891             # yada-yada or triple-dot operator
4892             elsif ($string =~ /\G (
4893             \.\.\.
4894              
4895 0         0 ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
  0         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 31         46 )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
  31         131  
4927              
4928             # other any character
4929 131         420 elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
4930              
4931             # system error
4932             else {
4933 0         0 die __FILE__, ": Oops, this shouldn't happen!\n";
4934             }
4935             }
4936              
4937 17         80 return $e_string;
4938             }
4939              
4940             #
4941             # character class
4942             #
4943             sub character_class {
4944 1914     1914 0 2341 my($char,$modifier) = @_;
4945              
4946 1914 100       2687 if ($char eq '.') {
4947 52 100       95 if ($modifier =~ /s/) {
4948 17         30 return '${Elatin3::dot_s}';
4949             }
4950             else {
4951 35         72 return '${Elatin3::dot}';
4952             }
4953             }
4954             else {
4955 1862         2924 return Elatin3::classic_character_class($char);
4956             }
4957             }
4958              
4959             #
4960             # escape capture ($1, $2, $3, ...)
4961             #
4962             sub e_capture {
4963              
4964 212     212 0 785 return join '', '${', $_[0], '}';
4965             }
4966              
4967             #
4968             # escape transliteration (tr/// or y///)
4969             #
4970             sub e_tr {
4971 3     3 0 10 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
4972 3         4 my $e_tr = '';
4973 3   50     7 $modifier ||= '';
4974              
4975 3         5 $slash = 'div';
4976              
4977             # quote character class 1
4978 3         6 $charclass = q_tr($charclass);
4979              
4980             # quote character class 2
4981 3         6 $charclass2 = q_tr($charclass2);
4982              
4983             # /b /B modifier
4984 3 50       9 if ($modifier =~ tr/bB//d) {
4985 0 0       0 if ($variable eq '') {
4986 0         0 $e_tr = qq{tr$charclass$e$charclass2$modifier};
4987             }
4988             else {
4989 0         0 $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
4990             }
4991             }
4992             else {
4993 3 100       6 if ($variable eq '') {
4994 2         9 $e_tr = qq{Elatin3::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
4995             }
4996             else {
4997 1         7 $e_tr = qq{Elatin3::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
4998             }
4999             }
5000              
5001             # clear tr/// variable
5002 3         3 $tr_variable = '';
5003 3         3 $bind_operator = '';
5004              
5005 3         19 return $e_tr;
5006             }
5007              
5008             #
5009             # quote for escape transliteration (tr/// or y///)
5010             #
5011             sub q_tr {
5012 6     6 0 7 my($charclass) = @_;
5013              
5014             # quote character class
5015 6 50       13 if ($charclass !~ /'/oxms) {
    0          
    0          
    0          
    0          
    0          
5016 6         9 return e_q('', "'", "'", $charclass); # --> q' '
5017             }
5018             elsif ($charclass !~ /\//oxms) {
5019 0         0 return e_q('q', '/', '/', $charclass); # --> q/ /
5020             }
5021             elsif ($charclass !~ /\#/oxms) {
5022 0         0 return e_q('q', '#', '#', $charclass); # --> q# #
5023             }
5024             elsif ($charclass !~ /[\<\>]/oxms) {
5025 0         0 return e_q('q', '<', '>', $charclass); # --> q< >
5026             }
5027             elsif ($charclass !~ /[\(\)]/oxms) {
5028 0         0 return e_q('q', '(', ')', $charclass); # --> q( )
5029             }
5030             elsif ($charclass !~ /[\{\}]/oxms) {
5031 0         0 return e_q('q', '{', '}', $charclass); # --> q{ }
5032             }
5033             else {
5034 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5035 0 0       0 if ($charclass !~ /\Q$char\E/xms) {
5036 0         0 return e_q('q', $char, $char, $charclass);
5037             }
5038             }
5039             }
5040              
5041 0         0 return e_q('q', '{', '}', $charclass);
5042             }
5043              
5044             #
5045             # escape q string (q//, '')
5046             #
5047             sub e_q {
5048 1092     1092 0 2126 my($ope,$delimiter,$end_delimiter,$string) = @_;
5049              
5050 1092         1333 $slash = 'div';
5051              
5052 1092         5942 return join '', $ope, $delimiter, $string, $end_delimiter;
5053             }
5054              
5055             #
5056             # escape qq string (qq//, "", qx//, ``)
5057             #
5058             sub e_qq {
5059 3961     3961 0 7242 my($ope,$delimiter,$end_delimiter,$string) = @_;
5060              
5061 3961         4289 $slash = 'div';
5062              
5063 3961         3720 my $left_e = 0;
5064 3961         3096 my $right_e = 0;
5065              
5066             # split regexp
5067 3961         155723 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 3961         15003 for (my $i=0; $i <= $#char; $i++) {
5084              
5085             # "\L\u" --> "\u\L"
5086 111858 50 33     459853 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 33        
    100          
    100          
    50          
5087 0         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         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 1         11 $char[$i] = Elatin3::octchr($1);
5098             }
5099              
5100             # hexadecimal escape sequence
5101             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5102 1         5 $char[$i] = Elatin3::hexchr($1);
5103             }
5104              
5105             # \N{CHARNAME} --> N{CHARNAME}
5106             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5107 0         0 $char[$i] = $1;
5108             }
5109              
5110 111858 100       1256119 if (0) {
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
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         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5122 484 50       1142 if ($right_e < $left_e) {
5123 0         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         0 $char[$i] = '@{[Elatin3::ucfirst qq<';
5141 0         0 $left_e++;
5142             }
5143             elsif ($char[$i] eq '\l') {
5144 0         0 $char[$i] = '@{[Elatin3::lcfirst qq<';
5145 0         0 $left_e++;
5146             }
5147             elsif ($char[$i] eq '\U') {
5148 0         0 $char[$i] = '@{[Elatin3::uc qq<';
5149 0         0 $left_e++;
5150             }
5151             elsif ($char[$i] eq '\L') {
5152 0         0 $char[$i] = '@{[Elatin3::lc qq<';
5153 0         0 $left_e++;
5154             }
5155             elsif ($char[$i] eq '\F') {
5156 24         27 $char[$i] = '@{[Elatin3::fc qq<';
5157 24         43 $left_e++;
5158             }
5159             elsif ($char[$i] eq '\Q') {
5160 0         0 $char[$i] = '@{[CORE::quotemeta qq<';
5161 0         0 $left_e++;
5162             }
5163             elsif ($char[$i] eq '\E') {
5164 24 50       36 if ($right_e < $left_e) {
5165 24         29 $char[$i] = '>]}';
5166 24         43 $right_e++;
5167             }
5168             else {
5169 0         0 $char[$i] = '';
5170             }
5171             }
5172             elsif ($char[$i] eq '\Q') {
5173 0         0 while (1) {
5174 0 0       0 if (++$i > $#char) {
5175 0         0 last;
5176             }
5177 0 0       0 if ($char[$i] eq '\E') {
5178 0         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 205         355 $char[$i] = e_capture($1);
5199             }
5200             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5201 0         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         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         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         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 44         136 $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 45         130 $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 33         84 $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         0 $char[$i] = e_capture($1);
5241             }
5242             }
5243              
5244             # return string
5245 3961 50       7142 if ($left_e > $right_e) {
5246 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5247             }
5248 3961         38693 return join '', $ope, $delimiter, @char, $end_delimiter;
5249             }
5250              
5251             #
5252             # escape qw string (qw//)
5253             #
5254             sub e_qw {
5255 16     16 0 123 my($ope,$delimiter,$end_delimiter,$string) = @_;
5256              
5257 16         36 $slash = 'div';
5258              
5259             # choice again delimiter
5260 16         277 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
  483         723  
5261 16 50       121 if (not $octet{$end_delimiter}) {
    0          
    0          
    0          
    0          
5262 16         152 return join '', $ope, $delimiter, $string, $end_delimiter;
5263             }
5264             elsif (not $octet{')'}) {
5265 0         0 return join '', $ope, '(', $string, ')';
5266             }
5267             elsif (not $octet{'}'}) {
5268 0         0 return join '', $ope, '{', $string, '}';
5269             }
5270             elsif (not $octet{']'}) {
5271 0         0 return join '', $ope, '[', $string, ']';
5272             }
5273             elsif (not $octet{'>'}) {
5274 0         0 return join '', $ope, '<', $string, '>';
5275             }
5276             else {
5277 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5278 0 0       0 if (not $octet{$char}) {
5279 0         0 return join '', $ope, $char, $string, $char;
5280             }
5281             }
5282             }
5283              
5284             # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5285 0         0 my @string = CORE::split(/\s+/, $string);
5286 0         0 for my $string (@string) {
5287 0         0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5288 0         0 for my $octet (@octet) {
5289 0 0       0 if ($octet =~ /\A (['\\]) \z/oxms) {
5290 0         0 $octet = '\\' . $1;
5291             }
5292             }
5293 0         0 $string = join '', @octet;
5294             }
5295 0         0 return join '', '(', (join ', ', map { "'$_'" } @string), ')';
  0         0  
5296             }
5297              
5298             #
5299             # escape here document (<<"HEREDOC", <
5300             #
5301             sub e_heredoc {
5302 78     78 0 165 my($string) = @_;
5303              
5304 78         99 $slash = 'm//';
5305              
5306 78         280 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5307              
5308 78         97 my $left_e = 0;
5309 78         89 my $right_e = 0;
5310              
5311             # split regexp
5312 78         7209 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 78         421 for (my $i=0; $i <= $#char; $i++) {
5329              
5330             # "\L\u" --> "\u\L"
5331 2882 50 33     10431 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 33        
    100          
    100          
    50          
5332 0         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         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 1         5 $char[$i] = Elatin3::octchr($1);
5343             }
5344              
5345             # hexadecimal escape sequence
5346             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5347 1         4 $char[$i] = Elatin3::hexchr($1);
5348             }
5349              
5350             # \N{CHARNAME} --> N{CHARNAME}
5351             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5352 0         0 $char[$i] = $1;
5353             }
5354              
5355 2882 50       29366 if (0) {
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5356             }
5357              
5358             # \u \l \U \L \F \Q \E
5359 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5360 0 0       0 if ($right_e < $left_e) {
5361 0         0 $char[$i] = '\\' . $char[$i];
5362             }
5363             }
5364             elsif ($char[$i] eq '\u') {
5365 0         0 $char[$i] = '@{[Elatin3::ucfirst qq<';
5366 0         0 $left_e++;
5367             }
5368             elsif ($char[$i] eq '\l') {
5369 0         0 $char[$i] = '@{[Elatin3::lcfirst qq<';
5370 0         0 $left_e++;
5371             }
5372             elsif ($char[$i] eq '\U') {
5373 0         0 $char[$i] = '@{[Elatin3::uc qq<';
5374 0         0 $left_e++;
5375             }
5376             elsif ($char[$i] eq '\L') {
5377 0         0 $char[$i] = '@{[Elatin3::lc qq<';
5378 0         0 $left_e++;
5379             }
5380             elsif ($char[$i] eq '\F') {
5381 0         0 $char[$i] = '@{[Elatin3::fc qq<';
5382 0         0 $left_e++;
5383             }
5384             elsif ($char[$i] eq '\Q') {
5385 0         0 $char[$i] = '@{[CORE::quotemeta qq<';
5386 0         0 $left_e++;
5387             }
5388             elsif ($char[$i] eq '\E') {
5389 0 0       0 if ($right_e < $left_e) {
5390 0         0 $char[$i] = '>]}';
5391 0         0 $right_e++;
5392             }
5393             else {
5394 0         0 $char[$i] = '';
5395             }
5396             }
5397             elsif ($char[$i] eq '\Q') {
5398 0         0 while (1) {
5399 0 0       0 if (++$i > $#char) {
5400 0         0 last;
5401             }
5402 0 0       0 if ($char[$i] eq '\E') {
5403 0         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         0 $char[$i] = e_capture($1);
5424             }
5425             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5426 0         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         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         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         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 8         38 $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 8         43 $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 6         28 $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         0 $char[$i] = e_capture($1);
5466             }
5467             }
5468              
5469             # return string
5470 78 50       164 if ($left_e > $right_e) {
5471 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5472             }
5473 78         666 return join '', @char;
5474             }
5475              
5476             #
5477             # escape regexp (m//, qr//)
5478             #
5479             sub e_qr {
5480 651     651 0 1812 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5481 651   100     2514 $modifier ||= '';
5482              
5483 651         967 $modifier =~ tr/p//d;
5484 651 50       1611 if ($modifier =~ /([adlu])/oxms) {
5485 0         0 my $line = 0;
5486 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5487 0 0       0 if ($filename ne __FILE__) {
5488 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5489 0         0 last;
5490             }
5491             }
5492 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
5493             }
5494              
5495 651         895 $slash = 'div';
5496              
5497             # literal null string pattern
5498 651 100       2044 if ($string eq '') {
    100          
5499 8         10 $modifier =~ tr/bB//d;
5500 8         9 $modifier =~ tr/i//d;
5501 8         53 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 2 50       28 if ($delimiter =~ / [\@:] /oxms) {
5509 0         0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5510 0         0 my %octet = map {$_ => 1} @char;
  0         0  
5511 0 0       0 if (not $octet{')'}) {
    0          
    0          
    0          
5512 0         0 $delimiter = '(';
5513 0         0 $end_delimiter = ')';
5514             }
5515             elsif (not $octet{'}'}) {
5516 0         0 $delimiter = '{';
5517 0         0 $end_delimiter = '}';
5518             }
5519             elsif (not $octet{']'}) {
5520 0         0 $delimiter = '[';
5521 0         0 $end_delimiter = ']';
5522             }
5523             elsif (not $octet{'>'}) {
5524 0         0 $delimiter = '<';
5525 0         0 $end_delimiter = '>';
5526             }
5527             else {
5528 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5529 0 0       0 if (not $octet{$char}) {
5530 0         0 $delimiter = $char;
5531 0         0 $end_delimiter = $char;
5532 0         0 last;
5533             }
5534             }
5535             }
5536             }
5537              
5538 2 50 33     21 if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5539 0         0 return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5540             }
5541             else {
5542 2         16 return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5543             }
5544             }
5545              
5546 641 100       1372 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5547 641         2339 my $metachar = qr/[\@\\|[\]{^]/oxms;
5548              
5549             # split regexp
5550 641         71930 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 641 50       3215 if ($delimiter =~ / [\@:] /oxms) {
5576 0         0 my %octet = map {$_ => 1} @char;
  0         0  
5577 0 0       0 if (not $octet{')'}) {
    0          
    0          
    0          
5578 0         0 $delimiter = '(';
5579 0         0 $end_delimiter = ')';
5580             }
5581             elsif (not $octet{'}'}) {
5582 0         0 $delimiter = '{';
5583 0         0 $end_delimiter = '}';
5584             }
5585             elsif (not $octet{']'}) {
5586 0         0 $delimiter = '[';
5587 0         0 $end_delimiter = ']';
5588             }
5589             elsif (not $octet{'>'}) {
5590 0         0 $delimiter = '<';
5591 0         0 $end_delimiter = '>';
5592             }
5593             else {
5594 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5595 0 0       0 if (not $octet{$char}) {
5596 0         0 $delimiter = $char;
5597 0         0 $end_delimiter = $char;
5598 0         0 last;
5599             }
5600             }
5601             }
5602             }
5603              
5604 641         801 my $left_e = 0;
5605 641         640 my $right_e = 0;
5606 641         1751 for (my $i=0; $i <= $#char; $i++) {
5607              
5608             # "\L\u" --> "\u\L"
5609 1867 50 66     11672 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 66        
    100          
    100          
    100          
    100          
5610 0         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         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 1         5 $char[$i] = Elatin3::octchr($1);
5621             }
5622              
5623             # hexadecimal escape sequence
5624             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5625 1         4 $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 6         17 $char[$i] = $1 . '\\' . $2;
5635             }
5636              
5637             # \p, \P, \X --> p, P, X
5638             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5639 4         10 $char[$i] = $1;
5640             }
5641              
5642 1867 100 100     6236 if (0) {
    100 100        
    100 100        
    100          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
5643             }
5644              
5645             # join separated multiple-octet
5646 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5647 6 50 33     119 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)) {
    50 33        
    50 33        
      33        
      66        
      33        
5648 0         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         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         0 $char[$i] .= join '', splice @char, $i+1, 1;
5655             }
5656             }
5657              
5658             # open character class [...]
5659             elsif ($char[$i] eq '[') {
5660 328         382 my $left = $i;
5661              
5662             # [] make die "Unmatched [] in regexp ...\n"
5663             # (and so on)
5664              
5665 328 100       846 if ($char[$i+1] eq ']') {
5666 3         6 $i++;
5667             }
5668              
5669 328         324 while (1) {
5670 1379 50       1959 if (++$i > $#char) {
5671 0         0 die __FILE__, ": Unmatched [] in regexp\n";
5672             }
5673 1379 100       2205 if ($char[$i] eq ']') {
5674 328         308 my $right = $i;
5675              
5676             # [...]
5677 328 100       1941 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5678 30         72 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);
  90         135  
5679             }
5680             else {
5681 298         1186 splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
5682             }
5683              
5684 328         492 $i = $left;
5685 328         988 last;
5686             }
5687             }
5688             }
5689              
5690             # open character class [^...]
5691             elsif ($char[$i] eq '[^') {
5692 74         82 my $left = $i;
5693              
5694             # [^] make die "Unmatched [] in regexp ...\n"
5695             # (and so on)
5696              
5697 74 100       177 if ($char[$i+1] eq ']') {
5698 4         6 $i++;
5699             }
5700              
5701 74         64 while (1) {
5702 272 50       369 if (++$i > $#char) {
5703 0         0 die __FILE__, ": Unmatched [] in regexp\n";
5704             }
5705 272 100       444 if ($char[$i] eq ']') {
5706 74         70 my $right = $i;
5707              
5708             # [^...]
5709 74 100       429 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5710 30         80 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);
  90         113  
5711             }
5712             else {
5713 44         307 splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5714             }
5715              
5716 74         117 $i = $left;
5717 74         239 last;
5718             }
5719             }
5720             }
5721              
5722             # rewrite character class or escape character
5723             elsif (my $char = character_class($char[$i],$modifier)) {
5724 139         571 $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 20 50       34 if (CORE::length(Elatin3::fc($char[$i])) == 1) {
5730 20         30 $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
5731             }
5732             else {
5733 0         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 1 50       7 if ($right_e < $left_e) {
5740 0         0 $char[$i] = '\\' . $char[$i];
5741             }
5742             }
5743             elsif ($char[$i] eq '\u') {
5744 0         0 $char[$i] = '@{[Elatin3::ucfirst qq<';
5745 0         0 $left_e++;
5746             }
5747             elsif ($char[$i] eq '\l') {
5748 0         0 $char[$i] = '@{[Elatin3::lcfirst qq<';
5749 0         0 $left_e++;
5750             }
5751             elsif ($char[$i] eq '\U') {
5752 1         2 $char[$i] = '@{[Elatin3::uc qq<';
5753 1         7 $left_e++;
5754             }
5755             elsif ($char[$i] eq '\L') {
5756 1         3 $char[$i] = '@{[Elatin3::lc qq<';
5757 1         7 $left_e++;
5758             }
5759             elsif ($char[$i] eq '\F') {
5760 18         24 $char[$i] = '@{[Elatin3::fc qq<';
5761 18         78 $left_e++;
5762             }
5763             elsif ($char[$i] eq '\Q') {
5764 1         3 $char[$i] = '@{[CORE::quotemeta qq<';
5765 1         7 $left_e++;
5766             }
5767             elsif ($char[$i] eq '\E') {
5768 21 50       39 if ($right_e < $left_e) {
5769 21         23 $char[$i] = '>]}';
5770 21         114 $right_e++;
5771             }
5772             else {
5773 0         0 $char[$i] = '';
5774             }
5775             }
5776             elsif ($char[$i] eq '\Q') {
5777 0         0 while (1) {
5778 0 0       0 if (++$i > $#char) {
5779 0         0 last;
5780             }
5781 0 0       0 if ($char[$i] eq '\E') {
5782 0         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       0 if ($ignorecase) {
5792 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5793             }
5794             }
5795             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5796 0 0       0 if ($ignorecase) {
5797 0         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         0 $char[$i] = e_capture($1);
5809 0 0       0 if ($ignorecase) {
5810 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5811             }
5812             }
5813             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5814 0         0 $char[$i] = e_capture($1);
5815 0 0       0 if ($ignorecase) {
5816 0         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         0 $char[$i] = e_capture($1.'->'.$2);
5823 0 0       0 if ($ignorecase) {
5824 0         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         0 $char[$i] = e_capture($1.'->'.$2);
5831 0 0       0 if ($ignorecase) {
5832 0         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         0 $char[$i] = e_capture($1);
5839 0 0       0 if ($ignorecase) {
5840 0         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 8 50       19 if ($ignorecase) {
5847 0         0 $char[$i] = '@{[Elatin3::ignorecase(Elatin3::PREMATCH())]}';
5848             }
5849             else {
5850 8         38 $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 8 50       24 if ($ignorecase) {
5857 0         0 $char[$i] = '@{[Elatin3::ignorecase(Elatin3::MATCH())]}';
5858             }
5859             else {
5860 8         36 $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 6 50       16 if ($ignorecase) {
5867 0         0 $char[$i] = '@{[Elatin3::ignorecase(Elatin3::POSTMATCH())]}';
5868             }
5869             else {
5870 6         25 $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       0 if ($ignorecase) {
5877 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5878             }
5879             }
5880              
5881             # ${ ... }
5882             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5883 0         0 $char[$i] = e_capture($1);
5884 0 0       0 if ($ignorecase) {
5885 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5886             }
5887             }
5888              
5889             # $scalar or @array
5890             elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
5891 21         51 $char[$i] = e_string($char[$i]);
5892 21 100       82 if ($ignorecase) {
5893 11         62 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
5894             }
5895             }
5896              
5897             # quote character before ? + * {
5898             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
5899 138 100 33     1134 if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
    50          
5900             }
5901             elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5902 0         0 my $char = $char[$i-1];
5903 0 0       0 if ($char[$i] eq '{') {
5904 0         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         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 127         788 $char[$i-1] = '(?:' . $char[$i-1] . ')';
5912             }
5913             }
5914             }
5915              
5916             # make regexp string
5917 641         986 $modifier =~ tr/i//d;
5918 641 50       1364 if ($left_e > $right_e) {
5919 0 0 0     0 if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5920 0         0 return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
5921             }
5922             else {
5923 0         0 return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
5924             }
5925             }
5926 641 50 33     4056 if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5927 0         0 return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
5928             }
5929             else {
5930 641         5767 return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5931             }
5932             }
5933              
5934             #
5935             # double quote stuff
5936             #
5937             sub qq_stuff {
5938 180     180 0 186 my($delimiter,$end_delimiter,$stuff) = @_;
5939              
5940             # scalar variable or array variable
5941 180 100       385 if ($stuff =~ /\A [\$\@] /oxms) {
5942 100         358 return $stuff;
5943             }
5944              
5945             # quote by delimiter
5946 80         164 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
  80         231  
5947 80         181 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5948 80 50       125 next if $char eq $delimiter;
5949 80 50       113 next if $char eq $end_delimiter;
5950 80 50       139 if (not $octet{$char}) {
5951 80         378 return join '', 'qq', $char, $stuff, $char;
5952             }
5953             }
5954 0         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 10     10 0 35 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5962 10   50     48 $modifier ||= '';
5963              
5964 10         16 $modifier =~ tr/p//d;
5965 10 50       28 if ($modifier =~ /([adlu])/oxms) {
5966 0         0 my $line = 0;
5967 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5968 0 0       0 if ($filename ne __FILE__) {
5969 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5970 0         0 last;
5971             }
5972             }
5973 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
5974             }
5975              
5976 10         13 $slash = 'div';
5977              
5978             # literal null string pattern
5979 10 100       26 if ($string eq '') {
    50          
5980 8         9 $modifier =~ tr/bB//d;
5981 8         10 $modifier =~ tr/i//d;
5982 8         57 return join '', $ope, $delimiter, $end_delimiter, $modifier;
5983             }
5984              
5985             # with /b /B modifier
5986             elsif ($modifier =~ tr/bB//d) {
5987 0         0 return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
5988             }
5989              
5990             # without /b /B modifier
5991             else {
5992 2         8 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 2     2 0 7 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6001              
6002 2 50       6 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6003              
6004             # split regexp
6005 2         110 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 2         13 for (my $i=0; $i <= $#char; $i++) {
6018 2 50 33     18 if (0) {
    50 33        
    50 33        
    50          
    50          
    50          
6019             }
6020              
6021             # open character class [...]
6022 0         0 elsif ($char[$i] eq '[') {
6023 0         0 my $left = $i;
6024 0 0       0 if ($char[$i+1] eq ']') {
6025 0         0 $i++;
6026             }
6027 0         0 while (1) {
6028 0 0       0 if (++$i > $#char) {
6029 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6030             }
6031 0 0       0 if ($char[$i] eq ']') {
6032 0         0 my $right = $i;
6033              
6034             # [...]
6035 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
6036              
6037 0         0 $i = $left;
6038 0         0 last;
6039             }
6040             }
6041             }
6042              
6043             # open character class [^...]
6044             elsif ($char[$i] eq '[^') {
6045 0         0 my $left = $i;
6046 0 0       0 if ($char[$i+1] eq ']') {
6047 0         0 $i++;
6048             }
6049 0         0 while (1) {
6050 0 0       0 if (++$i > $#char) {
6051 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6052             }
6053 0 0       0 if ($char[$i] eq ']') {
6054 0         0 my $right = $i;
6055              
6056             # [^...]
6057 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6058              
6059 0         0 $i = $left;
6060 0         0 last;
6061             }
6062             }
6063             }
6064              
6065             # escape $ @ / and \
6066             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6067 0         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         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       0 if (CORE::length(Elatin3::fc($char[$i])) == 1) {
6078 0         0 $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
6079             }
6080             else {
6081 0         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       0 if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6088             }
6089             else {
6090 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
6091             }
6092             }
6093             }
6094              
6095 2         6 $delimiter = '/';
6096 2         5 $end_delimiter = '/';
6097              
6098 2         3 $modifier =~ tr/i//d;
6099 2         19 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 0 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6107              
6108             # split regexp
6109 0         0 my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6110              
6111             # unescape character
6112 0         0 for (my $i=0; $i <= $#char; $i++) {
6113 0 0       0 if (0) {
    0          
6114             }
6115              
6116             # remain \\
6117 0         0 elsif ($char[$i] eq '\\\\') {
6118             }
6119              
6120             # escape $ @ / and \
6121             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6122 0         0 $char[$i] = '\\' . $char[$i];
6123             }
6124             }
6125              
6126 0         0 $delimiter = '/';
6127 0         0 $end_delimiter = '/';
6128 0         0 return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6129             }
6130              
6131             #
6132             # escape regexp (s/here//)
6133             #
6134             sub e_s1 {
6135 76     76 0 176 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6136 76   100     290 $modifier ||= '';
6137              
6138 76         113 $modifier =~ tr/p//d;
6139 76 50       217 if ($modifier =~ /([adlu])/oxms) {
6140 0         0 my $line = 0;
6141 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6142 0 0       0 if ($filename ne __FILE__) {
6143 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6144 0         0 last;
6145             }
6146             }
6147 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
6148             }
6149              
6150 76         115 $slash = 'div';
6151              
6152             # literal null string pattern
6153 76 100       298 if ($string eq '') {
    50          
6154 8         9 $modifier =~ tr/bB//d;
6155 8         8 $modifier =~ tr/i//d;
6156 8         68 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       0 if ($delimiter =~ / [\@:] /oxms) {
6164 0         0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
6165 0         0 my %octet = map {$_ => 1} @char;
  0         0  
6166 0 0       0 if (not $octet{')'}) {
    0          
    0          
    0          
6167 0         0 $delimiter = '(';
6168 0         0 $end_delimiter = ')';
6169             }
6170             elsif (not $octet{'}'}) {
6171 0         0 $delimiter = '{';
6172 0         0 $end_delimiter = '}';
6173             }
6174             elsif (not $octet{']'}) {
6175 0         0 $delimiter = '[';
6176 0         0 $end_delimiter = ']';
6177             }
6178             elsif (not $octet{'>'}) {
6179 0         0 $delimiter = '<';
6180 0         0 $end_delimiter = '>';
6181             }
6182             else {
6183 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6184 0 0       0 if (not $octet{$char}) {
6185 0         0 $delimiter = $char;
6186 0         0 $end_delimiter = $char;
6187 0         0 last;
6188             }
6189             }
6190             }
6191             }
6192              
6193 0         0 my $prematch = '';
6194 0         0 return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6195             }
6196              
6197 68 100       181 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6198 68         298 my $metachar = qr/[\@\\|[\]{^]/oxms;
6199              
6200             # split regexp
6201 68         18175 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 68 50       596 if ($delimiter =~ / [\@:] /oxms) {
6231 0         0 my %octet = map {$_ => 1} @char;
  0         0  
6232 0 0       0 if (not $octet{')'}) {
    0          
    0          
    0          
6233 0         0 $delimiter = '(';
6234 0         0 $end_delimiter = ')';
6235             }
6236             elsif (not $octet{'}'}) {
6237 0         0 $delimiter = '{';
6238 0         0 $end_delimiter = '}';
6239             }
6240             elsif (not $octet{']'}) {
6241 0         0 $delimiter = '[';
6242 0         0 $end_delimiter = ']';
6243             }
6244             elsif (not $octet{'>'}) {
6245 0         0 $delimiter = '<';
6246 0         0 $end_delimiter = '>';
6247             }
6248             else {
6249 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6250 0 0       0 if (not $octet{$char}) {
6251 0         0 $delimiter = $char;
6252 0         0 $end_delimiter = $char;
6253 0         0 last;
6254             }
6255             }
6256             }
6257             }
6258              
6259             # count '('
6260 68         130 my $parens = grep { $_ eq '(' } @char;
  253         414  
6261              
6262 68         120 my $left_e = 0;
6263 68         98 my $right_e = 0;
6264 68         232 for (my $i=0; $i <= $#char; $i++) {
6265              
6266             # "\L\u" --> "\u\L"
6267 195 50 33     1460 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 33        
    100          
    100          
    50          
    50          
6268 0         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         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 1         4 $char[$i] = Elatin3::octchr($1);
6279             }
6280              
6281             # hexadecimal escape sequence
6282             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6283 1         5 $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         0 $char[$i] = $1 . '\\' . $2;
6293             }
6294              
6295             # \p, \P, \X --> p, P, X
6296             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6297 0         0 $char[$i] = $1;
6298             }
6299              
6300 195 50 66     794 if (0) {
    100 66        
    50 100        
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
6301             }
6302              
6303             # join separated multiple-octet
6304 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6305 0 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         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         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         0 $char[$i] .= join '', splice @char, $i+1, 1;
6313             }
6314             }
6315              
6316             # open character class [...]
6317             elsif ($char[$i] eq '[') {
6318 13         20 my $left = $i;
6319 13 50       46 if ($char[$i+1] eq ']') {
6320 0         0 $i++;
6321             }
6322 13         13 while (1) {
6323 58 50       86 if (++$i > $#char) {
6324 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6325             }
6326 58 100       91 if ($char[$i] eq ']') {
6327 13         14 my $right = $i;
6328              
6329             # [...]
6330 13 50       84 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6331 0         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         0  
6332             }
6333             else {
6334 13         94 splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
6335             }
6336              
6337 13         27 $i = $left;
6338 13         37 last;
6339             }
6340             }
6341             }
6342              
6343             # open character class [^...]
6344             elsif ($char[$i] eq '[^') {
6345 0         0 my $left = $i;
6346 0 0       0 if ($char[$i+1] eq ']') {
6347 0         0 $i++;
6348             }
6349 0         0 while (1) {
6350 0 0       0 if (++$i > $#char) {
6351 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6352             }
6353 0 0       0 if ($char[$i] eq ']') {
6354 0         0 my $right = $i;
6355              
6356             # [^...]
6357 0 0       0 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6358 0         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         0  
6359             }
6360             else {
6361 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6362             }
6363              
6364 0         0 $i = $left;
6365 0         0 last;
6366             }
6367             }
6368             }
6369              
6370             # rewrite character class or escape character
6371             elsif (my $char = character_class($char[$i],$modifier)) {
6372 7         21 $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 3 50       4 if (CORE::length(Elatin3::fc($char[$i])) == 1) {
6378 3         5 $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
6379             }
6380             else {
6381 0         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       0 if ($right_e < $left_e) {
6388 0         0 $char[$i] = '\\' . $char[$i];
6389             }
6390             }
6391             elsif ($char[$i] eq '\u') {
6392 0         0 $char[$i] = '@{[Elatin3::ucfirst qq<';
6393 0         0 $left_e++;
6394             }
6395             elsif ($char[$i] eq '\l') {
6396 0         0 $char[$i] = '@{[Elatin3::lcfirst qq<';
6397 0         0 $left_e++;
6398             }
6399             elsif ($char[$i] eq '\U') {
6400 0         0 $char[$i] = '@{[Elatin3::uc qq<';
6401 0         0 $left_e++;
6402             }
6403             elsif ($char[$i] eq '\L') {
6404 0         0 $char[$i] = '@{[Elatin3::lc qq<';
6405 0         0 $left_e++;
6406             }
6407             elsif ($char[$i] eq '\F') {
6408 0         0 $char[$i] = '@{[Elatin3::fc qq<';
6409 0         0 $left_e++;
6410             }
6411             elsif ($char[$i] eq '\Q') {
6412 0         0 $char[$i] = '@{[CORE::quotemeta qq<';
6413 0         0 $left_e++;
6414             }
6415             elsif ($char[$i] eq '\E') {
6416 0 0       0 if ($right_e < $left_e) {
6417 0         0 $char[$i] = '>]}';
6418 0         0 $right_e++;
6419             }
6420             else {
6421 0         0 $char[$i] = '';
6422             }
6423             }
6424             elsif ($char[$i] eq '\Q') {
6425 0         0 while (1) {
6426 0 0       0 if (++$i > $#char) {
6427 0         0 last;
6428             }
6429 0 0       0 if ($char[$i] eq '\E') {
6430 0         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       0 if ($ignorecase) {
6470 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6471             }
6472             }
6473             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6474 0 0       0 if ($ignorecase) {
6475 0         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         0 $char[$i] = e_capture($1);
6487 0 0       0 if ($ignorecase) {
6488 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6489             }
6490             }
6491             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6492 0         0 $char[$i] = e_capture($1);
6493 0 0       0 if ($ignorecase) {
6494 0         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         0 $char[$i] = e_capture($1.'->'.$2);
6501 0 0       0 if ($ignorecase) {
6502 0         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         0 $char[$i] = e_capture($1.'->'.$2);
6509 0 0       0 if ($ignorecase) {
6510 0         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         0 $char[$i] = e_capture($1);
6517 0 0       0 if ($ignorecase) {
6518 0         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 4 50       11 if ($ignorecase) {
6525 0         0 $char[$i] = '@{[Elatin3::ignorecase(Elatin3::PREMATCH())]}';
6526             }
6527             else {
6528 4         24 $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 4 50       12 if ($ignorecase) {
6535 0         0 $char[$i] = '@{[Elatin3::ignorecase(Elatin3::MATCH())]}';
6536             }
6537             else {
6538 4         24 $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 3 50       10 if ($ignorecase) {
6545 0         0 $char[$i] = '@{[Elatin3::ignorecase(Elatin3::POSTMATCH())]}';
6546             }
6547             else {
6548 3         17 $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       0 if ($ignorecase) {
6555 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6556             }
6557             }
6558              
6559             # ${ ... }
6560             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6561 0         0 $char[$i] = e_capture($1);
6562 0 0       0 if ($ignorecase) {
6563 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
6564             }
6565             }
6566              
6567             # $scalar or @array
6568             elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6569 4         18 $char[$i] = e_string($char[$i]);
6570 4 50       49 if ($ignorecase) {
6571 0         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 13 50       55 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 13         94 $char[$i-1] = '(?:' . $char[$i-1] . ')';
6581             }
6582             }
6583             }
6584              
6585             # make regexp string
6586 68         133 my $prematch = '';
6587 68         113 $modifier =~ tr/i//d;
6588 68 50       266 if ($left_e > $right_e) {
6589 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6590             }
6591 68         873 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 21     21 0 47 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6599 21   100     74 $modifier ||= '';
6600              
6601 21         29 $modifier =~ tr/p//d;
6602 21 50       67 if ($modifier =~ /([adlu])/oxms) {
6603 0         0 my $line = 0;
6604 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6605 0 0       0 if ($filename ne __FILE__) {
6606 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6607 0         0 last;
6608             }
6609             }
6610 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
6611             }
6612              
6613 21         29 $slash = 'div';
6614              
6615             # literal null string pattern
6616 21 100       61 if ($string eq '') {
    50          
6617 8         12 $modifier =~ tr/bB//d;
6618 8         8 $modifier =~ tr/i//d;
6619 8         70 return join '', $ope, $delimiter, $end_delimiter, $modifier;
6620             }
6621              
6622             # with /b /B modifier
6623             elsif ($modifier =~ tr/bB//d) {
6624 0         0 return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6625             }
6626              
6627             # without /b /B modifier
6628             else {
6629 13         39 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 13     13 0 26 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6638              
6639 13 50       31 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6640              
6641             # split regexp
6642 13         298 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 13         48 for (my $i=0; $i <= $#char; $i++) {
6655 25 50 33     145 if (0) {
    50 33        
    50 66        
    100          
    50          
    50          
6656             }
6657              
6658             # open character class [...]
6659 0         0 elsif ($char[$i] eq '[') {
6660 0         0 my $left = $i;
6661 0 0       0 if ($char[$i+1] eq ']') {
6662 0         0 $i++;
6663             }
6664 0         0 while (1) {
6665 0 0       0 if (++$i > $#char) {
6666 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6667             }
6668 0 0       0 if ($char[$i] eq ']') {
6669 0         0 my $right = $i;
6670              
6671             # [...]
6672 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
6673              
6674 0         0 $i = $left;
6675 0         0 last;
6676             }
6677             }
6678             }
6679              
6680             # open character class [^...]
6681             elsif ($char[$i] eq '[^') {
6682 0         0 my $left = $i;
6683 0 0       0 if ($char[$i+1] eq ']') {
6684 0         0 $i++;
6685             }
6686 0         0 while (1) {
6687 0 0       0 if (++$i > $#char) {
6688 0         0 die __FILE__, ": Unmatched [] in regexp\n";
6689             }
6690 0 0       0 if ($char[$i] eq ']') {
6691 0         0 my $right = $i;
6692              
6693             # [^...]
6694 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6695              
6696 0         0 $i = $left;
6697 0         0 last;
6698             }
6699             }
6700             }
6701              
6702             # escape $ @ / and \
6703             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6704 0         0 $char[$i] = '\\' . $char[$i];
6705             }
6706              
6707             # rewrite character class or escape character
6708             elsif (my $char = character_class($char[$i],$modifier)) {
6709 6         18 $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       0 if (CORE::length(Elatin3::fc($char[$i])) == 1) {
6715 0         0 $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
6716             }
6717             else {
6718 0         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       0 if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6725             }
6726             else {
6727 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
6728             }
6729             }
6730             }
6731              
6732 13         16 $modifier =~ tr/i//d;
6733 13         19 $delimiter = '/';
6734 13         14 $end_delimiter = '/';
6735 13         16 my $prematch = '';
6736 13         116 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 0 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6744              
6745             # split regexp
6746 0         0 my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6747              
6748             # unescape character
6749 0         0 for (my $i=0; $i <= $#char; $i++) {
6750 0 0       0 if (0) {
    0          
6751             }
6752              
6753             # remain \\
6754 0         0 elsif ($char[$i] eq '\\\\') {
6755             }
6756              
6757             # escape $ @ / and \
6758             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6759 0         0 $char[$i] = '\\' . $char[$i];
6760             }
6761             }
6762              
6763 0         0 $delimiter = '/';
6764 0         0 $end_delimiter = '/';
6765 0         0 my $prematch = '';
6766 0         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 16     16 0 28 my($ope,$delimiter,$end_delimiter,$string) = @_;
6774              
6775 16         25 $slash = 'div';
6776              
6777 16         132 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
6778 16         230 for (my $i=0; $i <= $#char; $i++) {
6779 9 100       35 if (0) {
    100          
6780             }
6781              
6782             # not escape \\
6783 0         0 elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
6784             }
6785              
6786             # escape $ @ / and \
6787             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6788 5         15 $char[$i] = '\\' . $char[$i];
6789             }
6790             }
6791              
6792 16         65 return join '', $ope, $delimiter, @char, $end_delimiter;
6793             }
6794              
6795             #
6796             # escape regexp (s/here/and here/modifier)
6797             #
6798             sub e_sub {
6799 97     97 0 549 my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
6800 97   100     390 $modifier ||= '';
6801              
6802 97         179 $modifier =~ tr/p//d;
6803 97 50       294 if ($modifier =~ /([adlu])/oxms) {
6804 0         0 my $line = 0;
6805 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6806 0 0       0 if ($filename ne __FILE__) {
6807 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6808 0         0 last;
6809             }
6810             }
6811 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
6812             }
6813              
6814 97 100       245 if ($variable eq '') {
6815 36         52 $variable = '$_';
6816 36         50 $bind_operator = ' =~ ';
6817             }
6818              
6819 97         131 $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 97         143 my $e_modifier = $modifier =~ tr/e//d;
6837 97         147 my $r_modifier = $modifier =~ tr/r//d;
6838              
6839 97         129 my $my = '';
6840 97 50       258 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
6841 0         0 $my = $variable;
6842 0         0 $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
6843 0         0 $variable =~ s/ = .+ \z//oxms;
6844             }
6845              
6846 97         228 (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
6847 97         183 $variable_basename =~ s/ \s+ \z//oxms;
6848              
6849             # quote replacement string
6850 97         176 my $e_replacement = '';
6851 97 100       222 if ($e_modifier >= 1) {
6852 17         39 $e_replacement = e_qq('', '', '', $replacement);
6853 17         26 $e_modifier--;
6854             }
6855             else {
6856 80 100       185 if ($delimiter2 eq "'") {
6857 16         43 $e_replacement = e_s2_q('qq', '/', '/', $replacement);
6858             }
6859             else {
6860 64         169 $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
6861             }
6862             }
6863              
6864 97         151 my $sub = '';
6865              
6866             # with /r
6867 97 100       224 if ($r_modifier) {
6868 8 100       16 if (0) {
6869             }
6870              
6871             # s///gr without multibyte anchoring
6872 0         0 elsif ($modifier =~ /g/oxms) {
6873 4 50       16 $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 4         5 my $prematch = q{$`};
6891              
6892 4 50       10 $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 8 50       22 if ($bind_operator =~ / !~ /oxms) {
6910 0         0 $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
6911             }
6912             }
6913              
6914             # without /r
6915             else {
6916 89 100       233 if (0) {
6917             }
6918              
6919             # s///g without multibyte anchoring
6920 0         0 elsif ($modifier =~ /g/oxms) {
6921 22 100       120 $sub = sprintf(
    100          
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 67         94 my $prematch = q{$`};
6942              
6943 67 100       430 $sub = sprintf(
    100          
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 97 50       290 if ($my ne '') {
6969 0         0 $sub = "($my, $sub)[1]";
6970             }
6971              
6972             # clear s/// variable
6973 97         149 $sub_variable = '';
6974 97         123 $bind_operator = '';
6975              
6976 97         821 return $sub;
6977             }
6978              
6979             #
6980             # escape regexp of split qr//
6981             #
6982             sub e_split {
6983 74     74 0 264 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6984 74   100     394 $modifier ||= '';
6985              
6986 74         125 $modifier =~ tr/p//d;
6987 74 50       345 if ($modifier =~ /([adlu])/oxms) {
6988 0         0 my $line = 0;
6989 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6990 0 0       0 if ($filename ne __FILE__) {
6991 0         0 $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6992 0         0 last;
6993             }
6994             }
6995 0         0 die qq{Unsupported modifier "$1" used at line $line.\n};
6996             }
6997              
6998 74         131 $slash = 'div';
6999              
7000             # /b /B modifier
7001 74 50       178 if ($modifier =~ tr/bB//d) {
7002 0         0 return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7003             }
7004              
7005 74 50       193 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7006 74         402 my $metachar = qr/[\@\\|[\]{^]/oxms;
7007              
7008             # split regexp
7009 74         10694 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 74         342 my $left_e = 0;
7034 74         92 my $right_e = 0;
7035 74         362 for (my $i=0; $i <= $#char; $i++) {
7036              
7037             # "\L\u" --> "\u\L"
7038 249 50 33     1660 if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
    50 33        
    100          
    100          
    50          
    50          
7039 0         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         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 1         3 $char[$i] = Elatin3::octchr($1);
7050             }
7051              
7052             # hexadecimal escape sequence
7053             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7054 1         4 $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         0 $char[$i] = $1 . '\\' . $2;
7064             }
7065              
7066             # \p, \P, \X --> p, P, X
7067             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7068 0         0 $char[$i] = $1;
7069             }
7070              
7071 249 50 100     894 if (0) {
    100 33        
    50 33        
    100 100        
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
7072             }
7073              
7074             # join separated multiple-octet
7075 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7076 0 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         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         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         0 $char[$i] .= join '', splice @char, $i+1, 1;
7084             }
7085             }
7086              
7087             # open character class [...]
7088             elsif ($char[$i] eq '[') {
7089 3         5 my $left = $i;
7090 3 50       10 if ($char[$i+1] eq ']') {
7091 0         0 $i++;
7092             }
7093 3         4 while (1) {
7094 7 50       21 if (++$i > $#char) {
7095 0         0 die __FILE__, ": Unmatched [] in regexp\n";
7096             }
7097 7 100       12 if ($char[$i] eq ']') {
7098 3         3 my $right = $i;
7099              
7100             # [...]
7101 3 50       23 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7102 0         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         0  
7103             }
7104             else {
7105 3         17 splice @char, $left, $right-$left+1, Elatin3::charlist_qr(@char[$left+1..$right-1], $modifier);
7106             }
7107              
7108 3         5 $i = $left;
7109 3         8 last;
7110             }
7111             }
7112             }
7113              
7114             # open character class [^...]
7115             elsif ($char[$i] eq '[^') {
7116 0         0 my $left = $i;
7117 0 0       0 if ($char[$i+1] eq ']') {
7118 0         0 $i++;
7119             }
7120 0         0 while (1) {
7121 0 0       0 if (++$i > $#char) {
7122 0         0 die __FILE__, ": Unmatched [] in regexp\n";
7123             }
7124 0 0       0 if ($char[$i] eq ']') {
7125 0         0 my $right = $i;
7126              
7127             # [^...]
7128 0 0       0 if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7129 0         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         0  
7130             }
7131             else {
7132 0         0 splice @char, $left, $right-$left+1, Elatin3::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7133             }
7134              
7135 0         0 $i = $left;
7136 0         0 last;
7137             }
7138             }
7139             }
7140              
7141             # rewrite character class or escape character
7142             elsif (my $char = character_class($char[$i],$modifier)) {
7143 1         4 $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 7         49 $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       0 if (CORE::length(Elatin3::fc($char[$i])) == 1) {
7166 0         0 $char[$i] = '[' . Elatin3::uc($char[$i]) . Elatin3::fc($char[$i]) . ']';
7167             }
7168             else {
7169 0         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       0 if ($right_e < $left_e) {
7176 0         0 $char[$i] = '\\' . $char[$i];
7177             }
7178             }
7179             elsif ($char[$i] eq '\u') {
7180 0         0 $char[$i] = '@{[Elatin3::ucfirst qq<';
7181 0         0 $left_e++;
7182             }
7183             elsif ($char[$i] eq '\l') {
7184 0         0 $char[$i] = '@{[Elatin3::lcfirst qq<';
7185 0         0 $left_e++;
7186             }
7187             elsif ($char[$i] eq '\U') {
7188 0         0 $char[$i] = '@{[Elatin3::uc qq<';
7189 0         0 $left_e++;
7190             }
7191             elsif ($char[$i] eq '\L') {
7192 0         0 $char[$i] = '@{[Elatin3::lc qq<';
7193 0         0 $left_e++;
7194             }
7195             elsif ($char[$i] eq '\F') {
7196 0         0 $char[$i] = '@{[Elatin3::fc qq<';
7197 0         0 $left_e++;
7198             }
7199             elsif ($char[$i] eq '\Q') {
7200 0         0 $char[$i] = '@{[CORE::quotemeta qq<';
7201 0         0 $left_e++;
7202             }
7203             elsif ($char[$i] eq '\E') {
7204 0 0       0 if ($right_e < $left_e) {
7205 0         0 $char[$i] = '>]}';
7206 0         0 $right_e++;
7207             }
7208             else {
7209 0         0 $char[$i] = '';
7210             }
7211             }
7212             elsif ($char[$i] eq '\Q') {
7213 0         0 while (1) {
7214 0 0       0 if (++$i > $#char) {
7215 0         0 last;
7216             }
7217 0 0       0 if ($char[$i] eq '\E') {
7218 0         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       0 if ($ignorecase) {
7228 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7229             }
7230             }
7231             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7232 0 0       0 if ($ignorecase) {
7233 0         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         0 $char[$i] = e_capture($1);
7245 0 0       0 if ($ignorecase) {
7246 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7247             }
7248             }
7249             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7250 0         0 $char[$i] = e_capture($1);
7251 0 0       0 if ($ignorecase) {
7252 0         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         0 $char[$i] = e_capture($1.'->'.$2);
7259 0 0       0 if ($ignorecase) {
7260 0         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         0 $char[$i] = e_capture($1.'->'.$2);
7267 0 0       0 if ($ignorecase) {
7268 0         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         0 $char[$i] = e_capture($1);
7275 0 0       0 if ($ignorecase) {
7276 0         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 12 50       22 if ($ignorecase) {
7283 0         0 $char[$i] = '@{[Elatin3::ignorecase(Elatin3::PREMATCH())]}';
7284             }
7285             else {
7286 12         84 $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 12 50       51 if ($ignorecase) {
7293 0         0 $char[$i] = '@{[Elatin3::ignorecase(Elatin3::MATCH())]}';
7294             }
7295             else {
7296 12         88 $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 9 50       15 if ($ignorecase) {
7303 0         0 $char[$i] = '@{[Elatin3::ignorecase(Elatin3::POSTMATCH())]}';
7304             }
7305             else {
7306 9         60 $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       0 if ($ignorecase) {
7313 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $1 . ')]}';
7314             }
7315             }
7316              
7317             # ${ ... }
7318             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7319 0         0 $char[$i] = e_capture($1);
7320 0 0       0 if ($ignorecase) {
7321 0         0 $char[$i] = '@{[Elatin3::ignorecase(' . $char[$i] . ')]}';
7322             }
7323             }
7324              
7325             # $scalar or @array
7326             elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7327 3         12 $char[$i] = e_string($char[$i]);
7328 3 50       32 if ($ignorecase) {
7329 0         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 1 50       7 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         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
7339             }
7340             }
7341             }
7342              
7343             # make regexp string
7344 74         128 $modifier =~ tr/i//d;
7345 74 50       184 if ($left_e > $right_e) {
7346 0         0 return join '', 'Elatin3::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7347             }
7348 74         803 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__