File Coverage

blib/lib/Elatin1.pm
Criterion Covered Total %
statement 905 3194 28.3
branch 968 2740 35.3
condition 98 355 27.6
subroutine 52 110 47.2
pod 7 74 9.4
total 2030 6473 31.3


line stmt bran cond sub pod time code
1             package Elatin1;
2 204     204   1124 use strict;
  204         356  
  204         6571  
3             ######################################################################
4             #
5             # Elatin1 - Run-time routines for Latin1.pm
6             #
7             # http://search.cpan.org/dist/Char-Latin1/
8             #
9             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
10             ######################################################################
11              
12 204     204   2737 use 5.00503; # Galapagos Consensus 1998 for primetools
  204         584  
13             # use 5.008001; # Lancaster Consensus 2013 for toolchains
14              
15             # 12.3. Delaying use Until Runtime
16             # in Chapter 12. Packages, Libraries, and Modules
17             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
18             # (and so on)
19              
20             # Version numbers should be boring
21             # http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
22             # For the impatient, the disinterested or those who just want to follow
23             # a recipe, my advice for all modules is this:
24             # our $VERSION = "0.001"; # or "0.001_001" for a dev release
25             # $VERSION = eval $VERSION; # No!! because '1.10' makes '1.1'
26              
27 204     204   1070 use vars qw($VERSION);
  204         387  
  204         32387  
28             $VERSION = '1.13';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 204 50   204   1650 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 204         419 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 204         33324 if (CORE::ord('A') != 0x41) {
39             die __FILE__, ": is not US-ASCII script (must be US-ASCII script).\n";
40             }
41             }
42              
43             BEGIN {
44              
45             # instead of utf8.pm
46 204     204   13915 CORE::eval q{
  204     204   1212  
  204     64   379  
  204         24596  
  0         0  
  0         0  
  0         0  
  0         0  
47             no warnings qw(redefine);
48             *utf8::upgrade = sub { CORE::length $_[0] };
49             *utf8::downgrade = sub { 1 };
50             *utf8::encode = sub { };
51             *utf8::decode = sub { 1 };
52             *utf8::is_utf8 = sub { };
53             *utf8::valid = sub { 1 };
54             };
55 204 50       78705 if ($@) {
56 0         0 *utf8::upgrade = sub { CORE::length $_[0] };
  0         0  
57 0         0 *utf8::downgrade = sub { 1 };
  0         0  
58 0         0 *utf8::encode = sub { };
59 0         0 *utf8::decode = sub { 1 };
  0         0  
60 0         0 *utf8::is_utf8 = sub { };
61 0         0 *utf8::valid = sub { 1 };
  0         0  
62             }
63             }
64              
65             # instead of Symbol.pm
66 0         0 BEGIN {
67             sub gensym () {
68 0     0 0 0 return \do { local *_ };
  0         0  
69             }
70              
71             sub qualify ($$) {
72 0     0 0 0 my($name) = @_;
73              
74 0 0       0 if (ref $name) {
    0          
    0          
    0          
    0          
    0          
    0          
75 0         0 return $name;
76             }
77             elsif (Elatin1::index($name,'::') >= 0) {
78 0         0 return $name;
79             }
80             elsif (Elatin1::index($name,"'") >= 0) {
81 0         0 return $name;
82             }
83              
84             # special character, "^xyz"
85             elsif ($name =~ /\A \^ [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+ \z/x) {
86              
87             # RGS 2001-11-05 : translate leading ^X to control-char
88 0         0 $name =~ s{\A \^ ([ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]) }{'qq(\c'.$1.')'}xee;
  0         0  
89 0         0 return 'main::' . $name;
90             }
91              
92             # Global names
93             elsif ($name =~ /\A (?: ARGV | ARGVOUT | ENV | INC | SIG | STDERR | STDIN | STDOUT ) \z/x) {
94 0         0 return 'main::' . $name;
95             }
96              
97             # or other
98             elsif ($name =~ /\A [^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz] \z/x) {
99 0         0 return 'main::' . $name;
100             }
101              
102             elsif (defined $_[1]) {
103 0         0 return $_[1] . '::' . $name;
104             }
105             else {
106 0         0 return (caller)[0] . '::' . $name;
107             }
108             }
109              
110             sub qualify_to_ref ($;$) {
111 0 0   0 0 0 if (defined $_[1]) {
112 204     204   1472 no strict qw(refs);
  204         366  
  204         14741  
113 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
114             }
115             else {
116 204     204   1418 no strict qw(refs);
  204     0   369  
  204         39092  
117 0         0 return \*{ qualify $_[0], (caller)[0] };
  0         0  
118             }
119             }
120             }
121              
122             # P.714 29.2.39. flock
123             # in Chapter 29: Functions
124             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
125              
126             # P.863 flock
127             # in Chapter 27: Functions
128             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
129              
130             sub LOCK_SH() {1}
131             sub LOCK_EX() {2}
132             sub LOCK_UN() {8}
133             sub LOCK_NB() {4}
134              
135             # instead of Carp.pm
136             sub carp;
137             sub croak;
138             sub cluck;
139             sub confess;
140              
141             # 6.18. Matching Multiple-Byte Characters
142             # in Chapter 6. Pattern Matching
143             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
144             # (and so on)
145              
146             # regexp of character
147             my $your_char = q{[\x00-\xFF]};
148 204     204   1276 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  204         446  
  204         16068  
149 204     204   1347 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  204         369  
  204         333531  
150              
151             #
152             # Latin-1 character range per length
153             #
154             my %range_tr = ();
155              
156             #
157             # Latin-1 case conversion
158             #
159             my %lc = ();
160             @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)} =
161             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);
162             my %uc = ();
163             @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)} =
164             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);
165             my %fc = ();
166             @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)} =
167             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);
168              
169             if (0) {
170             }
171              
172             elsif (__PACKAGE__ =~ / \b Elatin1 \z/oxms) {
173             %range_tr = (
174             1 => [ [0x00..0xFF],
175             ],
176             );
177              
178             %lc = (%lc,
179             "\xC0" => "\xE0", # LATIN LETTER A WITH GRAVE
180             "\xC1" => "\xE1", # LATIN LETTER A WITH ACUTE
181             "\xC2" => "\xE2", # LATIN LETTER A WITH CIRCUMFLEX
182             "\xC3" => "\xE3", # LATIN LETTER A WITH TILDE
183             "\xC4" => "\xE4", # LATIN LETTER A WITH DIAERESIS
184             "\xC5" => "\xE5", # LATIN LETTER A WITH RING ABOVE
185             "\xC6" => "\xE6", # LATIN LETTER AE
186             "\xC7" => "\xE7", # LATIN LETTER C WITH CEDILLA
187             "\xC8" => "\xE8", # LATIN LETTER E WITH GRAVE
188             "\xC9" => "\xE9", # LATIN LETTER E WITH ACUTE
189             "\xCA" => "\xEA", # LATIN LETTER E WITH CIRCUMFLEX
190             "\xCB" => "\xEB", # LATIN LETTER E WITH DIAERESIS
191             "\xCC" => "\xEC", # LATIN LETTER I WITH GRAVE
192             "\xCD" => "\xED", # LATIN LETTER I WITH ACUTE
193             "\xCE" => "\xEE", # LATIN LETTER I WITH CIRCUMFLEX
194             "\xCF" => "\xEF", # LATIN LETTER I WITH DIAERESIS
195             "\xD0" => "\xF0", # LATIN LETTER ETH (Icelandic)
196             "\xD1" => "\xF1", # LATIN LETTER N WITH TILDE
197             "\xD2" => "\xF2", # LATIN LETTER O WITH GRAVE
198             "\xD3" => "\xF3", # LATIN LETTER O WITH ACUTE
199             "\xD4" => "\xF4", # LATIN LETTER O WITH CIRCUMFLEX
200             "\xD5" => "\xF5", # LATIN LETTER O WITH TILDE
201             "\xD6" => "\xF6", # LATIN LETTER O WITH DIAERESIS
202             "\xD8" => "\xF8", # LATIN LETTER O WITH STROKE
203             "\xD9" => "\xF9", # LATIN LETTER U WITH GRAVE
204             "\xDA" => "\xFA", # LATIN LETTER U WITH ACUTE
205             "\xDB" => "\xFB", # LATIN LETTER U WITH CIRCUMFLEX
206             "\xDC" => "\xFC", # LATIN LETTER U WITH DIAERESIS
207             "\xDD" => "\xFD", # LATIN LETTER Y WITH ACUTE
208             "\xDE" => "\xFE", # LATIN LETTER THORN (Icelandic)
209             );
210              
211             %uc = (%uc,
212             "\xE0" => "\xC0", # LATIN LETTER A WITH GRAVE
213             "\xE1" => "\xC1", # LATIN LETTER A WITH ACUTE
214             "\xE2" => "\xC2", # LATIN LETTER A WITH CIRCUMFLEX
215             "\xE3" => "\xC3", # LATIN LETTER A WITH TILDE
216             "\xE4" => "\xC4", # LATIN LETTER A WITH DIAERESIS
217             "\xE5" => "\xC5", # LATIN LETTER A WITH RING ABOVE
218             "\xE6" => "\xC6", # LATIN LETTER AE
219             "\xE7" => "\xC7", # LATIN LETTER C WITH CEDILLA
220             "\xE8" => "\xC8", # LATIN LETTER E WITH GRAVE
221             "\xE9" => "\xC9", # LATIN LETTER E WITH ACUTE
222             "\xEA" => "\xCA", # LATIN LETTER E WITH CIRCUMFLEX
223             "\xEB" => "\xCB", # LATIN LETTER E WITH DIAERESIS
224             "\xEC" => "\xCC", # LATIN LETTER I WITH GRAVE
225             "\xED" => "\xCD", # LATIN LETTER I WITH ACUTE
226             "\xEE" => "\xCE", # LATIN LETTER I WITH CIRCUMFLEX
227             "\xEF" => "\xCF", # LATIN LETTER I WITH DIAERESIS
228             "\xF0" => "\xD0", # LATIN LETTER ETH (Icelandic)
229             "\xF1" => "\xD1", # LATIN LETTER N WITH TILDE
230             "\xF2" => "\xD2", # LATIN LETTER O WITH GRAVE
231             "\xF3" => "\xD3", # LATIN LETTER O WITH ACUTE
232             "\xF4" => "\xD4", # LATIN LETTER O WITH CIRCUMFLEX
233             "\xF5" => "\xD5", # LATIN LETTER O WITH TILDE
234             "\xF6" => "\xD6", # LATIN LETTER O WITH DIAERESIS
235             "\xF8" => "\xD8", # LATIN LETTER O WITH STROKE
236             "\xF9" => "\xD9", # LATIN LETTER U WITH GRAVE
237             "\xFA" => "\xDA", # LATIN LETTER U WITH ACUTE
238             "\xFB" => "\xDB", # LATIN LETTER U WITH CIRCUMFLEX
239             "\xFC" => "\xDC", # LATIN LETTER U WITH DIAERESIS
240             "\xFD" => "\xDD", # LATIN LETTER Y WITH ACUTE
241             "\xFE" => "\xDE", # LATIN LETTER THORN (Icelandic)
242             );
243              
244             %fc = (%fc,
245             "\xC0" => "\xE0", # LATIN CAPITAL LETTER A WITH GRAVE --> LATIN SMALL LETTER A WITH GRAVE
246             "\xC1" => "\xE1", # LATIN CAPITAL LETTER A WITH ACUTE --> LATIN SMALL LETTER A WITH ACUTE
247             "\xC2" => "\xE2", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX --> LATIN SMALL LETTER A WITH CIRCUMFLEX
248             "\xC3" => "\xE3", # LATIN CAPITAL LETTER A WITH TILDE --> LATIN SMALL LETTER A WITH TILDE
249             "\xC4" => "\xE4", # LATIN CAPITAL LETTER A WITH DIAERESIS --> LATIN SMALL LETTER A WITH DIAERESIS
250             "\xC5" => "\xE5", # LATIN CAPITAL LETTER A WITH RING ABOVE --> LATIN SMALL LETTER A WITH RING ABOVE
251             "\xC6" => "\xE6", # LATIN CAPITAL LETTER AE --> LATIN SMALL LETTER AE
252             "\xC7" => "\xE7", # LATIN CAPITAL LETTER C WITH CEDILLA --> LATIN SMALL LETTER C WITH CEDILLA
253             "\xC8" => "\xE8", # LATIN CAPITAL LETTER E WITH GRAVE --> LATIN SMALL LETTER E WITH GRAVE
254             "\xC9" => "\xE9", # LATIN CAPITAL LETTER E WITH ACUTE --> LATIN SMALL LETTER E WITH ACUTE
255             "\xCA" => "\xEA", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX --> LATIN SMALL LETTER E WITH CIRCUMFLEX
256             "\xCB" => "\xEB", # LATIN CAPITAL LETTER E WITH DIAERESIS --> LATIN SMALL LETTER E WITH DIAERESIS
257             "\xCC" => "\xEC", # LATIN CAPITAL LETTER I WITH GRAVE --> LATIN SMALL LETTER I WITH GRAVE
258             "\xCD" => "\xED", # LATIN CAPITAL LETTER I WITH ACUTE --> LATIN SMALL LETTER I WITH ACUTE
259             "\xCE" => "\xEE", # LATIN CAPITAL LETTER I WITH CIRCUMFLEX --> LATIN SMALL LETTER I WITH CIRCUMFLEX
260             "\xCF" => "\xEF", # LATIN CAPITAL LETTER I WITH DIAERESIS --> LATIN SMALL LETTER I WITH DIAERESIS
261             "\xD0" => "\xF0", # LATIN CAPITAL LETTER ETH --> LATIN SMALL LETTER ETH
262             "\xD1" => "\xF1", # LATIN CAPITAL LETTER N WITH TILDE --> LATIN SMALL LETTER N WITH TILDE
263             "\xD2" => "\xF2", # LATIN CAPITAL LETTER O WITH GRAVE --> LATIN SMALL LETTER O WITH GRAVE
264             "\xD3" => "\xF3", # LATIN CAPITAL LETTER O WITH ACUTE --> LATIN SMALL LETTER O WITH ACUTE
265             "\xD4" => "\xF4", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX --> LATIN SMALL LETTER O WITH CIRCUMFLEX
266             "\xD5" => "\xF5", # LATIN CAPITAL LETTER O WITH TILDE --> LATIN SMALL LETTER O WITH TILDE
267             "\xD6" => "\xF6", # LATIN CAPITAL LETTER O WITH DIAERESIS --> LATIN SMALL LETTER O WITH DIAERESIS
268             "\xD8" => "\xF8", # LATIN CAPITAL LETTER O WITH STROKE --> LATIN SMALL LETTER O WITH STROKE
269             "\xD9" => "\xF9", # LATIN CAPITAL LETTER U WITH GRAVE --> LATIN SMALL LETTER U WITH GRAVE
270             "\xDA" => "\xFA", # LATIN CAPITAL LETTER U WITH ACUTE --> LATIN SMALL LETTER U WITH ACUTE
271             "\xDB" => "\xFB", # LATIN CAPITAL LETTER U WITH CIRCUMFLEX --> LATIN SMALL LETTER U WITH CIRCUMFLEX
272             "\xDC" => "\xFC", # LATIN CAPITAL LETTER U WITH DIAERESIS --> LATIN SMALL LETTER U WITH DIAERESIS
273             "\xDD" => "\xFD", # LATIN CAPITAL LETTER Y WITH ACUTE --> LATIN SMALL LETTER Y WITH ACUTE
274             "\xDE" => "\xFE", # LATIN CAPITAL LETTER THORN --> LATIN SMALL LETTER THORN
275             "\xDF" => "\x73\x73", # LATIN SMALL LETTER SHARP S --> LATIN SMALL LETTER S, LATIN SMALL LETTER S
276             );
277             }
278              
279             else {
280             croak "Don't know my package name '@{[__PACKAGE__]}'";
281             }
282              
283             #
284             # @ARGV wildcard globbing
285             #
286             sub import {
287              
288 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
289 0         0 my @argv = ();
290 0         0 for (@ARGV) {
291              
292             # has space
293 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
294 0 0       0 if (my @glob = Elatin1::glob(qq{"$_"})) {
295 0         0 push @argv, @glob;
296             }
297             else {
298 0         0 push @argv, $_;
299             }
300             }
301              
302             # has wildcard metachar
303             elsif (/\A (?:$q_char)*? [*?] /oxms) {
304 0 0       0 if (my @glob = Elatin1::glob($_)) {
305 0         0 push @argv, @glob;
306             }
307             else {
308 0         0 push @argv, $_;
309             }
310             }
311              
312             # no wildcard globbing
313             else {
314 0         0 push @argv, $_;
315             }
316             }
317 0         0 @ARGV = @argv;
318             }
319              
320 0         0 *Char::ord = \&Latin1::ord;
321 0         0 *Char::ord_ = \&Latin1::ord_;
322 0         0 *Char::reverse = \&Latin1::reverse;
323 0         0 *Char::getc = \&Latin1::getc;
324 0         0 *Char::length = \&Latin1::length;
325 0         0 *Char::substr = \&Latin1::substr;
326 0         0 *Char::index = \&Latin1::index;
327 0         0 *Char::rindex = \&Latin1::rindex;
328 0         0 *Char::eval = \&Latin1::eval;
329 0         0 *Char::escape = \&Latin1::escape;
330 0         0 *Char::escape_token = \&Latin1::escape_token;
331 0         0 *Char::escape_script = \&Latin1::escape_script;
332             }
333              
334             # P.230 Care with Prototypes
335             # in Chapter 6: Subroutines
336             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
337             #
338             # If you aren't careful, you can get yourself into trouble with prototypes.
339             # But if you are careful, you can do a lot of neat things with them. This is
340             # all very powerful, of course, and should only be used in moderation to make
341             # the world a better place.
342              
343             # P.332 Care with Prototypes
344             # in Chapter 7: Subroutines
345             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
346             #
347             # If you aren't careful, you can get yourself into trouble with prototypes.
348             # But if you are careful, you can do a lot of neat things with them. This is
349             # all very powerful, of course, and should only be used in moderation to make
350             # the world a better place.
351              
352             #
353             # Prototypes of subroutines
354             #
355       0     sub unimport {}
356             sub Elatin1::split(;$$$);
357             sub Elatin1::tr($$$$;$);
358             sub Elatin1::chop(@);
359             sub Elatin1::index($$;$);
360             sub Elatin1::rindex($$;$);
361             sub Elatin1::lcfirst(@);
362             sub Elatin1::lcfirst_();
363             sub Elatin1::lc(@);
364             sub Elatin1::lc_();
365             sub Elatin1::ucfirst(@);
366             sub Elatin1::ucfirst_();
367             sub Elatin1::uc(@);
368             sub Elatin1::uc_();
369             sub Elatin1::fc(@);
370             sub Elatin1::fc_();
371             sub Elatin1::ignorecase;
372             sub Elatin1::classic_character_class;
373             sub Elatin1::capture;
374             sub Elatin1::chr(;$);
375             sub Elatin1::chr_();
376             sub Elatin1::glob($);
377             sub Elatin1::glob_();
378              
379             sub Latin1::ord(;$);
380             sub Latin1::ord_();
381             sub Latin1::reverse(@);
382             sub Latin1::getc(;*@);
383             sub Latin1::length(;$);
384             sub Latin1::substr($$;$$);
385             sub Latin1::index($$;$);
386             sub Latin1::rindex($$;$);
387             sub Latin1::escape(;$);
388              
389             #
390             # Regexp work
391             #
392 204         20172 use vars qw(
393             $re_a
394             $re_t
395             $re_n
396             $re_r
397 204     204   1877 );
  204         396  
398              
399             #
400             # Character class
401             #
402 204         2048349 use vars qw(
403             $dot
404             $dot_s
405             $eD
406             $eS
407             $eW
408             $eH
409             $eV
410             $eR
411             $eN
412             $not_alnum
413             $not_alpha
414             $not_ascii
415             $not_blank
416             $not_cntrl
417             $not_digit
418             $not_graph
419             $not_lower
420             $not_lower_i
421             $not_print
422             $not_punct
423             $not_space
424             $not_upper
425             $not_upper_i
426             $not_word
427             $not_xdigit
428             $eb
429             $eB
430 204     204   1235 );
  204         356  
431              
432             ${Elatin1::dot} = qr{(?>[^\x0A])};
433             ${Elatin1::dot_s} = qr{(?>[\x00-\xFF])};
434             ${Elatin1::eD} = qr{(?>[^0-9])};
435              
436             # Vertical tabs are now whitespace
437             # \s in a regex now matches a vertical tab in all circumstances.
438             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
439             # ${Elatin1::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
440             # ${Elatin1::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
441             ${Elatin1::eS} = qr{(?>[^\s])};
442              
443             ${Elatin1::eW} = qr{(?>[^0-9A-Z_a-z])};
444             ${Elatin1::eH} = qr{(?>[^\x09\x20])};
445             ${Elatin1::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
446             ${Elatin1::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
447             ${Elatin1::eN} = qr{(?>[^\x0A])};
448             ${Elatin1::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
449             ${Elatin1::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
450             ${Elatin1::not_ascii} = qr{(?>[^\x00-\x7F])};
451             ${Elatin1::not_blank} = qr{(?>[^\x09\x20])};
452             ${Elatin1::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
453             ${Elatin1::not_digit} = qr{(?>[^\x30-\x39])};
454             ${Elatin1::not_graph} = qr{(?>[^\x21-\x7F])};
455             ${Elatin1::not_lower} = qr{(?>[^\x61-\x7A])};
456             ${Elatin1::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
457             # ${Elatin1::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
458             ${Elatin1::not_print} = qr{(?>[^\x20-\x7F])};
459             ${Elatin1::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
460             ${Elatin1::not_space} = qr{(?>[^\s\x0B])};
461             ${Elatin1::not_upper} = qr{(?>[^\x41-\x5A])};
462             ${Elatin1::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
463             # ${Elatin1::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
464             ${Elatin1::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
465             ${Elatin1::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
466             ${Elatin1::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))};
467             ${Elatin1::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]))};
468              
469             # avoid: Name "Elatin1::foo" used only once: possible typo at here.
470             ${Elatin1::dot} = ${Elatin1::dot};
471             ${Elatin1::dot_s} = ${Elatin1::dot_s};
472             ${Elatin1::eD} = ${Elatin1::eD};
473             ${Elatin1::eS} = ${Elatin1::eS};
474             ${Elatin1::eW} = ${Elatin1::eW};
475             ${Elatin1::eH} = ${Elatin1::eH};
476             ${Elatin1::eV} = ${Elatin1::eV};
477             ${Elatin1::eR} = ${Elatin1::eR};
478             ${Elatin1::eN} = ${Elatin1::eN};
479             ${Elatin1::not_alnum} = ${Elatin1::not_alnum};
480             ${Elatin1::not_alpha} = ${Elatin1::not_alpha};
481             ${Elatin1::not_ascii} = ${Elatin1::not_ascii};
482             ${Elatin1::not_blank} = ${Elatin1::not_blank};
483             ${Elatin1::not_cntrl} = ${Elatin1::not_cntrl};
484             ${Elatin1::not_digit} = ${Elatin1::not_digit};
485             ${Elatin1::not_graph} = ${Elatin1::not_graph};
486             ${Elatin1::not_lower} = ${Elatin1::not_lower};
487             ${Elatin1::not_lower_i} = ${Elatin1::not_lower_i};
488             ${Elatin1::not_print} = ${Elatin1::not_print};
489             ${Elatin1::not_punct} = ${Elatin1::not_punct};
490             ${Elatin1::not_space} = ${Elatin1::not_space};
491             ${Elatin1::not_upper} = ${Elatin1::not_upper};
492             ${Elatin1::not_upper_i} = ${Elatin1::not_upper_i};
493             ${Elatin1::not_word} = ${Elatin1::not_word};
494             ${Elatin1::not_xdigit} = ${Elatin1::not_xdigit};
495             ${Elatin1::eb} = ${Elatin1::eb};
496             ${Elatin1::eB} = ${Elatin1::eB};
497              
498             #
499             # Latin-1 split
500             #
501             sub Elatin1::split(;$$$) {
502              
503             # P.794 29.2.161. split
504             # in Chapter 29: Functions
505             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
506              
507             # P.951 split
508             # in Chapter 27: Functions
509             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
510              
511 0     0 0 0 my $pattern = $_[0];
512 0         0 my $string = $_[1];
513 0         0 my $limit = $_[2];
514              
515             # if $pattern is also omitted or is the literal space, " "
516 0 0       0 if (not defined $pattern) {
517 0         0 $pattern = ' ';
518             }
519              
520             # if $string is omitted, the function splits the $_ string
521 0 0       0 if (not defined $string) {
522 0 0       0 if (defined $_) {
523 0         0 $string = $_;
524             }
525             else {
526 0         0 $string = '';
527             }
528             }
529              
530 0         0 my @split = ();
531              
532             # when string is empty
533 0 0       0 if ($string eq '') {
    0          
534              
535             # resulting list value in list context
536 0 0       0 if (wantarray) {
537 0         0 return @split;
538             }
539              
540             # count of substrings in scalar context
541             else {
542 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
543 0         0 @_ = @split;
544 0         0 return scalar @_;
545             }
546             }
547              
548             # split's first argument is more consistently interpreted
549             #
550             # After some changes earlier in v5.17, split's behavior has been simplified:
551             # if the PATTERN argument evaluates to a string containing one space, it is
552             # treated the way that a literal string containing one space once was.
553             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
554              
555             # if $pattern is also omitted or is the literal space, " ", the function splits
556             # on whitespace, /\s+/, after skipping any leading whitespace
557             # (and so on)
558              
559             elsif ($pattern eq ' ') {
560 0 0       0 if (not defined $limit) {
561 0         0 return CORE::split(' ', $string);
562             }
563             else {
564 0         0 return CORE::split(' ', $string, $limit);
565             }
566             }
567              
568             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
569 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
570              
571             # a pattern capable of matching either the null string or something longer than the
572             # null string will split the value of $string into separate characters wherever it
573             # matches the null string between characters
574             # (and so on)
575              
576 0 0       0 if ('' =~ / \A $pattern \z /xms) {
577 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
578 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
579              
580             # P.1024 Appendix W.10 Multibyte Processing
581             # of ISBN 1-56592-224-7 CJKV Information Processing
582             # (and so on)
583              
584             # the //m modifier is assumed when you split on the pattern /^/
585             # (and so on)
586              
587             # V
588 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
589              
590             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
591             # is included in the resulting list, interspersed with the fields that are ordinarily returned
592             # (and so on)
593              
594 0         0 local $@;
595 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
596 0         0 push @split, CORE::eval('$' . $digit);
597             }
598             }
599             }
600              
601             else {
602 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
603              
604             # V
605 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
606 0         0 local $@;
607 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
608 0         0 push @split, CORE::eval('$' . $digit);
609             }
610             }
611             }
612             }
613              
614             elsif ($limit > 0) {
615 0 0       0 if ('' =~ / \A $pattern \z /xms) {
616 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
617 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
618              
619             # V
620 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
621 0         0 local $@;
622 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
623 0         0 push @split, CORE::eval('$' . $digit);
624             }
625             }
626             }
627             }
628             else {
629 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
630 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
631              
632             # V
633 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
634 0         0 local $@;
635 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
636 0         0 push @split, CORE::eval('$' . $digit);
637             }
638             }
639             }
640             }
641             }
642              
643 0 0       0 if (CORE::length($string) > 0) {
644 0         0 push @split, $string;
645             }
646              
647             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
648 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
649 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
650 0         0 pop @split;
651             }
652             }
653              
654             # resulting list value in list context
655 0 0       0 if (wantarray) {
656 0         0 return @split;
657             }
658              
659             # count of substrings in scalar context
660             else {
661 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
662 0         0 @_ = @split;
663 0         0 return scalar @_;
664             }
665             }
666              
667             #
668             # get last subexpression offsets
669             #
670             sub _last_subexpression_offsets {
671 0     0   0 my $pattern = $_[0];
672              
673             # remove comment
674 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
675              
676 0         0 my $modifier = '';
677 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
678 0         0 $modifier = $1;
679 0         0 $modifier =~ s/-[A-Za-z]*//;
680             }
681              
682             # with /x modifier
683 0         0 my @char = ();
684 0 0       0 if ($modifier =~ /x/oxms) {
685 0         0 @char = $pattern =~ /\G((?>
686             [^\\\#\[\(] |
687             \\ $q_char |
688             \# (?>[^\n]*) $ |
689             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
690             \(\? |
691             $q_char
692             ))/oxmsg;
693             }
694              
695             # without /x modifier
696             else {
697 0         0 @char = $pattern =~ /\G((?>
698             [^\\\[\(] |
699             \\ $q_char |
700             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
701             \(\? |
702             $q_char
703             ))/oxmsg;
704             }
705              
706 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
707             }
708              
709             #
710             # Latin-1 transliteration (tr///)
711             #
712             sub Elatin1::tr($$$$;$) {
713              
714 0     0 0 0 my $bind_operator = $_[1];
715 0         0 my $searchlist = $_[2];
716 0         0 my $replacementlist = $_[3];
717 0   0     0 my $modifier = $_[4] || '';
718              
719 0 0       0 if ($modifier =~ /r/oxms) {
720 0 0       0 if ($bind_operator =~ / !~ /oxms) {
721 0         0 croak "Using !~ with tr///r doesn't make sense";
722             }
723             }
724              
725 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
726 0         0 my @searchlist = _charlist_tr($searchlist);
727 0         0 my @replacementlist = _charlist_tr($replacementlist);
728              
729 0         0 my %tr = ();
730 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
731 0 0       0 if (not exists $tr{$searchlist[$i]}) {
732 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
733 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
734             }
735             elsif ($modifier =~ /d/oxms) {
736 0         0 $tr{$searchlist[$i]} = '';
737             }
738             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
739 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
740             }
741             else {
742 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
743             }
744             }
745             }
746              
747 0         0 my $tr = 0;
748 0         0 my $replaced = '';
749 0 0       0 if ($modifier =~ /c/oxms) {
750 0         0 while (defined(my $char = shift @char)) {
751 0 0       0 if (not exists $tr{$char}) {
752 0 0       0 if (defined $replacementlist[0]) {
753 0         0 $replaced .= $replacementlist[0];
754             }
755 0         0 $tr++;
756 0 0       0 if ($modifier =~ /s/oxms) {
757 0   0     0 while (@char and (not exists $tr{$char[0]})) {
758 0         0 shift @char;
759 0         0 $tr++;
760             }
761             }
762             }
763             else {
764 0         0 $replaced .= $char;
765             }
766             }
767             }
768             else {
769 0         0 while (defined(my $char = shift @char)) {
770 0 0       0 if (exists $tr{$char}) {
771 0         0 $replaced .= $tr{$char};
772 0         0 $tr++;
773 0 0       0 if ($modifier =~ /s/oxms) {
774 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
775 0         0 shift @char;
776 0         0 $tr++;
777             }
778             }
779             }
780             else {
781 0         0 $replaced .= $char;
782             }
783             }
784             }
785              
786 0 0       0 if ($modifier =~ /r/oxms) {
787 0         0 return $replaced;
788             }
789             else {
790 0         0 $_[0] = $replaced;
791 0 0       0 if ($bind_operator =~ / !~ /oxms) {
792 0         0 return not $tr;
793             }
794             else {
795 0         0 return $tr;
796             }
797             }
798             }
799              
800             #
801             # Latin-1 chop
802             #
803             sub Elatin1::chop(@) {
804              
805 0     0 0 0 my $chop;
806 0 0       0 if (@_ == 0) {
807 0         0 my @char = /\G (?>$q_char) /oxmsg;
808 0         0 $chop = pop @char;
809 0         0 $_ = join '', @char;
810             }
811             else {
812 0         0 for (@_) {
813 0         0 my @char = /\G (?>$q_char) /oxmsg;
814 0         0 $chop = pop @char;
815 0         0 $_ = join '', @char;
816             }
817             }
818 0         0 return $chop;
819             }
820              
821             #
822             # Latin-1 index by octet
823             #
824             sub Elatin1::index($$;$) {
825              
826 0     0 1 0 my($str,$substr,$position) = @_;
827 0   0     0 $position ||= 0;
828 0         0 my $pos = 0;
829              
830 0         0 while ($pos < CORE::length($str)) {
831 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
832 0 0       0 if ($pos >= $position) {
833 0         0 return $pos;
834             }
835             }
836 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
837 0         0 $pos += CORE::length($1);
838             }
839             else {
840 0         0 $pos += 1;
841             }
842             }
843 0         0 return -1;
844             }
845              
846             #
847             # Latin-1 reverse index
848             #
849             sub Elatin1::rindex($$;$) {
850              
851 0     0 0 0 my($str,$substr,$position) = @_;
852 0   0     0 $position ||= CORE::length($str) - 1;
853 0         0 my $pos = 0;
854 0         0 my $rindex = -1;
855              
856 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
857 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
858 0         0 $rindex = $pos;
859             }
860 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
861 0         0 $pos += CORE::length($1);
862             }
863             else {
864 0         0 $pos += 1;
865             }
866             }
867 0         0 return $rindex;
868             }
869              
870             #
871             # Latin-1 lower case first with parameter
872             #
873             sub Elatin1::lcfirst(@) {
874 0 0   0 0 0 if (@_) {
875 0         0 my $s = shift @_;
876 0 0 0     0 if (@_ and wantarray) {
877 0         0 return Elatin1::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
878             }
879             else {
880 0         0 return Elatin1::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
881             }
882             }
883             else {
884 0         0 return Elatin1::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
885             }
886             }
887              
888             #
889             # Latin-1 lower case first without parameter
890             #
891             sub Elatin1::lcfirst_() {
892 0     0 0 0 return Elatin1::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
893             }
894              
895             #
896             # Latin-1 lower case with parameter
897             #
898             sub Elatin1::lc(@) {
899 0 0   0 0 0 if (@_) {
900 0         0 my $s = shift @_;
901 0 0 0     0 if (@_ and wantarray) {
902 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
903             }
904             else {
905 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
906             }
907             }
908             else {
909 0         0 return Elatin1::lc_();
910             }
911             }
912              
913             #
914             # Latin-1 lower case without parameter
915             #
916             sub Elatin1::lc_() {
917 0     0 0 0 my $s = $_;
918 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
919             }
920              
921             #
922             # Latin-1 upper case first with parameter
923             #
924             sub Elatin1::ucfirst(@) {
925 0 0   0 0 0 if (@_) {
926 0         0 my $s = shift @_;
927 0 0 0     0 if (@_ and wantarray) {
928 0         0 return Elatin1::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
929             }
930             else {
931 0         0 return Elatin1::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
932             }
933             }
934             else {
935 0         0 return Elatin1::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
936             }
937             }
938              
939             #
940             # Latin-1 upper case first without parameter
941             #
942             sub Elatin1::ucfirst_() {
943 0     0 0 0 return Elatin1::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
944             }
945              
946             #
947             # Latin-1 upper case with parameter
948             #
949             sub Elatin1::uc(@) {
950 0 50   174 0 0 if (@_) {
951 174         254 my $s = shift @_;
952 174 50 33     218 if (@_ and wantarray) {
953 174 0       293 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
954             }
955             else {
956 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         536  
957             }
958             }
959             else {
960 174         904 return Elatin1::uc_();
961             }
962             }
963              
964             #
965             # Latin-1 upper case without parameter
966             #
967             sub Elatin1::uc_() {
968 0     0 0 0 my $s = $_;
969 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
970             }
971              
972             #
973             # Latin-1 fold case with parameter
974             #
975             sub Elatin1::fc(@) {
976 0 50   197 0 0 if (@_) {
977 197         267 my $s = shift @_;
978 197 50 33     234 if (@_ and wantarray) {
979 197 0       334 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
980             }
981             else {
982 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         500  
983             }
984             }
985             else {
986 197         1629 return Elatin1::fc_();
987             }
988             }
989              
990             #
991             # Latin-1 fold case without parameter
992             #
993             sub Elatin1::fc_() {
994 0     0 0 0 my $s = $_;
995 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
996             }
997              
998             #
999             # Latin-1 regexp capture
1000             #
1001             {
1002             sub Elatin1::capture {
1003 0     0 1 0 return $_[0];
1004             }
1005             }
1006              
1007             #
1008             # Latin-1 regexp ignore case modifier
1009             #
1010             sub Elatin1::ignorecase {
1011              
1012 0     0 0 0 my @string = @_;
1013 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1014              
1015             # ignore case of $scalar or @array
1016 0         0 for my $string (@string) {
1017              
1018             # split regexp
1019 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1020              
1021             # unescape character
1022 0         0 for (my $i=0; $i <= $#char; $i++) {
1023 0 0       0 next if not defined $char[$i];
1024              
1025             # open character class [...]
1026 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1027 0         0 my $left = $i;
1028              
1029             # [] make die "unmatched [] in regexp ...\n"
1030              
1031 0 0       0 if ($char[$i+1] eq ']') {
1032 0         0 $i++;
1033             }
1034              
1035 0         0 while (1) {
1036 0 0       0 if (++$i > $#char) {
1037 0         0 croak "Unmatched [] in regexp";
1038             }
1039 0 0       0 if ($char[$i] eq ']') {
1040 0         0 my $right = $i;
1041 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1042              
1043             # escape character
1044 0         0 for my $char (@charlist) {
1045 0 0       0 if (0) {
1046             }
1047              
1048 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1049 0         0 $char = '\\' . $char;
1050             }
1051             }
1052              
1053             # [...]
1054 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1055              
1056 0         0 $i = $left;
1057 0         0 last;
1058             }
1059             }
1060             }
1061              
1062             # open character class [^...]
1063             elsif ($char[$i] eq '[^') {
1064 0         0 my $left = $i;
1065              
1066             # [^] make die "unmatched [] in regexp ...\n"
1067              
1068 0 0       0 if ($char[$i+1] eq ']') {
1069 0         0 $i++;
1070             }
1071              
1072 0         0 while (1) {
1073 0 0       0 if (++$i > $#char) {
1074 0         0 croak "Unmatched [] in regexp";
1075             }
1076 0 0       0 if ($char[$i] eq ']') {
1077 0         0 my $right = $i;
1078 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1079              
1080             # escape character
1081 0         0 for my $char (@charlist) {
1082 0 0       0 if (0) {
1083             }
1084              
1085 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1086 0         0 $char = '\\' . $char;
1087             }
1088             }
1089              
1090             # [^...]
1091 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1092              
1093 0         0 $i = $left;
1094 0         0 last;
1095             }
1096             }
1097             }
1098              
1099             # rewrite classic character class or escape character
1100             elsif (my $char = classic_character_class($char[$i])) {
1101 0         0 $char[$i] = $char;
1102             }
1103              
1104             # with /i modifier
1105             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1106 0         0 my $uc = Elatin1::uc($char[$i]);
1107 0         0 my $fc = Elatin1::fc($char[$i]);
1108 0 0       0 if ($uc ne $fc) {
1109 0 0       0 if (CORE::length($fc) == 1) {
1110 0         0 $char[$i] = '[' . $uc . $fc . ']';
1111             }
1112             else {
1113 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1114             }
1115             }
1116             }
1117             }
1118              
1119             # characterize
1120 0         0 for (my $i=0; $i <= $#char; $i++) {
1121 0 0       0 next if not defined $char[$i];
1122              
1123 0 0       0 if (0) {
1124             }
1125              
1126             # quote character before ? + * {
1127 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1128 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1129 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1130             }
1131             }
1132             }
1133              
1134 0         0 $string = join '', @char;
1135             }
1136              
1137             # make regexp string
1138 0         0 return @string;
1139             }
1140              
1141             #
1142             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1143             #
1144             sub Elatin1::classic_character_class {
1145 0     1867 0 0 my($char) = @_;
1146              
1147             return {
1148             '\D' => '${Elatin1::eD}',
1149             '\S' => '${Elatin1::eS}',
1150             '\W' => '${Elatin1::eW}',
1151             '\d' => '[0-9]',
1152              
1153             # Before Perl 5.6, \s only matched the five whitespace characters
1154             # tab, newline, form-feed, carriage return, and the space character
1155             # itself, which, taken together, is the character class [\t\n\f\r ].
1156              
1157             # Vertical tabs are now whitespace
1158             # \s in a regex now matches a vertical tab in all circumstances.
1159             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1160             # \t \n \v \f \r space
1161             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1162             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1163             '\s' => '\s',
1164              
1165             '\w' => '[0-9A-Z_a-z]',
1166             '\C' => '[\x00-\xFF]',
1167             '\X' => 'X',
1168              
1169             # \h \v \H \V
1170              
1171             # P.114 Character Class Shortcuts
1172             # in Chapter 7: In the World of Regular Expressions
1173             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1174              
1175             # P.357 13.2.3 Whitespace
1176             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1177             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1178             #
1179             # 0x00009 CHARACTER TABULATION h s
1180             # 0x0000a LINE FEED (LF) vs
1181             # 0x0000b LINE TABULATION v
1182             # 0x0000c FORM FEED (FF) vs
1183             # 0x0000d CARRIAGE RETURN (CR) vs
1184             # 0x00020 SPACE h s
1185              
1186             # P.196 Table 5-9. Alphanumeric regex metasymbols
1187             # in Chapter 5. Pattern Matching
1188             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1189              
1190             # (and so on)
1191              
1192             '\H' => '${Elatin1::eH}',
1193             '\V' => '${Elatin1::eV}',
1194             '\h' => '[\x09\x20]',
1195             '\v' => '[\x0A\x0B\x0C\x0D]',
1196             '\R' => '${Elatin1::eR}',
1197              
1198             # \N
1199             #
1200             # http://perldoc.perl.org/perlre.html
1201             # Character Classes and other Special Escapes
1202             # Any character but \n (experimental). Not affected by /s modifier
1203              
1204             '\N' => '${Elatin1::eN}',
1205              
1206             # \b \B
1207              
1208             # P.180 Boundaries: The \b and \B Assertions
1209             # in Chapter 5: Pattern Matching
1210             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1211              
1212             # P.219 Boundaries: The \b and \B Assertions
1213             # in Chapter 5: Pattern Matching
1214             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1215              
1216             # \b really means (?:(?<=\w)(?!\w)|(?
1217             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1218             '\b' => '${Elatin1::eb}',
1219              
1220             # \B really means (?:(?<=\w)(?=\w)|(?
1221             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1222             '\B' => '${Elatin1::eB}',
1223              
1224 1867   100     2553 }->{$char} || '';
1225             }
1226              
1227             #
1228             # prepare Latin-1 characters per length
1229             #
1230              
1231             # 1 octet characters
1232             my @chars1 = ();
1233             sub chars1 {
1234 1867 0   0 0 65624 if (@chars1) {
1235 0         0 return @chars1;
1236             }
1237 0 0       0 if (exists $range_tr{1}) {
1238 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1239 0         0 while (my @range = splice(@ranges,0,1)) {
1240 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1241 0         0 push @chars1, pack 'C', $oct0;
1242             }
1243             }
1244             }
1245 0         0 return @chars1;
1246             }
1247              
1248             # 2 octets characters
1249             my @chars2 = ();
1250             sub chars2 {
1251 0 0   0 0 0 if (@chars2) {
1252 0         0 return @chars2;
1253             }
1254 0 0       0 if (exists $range_tr{2}) {
1255 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1256 0         0 while (my @range = splice(@ranges,0,2)) {
1257 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1258 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1259 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1260             }
1261             }
1262             }
1263             }
1264 0         0 return @chars2;
1265             }
1266              
1267             # 3 octets characters
1268             my @chars3 = ();
1269             sub chars3 {
1270 0 0   0 0 0 if (@chars3) {
1271 0         0 return @chars3;
1272             }
1273 0 0       0 if (exists $range_tr{3}) {
1274 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1275 0         0 while (my @range = splice(@ranges,0,3)) {
1276 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1277 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1278 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1279 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1280             }
1281             }
1282             }
1283             }
1284             }
1285 0         0 return @chars3;
1286             }
1287              
1288             # 4 octets characters
1289             my @chars4 = ();
1290             sub chars4 {
1291 0 0   0 0 0 if (@chars4) {
1292 0         0 return @chars4;
1293             }
1294 0 0       0 if (exists $range_tr{4}) {
1295 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1296 0         0 while (my @range = splice(@ranges,0,4)) {
1297 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1298 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1299 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1300 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1301 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1302             }
1303             }
1304             }
1305             }
1306             }
1307             }
1308 0         0 return @chars4;
1309             }
1310              
1311             #
1312             # Latin-1 open character list for tr
1313             #
1314             sub _charlist_tr {
1315              
1316 0     0   0 local $_ = shift @_;
1317              
1318             # unescape character
1319 0         0 my @char = ();
1320 0         0 while (not /\G \z/oxmsgc) {
1321 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1322 0         0 push @char, '\-';
1323             }
1324             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1325 0         0 push @char, CORE::chr(oct $1);
1326             }
1327             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1328 0         0 push @char, CORE::chr(hex $1);
1329             }
1330             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1331 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1332             }
1333             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1334             push @char, {
1335             '\0' => "\0",
1336             '\n' => "\n",
1337             '\r' => "\r",
1338             '\t' => "\t",
1339             '\f' => "\f",
1340             '\b' => "\x08", # \b means backspace in character class
1341             '\a' => "\a",
1342             '\e' => "\e",
1343 0         0 }->{$1};
1344             }
1345             elsif (/\G \\ ($q_char) /oxmsgc) {
1346 0         0 push @char, $1;
1347             }
1348             elsif (/\G ($q_char) /oxmsgc) {
1349 0         0 push @char, $1;
1350             }
1351             }
1352              
1353             # join separated multiple-octet
1354 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1355              
1356             # unescape '-'
1357 0         0 my @i = ();
1358 0         0 for my $i (0 .. $#char) {
1359 0 0       0 if ($char[$i] eq '\-') {
    0          
1360 0         0 $char[$i] = '-';
1361             }
1362             elsif ($char[$i] eq '-') {
1363 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1364 0         0 push @i, $i;
1365             }
1366             }
1367             }
1368              
1369             # open character list (reverse for splice)
1370 0         0 for my $i (CORE::reverse @i) {
1371 0         0 my @range = ();
1372              
1373             # range error
1374 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1375 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1376             }
1377              
1378             # range of multiple-octet code
1379 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1380 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1381 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1382             }
1383             elsif (CORE::length($char[$i+1]) == 2) {
1384 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1385 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1386             }
1387             elsif (CORE::length($char[$i+1]) == 3) {
1388 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1389 0         0 push @range, chars2();
1390 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1391             }
1392             elsif (CORE::length($char[$i+1]) == 4) {
1393 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1394 0         0 push @range, chars2();
1395 0         0 push @range, chars3();
1396 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1397             }
1398             else {
1399 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1400             }
1401             }
1402             elsif (CORE::length($char[$i-1]) == 2) {
1403 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1404 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1405             }
1406             elsif (CORE::length($char[$i+1]) == 3) {
1407 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1408 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1409             }
1410             elsif (CORE::length($char[$i+1]) == 4) {
1411 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1412 0         0 push @range, chars3();
1413 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1414             }
1415             else {
1416 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1417             }
1418             }
1419             elsif (CORE::length($char[$i-1]) == 3) {
1420 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1421 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1422             }
1423             elsif (CORE::length($char[$i+1]) == 4) {
1424 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1425 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1426             }
1427             else {
1428 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1429             }
1430             }
1431             elsif (CORE::length($char[$i-1]) == 4) {
1432 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1433 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1434             }
1435             else {
1436 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1437             }
1438             }
1439             else {
1440 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1441             }
1442              
1443 0         0 splice @char, $i-1, 3, @range;
1444             }
1445              
1446 0         0 return @char;
1447             }
1448              
1449             #
1450             # Latin-1 open character class
1451             #
1452             sub _cc {
1453 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1454 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1455             }
1456             elsif (scalar(@_) == 1) {
1457 0         0 return sprintf('\x%02X',$_[0]);
1458             }
1459             elsif (scalar(@_) == 2) {
1460 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1461 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1462             }
1463             elsif ($_[0] == $_[1]) {
1464 0         0 return sprintf('\x%02X',$_[0]);
1465             }
1466             elsif (($_[0]+1) == $_[1]) {
1467 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1468             }
1469             else {
1470 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1471             }
1472             }
1473             else {
1474 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1475             }
1476             }
1477              
1478             #
1479             # Latin-1 octet range
1480             #
1481             sub _octets {
1482 0     182   0 my $length = shift @_;
1483              
1484 182 50       817 if ($length == 1) {
1485 182         364 my($a1) = unpack 'C', $_[0];
1486 182         527 my($z1) = unpack 'C', $_[1];
1487              
1488 182 50       349 if ($a1 > $z1) {
1489 182         346 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1490             }
1491              
1492 0 50       0 if ($a1 == $z1) {
    50          
1493 182         409 return sprintf('\x%02X',$a1);
1494             }
1495             elsif (($a1+1) == $z1) {
1496 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1497             }
1498             else {
1499 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1500             }
1501             }
1502             else {
1503 182         1129 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1504             }
1505             }
1506              
1507             #
1508             # Latin-1 range regexp
1509             #
1510             sub _range_regexp {
1511 0     182   0 my($length,$first,$last) = @_;
1512              
1513 182         424 my @range_regexp = ();
1514 182 50       228 if (not exists $range_tr{$length}) {
1515 182         423 return @range_regexp;
1516             }
1517              
1518 0         0 my @ranges = @{ $range_tr{$length} };
  182         260  
1519 182         405 while (my @range = splice(@ranges,0,$length)) {
1520 182         598 my $min = '';
1521 182         296 my $max = '';
1522 182         218 for (my $i=0; $i < $length; $i++) {
1523 182         452 $min .= pack 'C', $range[$i][0];
1524 182         647 $max .= pack 'C', $range[$i][-1];
1525             }
1526              
1527             # min___max
1528             # FIRST_____________LAST
1529             # (nothing)
1530              
1531 182 50 33     456 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1532             }
1533              
1534             # **********
1535             # min_________max
1536             # FIRST_____________LAST
1537             # **********
1538              
1539             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1540 182         1968 push @range_regexp, _octets($length,$first,$max,$min,$max);
1541             }
1542              
1543             # **********************
1544             # min________________max
1545             # FIRST_____________LAST
1546             # **********************
1547              
1548             elsif (($min eq $first) and ($max eq $last)) {
1549 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1550             }
1551              
1552             # *********
1553             # min___max
1554             # FIRST_____________LAST
1555             # *********
1556              
1557             elsif (($first le $min) and ($max le $last)) {
1558 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1559             }
1560              
1561             # **********************
1562             # min__________________________max
1563             # FIRST_____________LAST
1564             # **********************
1565              
1566             elsif (($min le $first) and ($last le $max)) {
1567 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1568             }
1569              
1570             # *********
1571             # min________max
1572             # FIRST_____________LAST
1573             # *********
1574              
1575             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1576 182         449 push @range_regexp, _octets($length,$min,$last,$min,$max);
1577             }
1578              
1579             # min___max
1580             # FIRST_____________LAST
1581             # (nothing)
1582              
1583             elsif ($last lt $min) {
1584             }
1585              
1586             else {
1587 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1588             }
1589             }
1590              
1591 0         0 return @range_regexp;
1592             }
1593              
1594             #
1595             # Latin-1 open character list for qr and not qr
1596             #
1597             sub _charlist {
1598              
1599 182     358   514 my $modifier = pop @_;
1600 358         523 my @char = @_;
1601              
1602 358 100       772 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1603              
1604             # unescape character
1605 358         802 for (my $i=0; $i <= $#char; $i++) {
1606              
1607             # escape - to ...
1608 358 100 100     1195 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1609 1125 100 100     7965 if ((0 < $i) and ($i < $#char)) {
1610 206         813 $char[$i] = '...';
1611             }
1612             }
1613              
1614             # octal escape sequence
1615             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1616 182         382 $char[$i] = octchr($1);
1617             }
1618              
1619             # hexadecimal escape sequence
1620             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1621 0         0 $char[$i] = hexchr($1);
1622             }
1623              
1624             # \b{...} --> b\{...}
1625             # \B{...} --> B\{...}
1626             # \N{CHARNAME} --> N\{CHARNAME}
1627             # \p{PROPERTY} --> p\{PROPERTY}
1628             # \P{PROPERTY} --> P\{PROPERTY}
1629             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1630 0         0 $char[$i] = $1 . '\\' . $2;
1631             }
1632              
1633             # \p, \P, \X --> p, P, X
1634             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1635 0         0 $char[$i] = $1;
1636             }
1637              
1638             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1639 0         0 $char[$i] = CORE::chr oct $1;
1640             }
1641             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1642 0         0 $char[$i] = CORE::chr hex $1;
1643             }
1644             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1645 22         164 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1646             }
1647             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1648             $char[$i] = {
1649             '\0' => "\0",
1650             '\n' => "\n",
1651             '\r' => "\r",
1652             '\t' => "\t",
1653             '\f' => "\f",
1654             '\b' => "\x08", # \b means backspace in character class
1655             '\a' => "\a",
1656             '\e' => "\e",
1657             '\d' => '[0-9]',
1658              
1659             # Vertical tabs are now whitespace
1660             # \s in a regex now matches a vertical tab in all circumstances.
1661             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1662             # \t \n \v \f \r space
1663             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1664             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1665             '\s' => '\s',
1666              
1667             '\w' => '[0-9A-Z_a-z]',
1668             '\D' => '${Elatin1::eD}',
1669             '\S' => '${Elatin1::eS}',
1670             '\W' => '${Elatin1::eW}',
1671              
1672             '\H' => '${Elatin1::eH}',
1673             '\V' => '${Elatin1::eV}',
1674             '\h' => '[\x09\x20]',
1675             '\v' => '[\x0A\x0B\x0C\x0D]',
1676             '\R' => '${Elatin1::eR}',
1677              
1678 0         0 }->{$1};
1679             }
1680              
1681             # POSIX-style character classes
1682             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1683             $char[$i] = {
1684              
1685             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1686             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1687             '[:^lower:]' => '${Elatin1::not_lower_i}',
1688             '[:^upper:]' => '${Elatin1::not_upper_i}',
1689              
1690 25         396 }->{$1};
1691             }
1692             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1693             $char[$i] = {
1694              
1695             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1696             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1697             '[:ascii:]' => '[\x00-\x7F]',
1698             '[:blank:]' => '[\x09\x20]',
1699             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1700             '[:digit:]' => '[\x30-\x39]',
1701             '[:graph:]' => '[\x21-\x7F]',
1702             '[:lower:]' => '[\x61-\x7A]',
1703             '[:print:]' => '[\x20-\x7F]',
1704             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1705              
1706             # P.174 POSIX-Style Character Classes
1707             # in Chapter 5: Pattern Matching
1708             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1709              
1710             # P.311 11.2.4 Character Classes and other Special Escapes
1711             # in Chapter 11: perlre: Perl regular expressions
1712             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1713              
1714             # P.210 POSIX-Style Character Classes
1715             # in Chapter 5: Pattern Matching
1716             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1717              
1718             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1719              
1720             '[:upper:]' => '[\x41-\x5A]',
1721             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1722             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1723             '[:^alnum:]' => '${Elatin1::not_alnum}',
1724             '[:^alpha:]' => '${Elatin1::not_alpha}',
1725             '[:^ascii:]' => '${Elatin1::not_ascii}',
1726             '[:^blank:]' => '${Elatin1::not_blank}',
1727             '[:^cntrl:]' => '${Elatin1::not_cntrl}',
1728             '[:^digit:]' => '${Elatin1::not_digit}',
1729             '[:^graph:]' => '${Elatin1::not_graph}',
1730             '[:^lower:]' => '${Elatin1::not_lower}',
1731             '[:^print:]' => '${Elatin1::not_print}',
1732             '[:^punct:]' => '${Elatin1::not_punct}',
1733             '[:^space:]' => '${Elatin1::not_space}',
1734             '[:^upper:]' => '${Elatin1::not_upper}',
1735             '[:^word:]' => '${Elatin1::not_word}',
1736             '[:^xdigit:]' => '${Elatin1::not_xdigit}',
1737              
1738 8         55 }->{$1};
1739             }
1740             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1741 70         1194 $char[$i] = $1;
1742             }
1743             }
1744              
1745             # open character list
1746 7         31 my @singleoctet = ();
1747 358         577 my @multipleoctet = ();
1748 358         571 for (my $i=0; $i <= $#char; ) {
1749              
1750             # escaped -
1751 358 100 100     754 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1752 943         3804 $i += 1;
1753 182         239 next;
1754             }
1755              
1756             # make range regexp
1757             elsif ($char[$i] eq '...') {
1758              
1759             # range error
1760 182 50       363 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1761 182         682 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1762             }
1763             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1764 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1765 182         459 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1766             }
1767             }
1768              
1769             # make range regexp per length
1770 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1771 182         548 my @regexp = ();
1772              
1773             # is first and last
1774 182 50 33     244 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1775 182         622 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1776             }
1777              
1778             # is first
1779             elsif ($length == CORE::length($char[$i-1])) {
1780 182         452 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1781             }
1782              
1783             # is inside in first and last
1784             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1785 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1786             }
1787              
1788             # is last
1789             elsif ($length == CORE::length($char[$i+1])) {
1790 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1791             }
1792              
1793             else {
1794 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1795             }
1796              
1797 0 50       0 if ($length == 1) {
1798 182         325 push @singleoctet, @regexp;
1799             }
1800             else {
1801 182         473 push @multipleoctet, @regexp;
1802             }
1803             }
1804              
1805 0         0 $i += 2;
1806             }
1807              
1808             # with /i modifier
1809             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1810 182 100       376 if ($modifier =~ /i/oxms) {
1811 493         713 my $uc = Elatin1::uc($char[$i]);
1812 24         47 my $fc = Elatin1::fc($char[$i]);
1813 24 100       45 if ($uc ne $fc) {
1814 24 50       41 if (CORE::length($fc) == 1) {
1815 12         23 push @singleoctet, $uc, $fc;
1816             }
1817             else {
1818 12         19 push @singleoctet, $uc;
1819 0         0 push @multipleoctet, $fc;
1820             }
1821             }
1822             else {
1823 0         0 push @singleoctet, $char[$i];
1824             }
1825             }
1826             else {
1827 12         24 push @singleoctet, $char[$i];
1828             }
1829 469         682 $i += 1;
1830             }
1831              
1832             # single character of single octet code
1833             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1834 493         782 push @singleoctet, "\t", "\x20";
1835 0         0 $i += 1;
1836             }
1837             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1838 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1839 0         0 $i += 1;
1840             }
1841             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1842 0         0 push @singleoctet, $char[$i];
1843 2         6 $i += 1;
1844             }
1845              
1846             # single character of multiple-octet code
1847             else {
1848 2         4 push @multipleoctet, $char[$i];
1849 84         149 $i += 1;
1850             }
1851             }
1852              
1853             # quote metachar
1854 84         148 for (@singleoctet) {
1855 358 50       691 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1856 689         2828 $_ = '-';
1857             }
1858             elsif (/\A \n \z/oxms) {
1859 0         0 $_ = '\n';
1860             }
1861             elsif (/\A \r \z/oxms) {
1862 8         17 $_ = '\r';
1863             }
1864             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1865 8         17 $_ = sprintf('\x%02X', CORE::ord $1);
1866             }
1867             elsif (/\A [\x00-\xFF] \z/oxms) {
1868 60         185 $_ = quotemeta $_;
1869             }
1870             }
1871              
1872             # return character list
1873 429         666 return \@singleoctet, \@multipleoctet;
1874             }
1875              
1876             #
1877             # Latin-1 octal escape sequence
1878             #
1879             sub octchr {
1880 358     5 0 1216 my($octdigit) = @_;
1881              
1882 5         14 my @binary = ();
1883 5         17 for my $octal (split(//,$octdigit)) {
1884             push @binary, {
1885             '0' => '000',
1886             '1' => '001',
1887             '2' => '010',
1888             '3' => '011',
1889             '4' => '100',
1890             '5' => '101',
1891             '6' => '110',
1892             '7' => '111',
1893 5         30 }->{$octal};
1894             }
1895 50         180 my $binary = join '', @binary;
1896              
1897             my $octchr = {
1898             # 1234567
1899             1 => pack('B*', "0000000$binary"),
1900             2 => pack('B*', "000000$binary"),
1901             3 => pack('B*', "00000$binary"),
1902             4 => pack('B*', "0000$binary"),
1903             5 => pack('B*', "000$binary"),
1904             6 => pack('B*', "00$binary"),
1905             7 => pack('B*', "0$binary"),
1906             0 => pack('B*', "$binary"),
1907              
1908 5         16 }->{CORE::length($binary) % 8};
1909              
1910 5         61 return $octchr;
1911             }
1912              
1913             #
1914             # Latin-1 hexadecimal escape sequence
1915             #
1916             sub hexchr {
1917 5     5 0 19 my($hexdigit) = @_;
1918              
1919             my $hexchr = {
1920             1 => pack('H*', "0$hexdigit"),
1921             0 => pack('H*', "$hexdigit"),
1922              
1923 5         13 }->{CORE::length($_[0]) % 2};
1924              
1925 5         41 return $hexchr;
1926             }
1927              
1928             #
1929             # Latin-1 open character list for qr
1930             #
1931             sub charlist_qr {
1932              
1933 5     314 0 17 my $modifier = pop @_;
1934 314         575 my @char = @_;
1935              
1936 314         894 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1937 314         888 my @singleoctet = @$singleoctet;
1938 314         648 my @multipleoctet = @$multipleoctet;
1939              
1940             # return character list
1941 314 100       493 if (scalar(@singleoctet) >= 1) {
1942              
1943             # with /i modifier
1944 314 100       715 if ($modifier =~ m/i/oxms) {
1945 236         547 my %singleoctet_ignorecase = ();
1946 22         39 for (@singleoctet) {
1947 22   100     42 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1948 46         200 for my $ord (hex($1) .. hex($2)) {
1949 46         127 my $char = CORE::chr($ord);
1950 66         98 my $uc = Elatin1::uc($char);
1951 66         99 my $fc = Elatin1::fc($char);
1952 66 100       102 if ($uc eq $fc) {
1953 66         106 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1954             }
1955             else {
1956 12 50       73 if (CORE::length($fc) == 1) {
1957 54         74 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1958 54         112 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1959             }
1960             else {
1961 54         185 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1962 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1963             }
1964             }
1965             }
1966             }
1967 0 50       0 if ($_ ne '') {
1968 46         98 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1969             }
1970             }
1971 0         0 my $i = 0;
1972 22         28 my @singleoctet_ignorecase = ();
1973 22         30 for my $ord (0 .. 255) {
1974 22 100       36 if (exists $singleoctet_ignorecase{$ord}) {
1975 5632         6288 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         94  
1976             }
1977             else {
1978 96         195 $i++;
1979             }
1980             }
1981 5536         5490 @singleoctet = ();
1982 22         29 for my $range (@singleoctet_ignorecase) {
1983 22 100       64 if (ref $range) {
1984 3648 100       5395 if (scalar(@{$range}) == 1) {
  56 50       59  
1985 56         85 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         40  
1986             }
1987 36         110 elsif (scalar(@{$range}) == 2) {
1988 20         28 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
1989             }
1990             else {
1991 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         23  
  20         24  
1992             }
1993             }
1994             }
1995             }
1996              
1997 20         71 my $not_anchor = '';
1998              
1999 236         348 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2000             }
2001 236 100       619 if (scalar(@multipleoctet) >= 2) {
2002 314         674 return '(?:' . join('|', @multipleoctet) . ')';
2003             }
2004             else {
2005 6         31 return $multipleoctet[0];
2006             }
2007             }
2008              
2009             #
2010             # Latin-1 open character list for not qr
2011             #
2012             sub charlist_not_qr {
2013              
2014 308     44 0 1275 my $modifier = pop @_;
2015 44         111 my @char = @_;
2016              
2017 44         103 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2018 44         143 my @singleoctet = @$singleoctet;
2019 44         93 my @multipleoctet = @$multipleoctet;
2020              
2021             # with /i modifier
2022 44 100       70 if ($modifier =~ m/i/oxms) {
2023 44         115 my %singleoctet_ignorecase = ();
2024 10         14 for (@singleoctet) {
2025 10   66     12 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2026 10         44 for my $ord (hex($1) .. hex($2)) {
2027 10         31 my $char = CORE::chr($ord);
2028 30         45 my $uc = Elatin1::uc($char);
2029 30         40 my $fc = Elatin1::fc($char);
2030 30 50       44 if ($uc eq $fc) {
2031 30         45 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2032             }
2033             else {
2034 0 50       0 if (CORE::length($fc) == 1) {
2035 30         41 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2036 30         66 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2037             }
2038             else {
2039 30         90 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2040 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2041             }
2042             }
2043             }
2044             }
2045 0 50       0 if ($_ ne '') {
2046 10         27 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2047             }
2048             }
2049 0         0 my $i = 0;
2050 10         12 my @singleoctet_ignorecase = ();
2051 10         13 for my $ord (0 .. 255) {
2052 10 100       16 if (exists $singleoctet_ignorecase{$ord}) {
2053 2560         3212 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         55  
2054             }
2055             else {
2056 60         96 $i++;
2057             }
2058             }
2059 2500         2514 @singleoctet = ();
2060 10         16 for my $range (@singleoctet_ignorecase) {
2061 10 100       23 if (ref $range) {
2062 960 50       1451 if (scalar(@{$range}) == 1) {
  20 50       20  
2063 20         31 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2064             }
2065 0         0 elsif (scalar(@{$range}) == 2) {
2066 20         27 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2067             }
2068             else {
2069 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         19  
  20         25  
2070             }
2071             }
2072             }
2073             }
2074              
2075             # return character list
2076 20 50       73 if (scalar(@multipleoctet) >= 1) {
2077 44 0       127 if (scalar(@singleoctet) >= 1) {
2078              
2079             # any character other than multiple-octet and single octet character class
2080 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2081             }
2082             else {
2083              
2084             # any character other than multiple-octet character class
2085 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2086             }
2087             }
2088             else {
2089 0 50       0 if (scalar(@singleoctet) >= 1) {
2090              
2091             # any character other than single octet character class
2092 44         86 return '(?:[^' . join('', @singleoctet) . '])';
2093             }
2094             else {
2095              
2096             # any character
2097 44         286 return "(?:$your_char)";
2098             }
2099             }
2100             }
2101              
2102             #
2103             # open file in read mode
2104             #
2105             sub _open_r {
2106 0     408   0 my(undef,$file) = @_;
2107 204     204   2315 use Fcntl qw(O_RDONLY);
  204         443  
  204         28241  
2108 408         1111 return CORE::sysopen($_[0], $file, &O_RDONLY);
2109             }
2110              
2111             #
2112             # open file in append mode
2113             #
2114             sub _open_a {
2115 408     204   17975 my(undef,$file) = @_;
2116 204     204   1366 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  204         414  
  204         669410  
2117 204         677 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2118             }
2119              
2120             #
2121             # safe system
2122             #
2123             sub _systemx {
2124              
2125             # P.707 29.2.33. exec
2126             # in Chapter 29: Functions
2127             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2128             #
2129             # Be aware that in older releases of Perl, exec (and system) did not flush
2130             # your output buffer, so you needed to enable command buffering by setting $|
2131             # on one or more filehandles to avoid lost output in the case of exec, or
2132             # misordererd output in the case of system. This situation was largely remedied
2133             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2134              
2135             # P.855 exec
2136             # in Chapter 27: Functions
2137             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2138             #
2139             # In very old release of Perl (before v5.6), exec (and system) did not flush
2140             # your output buffer, so you needed to enable command buffering by setting $|
2141             # on one or more filehandles to avoid lost output with exec or misordered
2142             # output with system.
2143              
2144 204     204   25794 $| = 1;
2145              
2146             # P.565 23.1.2. Cleaning Up Your Environment
2147             # in Chapter 23: Security
2148             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2149              
2150             # P.656 Cleaning Up Your Environment
2151             # in Chapter 20: Security
2152             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2153              
2154             # local $ENV{'PATH'} = '.';
2155 204         944 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2156              
2157             # P.707 29.2.33. exec
2158             # in Chapter 29: Functions
2159             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2160             #
2161             # As we mentioned earlier, exec treats a discrete list of arguments as an
2162             # indication that it should bypass shell processing. However, there is one
2163             # place where you might still get tripped up. The exec call (and system, too)
2164             # will not distinguish between a single scalar argument and an array containing
2165             # only one element.
2166             #
2167             # @args = ("echo surprise"); # just one element in list
2168             # exec @args # still subject to shell escapes
2169             # or die "exec: $!"; # because @args == 1
2170             #
2171             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2172             # first argument as the pathname, which forces the rest of the arguments to be
2173             # interpreted as a list, even if there is only one of them:
2174             #
2175             # exec { $args[0] } @args # safe even with one-argument list
2176             # or die "can't exec @args: $!";
2177              
2178             # P.855 exec
2179             # in Chapter 27: Functions
2180             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2181             #
2182             # As we mentioned earlier, exec treats a discrete list of arguments as a
2183             # directive to bypass shell processing. However, there is one place where
2184             # you might still get tripped up. The exec call (and system, too) cannot
2185             # distinguish between a single scalar argument and an array containing
2186             # only one element.
2187             #
2188             # @args = ("echo surprise"); # just one element in list
2189             # exec @args # still subject to shell escapes
2190             # || die "exec: $!"; # because @args == 1
2191             #
2192             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2193             # argument as the pathname, which forces the rest of the arguments to be
2194             # interpreted as a list, even if there is only one of them:
2195             #
2196             # exec { $args[0] } @args # safe even with one-argument list
2197             # || die "can't exec @args: $!";
2198              
2199 204         1829 return CORE::system { $_[0] } @_; # safe even with one-argument list
  204         426  
2200             }
2201              
2202             #
2203             # Latin-1 order to character (with parameter)
2204             #
2205             sub Elatin1::chr(;$) {
2206              
2207 204 0   0 0 18187270 my $c = @_ ? $_[0] : $_;
2208              
2209 0 0       0 if ($c == 0x00) {
2210 0         0 return "\x00";
2211             }
2212             else {
2213 0         0 my @chr = ();
2214 0         0 while ($c > 0) {
2215 0         0 unshift @chr, ($c % 0x100);
2216 0         0 $c = int($c / 0x100);
2217             }
2218 0         0 return pack 'C*', @chr;
2219             }
2220             }
2221              
2222             #
2223             # Latin-1 order to character (without parameter)
2224             #
2225             sub Elatin1::chr_() {
2226              
2227 0     0 0 0 my $c = $_;
2228              
2229 0 0       0 if ($c == 0x00) {
2230 0         0 return "\x00";
2231             }
2232             else {
2233 0         0 my @chr = ();
2234 0         0 while ($c > 0) {
2235 0         0 unshift @chr, ($c % 0x100);
2236 0         0 $c = int($c / 0x100);
2237             }
2238 0         0 return pack 'C*', @chr;
2239             }
2240             }
2241              
2242             #
2243             # Latin-1 path globbing (with parameter)
2244             #
2245             sub Elatin1::glob($) {
2246              
2247 0 0   0 0 0 if (wantarray) {
2248 0         0 my @glob = _DOS_like_glob(@_);
2249 0         0 for my $glob (@glob) {
2250 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2251             }
2252 0         0 return @glob;
2253             }
2254             else {
2255 0         0 my $glob = _DOS_like_glob(@_);
2256 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2257 0         0 return $glob;
2258             }
2259             }
2260              
2261             #
2262             # Latin-1 path globbing (without parameter)
2263             #
2264             sub Elatin1::glob_() {
2265              
2266 0 0   0 0 0 if (wantarray) {
2267 0         0 my @glob = _DOS_like_glob();
2268 0         0 for my $glob (@glob) {
2269 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2270             }
2271 0         0 return @glob;
2272             }
2273             else {
2274 0         0 my $glob = _DOS_like_glob();
2275 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2276 0         0 return $glob;
2277             }
2278             }
2279              
2280             #
2281             # Latin-1 path globbing via File::DosGlob 1.10
2282             #
2283             # Often I confuse "_dosglob" and "_doglob".
2284             # So, I renamed "_dosglob" to "_DOS_like_glob".
2285             #
2286             my %iter;
2287             my %entries;
2288             sub _DOS_like_glob {
2289              
2290             # context (keyed by second cxix argument provided by core)
2291 0     0   0 my($expr,$cxix) = @_;
2292              
2293             # glob without args defaults to $_
2294 0 0       0 $expr = $_ if not defined $expr;
2295              
2296             # represents the current user's home directory
2297             #
2298             # 7.3. Expanding Tildes in Filenames
2299             # in Chapter 7. File Access
2300             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2301             #
2302             # and File::HomeDir, File::HomeDir::Windows module
2303              
2304             # DOS-like system
2305 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2306 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2307             { my_home_MSWin32() }oxmse;
2308             }
2309              
2310             # UNIX-like system
2311 0 0 0     0 else {
  0         0  
2312             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2313             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2314             }
2315 0 0       0  
2316 0 0       0 # assume global context if not provided one
2317             $cxix = '_G_' if not defined $cxix;
2318             $iter{$cxix} = 0 if not exists $iter{$cxix};
2319 0 0       0  
2320 0         0 # if we're just beginning, do it all first
2321             if ($iter{$cxix} == 0) {
2322             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2323             }
2324 0 0       0  
2325 0         0 # chuck it all out, quick or slow
2326 0         0 if (wantarray) {
  0         0  
2327             delete $iter{$cxix};
2328             return @{delete $entries{$cxix}};
2329 0 0       0 }
  0         0  
2330 0         0 else {
  0         0  
2331             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2332             return shift @{$entries{$cxix}};
2333             }
2334 0         0 else {
2335 0         0 # return undef for EOL
2336 0         0 delete $iter{$cxix};
2337             delete $entries{$cxix};
2338             return undef;
2339             }
2340             }
2341             }
2342              
2343             #
2344             # Latin-1 path globbing subroutine
2345             #
2346 0     0   0 sub _do_glob {
2347 0         0  
2348 0         0 my($cond,@expr) = @_;
2349             my @glob = ();
2350             my $fix_drive_relative_paths = 0;
2351 0         0  
2352 0 0       0 OUTER:
2353 0 0       0 for my $expr (@expr) {
2354             next OUTER if not defined $expr;
2355 0         0 next OUTER if $expr eq '';
2356 0         0  
2357 0         0 my @matched = ();
2358 0         0 my @globdir = ();
2359 0         0 my $head = '.';
2360             my $pathsep = '/';
2361             my $tail;
2362 0 0       0  
2363 0         0 # if argument is within quotes strip em and do no globbing
2364 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2365 0 0       0 $expr = $1;
2366 0         0 if ($cond eq 'd') {
2367             if (-d $expr) {
2368             push @glob, $expr;
2369             }
2370 0 0       0 }
2371 0         0 else {
2372             if (-e $expr) {
2373             push @glob, $expr;
2374 0         0 }
2375             }
2376             next OUTER;
2377             }
2378              
2379 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2380 0 0       0 # to h:./*.pm to expand correctly
2381 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2382             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2383             $fix_drive_relative_paths = 1;
2384             }
2385 0 0       0 }
2386 0 0       0  
2387 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2388 0         0 if ($tail eq '') {
2389             push @glob, $expr;
2390 0 0       0 next OUTER;
2391 0 0       0 }
2392 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2393 0         0 if (@globdir = _do_glob('d', $head)) {
2394             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2395             next OUTER;
2396 0 0 0     0 }
2397 0         0 }
2398             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2399 0         0 $head .= $pathsep;
2400             }
2401             $expr = $tail;
2402             }
2403 0 0       0  
2404 0 0       0 # If file component has no wildcards, we can avoid opendir
2405 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2406             if ($head eq '.') {
2407 0 0 0     0 $head = '';
2408 0         0 }
2409             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2410 0         0 $head .= $pathsep;
2411 0 0       0 }
2412 0 0       0 $head .= $expr;
2413 0         0 if ($cond eq 'd') {
2414             if (-d $head) {
2415             push @glob, $head;
2416             }
2417 0 0       0 }
2418 0         0 else {
2419             if (-e $head) {
2420             push @glob, $head;
2421 0         0 }
2422             }
2423 0 0       0 next OUTER;
2424 0         0 }
2425 0         0 opendir(*DIR, $head) or next OUTER;
2426             my @leaf = readdir DIR;
2427 0 0       0 closedir DIR;
2428 0         0  
2429             if ($head eq '.') {
2430 0 0 0     0 $head = '';
2431 0         0 }
2432             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2433             $head .= $pathsep;
2434 0         0 }
2435 0         0  
2436 0         0 my $pattern = '';
2437             while ($expr =~ / \G ($q_char) /oxgc) {
2438             my $char = $1;
2439              
2440             # 6.9. Matching Shell Globs as Regular Expressions
2441             # in Chapter 6. Pattern Matching
2442             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2443 0 0       0 # (and so on)
    0          
    0          
2444 0         0  
2445             if ($char eq '*') {
2446             $pattern .= "(?:$your_char)*",
2447 0         0 }
2448             elsif ($char eq '?') {
2449             $pattern .= "(?:$your_char)?", # DOS style
2450             # $pattern .= "(?:$your_char)", # UNIX style
2451 0         0 }
2452             elsif ((my $fc = Elatin1::fc($char)) ne $char) {
2453             $pattern .= $fc;
2454 0         0 }
2455             else {
2456             $pattern .= quotemeta $char;
2457 0     0   0 }
  0         0  
2458             }
2459             my $matchsub = sub { Elatin1::fc($_[0]) =~ /\A $pattern \z/xms };
2460              
2461             # if ($@) {
2462             # print STDERR "$0: $@\n";
2463             # next OUTER;
2464             # }
2465 0         0  
2466 0 0 0     0 INNER:
2467 0         0 for my $leaf (@leaf) {
2468             if ($leaf eq '.' or $leaf eq '..') {
2469 0 0 0     0 next INNER;
2470 0         0 }
2471             if ($cond eq 'd' and not -d "$head$leaf") {
2472             next INNER;
2473 0 0       0 }
2474 0         0  
2475 0         0 if (&$matchsub($leaf)) {
2476             push @matched, "$head$leaf";
2477             next INNER;
2478             }
2479              
2480             # [DOS compatibility special case]
2481 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2482              
2483             if (Elatin1::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2484             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2485 0 0       0 Elatin1::index($pattern,'\\.') != -1 # pattern has a dot.
2486 0         0 ) {
2487 0         0 if (&$matchsub("$leaf.")) {
2488             push @matched, "$head$leaf";
2489             next INNER;
2490             }
2491 0 0       0 }
2492 0         0 }
2493             if (@matched) {
2494             push @glob, @matched;
2495 0 0       0 }
2496 0         0 }
2497 0         0 if ($fix_drive_relative_paths) {
2498             for my $glob (@glob) {
2499             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2500 0         0 }
2501             }
2502             return @glob;
2503             }
2504              
2505             #
2506             # Latin-1 parse line
2507             #
2508 0     0   0 sub _parse_line {
2509              
2510 0         0 my($line) = @_;
2511 0         0  
2512 0         0 $line .= ' ';
2513             my @piece = ();
2514             while ($line =~ /
2515             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2516             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2517 0 0       0 /oxmsg
2518             ) {
2519 0         0 push @piece, defined($1) ? $1 : $2;
2520             }
2521             return @piece;
2522             }
2523              
2524             #
2525             # Latin-1 parse path
2526             #
2527 0     0   0 sub _parse_path {
2528              
2529 0         0 my($path,$pathsep) = @_;
2530 0         0  
2531 0         0 $path .= '/';
2532             my @subpath = ();
2533             while ($path =~ /
2534             ((?: [^\/\\] )+?) [\/\\]
2535 0         0 /oxmsg
2536             ) {
2537             push @subpath, $1;
2538 0         0 }
2539 0         0  
2540 0         0 my $tail = pop @subpath;
2541             my $head = join $pathsep, @subpath;
2542             return $head, $tail;
2543             }
2544              
2545             #
2546             # via File::HomeDir::Windows 1.00
2547             #
2548             sub my_home_MSWin32 {
2549              
2550             # A lot of unix people and unix-derived tools rely on
2551 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2552 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2553             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2554             return $ENV{'HOME'};
2555             }
2556              
2557 0         0 # Do we have a user profile?
2558             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2559             return $ENV{'USERPROFILE'};
2560             }
2561              
2562 0         0 # Some Windows use something like $ENV{'HOME'}
2563             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2564             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2565 0         0 }
2566              
2567             return undef;
2568             }
2569              
2570             #
2571             # via File::HomeDir::Unix 1.00
2572 0     0 0 0 #
2573             sub my_home {
2574 0 0 0     0 my $home;
    0 0        
2575 0         0  
2576             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2577             $home = $ENV{'HOME'};
2578             }
2579              
2580             # This is from the original code, but I'm guessing
2581 0         0 # it means "login directory" and exists on some Unixes.
2582             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2583             $home = $ENV{'LOGDIR'};
2584             }
2585              
2586             ### More-desperate methods
2587              
2588 0         0 # Light desperation on any (Unixish) platform
2589             else {
2590             $home = CORE::eval q{ (getpwuid($<))[7] };
2591             }
2592              
2593 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2594 0         0 # For example, "nobody"-like users might use /nonexistant
2595             if (defined $home and ! -d($home)) {
2596 0         0 $home = undef;
2597             }
2598             return $home;
2599             }
2600              
2601             #
2602             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2603 0     0 0 0 #
2604             sub Elatin1::PREMATCH {
2605             return $`;
2606             }
2607              
2608             #
2609             # ${^MATCH}, $MATCH, $& the string that matched
2610 0     0 0 0 #
2611             sub Elatin1::MATCH {
2612             return $&;
2613             }
2614              
2615             #
2616             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2617 0     0 0 0 #
2618             sub Elatin1::POSTMATCH {
2619             return $';
2620             }
2621              
2622             #
2623             # Latin-1 character to order (with parameter)
2624             #
2625 0 0   0 1 0 sub Latin1::ord(;$) {
2626              
2627 0 0       0 local $_ = shift if @_;
2628 0         0  
2629 0         0 if (/\A ($q_char) /oxms) {
2630 0         0 my @ord = unpack 'C*', $1;
2631 0         0 my $ord = 0;
2632             while (my $o = shift @ord) {
2633 0         0 $ord = $ord * 0x100 + $o;
2634             }
2635             return $ord;
2636 0         0 }
2637             else {
2638             return CORE::ord $_;
2639             }
2640             }
2641              
2642             #
2643             # Latin-1 character to order (without parameter)
2644             #
2645 0 0   0 0 0 sub Latin1::ord_() {
2646 0         0  
2647 0         0 if (/\A ($q_char) /oxms) {
2648 0         0 my @ord = unpack 'C*', $1;
2649 0         0 my $ord = 0;
2650             while (my $o = shift @ord) {
2651 0         0 $ord = $ord * 0x100 + $o;
2652             }
2653             return $ord;
2654 0         0 }
2655             else {
2656             return CORE::ord $_;
2657             }
2658             }
2659              
2660             #
2661             # Latin-1 reverse
2662             #
2663 0 0   0 0 0 sub Latin1::reverse(@) {
2664 0         0  
2665             if (wantarray) {
2666             return CORE::reverse @_;
2667             }
2668             else {
2669              
2670             # One of us once cornered Larry in an elevator and asked him what
2671             # problem he was solving with this, but he looked as far off into
2672             # the distance as he could in an elevator and said, "It seemed like
2673 0         0 # a good idea at the time."
2674              
2675             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2676             }
2677             }
2678              
2679             #
2680             # Latin-1 getc (with parameter, without parameter)
2681             #
2682 0     0 0 0 sub Latin1::getc(;*@) {
2683 0 0       0  
2684 0 0 0     0 my($package) = caller;
2685             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2686 0         0 croak 'Too many arguments for Latin1::getc' if @_ and not wantarray;
  0         0  
2687 0         0  
2688 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2689 0         0 my $getc = '';
2690 0 0       0 for my $length ($length[0] .. $length[-1]) {
2691 0 0       0 $getc .= CORE::getc($fh);
2692 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2693             if ($getc =~ /\A ${Elatin1::dot_s} \z/oxms) {
2694             return wantarray ? ($getc,@_) : $getc;
2695             }
2696 0 0       0 }
2697             }
2698             return wantarray ? ($getc,@_) : $getc;
2699             }
2700              
2701             #
2702             # Latin-1 length by character
2703             #
2704 0 0   0 1 0 sub Latin1::length(;$) {
2705              
2706 0         0 local $_ = shift if @_;
2707 0         0  
2708             local @_ = /\G ($q_char) /oxmsg;
2709             return scalar @_;
2710             }
2711              
2712             #
2713             # Latin-1 substr by character
2714             #
2715             BEGIN {
2716              
2717             # P.232 The lvalue Attribute
2718             # in Chapter 6: Subroutines
2719             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2720              
2721             # P.336 The lvalue Attribute
2722             # in Chapter 7: Subroutines
2723             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2724              
2725             # P.144 8.4 Lvalue subroutines
2726             # in Chapter 8: perlsub: Perl subroutines
2727 204 50 0 204 1 120857 # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
  0 0   0   0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
2728              
2729             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2730             # vv----------------------*******
2731             sub Latin1::substr($$;$$) %s {
2732              
2733             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2734              
2735             # If the substring is beyond either end of the string, substr() returns the undefined
2736             # value and produces a warning. When used as an lvalue, specifying a substring that
2737             # is entirely outside the string raises an exception.
2738             # http://perldoc.perl.org/functions/substr.html
2739              
2740             # A return with no argument returns the scalar value undef in scalar context,
2741             # an empty list () in list context, and (naturally) nothing at all in void
2742             # context.
2743              
2744             my $offset = $_[1];
2745             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2746             return;
2747             }
2748              
2749             # substr($string,$offset,$length,$replacement)
2750             if (@_ == 4) {
2751             my(undef,undef,$length,$replacement) = @_;
2752             my $substr = join '', splice(@char, $offset, $length, $replacement);
2753             $_[0] = join '', @char;
2754              
2755             # return $substr; this doesn't work, don't say "return"
2756             $substr;
2757             }
2758              
2759             # substr($string,$offset,$length)
2760             elsif (@_ == 3) {
2761             my(undef,undef,$length) = @_;
2762             my $octet_offset = 0;
2763             my $octet_length = 0;
2764             if ($offset == 0) {
2765             $octet_offset = 0;
2766             }
2767             elsif ($offset > 0) {
2768             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2769             }
2770             else {
2771             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2772             }
2773             if ($length == 0) {
2774             $octet_length = 0;
2775             }
2776             elsif ($length > 0) {
2777             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2778             }
2779             else {
2780             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2781             }
2782             CORE::substr($_[0], $octet_offset, $octet_length);
2783             }
2784              
2785             # substr($string,$offset)
2786             else {
2787             my $octet_offset = 0;
2788             if ($offset == 0) {
2789             $octet_offset = 0;
2790             }
2791             elsif ($offset > 0) {
2792             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2793             }
2794             else {
2795             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2796             }
2797             CORE::substr($_[0], $octet_offset);
2798             }
2799             }
2800             END
2801             }
2802              
2803             #
2804             # Latin-1 index by character
2805             #
2806 0     0 1 0 sub Latin1::index($$;$) {
2807 0 0       0  
2808 0         0 my $index;
2809             if (@_ == 3) {
2810             $index = Elatin1::index($_[0], $_[1], CORE::length(Latin1::substr($_[0], 0, $_[2])));
2811 0         0 }
2812             else {
2813             $index = Elatin1::index($_[0], $_[1]);
2814 0 0       0 }
2815 0         0  
2816             if ($index == -1) {
2817             return -1;
2818 0         0 }
2819             else {
2820             return Latin1::length(CORE::substr $_[0], 0, $index);
2821             }
2822             }
2823              
2824             #
2825             # Latin-1 rindex by character
2826             #
2827 0     0 1 0 sub Latin1::rindex($$;$) {
2828 0 0       0  
2829 0         0 my $rindex;
2830             if (@_ == 3) {
2831             $rindex = Elatin1::rindex($_[0], $_[1], CORE::length(Latin1::substr($_[0], 0, $_[2])));
2832 0         0 }
2833             else {
2834             $rindex = Elatin1::rindex($_[0], $_[1]);
2835 0 0       0 }
2836 0         0  
2837             if ($rindex == -1) {
2838             return -1;
2839 0         0 }
2840             else {
2841             return Latin1::length(CORE::substr $_[0], 0, $rindex);
2842             }
2843             }
2844              
2845 204     204   1610 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  204         454  
  204         44802  
2846             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2847             use vars qw($slash); $slash = 'm//';
2848              
2849             # ord() to ord() or Latin1::ord()
2850             my $function_ord = 'ord';
2851              
2852             # ord to ord or Latin1::ord_
2853             my $function_ord_ = 'ord';
2854              
2855             # reverse to reverse or Latin1::reverse
2856             my $function_reverse = 'reverse';
2857              
2858             # getc to getc or Latin1::getc
2859             my $function_getc = 'getc';
2860              
2861             # P.1023 Appendix W.9 Multibyte Anchoring
2862             # of ISBN 1-56592-224-7 CJKV Information Processing
2863              
2864 204     204   1514 my $anchor = '';
  204     0   350  
  204         9154268  
2865              
2866             use vars qw($nest);
2867              
2868             # regexp of nested parens in qqXX
2869              
2870             # P.340 Matching Nested Constructs with Embedded Code
2871             # in Chapter 7: Perl
2872             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2873              
2874             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2875             [^\\()] |
2876             \( (?{$nest++}) |
2877             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2878             \\ [^c] |
2879             \\c[\x40-\x5F] |
2880             [\x00-\xFF]
2881             }xms;
2882              
2883             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2884             [^\\{}] |
2885             \{ (?{$nest++}) |
2886             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2887             \\ [^c] |
2888             \\c[\x40-\x5F] |
2889             [\x00-\xFF]
2890             }xms;
2891              
2892             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2893             [^\\\[\]] |
2894             \[ (?{$nest++}) |
2895             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2896             \\ [^c] |
2897             \\c[\x40-\x5F] |
2898             [\x00-\xFF]
2899             }xms;
2900              
2901             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2902             [^\\<>] |
2903             \< (?{$nest++}) |
2904             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2905             \\ [^c] |
2906             \\c[\x40-\x5F] |
2907             [\x00-\xFF]
2908             }xms;
2909              
2910             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2911             (?: ::)? (?:
2912             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2913             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2914             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2915             ))
2916             }xms;
2917              
2918             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2919             (?: ::)? (?:
2920             (?>[0-9]+) |
2921             [^a-zA-Z_0-9\[\]] |
2922             ^[A-Z] |
2923             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2924             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2925             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2926             ))
2927             }xms;
2928              
2929             my $qq_substr = qr{(?> Char::substr | Latin1::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2930             }xms;
2931              
2932             # regexp of nested parens in qXX
2933             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2934             [^()] |
2935             \( (?{$nest++}) |
2936             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2937             [\x00-\xFF]
2938             }xms;
2939              
2940             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2941             [^\{\}] |
2942             \{ (?{$nest++}) |
2943             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2944             [\x00-\xFF]
2945             }xms;
2946              
2947             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2948             [^\[\]] |
2949             \[ (?{$nest++}) |
2950             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2951             [\x00-\xFF]
2952             }xms;
2953              
2954             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2955             [^<>] |
2956             \< (?{$nest++}) |
2957             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2958             [\x00-\xFF]
2959             }xms;
2960              
2961             my $matched = '';
2962             my $s_matched = '';
2963              
2964             my $tr_variable = ''; # variable of tr///
2965             my $sub_variable = ''; # variable of s///
2966             my $bind_operator = ''; # =~ or !~
2967              
2968             my @heredoc = (); # here document
2969             my @heredoc_delimiter = ();
2970             my $here_script = ''; # here script
2971              
2972             #
2973             # escape Latin-1 script
2974 0 50   204 0 0 #
2975             sub Latin1::escape(;$) {
2976             local($_) = $_[0] if @_;
2977              
2978             # P.359 The Study Function
2979             # in Chapter 7: Perl
2980 204         719 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2981              
2982             study $_; # Yes, I studied study yesterday.
2983              
2984             # while all script
2985              
2986             # 6.14. Matching from Where the Last Pattern Left Off
2987             # in Chapter 6. Pattern Matching
2988             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2989             # (and so on)
2990              
2991             # one member of Tag-team
2992             #
2993             # P.128 Start of match (or end of previous match): \G
2994             # P.130 Advanced Use of \G with Perl
2995             # in Chapter 3: Overview of Regular Expression Features and Flavors
2996             # P.255 Use leading anchors
2997             # P.256 Expose ^ and \G at the front expressions
2998             # in Chapter 6: Crafting an Efficient Expression
2999             # P.315 "Tag-team" matching with /gc
3000             # in Chapter 7: Perl
3001 204         413 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3002 204         352  
3003 204         744 my $e_script = '';
3004             while (not /\G \z/oxgc) { # member
3005             $e_script .= Latin1::escape_token();
3006 74677         112959 }
3007              
3008             return $e_script;
3009             }
3010              
3011             #
3012             # escape Latin-1 token of script
3013             #
3014             sub Latin1::escape_token {
3015              
3016 204     74677 0 2586 # \n output here document
3017              
3018             my $ignore_modules = join('|', qw(
3019             utf8
3020             bytes
3021             charnames
3022             I18N::Japanese
3023             I18N::Collate
3024             I18N::JExt
3025             File::DosGlob
3026             Wild
3027             Wildcard
3028             Japanese
3029             ));
3030              
3031             # another member of Tag-team
3032             #
3033             # P.315 "Tag-team" matching with /gc
3034             # in Chapter 7: Perl
3035 74677 100 100     86461 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
    100 66        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
3036 74677         2890253  
3037 12502 100       16232 if (/\G ( \n ) /oxgc) { # another member (and so on)
3038 12502         22967 my $heredoc = '';
3039             if (scalar(@heredoc_delimiter) >= 1) {
3040 174         265 $slash = 'm//';
3041 174         342  
3042             $heredoc = join '', @heredoc;
3043             @heredoc = ();
3044 174         291  
3045 174         304 # skip here document
3046             for my $heredoc_delimiter (@heredoc_delimiter) {
3047 174         1048 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3048             }
3049 174         297 @heredoc_delimiter = ();
3050              
3051 174         240 $here_script = '';
3052             }
3053             return "\n" . $heredoc;
3054             }
3055 12502         37660  
3056             # ignore space, comment
3057             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3058              
3059             # if (, elsif (, unless (, while (, until (, given (, and when (
3060              
3061             # given, when
3062              
3063             # P.225 The given Statement
3064             # in Chapter 15: Smart Matching and given-when
3065             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3066              
3067             # P.133 The given Statement
3068             # in Chapter 4: Statements and Declarations
3069             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3070 17874         54667  
3071 1401         3112 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3072             $slash = 'm//';
3073             return $1;
3074             }
3075              
3076             # scalar variable ($scalar = ...) =~ tr///;
3077             # scalar variable ($scalar = ...) =~ s///;
3078              
3079             # state
3080              
3081             # P.68 Persistent, Private Variables
3082             # in Chapter 4: Subroutines
3083             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3084              
3085             # P.160 Persistent Lexically Scoped Variables: state
3086             # in Chapter 4: Statements and Declarations
3087             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3088              
3089             # (and so on)
3090 1401         5512  
3091             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3092 86 50       180 my $e_string = e_string($1);
    50          
3093 86         1970  
3094 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3095 0         0 $tr_variable = $e_string . e_string($1);
3096 0         0 $bind_operator = $2;
3097             $slash = 'm//';
3098             return '';
3099 0         0 }
3100 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3101 0         0 $sub_variable = $e_string . e_string($1);
3102 0         0 $bind_operator = $2;
3103             $slash = 'm//';
3104             return '';
3105 0         0 }
3106 86         165 else {
3107             $slash = 'div';
3108             return $e_string;
3109             }
3110             }
3111              
3112 86         284 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
3113 4         8 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3114             $slash = 'div';
3115             return q{Elatin1::PREMATCH()};
3116             }
3117              
3118 4         14 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
3119 28         48 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3120             $slash = 'div';
3121             return q{Elatin1::MATCH()};
3122             }
3123              
3124 28         94 # $', ${'} --> $', ${'}
3125 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3126             $slash = 'div';
3127             return $1;
3128             }
3129              
3130 1         5 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
3131 3         6 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3132             $slash = 'div';
3133             return q{Elatin1::POSTMATCH()};
3134             }
3135              
3136             # scalar variable $scalar =~ tr///;
3137             # scalar variable $scalar =~ s///;
3138             # substr() =~ tr///;
3139 3         11 # substr() =~ s///;
3140             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3141 1671 100       3514 my $scalar = e_string($1);
    100          
3142 1671         6569  
3143 1         2 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3144 1         3 $tr_variable = $scalar;
3145 1         2 $bind_operator = $1;
3146             $slash = 'm//';
3147             return '';
3148 1         3 }
3149 61         139 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3150 61         124 $sub_variable = $scalar;
3151 61         90 $bind_operator = $1;
3152             $slash = 'm//';
3153             return '';
3154 61         176 }
3155 1609         2383 else {
3156             $slash = 'div';
3157             return $scalar;
3158             }
3159             }
3160              
3161 1609         4489 # end of statement
3162             elsif (/\G ( [,;] ) /oxgc) {
3163             $slash = 'm//';
3164 4978         8254  
3165             # clear tr/// variable
3166             $tr_variable = '';
3167 4978         5929  
3168             # clear s/// variable
3169 4978         5403 $sub_variable = '';
3170              
3171 4978         5267 $bind_operator = '';
3172              
3173             return $1;
3174             }
3175              
3176 4978         16166 # bareword
3177             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3178             return $1;
3179             }
3180              
3181 0         0 # $0 --> $0
3182 2         5 elsif (/\G ( \$ 0 ) /oxmsgc) {
3183             $slash = 'div';
3184             return $1;
3185 2         7 }
3186 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3187             $slash = 'div';
3188             return $1;
3189             }
3190              
3191 0         0 # $$ --> $$
3192 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3193             $slash = 'div';
3194             return $1;
3195             }
3196              
3197             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3198 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
3199 4         6 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3200             $slash = 'div';
3201             return e_capture($1);
3202 4         8 }
3203 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3204             $slash = 'div';
3205             return e_capture($1);
3206             }
3207              
3208 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3209 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3210             $slash = 'div';
3211             return e_capture($1.'->'.$2);
3212             }
3213              
3214 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3215 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3216             $slash = 'div';
3217             return e_capture($1.'->'.$2);
3218             }
3219              
3220 0         0 # $$foo
3221 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3222             $slash = 'div';
3223             return e_capture($1);
3224             }
3225              
3226 0         0 # ${ foo }
3227 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3228             $slash = 'div';
3229             return '${' . $1 . '}';
3230             }
3231              
3232 0         0 # ${ ... }
3233 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3234             $slash = 'div';
3235             return e_capture($1);
3236             }
3237              
3238             # variable or function
3239 0         0 # $ @ % & * $ #
3240 42         65 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) {
3241             $slash = 'div';
3242             return $1;
3243             }
3244             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3245 42         132 # $ @ # \ ' " / ? ( ) [ ] < >
3246 62         113 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3247             $slash = 'div';
3248             return $1;
3249             }
3250              
3251 62         214 # while ()
3252             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3253             return $1;
3254             }
3255              
3256             # while () --- glob
3257              
3258             # avoid "Error: Runtime exception" of perl version 5.005_03
3259 0         0  
3260             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3261             return 'while ($_ = Elatin1::glob("' . $1 . '"))';
3262             }
3263              
3264 0         0 # while (glob)
3265             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3266             return 'while ($_ = Elatin1::glob_)';
3267             }
3268              
3269 0         0 # while (glob(WILDCARD))
3270             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3271             return 'while ($_ = Elatin1::glob';
3272             }
3273 0         0  
  248         499  
3274             # doit if, doit unless, doit while, doit until, doit for, doit when
3275             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3276 248         942  
  19         32  
3277 19         63 # subroutines of package Elatin1
  0         0  
3278 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         19  
3279 13         31 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3280 0         0 elsif (/\G \b Latin1::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         155  
3281 114         318 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         4  
3282 2         7 elsif (/\G \b Latin1::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Latin1::escape'; }
  0         0  
3283 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         4  
3284 2         6 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::chop'; }
  0         0  
3285 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3286 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3287 0         0 elsif (/\G \b Latin1::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin1::index'; }
  2         4  
3288 2         6 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::index'; }
  0         0  
3289 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3290 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3291 0         0 elsif (/\G \b Latin1::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin1::rindex'; }
  1         3  
3292 1         3 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::rindex'; }
  0         0  
3293 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::lc'; }
  1         2  
3294 1         3 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::lcfirst'; }
  0         0  
3295 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::uc'; }
  6         10  
3296             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::ucfirst'; }
3297             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::fc'; }
3298 6         18  
  0         0  
3299 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3300 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3301 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3302 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3303 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3304 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3305             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3306 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  
3307 0         0  
  0         0  
3308 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3309 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3310 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3311 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3312 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3313             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3314             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3315 0         0  
  0         0  
3316 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3317 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3318 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3319             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3320 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         7  
3321 2         7  
  2         7  
3322 2         7 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         59  
3323 36         103 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         5  
3324 2         6 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::chr'; }
  8         15  
3325 8         21 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3326 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3327 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::glob'; }
  0         0  
3328 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::lc_'; }
  0         0  
3329 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::lcfirst_'; }
  0         0  
3330 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::uc_'; }
  0         0  
3331 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::ucfirst_'; }
  0         0  
3332             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::fc_'; }
3333 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3334 0         0  
  0         0  
3335 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3336 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3337 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::chr_'; }
  0         0  
3338 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3339 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3340 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::glob_'; }
  8         18  
3341             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3342             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3343 8         28 # split
3344             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3345 87         173 $slash = 'm//';
3346 87         135  
3347 87         306 my $e = '';
3348             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3349             $e .= $1;
3350             }
3351 85 100       330  
  87 100       5656  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3352             # end of split
3353             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Elatin1::split' . $e; }
3354 2         10  
3355             # split scalar value
3356             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Elatin1::split' . $e . e_string($1); }
3357 1         11  
3358 0         0 # split literal space
3359 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Elatin1::split' . $e . qq {qq$1 $2}; }
3360 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3361 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3362 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3363 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3364 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3365 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Elatin1::split' . $e . qq {q$1 $2}; }
3366 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3367 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3368 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3369 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3370 10         43 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3371             elsif (/\G ' [ ] ' /oxgc) { return 'Elatin1::split' . $e . qq {' '}; }
3372             elsif (/\G " [ ] " /oxgc) { return 'Elatin1::split' . $e . qq {" "}; }
3373              
3374 0 0       0 # split qq//
  0         0  
3375             elsif (/\G \b (qq) \b /oxgc) {
3376 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3377 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3378 0         0 while (not /\G \z/oxgc) {
3379 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3380 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3381 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3382 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3383 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3384             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3385 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3386             }
3387             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3388             }
3389             }
3390              
3391 0 50       0 # split qr//
  12         432  
3392             elsif (/\G \b (qr) \b /oxgc) {
3393 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3394 12 50       65 else {
  12 50       3082  
    50          
    50          
    50          
    50          
    50          
    50          
3395 0         0 while (not /\G \z/oxgc) {
3396 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3397 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3398 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3399 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3400 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3401 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3402             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3403 12         91 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3404             }
3405             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3406             }
3407             }
3408              
3409 0 0       0 # split q//
  0         0  
3410             elsif (/\G \b (q) \b /oxgc) {
3411 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3412 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3413 0         0 while (not /\G \z/oxgc) {
3414 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3415 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3416 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3417 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3418 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3419             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3420 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3421             }
3422             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3423             }
3424             }
3425              
3426 0 50       0 # split m//
  18         490  
3427             elsif (/\G \b (m) \b /oxgc) {
3428 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3429 18 50       81 else {
  18 50       3941  
    50          
    50          
    50          
    50          
    50          
    50          
3430 0         0 while (not /\G \z/oxgc) {
3431 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3432 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3433 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3434 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3435 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3436 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3437             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3438 18         118 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3439             }
3440             die __FILE__, ": Search pattern not terminated\n";
3441             }
3442             }
3443              
3444 0         0 # split ''
3445 0         0 elsif (/\G (\') /oxgc) {
3446 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3447 0         0 while (not /\G \z/oxgc) {
3448 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3449 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3450             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3451 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3452             }
3453             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3454             }
3455              
3456 0         0 # split ""
3457 0         0 elsif (/\G (\") /oxgc) {
3458 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3459 0         0 while (not /\G \z/oxgc) {
3460 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3461 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3462             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3463 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3464             }
3465             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3466             }
3467              
3468 0         0 # split //
3469 44         118 elsif (/\G (\/) /oxgc) {
3470 44 50       141 my $regexp = '';
  381 50       1509  
    100          
    50          
3471 0         0 while (not /\G \z/oxgc) {
3472 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3473 44         206 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3474             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3475 337         666 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3476             }
3477             die __FILE__, ": Search pattern not terminated\n";
3478             }
3479             }
3480              
3481             # tr/// or y///
3482              
3483             # about [cdsrbB]* (/B modifier)
3484             #
3485             # P.559 appendix C
3486             # of ISBN 4-89052-384-7 Programming perl
3487             # (Japanese title is: Perl puroguramingu)
3488 0         0  
3489             elsif (/\G \b ( tr | y ) \b /oxgc) {
3490             my $ope = $1;
3491 3 50       6  
3492 3         38 # $1 $2 $3 $4 $5 $6
3493 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3494             my @tr = ($tr_variable,$2);
3495             return e_tr(@tr,'',$4,$6);
3496 0         0 }
3497 3         7 else {
3498 3 50       7 my $e = '';
  3 50       226  
    50          
    50          
    50          
    50          
3499             while (not /\G \z/oxgc) {
3500 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3501 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3502 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3503 0         0 while (not /\G \z/oxgc) {
3504 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3505 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3506 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3507 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3508             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3509 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3510             }
3511             die __FILE__, ": Transliteration replacement not terminated\n";
3512 0         0 }
3513 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3514 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3515 0         0 while (not /\G \z/oxgc) {
3516 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3517 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3518 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3519 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3520             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3521 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3522             }
3523             die __FILE__, ": Transliteration replacement not terminated\n";
3524 0         0 }
3525 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3526 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3527 0         0 while (not /\G \z/oxgc) {
3528 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3529 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3530 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3531 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3532             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3533 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3534             }
3535             die __FILE__, ": Transliteration replacement not terminated\n";
3536 0         0 }
3537 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3538 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3539 0         0 while (not /\G \z/oxgc) {
3540 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3541 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3542 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3543 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3544             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3545 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3546             }
3547             die __FILE__, ": Transliteration replacement not terminated\n";
3548             }
3549 0         0 # $1 $2 $3 $4 $5 $6
3550 3         11 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3551             my @tr = ($tr_variable,$2);
3552             return e_tr(@tr,'',$4,$6);
3553 3         7 }
3554             }
3555             die __FILE__, ": Transliteration pattern not terminated\n";
3556             }
3557             }
3558              
3559 0         0 # qq//
3560             elsif (/\G \b (qq) \b /oxgc) {
3561             my $ope = $1;
3562 2180 50       4735  
3563 2180         3834 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3564 0         0 if (/\G (\#) /oxgc) { # qq# #
3565 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3566 0         0 while (not /\G \z/oxgc) {
3567 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3568 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3569             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3570 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3571             }
3572             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3573             }
3574 0         0  
3575 2180         2929 else {
3576 2180 50       4924 my $e = '';
  2180 50       7793  
    100          
    50          
    50          
    0          
3577             while (not /\G \z/oxgc) {
3578             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3579              
3580 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3581 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3582 0         0 my $qq_string = '';
3583 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3584 0         0 while (not /\G \z/oxgc) {
3585 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3586             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3587 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3588 0         0 elsif (/\G (\)) /oxgc) {
3589             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3590 0         0 else { $qq_string .= $1; }
3591             }
3592 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3593             }
3594             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3595             }
3596              
3597 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3598 2150         8549 elsif (/\G (\{) /oxgc) { # qq { }
3599 2150         2824 my $qq_string = '';
3600 2150 100       4271 local $nest = 1;
  84006 50       280711  
    100          
    100          
    50          
3601 722         1332 while (not /\G \z/oxgc) {
3602 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         2729  
3603             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3604 1153 100       2018 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         4833  
3605 2150         5336 elsif (/\G (\}) /oxgc) {
3606             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3607 1153         2402 else { $qq_string .= $1; }
3608             }
3609 78828         156066 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3610             }
3611             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3612             }
3613              
3614 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3615 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3616 0         0 my $qq_string = '';
3617 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3618 0         0 while (not /\G \z/oxgc) {
3619 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3620             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3621 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3622 0         0 elsif (/\G (\]) /oxgc) {
3623             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3624 0         0 else { $qq_string .= $1; }
3625             }
3626 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3627             }
3628             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3629             }
3630              
3631 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3632 30         52 elsif (/\G (\<) /oxgc) { # qq < >
3633 30         49 my $qq_string = '';
3634 30 100       95 local $nest = 1;
  1166 50       4079  
    50          
    100          
    50          
3635 22         51 while (not /\G \z/oxgc) {
3636 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3637             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3638 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         64  
3639 30         98 elsif (/\G (\>) /oxgc) {
3640             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3641 0         0 else { $qq_string .= $1; }
3642             }
3643 1114         2402 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3644             }
3645             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3646             }
3647              
3648 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3649 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3650 0         0 my $delimiter = $1;
3651 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3652 0         0 while (not /\G \z/oxgc) {
3653 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3654 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3655             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3656 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3657             }
3658             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3659 0         0 }
3660             }
3661             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3662             }
3663             }
3664              
3665 0         0 # qr//
3666 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3667 0         0 my $ope = $1;
3668             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3669             return e_qr($ope,$1,$3,$2,$4);
3670 0         0 }
3671 0         0 else {
3672 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3673 0         0 while (not /\G \z/oxgc) {
3674 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3675 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3676 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3677 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3678 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3679 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3680             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3681 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3682             }
3683             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3684             }
3685             }
3686              
3687 0         0 # qw//
3688 16 50       52 elsif (/\G \b (qw) \b /oxgc) {
3689 16         55 my $ope = $1;
3690             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3691             return e_qw($ope,$1,$3,$2);
3692 0         0 }
3693 16         33 else {
3694 16 50       74 my $e = '';
  16 50       138  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3695             while (not /\G \z/oxgc) {
3696 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3697 16         63  
3698             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3699 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3700 0         0  
3701             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3702 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3703 0         0  
3704             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3705 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3706 0         0  
3707             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3708 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3709 0         0  
3710             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3711 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3712             }
3713             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3714             }
3715             }
3716              
3717 0         0 # qx//
3718 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3719 0         0 my $ope = $1;
3720             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3721             return e_qq($ope,$1,$3,$2);
3722 0         0 }
3723 0         0 else {
3724 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3725 0         0 while (not /\G \z/oxgc) {
3726 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3727 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3728 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3729 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3730 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3731             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3732 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3733             }
3734             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3735             }
3736             }
3737              
3738 0         0 # q//
3739             elsif (/\G \b (q) \b /oxgc) {
3740             my $ope = $1;
3741              
3742             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3743              
3744             # avoid "Error: Runtime exception" of perl version 5.005_03
3745 410 50       1095 # (and so on)
3746 410         982  
3747 0         0 if (/\G (\#) /oxgc) { # q# #
3748 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3749 0         0 while (not /\G \z/oxgc) {
3750 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3751 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3752             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3753 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3754             }
3755             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3756             }
3757 0         0  
3758 410         714 else {
3759 410 50       1184 my $e = '';
  410 50       2049  
    100          
    50          
    100          
    50          
3760             while (not /\G \z/oxgc) {
3761             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3762              
3763 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3764 0         0 elsif (/\G (\() /oxgc) { # q ( )
3765 0         0 my $q_string = '';
3766 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3767 0         0 while (not /\G \z/oxgc) {
3768 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3769 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3770             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3771 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3772 0         0 elsif (/\G (\)) /oxgc) {
3773             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3774 0         0 else { $q_string .= $1; }
3775             }
3776 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3777             }
3778             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3779             }
3780              
3781 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3782 404         678 elsif (/\G (\{) /oxgc) { # q { }
3783 404         634 my $q_string = '';
3784 404 50       1022 local $nest = 1;
  6770 50       24488  
    50          
    100          
    100          
    50          
3785 0         0 while (not /\G \z/oxgc) {
3786 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3787 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         155  
3788             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3789 107 100       202 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         971  
3790 404         997 elsif (/\G (\}) /oxgc) {
3791             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3792 107         209 else { $q_string .= $1; }
3793             }
3794 6152         11367 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3795             }
3796             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3797             }
3798              
3799 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3800 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3801 0         0 my $q_string = '';
3802 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3803 0         0 while (not /\G \z/oxgc) {
3804 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3805 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3806             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3807 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3808 0         0 elsif (/\G (\]) /oxgc) {
3809             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3810 0         0 else { $q_string .= $1; }
3811             }
3812 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3813             }
3814             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3815             }
3816              
3817 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3818 5         13 elsif (/\G (\<) /oxgc) { # q < >
3819 5         10 my $q_string = '';
3820 5 50       182 local $nest = 1;
  88 50       366  
    50          
    50          
    100          
    50          
3821 0         0 while (not /\G \z/oxgc) {
3822 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3823 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3824             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3825 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         15  
3826 5         14 elsif (/\G (\>) /oxgc) {
3827             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3828 0         0 else { $q_string .= $1; }
3829             }
3830 83         160 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3831             }
3832             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3833             }
3834              
3835 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3836 1         3 elsif (/\G (\S) /oxgc) { # q * *
3837 1         2 my $delimiter = $1;
3838 1 50       3 my $q_string = '';
  14 50       62  
    100          
    50          
3839 0         0 while (not /\G \z/oxgc) {
3840 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3841 1         2 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3842             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3843 13         27 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3844             }
3845             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3846 0         0 }
3847             }
3848             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3849             }
3850             }
3851              
3852 0         0 # m//
3853 209 50       478 elsif (/\G \b (m) \b /oxgc) {
3854 209         1313 my $ope = $1;
3855             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3856             return e_qr($ope,$1,$3,$2,$4);
3857 0         0 }
3858 209         305 else {
3859 209 50       578 my $e = '';
  209 50       12788  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3860 0         0 while (not /\G \z/oxgc) {
3861 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3862 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3863 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3864 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3865 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3866 10         32 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3867 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3868             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3869 199         655 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3870             }
3871             die __FILE__, ": Search pattern not terminated\n";
3872             }
3873             }
3874              
3875             # s///
3876              
3877             # about [cegimosxpradlunbB]* (/cg modifier)
3878             #
3879             # P.67 Pattern-Matching Operators
3880             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3881 0         0  
3882             elsif (/\G \b (s) \b /oxgc) {
3883             my $ope = $1;
3884 97 100       248  
3885 97         1631 # $1 $2 $3 $4 $5 $6
3886             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3887             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3888 1         5 }
3889 96         187 else {
3890 96 50       276 my $e = '';
  96 50       11850  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3891             while (not /\G \z/oxgc) {
3892 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3893 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3894 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3895             while (not /\G \z/oxgc) {
3896 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3897 0         0 # $1 $2 $3 $4
3898 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3899 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3900 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3901 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3902 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3903 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3904 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3905             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3906 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3907             }
3908             die __FILE__, ": Substitution replacement not terminated\n";
3909 0         0 }
3910 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3911 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3912             while (not /\G \z/oxgc) {
3913 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3914 0         0 # $1 $2 $3 $4
3915 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3916 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3917 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3918 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3919 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3920 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3921 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3922             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3923 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3924             }
3925             die __FILE__, ": Substitution replacement not terminated\n";
3926 0         0 }
3927 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3928 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3929             while (not /\G \z/oxgc) {
3930 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3931 0         0 # $1 $2 $3 $4
3932 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3933 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3934 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3935 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3936 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3937             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3938 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3939             }
3940             die __FILE__, ": Substitution replacement not terminated\n";
3941 0         0 }
3942 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3943 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3944             while (not /\G \z/oxgc) {
3945 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3946 0         0 # $1 $2 $3 $4
3947 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3948 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3949 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3950 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3951 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3952 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3953 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3954             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3955 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3956             }
3957             die __FILE__, ": Substitution replacement not terminated\n";
3958             }
3959 0         0 # $1 $2 $3 $4 $5 $6
3960             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3961             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3962             }
3963 21         67 # $1 $2 $3 $4 $5 $6
3964             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3965             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3966             }
3967 0         0 # $1 $2 $3 $4 $5 $6
3968             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3969             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3970             }
3971 0         0 # $1 $2 $3 $4 $5 $6
3972             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3973             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3974 75         337 }
3975             }
3976             die __FILE__, ": Substitution pattern not terminated\n";
3977             }
3978             }
3979 0         0  
3980 0         0 # require ignore module
3981 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
3982             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
3983             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
3984 0         0  
3985 37         281 # use strict; --> use strict; no strict qw(refs);
3986 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
3987             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
3988             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
3989              
3990 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
3991 2         23 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
3992             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
3993             return "use $1; no strict qw(refs);";
3994 0         0 }
3995             else {
3996             return "use $1;";
3997             }
3998 2 0 0     12 }
      0        
3999 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4000             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4001             return "use $1; no strict qw(refs);";
4002 0         0 }
4003             else {
4004             return "use $1;";
4005             }
4006             }
4007 0         0  
4008 2         20 # ignore use module
4009 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4010             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4011             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4012 0         0  
4013 0         0 # ignore no module
4014 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4015             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4016             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4017 0         0  
4018             # use else
4019             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4020 0         0  
4021             # use else
4022             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4023              
4024 2         9 # ''
4025 848         1643 elsif (/\G (?
4026 848 100       2101 my $q_string = '';
  8254 100       24419  
    100          
    50          
4027 4         10 while (not /\G \z/oxgc) {
4028 48         112 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4029 848         1835 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4030             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4031 7354         14365 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4032             }
4033             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4034             }
4035              
4036 0         0 # ""
4037 1764         3380 elsif (/\G (\") /oxgc) {
4038 1764 100       4154 my $qq_string = '';
  34989 100       99094  
    100          
    50          
4039 67         142 while (not /\G \z/oxgc) {
4040 12         27 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4041 1764         3894 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4042             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4043 33146         72037 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4044             }
4045             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4046             }
4047              
4048 0         0 # ``
4049 1         3 elsif (/\G (\`) /oxgc) {
4050 1 50       4 my $qx_string = '';
  19 50       64  
    100          
    50          
4051 0         0 while (not /\G \z/oxgc) {
4052 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4053 1         2 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4054             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4055 18         35 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4056             }
4057             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4058             }
4059              
4060 0         0 # // --- not divide operator (num / num), not defined-or
4061 453         1446 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4062 453 50       1236 my $regexp = '';
  4496 50       14738  
    100          
    50          
4063 0         0 while (not /\G \z/oxgc) {
4064 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4065 453         1583 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4066             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4067 4043         9240 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4068             }
4069             die __FILE__, ": Search pattern not terminated\n";
4070             }
4071              
4072 0         0 # ?? --- not conditional operator (condition ? then : else)
4073 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4074 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4075 0         0 while (not /\G \z/oxgc) {
4076 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4077 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4078             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4079 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4080             }
4081             die __FILE__, ": Search pattern not terminated\n";
4082             }
4083 0         0  
  0         0  
4084             # <<>> (a safer ARGV)
4085             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4086 0         0  
  0         0  
4087             # << (bit shift) --- not here document
4088             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4089              
4090 0         0 # <<~'HEREDOC'
4091 6         11 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4092 6         10 $slash = 'm//';
4093             my $here_quote = $1;
4094             my $delimiter = $2;
4095 6 50       9  
4096 6         13 # get here document
4097 6         26 if ($here_script eq '') {
4098             $here_script = CORE::substr $_, pos $_;
4099 6 50       26 $here_script =~ s/.*?\n//oxm;
4100 6         51 }
4101 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4102 6         7 my $heredoc = $1;
4103 6         44 my $indent = $2;
4104 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4105             push @heredoc, $heredoc . qq{\n$delimiter\n};
4106             push @heredoc_delimiter, qq{\\s*$delimiter};
4107 6         11 }
4108             else {
4109 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4110             }
4111             return qq{<<'$delimiter'};
4112             }
4113              
4114             # <<~\HEREDOC
4115              
4116             # P.66 2.6.6. "Here" Documents
4117             # in Chapter 2: Bits and Pieces
4118             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4119              
4120             # P.73 "Here" Documents
4121             # in Chapter 2: Bits and Pieces
4122             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4123 6         28  
4124 3         6 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4125 3         6 $slash = 'm//';
4126             my $here_quote = $1;
4127             my $delimiter = $2;
4128 3 50       4  
4129 3         7 # get here document
4130 3         20 if ($here_script eq '') {
4131             $here_script = CORE::substr $_, pos $_;
4132 3 50       15 $here_script =~ s/.*?\n//oxm;
4133 3         43 }
4134 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4135 3         4 my $heredoc = $1;
4136 3         33 my $indent = $2;
4137 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
4138             push @heredoc, $heredoc . qq{\n$delimiter\n};
4139             push @heredoc_delimiter, qq{\\s*$delimiter};
4140 3         6 }
4141             else {
4142 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4143             }
4144             return qq{<<\\$delimiter};
4145             }
4146              
4147 3         12 # <<~"HEREDOC"
4148 6         11 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4149 6         12 $slash = 'm//';
4150             my $here_quote = $1;
4151             my $delimiter = $2;
4152 6 50       8  
4153 6         12 # get here document
4154 6         27 if ($here_script eq '') {
4155             $here_script = CORE::substr $_, pos $_;
4156 6 50       29 $here_script =~ s/.*?\n//oxm;
4157 6         53 }
4158 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4159 6         9 my $heredoc = $1;
4160 6         43 my $indent = $2;
4161 6         15 $heredoc =~ s{^$indent}{}msg; # no /ox
4162             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4163             push @heredoc_delimiter, qq{\\s*$delimiter};
4164 6         13 }
4165             else {
4166 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4167             }
4168             return qq{<<"$delimiter"};
4169             }
4170              
4171 6         23 # <<~HEREDOC
4172 3         7 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4173 3         6 $slash = 'm//';
4174             my $here_quote = $1;
4175             my $delimiter = $2;
4176 3 50       5  
4177 3         7 # get here document
4178 3         10 if ($here_script eq '') {
4179             $here_script = CORE::substr $_, pos $_;
4180 3 50       23 $here_script =~ s/.*?\n//oxm;
4181 3         50 }
4182 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4183 3         6 my $heredoc = $1;
4184 3         34 my $indent = $2;
4185 3         10 $heredoc =~ s{^$indent}{}msg; # no /ox
4186             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4187             push @heredoc_delimiter, qq{\\s*$delimiter};
4188 3         8 }
4189             else {
4190 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4191             }
4192             return qq{<<$delimiter};
4193             }
4194              
4195 3         14 # <<~`HEREDOC`
4196 6         9 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4197 6         12 $slash = 'm//';
4198             my $here_quote = $1;
4199             my $delimiter = $2;
4200 6 50       9  
4201 6         11 # get here document
4202 6         21 if ($here_script eq '') {
4203             $here_script = CORE::substr $_, pos $_;
4204 6 50       30 $here_script =~ s/.*?\n//oxm;
4205 6         76 }
4206 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4207 6         9 my $heredoc = $1;
4208 6         45 my $indent = $2;
4209 6         18 $heredoc =~ s{^$indent}{}msg; # no /ox
4210             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4211             push @heredoc_delimiter, qq{\\s*$delimiter};
4212 6         13 }
4213             else {
4214 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4215             }
4216             return qq{<<`$delimiter`};
4217             }
4218              
4219 6         21 # <<'HEREDOC'
4220 72         137 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4221 72         150 $slash = 'm//';
4222             my $here_quote = $1;
4223             my $delimiter = $2;
4224 72 50       110  
4225 72         143 # get here document
4226 72         396 if ($here_script eq '') {
4227             $here_script = CORE::substr $_, pos $_;
4228 72 50       376 $here_script =~ s/.*?\n//oxm;
4229 72         516 }
4230 72         226 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4231             push @heredoc, $1 . qq{\n$delimiter\n};
4232             push @heredoc_delimiter, $delimiter;
4233 72         107 }
4234             else {
4235 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4236             }
4237             return $here_quote;
4238             }
4239              
4240             # <<\HEREDOC
4241              
4242             # P.66 2.6.6. "Here" Documents
4243             # in Chapter 2: Bits and Pieces
4244             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4245              
4246             # P.73 "Here" Documents
4247             # in Chapter 2: Bits and Pieces
4248             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4249 72         269  
4250 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4251 0         0 $slash = 'm//';
4252             my $here_quote = $1;
4253             my $delimiter = $2;
4254 0 0       0  
4255 0         0 # get here document
4256 0         0 if ($here_script eq '') {
4257             $here_script = CORE::substr $_, pos $_;
4258 0 0       0 $here_script =~ s/.*?\n//oxm;
4259 0         0 }
4260 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4261             push @heredoc, $1 . qq{\n$delimiter\n};
4262             push @heredoc_delimiter, $delimiter;
4263 0         0 }
4264             else {
4265 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4266             }
4267             return $here_quote;
4268             }
4269              
4270 0         0 # <<"HEREDOC"
4271 36         83 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4272 36         83 $slash = 'm//';
4273             my $here_quote = $1;
4274             my $delimiter = $2;
4275 36 50       64  
4276 36         145 # get here document
4277 36         301 if ($here_script eq '') {
4278             $here_script = CORE::substr $_, pos $_;
4279 36 50       224 $here_script =~ s/.*?\n//oxm;
4280 36         445 }
4281 36         109 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4282             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4283             push @heredoc_delimiter, $delimiter;
4284 36         104 }
4285             else {
4286 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4287             }
4288             return $here_quote;
4289             }
4290              
4291 36         148 # <
4292 42         96 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4293 42         92 $slash = 'm//';
4294             my $here_quote = $1;
4295             my $delimiter = $2;
4296 42 50       75  
4297 42         109 # get here document
4298 42         296 if ($here_script eq '') {
4299             $here_script = CORE::substr $_, pos $_;
4300 42 50       271 $here_script =~ s/.*?\n//oxm;
4301 42         570 }
4302 42         147 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4303             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4304             push @heredoc_delimiter, $delimiter;
4305 42         99 }
4306             else {
4307 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4308             }
4309             return $here_quote;
4310             }
4311              
4312 42         189 # <<`HEREDOC`
4313 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4314 0         0 $slash = 'm//';
4315             my $here_quote = $1;
4316             my $delimiter = $2;
4317 0 0       0  
4318 0         0 # get here document
4319 0         0 if ($here_script eq '') {
4320             $here_script = CORE::substr $_, pos $_;
4321 0 0       0 $here_script =~ s/.*?\n//oxm;
4322 0         0 }
4323 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4324             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4325             push @heredoc_delimiter, $delimiter;
4326 0         0 }
4327             else {
4328 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4329             }
4330             return $here_quote;
4331             }
4332              
4333 0         0 # <<= <=> <= < operator
4334             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4335             return $1;
4336             }
4337              
4338 12         61 #
4339             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4340             return $1;
4341             }
4342              
4343             # --- glob
4344              
4345             # avoid "Error: Runtime exception" of perl version 5.005_03
4346 0         0  
4347             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4348             return 'Elatin1::glob("' . $1 . '")';
4349             }
4350 0         0  
4351             # __DATA__
4352             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4353 0         0  
4354             # __END__
4355             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4356              
4357             # \cD Control-D
4358              
4359             # P.68 2.6.8. Other Literal Tokens
4360             # in Chapter 2: Bits and Pieces
4361             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4362              
4363             # P.76 Other Literal Tokens
4364             # in Chapter 2: Bits and Pieces
4365 204         1453 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4366              
4367             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4368 0         0  
4369             # \cZ Control-Z
4370             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4371              
4372             # any operator before div
4373             elsif (/\G (
4374             -- | \+\+ |
4375 0         0 [\)\}\]]
  5081         10897  
4376              
4377             ) /oxgc) { $slash = 'div'; return $1; }
4378              
4379             # yada-yada or triple-dot operator
4380             elsif (/\G (
4381 5081         26868 \.\.\.
  7         12  
4382              
4383             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4384              
4385             # any operator before m//
4386              
4387             # //, //= (defined-or)
4388              
4389             # P.164 Logical Operators
4390             # in Chapter 10: More Control Structures
4391             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4392              
4393             # P.119 C-Style Logical (Short-Circuit) Operators
4394             # in Chapter 3: Unary and Binary Operators
4395             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4396              
4397             # (and so on)
4398              
4399             # ~~
4400              
4401             # P.221 The Smart Match Operator
4402             # in Chapter 15: Smart Matching and given-when
4403             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4404              
4405             # P.112 Smartmatch Operator
4406             # in Chapter 3: Unary and Binary Operators
4407             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4408              
4409             # (and so on)
4410              
4411             elsif (/\G ((?>
4412              
4413             !~~ | !~ | != | ! |
4414             %= | % |
4415             &&= | && | &= | &\.= | &\. | & |
4416             -= | -> | - |
4417             :(?>\s*)= |
4418             : |
4419             <<>> |
4420             <<= | <=> | <= | < |
4421             == | => | =~ | = |
4422             >>= | >> | >= | > |
4423             \*\*= | \*\* | \*= | \* |
4424             \+= | \+ |
4425             \.\. | \.= | \. |
4426             \/\/= | \/\/ |
4427             \/= | \/ |
4428             \? |
4429             \\ |
4430             \^= | \^\.= | \^\. | \^ |
4431             \b x= |
4432             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4433             ~~ | ~\. | ~ |
4434             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4435             \b(?: print )\b |
4436              
4437 7         24 [,;\(\{\[]
  8826         16772  
4438              
4439             )) /oxgc) { $slash = 'm//'; return $1; }
4440 8826         37602  
  15137         27499  
4441             # other any character
4442             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4443              
4444 15137         79309 # system error
4445             else {
4446             die __FILE__, ": Oops, this shouldn't happen!\n";
4447             }
4448             }
4449              
4450 0     1786 0 0 # escape Latin-1 string
4451 1786         3925 sub e_string {
4452             my($string) = @_;
4453 1786         2442 my $e_string = '';
4454              
4455             local $slash = 'm//';
4456              
4457             # P.1024 Appendix W.10 Multibyte Processing
4458             # of ISBN 1-56592-224-7 CJKV Information Processing
4459 1786         2429 # (and so on)
4460              
4461             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4462 1786 100 66     13023  
4463 1786 50       7572 # without { ... }
4464 1769         3767 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4465             if ($string !~ /<
4466             return $string;
4467             }
4468             }
4469 1769         4146  
4470 17 50       64 E_STRING_LOOP:
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
4471             while ($string !~ /\G \z/oxgc) {
4472             if (0) {
4473             }
4474 190         11399  
4475 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Elatin1::PREMATCH()]}
4476 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4477             $e_string .= q{Elatin1::PREMATCH()};
4478             $slash = 'div';
4479             }
4480              
4481 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Elatin1::MATCH()]}
4482 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4483             $e_string .= q{Elatin1::MATCH()};
4484             $slash = 'div';
4485             }
4486              
4487 0         0 # $', ${'} --> $', ${'}
4488 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4489             $e_string .= $1;
4490             $slash = 'div';
4491             }
4492              
4493 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Elatin1::POSTMATCH()]}
4494 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4495             $e_string .= q{Elatin1::POSTMATCH()};
4496             $slash = 'div';
4497             }
4498              
4499 0         0 # bareword
4500 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4501             $e_string .= $1;
4502             $slash = 'div';
4503             }
4504              
4505 0         0 # $0 --> $0
4506 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4507             $e_string .= $1;
4508             $slash = 'div';
4509 0         0 }
4510 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4511             $e_string .= $1;
4512             $slash = 'div';
4513             }
4514              
4515 0         0 # $$ --> $$
4516 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4517             $e_string .= $1;
4518             $slash = 'div';
4519             }
4520              
4521             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4522 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4523 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4524             $e_string .= e_capture($1);
4525             $slash = 'div';
4526 0         0 }
4527 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4528             $e_string .= e_capture($1);
4529             $slash = 'div';
4530             }
4531              
4532 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4533 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4534             $e_string .= e_capture($1.'->'.$2);
4535             $slash = 'div';
4536             }
4537              
4538 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4539 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4540             $e_string .= e_capture($1.'->'.$2);
4541             $slash = 'div';
4542             }
4543              
4544 0         0 # $$foo
4545 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4546             $e_string .= e_capture($1);
4547             $slash = 'div';
4548             }
4549              
4550 0         0 # ${ foo }
4551 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4552             $e_string .= '${' . $1 . '}';
4553             $slash = 'div';
4554             }
4555              
4556 0         0 # ${ ... }
4557 3         10 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4558             $e_string .= e_capture($1);
4559             $slash = 'div';
4560             }
4561              
4562             # variable or function
4563 3         14 # $ @ % & * $ #
4564 7         20 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) {
4565             $e_string .= $1;
4566             $slash = 'div';
4567             }
4568             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4569 7         23 # $ @ # \ ' " / ? ( ) [ ] < >
4570 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4571             $e_string .= $1;
4572             $slash = 'div';
4573             }
4574 0         0  
  0         0  
4575 0         0 # subroutines of package Elatin1
  0         0  
4576 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4577 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4578 0         0 elsif ($string =~ /\G \b Latin1::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4579 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4580 0         0 elsif ($string =~ /\G \b Latin1::eval \b /oxgc) { $e_string .= 'eval Latin1::escape'; $slash = 'm//'; }
  0         0  
4581 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4582 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Elatin1::chop'; $slash = 'm//'; }
  0         0  
4583 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4584 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4585 0         0 elsif ($string =~ /\G \b Latin1::index \b /oxgc) { $e_string .= 'Latin1::index'; $slash = 'm//'; }
  0         0  
4586 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Elatin1::index'; $slash = 'm//'; }
  0         0  
4587 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4588 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4589 0         0 elsif ($string =~ /\G \b Latin1::rindex \b /oxgc) { $e_string .= 'Latin1::rindex'; $slash = 'm//'; }
  0         0  
4590 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Elatin1::rindex'; $slash = 'm//'; }
  0         0  
4591 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin1::lc'; $slash = 'm//'; }
  0         0  
4592 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin1::lcfirst'; $slash = 'm//'; }
  0         0  
4593 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin1::uc'; $slash = 'm//'; }
  0         0  
4594             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin1::ucfirst'; $slash = 'm//'; }
4595             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin1::fc'; $slash = 'm//'; }
4596 0         0  
  0         0  
4597 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4598 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4599 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  
4600 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  
4601 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  
4602 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  
4603             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
4604 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  
4605 0         0  
  0         0  
4606 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4607 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  
4608 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  
4609 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  
4610 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  
4611             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4612             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4613 0         0  
  0         0  
4614 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
4615 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4616 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4617             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
4618 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4619 0         0  
  0         0  
4620 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4621 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4622 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin1::chr'; $slash = 'm//'; }
  0         0  
4623 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4624 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4625 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Elatin1::glob'; $slash = 'm//'; }
  0         0  
4626 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Elatin1::lc_'; $slash = 'm//'; }
  0         0  
4627 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Elatin1::lcfirst_'; $slash = 'm//'; }
  0         0  
4628 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Elatin1::uc_'; $slash = 'm//'; }
  0         0  
4629 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Elatin1::ucfirst_'; $slash = 'm//'; }
  0         0  
4630             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Elatin1::fc_'; $slash = 'm//'; }
4631 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4632 0         0  
  0         0  
4633 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4634 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4635 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Elatin1::chr_'; $slash = 'm//'; }
  0         0  
4636 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4637 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4638 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Elatin1::glob_'; $slash = 'm//'; }
  0         0  
4639             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
4640             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
4641 0         0 # split
4642             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4643 0         0 $slash = 'm//';
4644 0         0  
4645 0         0 my $e = '';
4646             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4647             $e .= $1;
4648             }
4649 0 0       0  
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
4650             # end of split
4651             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Elatin1::split' . $e; }
4652 0         0  
  0         0  
4653             # split scalar value
4654             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Elatin1::split' . $e . e_string($1); next E_STRING_LOOP; }
4655 0         0  
  0         0  
4656 0         0 # split literal space
  0         0  
4657 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4658 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4659 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4660 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4661 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4662 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4663 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4664 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4665 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4666 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4667 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4668 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Elatin1::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4669             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Elatin1::split' . $e . qq {' '}; next E_STRING_LOOP; }
4670             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Elatin1::split' . $e . qq {" "}; next E_STRING_LOOP; }
4671              
4672 0 0       0 # split qq//
  0         0  
  0         0  
4673             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4674 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
4675 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4676 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4677 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4678 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  
4679 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  
4680 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  
4681 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  
4682             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
4683 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 * *
4684             }
4685             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4686             }
4687             }
4688              
4689 0 0       0 # split qr//
  0         0  
  0         0  
4690             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4691 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
4692 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4693 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4694 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4695 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  
4696 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  
4697 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  
4698 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  
4699 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  
4700             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
4701 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 * *
4702             }
4703             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4704             }
4705             }
4706              
4707 0 0       0 # split q//
  0         0  
  0         0  
4708             elsif ($string =~ /\G \b (q) \b /oxgc) {
4709 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
4710 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4711 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4712 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4713 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  
4714 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  
4715 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  
4716 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  
4717             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
4718 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 * *
4719             }
4720             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4721             }
4722             }
4723              
4724 0 0       0 # split m//
  0         0  
  0         0  
4725             elsif ($string =~ /\G \b (m) \b /oxgc) {
4726 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 # #
4727 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4728 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4729 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4730 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  
4731 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  
4732 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  
4733 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  
4734 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  
4735             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
4736 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 * *
4737             }
4738             die __FILE__, ": Search pattern not terminated\n";
4739             }
4740             }
4741              
4742 0         0 # split ''
4743 0         0 elsif ($string =~ /\G (\') /oxgc) {
4744 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
4745 0         0 while ($string !~ /\G \z/oxgc) {
4746 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
4747 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4748             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
4749 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4750             }
4751             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4752             }
4753              
4754 0         0 # split ""
4755 0         0 elsif ($string =~ /\G (\") /oxgc) {
4756 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
4757 0         0 while ($string !~ /\G \z/oxgc) {
4758 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
4759 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4760             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
4761 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4762             }
4763             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4764             }
4765              
4766 0         0 # split //
4767 0         0 elsif ($string =~ /\G (\/) /oxgc) {
4768 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4769 0         0 while ($string !~ /\G \z/oxgc) {
4770 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
4771 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4772             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
4773 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4774             }
4775             die __FILE__, ": Search pattern not terminated\n";
4776             }
4777             }
4778              
4779 0         0 # qq//
4780 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4781 0         0 my $ope = $1;
4782             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4783             $e_string .= e_qq($ope,$1,$3,$2);
4784 0         0 }
4785 0         0 else {
4786 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4787 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4788 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4789 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4790 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4791 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4792             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4793 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4794             }
4795             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4796             }
4797             }
4798              
4799 0         0 # qx//
4800 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4801 0         0 my $ope = $1;
4802             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4803             $e_string .= e_qq($ope,$1,$3,$2);
4804 0         0 }
4805 0         0 else {
4806 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4807 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4808 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4809 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4810 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4811 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4812 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4813             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4814 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4815             }
4816             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4817             }
4818             }
4819              
4820 0         0 # q//
4821 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4822 0         0 my $ope = $1;
4823             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4824             $e_string .= e_q($ope,$1,$3,$2);
4825 0         0 }
4826 0         0 else {
4827 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4828 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4829 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4830 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4831 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4832 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4833             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4834 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 * *
4835             }
4836             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4837             }
4838             }
4839 0         0  
4840             # ''
4841             elsif ($string =~ /\G (?
4842 0         0  
4843             # ""
4844             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4845 0         0  
4846             # ``
4847             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4848 0         0  
4849             # <<>> (a safer ARGV)
4850             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4851 0         0  
4852             # <<= <=> <= < operator
4853             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4854 0         0  
4855             #
4856             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4857              
4858 0         0 # --- glob
4859             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4860             $e_string .= 'Elatin1::glob("' . $1 . '")';
4861             }
4862              
4863 0         0 # << (bit shift) --- not here document
4864 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
4865             $slash = 'm//';
4866             $e_string .= $1;
4867             }
4868              
4869 0         0 # <<~'HEREDOC'
4870 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4871 0         0 $slash = 'm//';
4872             my $here_quote = $1;
4873             my $delimiter = $2;
4874 0 0       0  
4875 0         0 # get here document
4876 0         0 if ($here_script eq '') {
4877             $here_script = CORE::substr $_, pos $_;
4878 0 0       0 $here_script =~ s/.*?\n//oxm;
4879 0         0 }
4880 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4881 0         0 my $heredoc = $1;
4882 0         0 my $indent = $2;
4883 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4884             push @heredoc, $heredoc . qq{\n$delimiter\n};
4885             push @heredoc_delimiter, qq{\\s*$delimiter};
4886 0         0 }
4887             else {
4888 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4889             }
4890             $e_string .= qq{<<'$delimiter'};
4891             }
4892              
4893 0         0 # <<~\HEREDOC
4894 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4895 0         0 $slash = 'm//';
4896             my $here_quote = $1;
4897             my $delimiter = $2;
4898 0 0       0  
4899 0         0 # get here document
4900 0         0 if ($here_script eq '') {
4901             $here_script = CORE::substr $_, pos $_;
4902 0 0       0 $here_script =~ s/.*?\n//oxm;
4903 0         0 }
4904 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4905 0         0 my $heredoc = $1;
4906 0         0 my $indent = $2;
4907 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4908             push @heredoc, $heredoc . qq{\n$delimiter\n};
4909             push @heredoc_delimiter, qq{\\s*$delimiter};
4910 0         0 }
4911             else {
4912 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4913             }
4914             $e_string .= qq{<<\\$delimiter};
4915             }
4916              
4917 0         0 # <<~"HEREDOC"
4918 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4919 0         0 $slash = 'm//';
4920             my $here_quote = $1;
4921             my $delimiter = $2;
4922 0 0       0  
4923 0         0 # get here document
4924 0         0 if ($here_script eq '') {
4925             $here_script = CORE::substr $_, pos $_;
4926 0 0       0 $here_script =~ s/.*?\n//oxm;
4927 0         0 }
4928 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4929 0         0 my $heredoc = $1;
4930 0         0 my $indent = $2;
4931 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4932             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4933             push @heredoc_delimiter, qq{\\s*$delimiter};
4934 0         0 }
4935             else {
4936 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4937             }
4938             $e_string .= qq{<<"$delimiter"};
4939             }
4940              
4941 0         0 # <<~HEREDOC
4942 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4943 0         0 $slash = 'm//';
4944             my $here_quote = $1;
4945             my $delimiter = $2;
4946 0 0       0  
4947 0         0 # get here document
4948 0         0 if ($here_script eq '') {
4949             $here_script = CORE::substr $_, pos $_;
4950 0 0       0 $here_script =~ s/.*?\n//oxm;
4951 0         0 }
4952 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4953 0         0 my $heredoc = $1;
4954 0         0 my $indent = $2;
4955 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4956             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4957             push @heredoc_delimiter, qq{\\s*$delimiter};
4958 0         0 }
4959             else {
4960 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4961             }
4962             $e_string .= qq{<<$delimiter};
4963             }
4964              
4965 0         0 # <<~`HEREDOC`
4966 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4967 0         0 $slash = 'm//';
4968             my $here_quote = $1;
4969             my $delimiter = $2;
4970 0 0       0  
4971 0         0 # get here document
4972 0         0 if ($here_script eq '') {
4973             $here_script = CORE::substr $_, pos $_;
4974 0 0       0 $here_script =~ s/.*?\n//oxm;
4975 0         0 }
4976 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4977 0         0 my $heredoc = $1;
4978 0         0 my $indent = $2;
4979 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4980             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4981             push @heredoc_delimiter, qq{\\s*$delimiter};
4982 0         0 }
4983             else {
4984 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4985             }
4986             $e_string .= qq{<<`$delimiter`};
4987             }
4988              
4989 0         0 # <<'HEREDOC'
4990 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4991 0         0 $slash = 'm//';
4992             my $here_quote = $1;
4993             my $delimiter = $2;
4994 0 0       0  
4995 0         0 # get here document
4996 0         0 if ($here_script eq '') {
4997             $here_script = CORE::substr $_, pos $_;
4998 0 0       0 $here_script =~ s/.*?\n//oxm;
4999 0         0 }
5000 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5001             push @heredoc, $1 . qq{\n$delimiter\n};
5002             push @heredoc_delimiter, $delimiter;
5003 0         0 }
5004             else {
5005 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5006             }
5007             $e_string .= $here_quote;
5008             }
5009              
5010 0         0 # <<\HEREDOC
5011 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5012 0         0 $slash = 'm//';
5013             my $here_quote = $1;
5014             my $delimiter = $2;
5015 0 0       0  
5016 0         0 # get here document
5017 0         0 if ($here_script eq '') {
5018             $here_script = CORE::substr $_, pos $_;
5019 0 0       0 $here_script =~ s/.*?\n//oxm;
5020 0         0 }
5021 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5022             push @heredoc, $1 . qq{\n$delimiter\n};
5023             push @heredoc_delimiter, $delimiter;
5024 0         0 }
5025             else {
5026 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5027             }
5028             $e_string .= $here_quote;
5029             }
5030              
5031 0         0 # <<"HEREDOC"
5032 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5033 0         0 $slash = 'm//';
5034             my $here_quote = $1;
5035             my $delimiter = $2;
5036 0 0       0  
5037 0         0 # get here document
5038 0         0 if ($here_script eq '') {
5039             $here_script = CORE::substr $_, pos $_;
5040 0 0       0 $here_script =~ s/.*?\n//oxm;
5041 0         0 }
5042 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5043             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5044             push @heredoc_delimiter, $delimiter;
5045 0         0 }
5046             else {
5047 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5048             }
5049             $e_string .= $here_quote;
5050             }
5051              
5052 0         0 # <
5053 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5054 0         0 $slash = 'm//';
5055             my $here_quote = $1;
5056             my $delimiter = $2;
5057 0 0       0  
5058 0         0 # get here document
5059 0         0 if ($here_script eq '') {
5060             $here_script = CORE::substr $_, pos $_;
5061 0 0       0 $here_script =~ s/.*?\n//oxm;
5062 0         0 }
5063 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5064             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5065             push @heredoc_delimiter, $delimiter;
5066 0         0 }
5067             else {
5068 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5069             }
5070             $e_string .= $here_quote;
5071             }
5072              
5073 0         0 # <<`HEREDOC`
5074 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5075 0         0 $slash = 'm//';
5076             my $here_quote = $1;
5077             my $delimiter = $2;
5078 0 0       0  
5079 0         0 # get here document
5080 0         0 if ($here_script eq '') {
5081             $here_script = CORE::substr $_, pos $_;
5082 0 0       0 $here_script =~ s/.*?\n//oxm;
5083 0         0 }
5084 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5085             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5086             push @heredoc_delimiter, $delimiter;
5087 0         0 }
5088             else {
5089 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5090             }
5091             $e_string .= $here_quote;
5092             }
5093              
5094             # any operator before div
5095             elsif ($string =~ /\G (
5096             -- | \+\+ |
5097 0         0 [\)\}\]]
  18         31  
5098              
5099             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
5100              
5101             # yada-yada or triple-dot operator
5102             elsif ($string =~ /\G (
5103 18         72 \.\.\.
  0         0  
5104              
5105             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
5106              
5107             # any operator before m//
5108             elsif ($string =~ /\G ((?>
5109              
5110             !~~ | !~ | != | ! |
5111             %= | % |
5112             &&= | && | &= | &\.= | &\. | & |
5113             -= | -> | - |
5114             :(?>\s*)= |
5115             : |
5116             <<>> |
5117             <<= | <=> | <= | < |
5118             == | => | =~ | = |
5119             >>= | >> | >= | > |
5120             \*\*= | \*\* | \*= | \* |
5121             \+= | \+ |
5122             \.\. | \.= | \. |
5123             \/\/= | \/\/ |
5124             \/= | \/ |
5125             \? |
5126             \\ |
5127             \^= | \^\.= | \^\. | \^ |
5128             \b x= |
5129             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
5130             ~~ | ~\. | ~ |
5131             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
5132             \b(?: print )\b |
5133              
5134 0         0 [,;\(\{\[]
  31         57  
5135              
5136             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
5137 31         104  
5138             # other any character
5139             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
5140              
5141 131         347 # system error
5142             else {
5143             die __FILE__, ": Oops, this shouldn't happen!\n";
5144             }
5145 0         0 }
5146              
5147             return $e_string;
5148             }
5149              
5150             #
5151             # character class
5152 17     1919 0 75 #
5153             sub character_class {
5154 1919 100       3332 my($char,$modifier) = @_;
5155 1919 100       3091  
5156 52         186 if ($char eq '.') {
5157             if ($modifier =~ /s/) {
5158             return '${Elatin1::dot_s}';
5159 17         43 }
5160             else {
5161             return '${Elatin1::dot}';
5162             }
5163 35         77 }
5164             else {
5165             return Elatin1::classic_character_class($char);
5166             }
5167             }
5168              
5169             #
5170             # escape capture ($1, $2, $3, ...)
5171             #
5172 1867     212 0 3326 sub e_capture {
5173              
5174             return join '', '${', $_[0], '}';
5175             }
5176              
5177             #
5178             # escape transliteration (tr/// or y///)
5179 212     3 0 756 #
5180 3         15 sub e_tr {
5181 3   50     6 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
5182             my $e_tr = '';
5183 3         6 $modifier ||= '';
5184              
5185             $slash = 'div';
5186 3         3  
5187             # quote character class 1
5188             $charclass = q_tr($charclass);
5189 3         6  
5190             # quote character class 2
5191             $charclass2 = q_tr($charclass2);
5192 3 50       4  
5193 3 0       8 # /b /B modifier
5194 0         0 if ($modifier =~ tr/bB//d) {
5195             if ($variable eq '') {
5196             $e_tr = qq{tr$charclass$e$charclass2$modifier};
5197 0         0 }
5198             else {
5199             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
5200             }
5201 0 100       0 }
5202 3         6 else {
5203             if ($variable eq '') {
5204             $e_tr = qq{Elatin1::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
5205 2         5 }
5206             else {
5207             $e_tr = qq{Elatin1::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
5208             }
5209             }
5210 1         3  
5211 3         5 # clear tr/// variable
5212             $tr_variable = '';
5213 3         3 $bind_operator = '';
5214              
5215             return $e_tr;
5216             }
5217              
5218             #
5219             # quote for escape transliteration (tr/// or y///)
5220 3     6 0 16 #
5221             sub q_tr {
5222             my($charclass) = @_;
5223 6 50       8  
    0          
    0          
    0          
    0          
    0          
5224 6         13 # quote character class
5225             if ($charclass !~ /'/oxms) {
5226             return e_q('', "'", "'", $charclass); # --> q' '
5227 6         8 }
5228             elsif ($charclass !~ /\//oxms) {
5229             return e_q('q', '/', '/', $charclass); # --> q/ /
5230 0         0 }
5231             elsif ($charclass !~ /\#/oxms) {
5232             return e_q('q', '#', '#', $charclass); # --> q# #
5233 0         0 }
5234             elsif ($charclass !~ /[\<\>]/oxms) {
5235             return e_q('q', '<', '>', $charclass); # --> q< >
5236 0         0 }
5237             elsif ($charclass !~ /[\(\)]/oxms) {
5238             return e_q('q', '(', ')', $charclass); # --> q( )
5239 0         0 }
5240             elsif ($charclass !~ /[\{\}]/oxms) {
5241             return e_q('q', '{', '}', $charclass); # --> q{ }
5242 0         0 }
5243 0 0       0 else {
5244 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5245             if ($charclass !~ /\Q$char\E/xms) {
5246             return e_q('q', $char, $char, $charclass);
5247             }
5248             }
5249 0         0 }
5250              
5251             return e_q('q', '{', '}', $charclass);
5252             }
5253              
5254             #
5255             # escape q string (q//, '')
5256 0     1264 0 0 #
5257             sub e_q {
5258 1264         2808 my($ope,$delimiter,$end_delimiter,$string) = @_;
5259              
5260 1264         1696 $slash = 'div';
5261              
5262             return join '', $ope, $delimiter, $string, $end_delimiter;
5263             }
5264              
5265             #
5266             # escape qq string (qq//, "", qx//, ``)
5267 1264     4026 0 6446 #
5268             sub e_qq {
5269 4026         9123 my($ope,$delimiter,$end_delimiter,$string) = @_;
5270              
5271 4026         5014 $slash = 'div';
5272 4026         4775  
5273             my $left_e = 0;
5274             my $right_e = 0;
5275 4026         4630  
5276             # split regexp
5277             my @char = $string =~ /\G((?>
5278             [^\\\$] |
5279             \\x\{ (?>[0-9A-Fa-f]+) \} |
5280             \\o\{ (?>[0-7]+) \} |
5281             \\N\{ (?>[^0-9\}][^\}]*) \} |
5282             \\ $q_char |
5283             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5284             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5285             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5286             \$ (?>\s* [0-9]+) |
5287             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5288             \$ \$ (?![\w\{]) |
5289             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5290             $q_char
5291 4026         138520 ))/oxmsg;
5292              
5293             for (my $i=0; $i <= $#char; $i++) {
5294 4026 50 33     11847  
    50 33        
    100          
    100          
    50          
5295 113721         382024 # "\L\u" --> "\u\L"
5296             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5297             @char[$i,$i+1] = @char[$i+1,$i];
5298             }
5299              
5300 0         0 # "\U\l" --> "\l\U"
5301             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5302             @char[$i,$i+1] = @char[$i+1,$i];
5303             }
5304              
5305 0         0 # octal escape sequence
5306             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5307             $char[$i] = Elatin1::octchr($1);
5308             }
5309              
5310 1         4 # hexadecimal escape sequence
5311             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5312             $char[$i] = Elatin1::hexchr($1);
5313             }
5314              
5315 1         3 # \N{CHARNAME} --> N{CHARNAME}
5316             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5317             $char[$i] = $1;
5318 0 100       0 }
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5319              
5320             if (0) {
5321             }
5322              
5323             # \F
5324             #
5325             # P.69 Table 2-6. Translation escapes
5326             # in Chapter 2: Bits and Pieces
5327             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5328             # (and so on)
5329 113721         911769  
5330 0 50       0 # \u \l \U \L \F \Q \E
5331 484         1048 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5332             if ($right_e < $left_e) {
5333             $char[$i] = '\\' . $char[$i];
5334             }
5335             }
5336             elsif ($char[$i] eq '\u') {
5337              
5338             # "STRING @{[ LIST EXPR ]} MORE STRING"
5339              
5340             # P.257 Other Tricks You Can Do with Hard References
5341             # in Chapter 8: References
5342             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5343              
5344             # P.353 Other Tricks You Can Do with Hard References
5345             # in Chapter 8: References
5346             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5347              
5348 0         0 # (and so on)
5349 0         0  
5350             $char[$i] = '@{[Elatin1::ucfirst qq<';
5351             $left_e++;
5352 0         0 }
5353 0         0 elsif ($char[$i] eq '\l') {
5354             $char[$i] = '@{[Elatin1::lcfirst qq<';
5355             $left_e++;
5356 0         0 }
5357 0         0 elsif ($char[$i] eq '\U') {
5358             $char[$i] = '@{[Elatin1::uc qq<';
5359             $left_e++;
5360 0         0 }
5361 0         0 elsif ($char[$i] eq '\L') {
5362             $char[$i] = '@{[Elatin1::lc qq<';
5363             $left_e++;
5364 0         0 }
5365 24         33 elsif ($char[$i] eq '\F') {
5366             $char[$i] = '@{[Elatin1::fc qq<';
5367             $left_e++;
5368 24         45 }
5369 0         0 elsif ($char[$i] eq '\Q') {
5370             $char[$i] = '@{[CORE::quotemeta qq<';
5371             $left_e++;
5372 0 50       0 }
5373 24         40 elsif ($char[$i] eq '\E') {
5374 24         33 if ($right_e < $left_e) {
5375             $char[$i] = '>]}';
5376             $right_e++;
5377 24         40 }
5378             else {
5379             $char[$i] = '';
5380             }
5381 0         0 }
5382 0 0       0 elsif ($char[$i] eq '\Q') {
5383 0         0 while (1) {
5384             if (++$i > $#char) {
5385 0 0       0 last;
5386 0         0 }
5387             if ($char[$i] eq '\E') {
5388             last;
5389             }
5390             }
5391             }
5392             elsif ($char[$i] eq '\E') {
5393             }
5394              
5395             # $0 --> $0
5396             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5397             }
5398             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5399             }
5400              
5401             # $$ --> $$
5402             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5403             }
5404              
5405             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5406 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5407             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5408             $char[$i] = e_capture($1);
5409 205         396 }
5410             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5411             $char[$i] = e_capture($1);
5412             }
5413              
5414 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5415             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5416             $char[$i] = e_capture($1.'->'.$2);
5417             }
5418              
5419 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5420             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5421             $char[$i] = e_capture($1.'->'.$2);
5422             }
5423              
5424 0         0 # $$foo
5425             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5426             $char[$i] = e_capture($1);
5427             }
5428              
5429 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
5430             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5431             $char[$i] = '@{[Elatin1::PREMATCH()]}';
5432             }
5433              
5434 44         123 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
5435             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5436             $char[$i] = '@{[Elatin1::MATCH()]}';
5437             }
5438              
5439 45         115 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
5440             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5441             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
5442             }
5443              
5444             # ${ foo } --> ${ foo }
5445             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5446             }
5447              
5448 33         87 # ${ ... }
5449             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5450             $char[$i] = e_capture($1);
5451             }
5452             }
5453 0 50       0  
5454 4026         7180 # return string
5455             if ($left_e > $right_e) {
5456 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5457             }
5458             return join '', $ope, $delimiter, @char, $end_delimiter;
5459             }
5460              
5461             #
5462             # escape qw string (qw//)
5463 4026     16 0 32329 #
5464             sub e_qw {
5465 16         76 my($ope,$delimiter,$end_delimiter,$string) = @_;
5466              
5467             $slash = 'div';
5468 16         34  
  16         200  
5469 483 50       716 # choice again delimiter
    0          
    0          
    0          
    0          
5470 16         96 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5471             if (not $octet{$end_delimiter}) {
5472             return join '', $ope, $delimiter, $string, $end_delimiter;
5473 16         119 }
5474             elsif (not $octet{')'}) {
5475             return join '', $ope, '(', $string, ')';
5476 0         0 }
5477             elsif (not $octet{'}'}) {
5478             return join '', $ope, '{', $string, '}';
5479 0         0 }
5480             elsif (not $octet{']'}) {
5481             return join '', $ope, '[', $string, ']';
5482 0         0 }
5483             elsif (not $octet{'>'}) {
5484             return join '', $ope, '<', $string, '>';
5485 0         0 }
5486 0 0       0 else {
5487 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5488             if (not $octet{$char}) {
5489             return join '', $ope, $char, $string, $char;
5490             }
5491             }
5492             }
5493 0         0  
5494 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5495 0         0 my @string = CORE::split(/\s+/, $string);
5496 0         0 for my $string (@string) {
5497 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5498 0         0 for my $octet (@octet) {
5499             if ($octet =~ /\A (['\\]) \z/oxms) {
5500             $octet = '\\' . $1;
5501 0         0 }
5502             }
5503 0         0 $string = join '', @octet;
  0         0  
5504             }
5505             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5506             }
5507              
5508             #
5509             # escape here document (<<"HEREDOC", <
5510 0     93 0 0 #
5511             sub e_heredoc {
5512 93         345 my($string) = @_;
5513              
5514 93         143 $slash = 'm//';
5515              
5516 93         282 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5517 93         137  
5518             my $left_e = 0;
5519             my $right_e = 0;
5520 93         120  
5521             # split regexp
5522             my @char = $string =~ /\G((?>
5523             [^\\\$] |
5524             \\x\{ (?>[0-9A-Fa-f]+) \} |
5525             \\o\{ (?>[0-7]+) \} |
5526             \\N\{ (?>[^0-9\}][^\}]*) \} |
5527             \\ $q_char |
5528             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5529             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5530             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5531             \$ (?>\s* [0-9]+) |
5532             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5533             \$ \$ (?![\w\{]) |
5534             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5535             $q_char
5536 93         8019 ))/oxmsg;
5537              
5538             for (my $i=0; $i <= $#char; $i++) {
5539 93 50 33     389  
    50 33        
    100          
    100          
    50          
5540 3177         9417 # "\L\u" --> "\u\L"
5541             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5542             @char[$i,$i+1] = @char[$i+1,$i];
5543             }
5544              
5545 0         0 # "\U\l" --> "\l\U"
5546             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5547             @char[$i,$i+1] = @char[$i+1,$i];
5548             }
5549              
5550 0         0 # octal escape sequence
5551             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5552             $char[$i] = Elatin1::octchr($1);
5553             }
5554              
5555 1         3 # hexadecimal escape sequence
5556             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5557             $char[$i] = Elatin1::hexchr($1);
5558             }
5559              
5560 1         4 # \N{CHARNAME} --> N{CHARNAME}
5561             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5562             $char[$i] = $1;
5563 0 50       0 }
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5564              
5565             if (0) {
5566             }
5567 3177         25408  
5568 0 0       0 # \u \l \U \L \F \Q \E
5569 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5570             if ($right_e < $left_e) {
5571             $char[$i] = '\\' . $char[$i];
5572             }
5573 0         0 }
5574 0         0 elsif ($char[$i] eq '\u') {
5575             $char[$i] = '@{[Elatin1::ucfirst qq<';
5576             $left_e++;
5577 0         0 }
5578 0         0 elsif ($char[$i] eq '\l') {
5579             $char[$i] = '@{[Elatin1::lcfirst qq<';
5580             $left_e++;
5581 0         0 }
5582 0         0 elsif ($char[$i] eq '\U') {
5583             $char[$i] = '@{[Elatin1::uc qq<';
5584             $left_e++;
5585 0         0 }
5586 0         0 elsif ($char[$i] eq '\L') {
5587             $char[$i] = '@{[Elatin1::lc qq<';
5588             $left_e++;
5589 0         0 }
5590 0         0 elsif ($char[$i] eq '\F') {
5591             $char[$i] = '@{[Elatin1::fc qq<';
5592             $left_e++;
5593 0         0 }
5594 0         0 elsif ($char[$i] eq '\Q') {
5595             $char[$i] = '@{[CORE::quotemeta qq<';
5596             $left_e++;
5597 0 0       0 }
5598 0         0 elsif ($char[$i] eq '\E') {
5599 0         0 if ($right_e < $left_e) {
5600             $char[$i] = '>]}';
5601             $right_e++;
5602 0         0 }
5603             else {
5604             $char[$i] = '';
5605             }
5606 0         0 }
5607 0 0       0 elsif ($char[$i] eq '\Q') {
5608 0         0 while (1) {
5609             if (++$i > $#char) {
5610 0 0       0 last;
5611 0         0 }
5612             if ($char[$i] eq '\E') {
5613             last;
5614             }
5615             }
5616             }
5617             elsif ($char[$i] eq '\E') {
5618             }
5619              
5620             # $0 --> $0
5621             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5622             }
5623             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5624             }
5625              
5626             # $$ --> $$
5627             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5628             }
5629              
5630             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5631 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5632             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5633             $char[$i] = e_capture($1);
5634 0         0 }
5635             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5636             $char[$i] = e_capture($1);
5637             }
5638              
5639 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5640             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5641             $char[$i] = e_capture($1.'->'.$2);
5642             }
5643              
5644 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5645             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5646             $char[$i] = e_capture($1.'->'.$2);
5647             }
5648              
5649 0         0 # $$foo
5650             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5651             $char[$i] = e_capture($1);
5652             }
5653              
5654 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
5655             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5656             $char[$i] = '@{[Elatin1::PREMATCH()]}';
5657             }
5658              
5659 8         41 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
5660             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5661             $char[$i] = '@{[Elatin1::MATCH()]}';
5662             }
5663              
5664 8         42 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
5665             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5666             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
5667             }
5668              
5669             # ${ foo } --> ${ foo }
5670             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5671             }
5672              
5673 6         34 # ${ ... }
5674             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5675             $char[$i] = e_capture($1);
5676             }
5677             }
5678 0 50       0  
5679 93         209 # return string
5680             if ($left_e > $right_e) {
5681 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5682             }
5683             return join '', @char;
5684             }
5685              
5686             #
5687             # escape regexp (m//, qr//)
5688 93     652 0 671 #
5689 652   100     2965 sub e_qr {
5690             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5691 652         2655 $modifier ||= '';
5692 652 50       1174  
5693 652         1498 $modifier =~ tr/p//d;
5694 0         0 if ($modifier =~ /([adlu])/oxms) {
5695 0 0       0 my $line = 0;
5696 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5697 0         0 if ($filename ne __FILE__) {
5698             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5699             last;
5700 0         0 }
5701             }
5702             die qq{Unsupported modifier "$1" used at line $line.\n};
5703 0         0 }
5704              
5705             $slash = 'div';
5706 652 100       991  
    100          
5707 652         1905 # literal null string pattern
5708 8         12 if ($string eq '') {
5709 8         9 $modifier =~ tr/bB//d;
5710             $modifier =~ tr/i//d;
5711             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5712             }
5713              
5714             # /b /B modifier
5715             elsif ($modifier =~ tr/bB//d) {
5716 8 50       38  
5717 2         5 # choice again delimiter
5718 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5719 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5720 0         0 my %octet = map {$_ => 1} @char;
5721 0         0 if (not $octet{')'}) {
5722             $delimiter = '(';
5723             $end_delimiter = ')';
5724 0         0 }
5725 0         0 elsif (not $octet{'}'}) {
5726             $delimiter = '{';
5727             $end_delimiter = '}';
5728 0         0 }
5729 0         0 elsif (not $octet{']'}) {
5730             $delimiter = '[';
5731             $end_delimiter = ']';
5732 0         0 }
5733 0         0 elsif (not $octet{'>'}) {
5734             $delimiter = '<';
5735             $end_delimiter = '>';
5736 0         0 }
5737 0 0       0 else {
5738 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5739 0         0 if (not $octet{$char}) {
5740 0         0 $delimiter = $char;
5741             $end_delimiter = $char;
5742             last;
5743             }
5744             }
5745             }
5746 0 50 33     0 }
5747 2         11  
5748             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5749             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5750 0         0 }
5751             else {
5752             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5753             }
5754 2 100       11 }
5755 642         1531  
5756             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5757             my $metachar = qr/[\@\\|[\]{^]/oxms;
5758 642         2277  
5759             # split regexp
5760             my @char = $string =~ /\G((?>
5761             [^\\\$\@\[\(] |
5762             \\x (?>[0-9A-Fa-f]{1,2}) |
5763             \\ (?>[0-7]{2,3}) |
5764             \\c [\x40-\x5F] |
5765             \\x\{ (?>[0-9A-Fa-f]+) \} |
5766             \\o\{ (?>[0-7]+) \} |
5767             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5768             \\ $q_char |
5769             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5770             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5771             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5772             [\$\@] $qq_variable |
5773             \$ (?>\s* [0-9]+) |
5774             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5775             \$ \$ (?![\w\{]) |
5776             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5777             \[\^ |
5778             \[\: (?>[a-z]+) :\] |
5779             \[\:\^ (?>[a-z]+) :\] |
5780             \(\? |
5781             $q_char
5782             ))/oxmsg;
5783 642 50       64186  
5784 642         2756 # choice again delimiter
  0         0  
5785 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5786 0         0 my %octet = map {$_ => 1} @char;
5787 0         0 if (not $octet{')'}) {
5788             $delimiter = '(';
5789             $end_delimiter = ')';
5790 0         0 }
5791 0         0 elsif (not $octet{'}'}) {
5792             $delimiter = '{';
5793             $end_delimiter = '}';
5794 0         0 }
5795 0         0 elsif (not $octet{']'}) {
5796             $delimiter = '[';
5797             $end_delimiter = ']';
5798 0         0 }
5799 0         0 elsif (not $octet{'>'}) {
5800             $delimiter = '<';
5801             $end_delimiter = '>';
5802 0         0 }
5803 0 0       0 else {
5804 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5805 0         0 if (not $octet{$char}) {
5806 0         0 $delimiter = $char;
5807             $end_delimiter = $char;
5808             last;
5809             }
5810             }
5811             }
5812 0         0 }
5813 642         980  
5814 642         859 my $left_e = 0;
5815             my $right_e = 0;
5816             for (my $i=0; $i <= $#char; $i++) {
5817 642 50 66     2611  
    50 66        
    100          
    100          
    100          
    100          
5818 1872         9545 # "\L\u" --> "\u\L"
5819             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5820             @char[$i,$i+1] = @char[$i+1,$i];
5821             }
5822              
5823 0         0 # "\U\l" --> "\l\U"
5824             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5825             @char[$i,$i+1] = @char[$i+1,$i];
5826             }
5827              
5828 0         0 # octal escape sequence
5829             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5830             $char[$i] = Elatin1::octchr($1);
5831             }
5832              
5833 1         4 # hexadecimal escape sequence
5834             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5835             $char[$i] = Elatin1::hexchr($1);
5836             }
5837              
5838             # \b{...} --> b\{...}
5839             # \B{...} --> B\{...}
5840             # \N{CHARNAME} --> N\{CHARNAME}
5841             # \p{PROPERTY} --> p\{PROPERTY}
5842 1         4 # \P{PROPERTY} --> P\{PROPERTY}
5843             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5844             $char[$i] = $1 . '\\' . $2;
5845             }
5846              
5847 6         19 # \p, \P, \X --> p, P, X
5848             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5849             $char[$i] = $1;
5850 4 100 100     10 }
    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          
5851              
5852             if (0) {
5853             }
5854 1872         5264  
5855 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5856 6         74 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5857             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)) {
5858             $char[$i] .= join '', splice @char, $i+1, 3;
5859 0         0 }
5860             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)) {
5861             $char[$i] .= join '', splice @char, $i+1, 2;
5862 0         0 }
5863             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)) {
5864             $char[$i] .= join '', splice @char, $i+1, 1;
5865             }
5866             }
5867              
5868 0         0 # open character class [...]
5869             elsif ($char[$i] eq '[') {
5870             my $left = $i;
5871              
5872             # [] make die "Unmatched [] in regexp ...\n"
5873 328 100       412 # (and so on)
5874 328         679  
5875             if ($char[$i+1] eq ']') {
5876             $i++;
5877 3         6 }
5878 328 50       417  
5879 1379         2112 while (1) {
5880             if (++$i > $#char) {
5881 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5882 1379         1992 }
5883             if ($char[$i] eq ']') {
5884             my $right = $i;
5885 328 100       414  
5886 328         1519 # [...]
  30         209  
5887             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5888             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin1::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5889 90         138 }
5890             else {
5891             splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
5892 298         1020 }
5893 328         592  
5894             $i = $left;
5895             last;
5896             }
5897             }
5898             }
5899              
5900 328         804 # open character class [^...]
5901             elsif ($char[$i] eq '[^') {
5902             my $left = $i;
5903              
5904             # [^] make die "Unmatched [] in regexp ...\n"
5905 74 100       90 # (and so on)
5906 74         167  
5907             if ($char[$i+1] eq ']') {
5908             $i++;
5909 4         7 }
5910 74 50       86  
5911 272         375 while (1) {
5912             if (++$i > $#char) {
5913 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5914 272         405 }
5915             if ($char[$i] eq ']') {
5916             my $right = $i;
5917 74 100       98  
5918 74         396 # [^...]
  30         66  
5919             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5920             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin1::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5921 90         153 }
5922             else {
5923             splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5924 44         179 }
5925 74         160  
5926             $i = $left;
5927             last;
5928             }
5929             }
5930             }
5931              
5932 74         191 # rewrite character class or escape character
5933             elsif (my $char = character_class($char[$i],$modifier)) {
5934             $char[$i] = $char;
5935             }
5936              
5937 139 50       343 # /i modifier
5938 20         35 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
5939             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
5940             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
5941 20         34 }
5942             else {
5943             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
5944             }
5945             }
5946              
5947 0 50       0 # \u \l \U \L \F \Q \E
5948 1         4 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5949             if ($right_e < $left_e) {
5950             $char[$i] = '\\' . $char[$i];
5951             }
5952 0         0 }
5953 0         0 elsif ($char[$i] eq '\u') {
5954             $char[$i] = '@{[Elatin1::ucfirst qq<';
5955             $left_e++;
5956 0         0 }
5957 0         0 elsif ($char[$i] eq '\l') {
5958             $char[$i] = '@{[Elatin1::lcfirst qq<';
5959             $left_e++;
5960 0         0 }
5961 1         2 elsif ($char[$i] eq '\U') {
5962             $char[$i] = '@{[Elatin1::uc qq<';
5963             $left_e++;
5964 1         3 }
5965 1         2 elsif ($char[$i] eq '\L') {
5966             $char[$i] = '@{[Elatin1::lc qq<';
5967             $left_e++;
5968 1         2 }
5969 18         28 elsif ($char[$i] eq '\F') {
5970             $char[$i] = '@{[Elatin1::fc qq<';
5971             $left_e++;
5972 18         37 }
5973 1         2 elsif ($char[$i] eq '\Q') {
5974             $char[$i] = '@{[CORE::quotemeta qq<';
5975             $left_e++;
5976 1 50       2 }
5977 21         69 elsif ($char[$i] eq '\E') {
5978 21         33 if ($right_e < $left_e) {
5979             $char[$i] = '>]}';
5980             $right_e++;
5981 21         45 }
5982             else {
5983             $char[$i] = '';
5984             }
5985 0         0 }
5986 0 0       0 elsif ($char[$i] eq '\Q') {
5987 0         0 while (1) {
5988             if (++$i > $#char) {
5989 0 0       0 last;
5990 0         0 }
5991             if ($char[$i] eq '\E') {
5992             last;
5993             }
5994             }
5995             }
5996             elsif ($char[$i] eq '\E') {
5997             }
5998              
5999 0 0       0 # $0 --> $0
6000 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6001             if ($ignorecase) {
6002             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6003             }
6004 0 0       0 }
6005 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6006             if ($ignorecase) {
6007             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6008             }
6009             }
6010              
6011             # $$ --> $$
6012             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6013             }
6014              
6015             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6016 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6017 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6018 0         0 $char[$i] = e_capture($1);
6019             if ($ignorecase) {
6020             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6021             }
6022 0         0 }
6023 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6024 0         0 $char[$i] = e_capture($1);
6025             if ($ignorecase) {
6026             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6027             }
6028             }
6029              
6030 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6031 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
6032 0         0 $char[$i] = e_capture($1.'->'.$2);
6033             if ($ignorecase) {
6034             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6035             }
6036             }
6037              
6038 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6039 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
6040 0         0 $char[$i] = e_capture($1.'->'.$2);
6041             if ($ignorecase) {
6042             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6043             }
6044             }
6045              
6046 0         0 # $$foo
6047 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6048 0         0 $char[$i] = e_capture($1);
6049             if ($ignorecase) {
6050             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6051             }
6052             }
6053              
6054 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
6055 8         22 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6056             if ($ignorecase) {
6057             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::PREMATCH())]}';
6058 0         0 }
6059             else {
6060             $char[$i] = '@{[Elatin1::PREMATCH()]}';
6061             }
6062             }
6063              
6064 8 50       21 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
6065 8         20 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6066             if ($ignorecase) {
6067             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::MATCH())]}';
6068 0         0 }
6069             else {
6070             $char[$i] = '@{[Elatin1::MATCH()]}';
6071             }
6072             }
6073              
6074 8 50       21 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
6075 6         17 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6076             if ($ignorecase) {
6077             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::POSTMATCH())]}';
6078 0         0 }
6079             else {
6080             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
6081             }
6082             }
6083              
6084 6 0       30 # ${ foo }
6085 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
6086             if ($ignorecase) {
6087             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6088             }
6089             }
6090              
6091 0         0 # ${ ... }
6092 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6093 0         0 $char[$i] = e_capture($1);
6094             if ($ignorecase) {
6095             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6096             }
6097             }
6098              
6099 0         0 # $scalar or @array
6100 21 100       51 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6101 21         112 $char[$i] = e_string($char[$i]);
6102             if ($ignorecase) {
6103             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6104             }
6105             }
6106              
6107 11 100 33     34 # quote character before ? + * {
    50          
6108             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6109             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6110 138         1020 }
6111 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6112 0         0 my $char = $char[$i-1];
6113             if ($char[$i] eq '{') {
6114             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
6115 0         0 }
6116             else {
6117             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
6118             }
6119 0         0 }
6120             else {
6121             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6122             }
6123             }
6124             }
6125 127         466  
6126 642 50       1120 # make regexp string
6127 642 0 0     1312 $modifier =~ tr/i//d;
6128 0         0 if ($left_e > $right_e) {
6129             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6130             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
6131 0         0 }
6132             else {
6133             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6134 0 50 33     0 }
6135 642         3262 }
6136             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6137             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
6138 0         0 }
6139             else {
6140             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6141             }
6142             }
6143              
6144             #
6145             # double quote stuff
6146 642     180 0 5233 #
6147             sub qq_stuff {
6148             my($delimiter,$end_delimiter,$stuff) = @_;
6149 180 100       265  
6150 180         396 # scalar variable or array variable
6151             if ($stuff =~ /\A [\$\@] /oxms) {
6152             return $stuff;
6153             }
6154 100         538  
  80         174  
6155 80         227 # quote by delimiter
6156 80 50       306 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
6157 80 50       145 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6158 80 50       117 next if $char eq $delimiter;
6159 80         128 next if $char eq $end_delimiter;
6160             if (not $octet{$char}) {
6161             return join '', 'qq', $char, $stuff, $char;
6162 80         350 }
6163             }
6164             return join '', 'qq', '<', $stuff, '>';
6165             }
6166              
6167             #
6168             # escape regexp (m'', qr'', and m''b, qr''b)
6169 0     10 0 0 #
6170 10   50     43 sub e_qr_q {
6171             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6172 10         41 $modifier ||= '';
6173 10 50       14  
6174 10         23 $modifier =~ tr/p//d;
6175 0         0 if ($modifier =~ /([adlu])/oxms) {
6176 0 0       0 my $line = 0;
6177 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6178 0         0 if ($filename ne __FILE__) {
6179             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6180             last;
6181 0         0 }
6182             }
6183             die qq{Unsupported modifier "$1" used at line $line.\n};
6184 0         0 }
6185              
6186             $slash = 'div';
6187 10 100       14  
    50          
6188 10         22 # literal null string pattern
6189 8         11 if ($string eq '') {
6190 8         12 $modifier =~ tr/bB//d;
6191             $modifier =~ tr/i//d;
6192             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6193             }
6194              
6195 8         38 # with /b /B modifier
6196             elsif ($modifier =~ tr/bB//d) {
6197             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6198             }
6199              
6200 0         0 # without /b /B modifier
6201             else {
6202             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6203             }
6204             }
6205              
6206             #
6207             # escape regexp (m'', qr'')
6208 2     2 0 8 #
6209             sub e_qr_qt {
6210 2 50       8 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6211              
6212             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6213 2         4  
6214             # split regexp
6215             my @char = $string =~ /\G((?>
6216             [^\\\[\$\@\/] |
6217             [\x00-\xFF] |
6218             \[\^ |
6219             \[\: (?>[a-z]+) \:\] |
6220             \[\:\^ (?>[a-z]+) \:\] |
6221             [\$\@\/] |
6222             \\ (?:$q_char) |
6223             (?:$q_char)
6224             ))/oxmsg;
6225 2         61  
6226 2 50 33     10 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
6227             for (my $i=0; $i <= $#char; $i++) {
6228             if (0) {
6229             }
6230 2         19  
6231 0         0 # open character class [...]
6232 0 0       0 elsif ($char[$i] eq '[') {
6233 0         0 my $left = $i;
6234             if ($char[$i+1] eq ']') {
6235 0         0 $i++;
6236 0 0       0 }
6237 0         0 while (1) {
6238             if (++$i > $#char) {
6239 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6240 0         0 }
6241             if ($char[$i] eq ']') {
6242             my $right = $i;
6243 0         0  
6244             # [...]
6245 0         0 splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
6246 0         0  
6247             $i = $left;
6248             last;
6249             }
6250             }
6251             }
6252              
6253 0         0 # open character class [^...]
6254 0 0       0 elsif ($char[$i] eq '[^') {
6255 0         0 my $left = $i;
6256             if ($char[$i+1] eq ']') {
6257 0         0 $i++;
6258 0 0       0 }
6259 0         0 while (1) {
6260             if (++$i > $#char) {
6261 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6262 0         0 }
6263             if ($char[$i] eq ']') {
6264             my $right = $i;
6265 0         0  
6266             # [^...]
6267 0         0 splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6268 0         0  
6269             $i = $left;
6270             last;
6271             }
6272             }
6273             }
6274              
6275 0         0 # escape $ @ / and \
6276             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6277             $char[$i] = '\\' . $char[$i];
6278             }
6279              
6280 0         0 # rewrite character class or escape character
6281             elsif (my $char = character_class($char[$i],$modifier)) {
6282             $char[$i] = $char;
6283             }
6284              
6285 0 0       0 # /i modifier
6286 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
6287             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
6288             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
6289 0         0 }
6290             else {
6291             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
6292             }
6293             }
6294              
6295 0 0       0 # quote character before ? + * {
6296             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6297             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6298 0         0 }
6299             else {
6300             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6301             }
6302             }
6303 0         0 }
6304 2         5  
6305             $delimiter = '/';
6306 2         4 $end_delimiter = '/';
6307 2         3  
6308             $modifier =~ tr/i//d;
6309             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6310             }
6311              
6312             #
6313             # escape regexp (m''b, qr''b)
6314 2     0 0 16 #
6315             sub e_qr_qb {
6316             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6317 0         0  
6318             # split regexp
6319             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6320 0         0  
6321 0 0       0 # unescape character
    0          
6322             for (my $i=0; $i <= $#char; $i++) {
6323             if (0) {
6324             }
6325 0         0  
6326             # remain \\
6327             elsif ($char[$i] eq '\\\\') {
6328             }
6329              
6330 0         0 # escape $ @ / and \
6331             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6332             $char[$i] = '\\' . $char[$i];
6333             }
6334 0         0 }
6335 0         0  
6336 0         0 $delimiter = '/';
6337             $end_delimiter = '/';
6338             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6339             }
6340              
6341             #
6342             # escape regexp (s/here//)
6343 0     76 0 0 #
6344 76   100     232 sub e_s1 {
6345             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6346 76         312 $modifier ||= '';
6347 76 50       126  
6348 76         210 $modifier =~ tr/p//d;
6349 0         0 if ($modifier =~ /([adlu])/oxms) {
6350 0 0       0 my $line = 0;
6351 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6352 0         0 if ($filename ne __FILE__) {
6353             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6354             last;
6355 0         0 }
6356             }
6357             die qq{Unsupported modifier "$1" used at line $line.\n};
6358 0         0 }
6359              
6360             $slash = 'div';
6361 76 100       136  
    50          
6362 76         311 # literal null string pattern
6363 8         10 if ($string eq '') {
6364 8         8 $modifier =~ tr/bB//d;
6365             $modifier =~ tr/i//d;
6366             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6367             }
6368              
6369             # /b /B modifier
6370             elsif ($modifier =~ tr/bB//d) {
6371 8 0       50  
6372 0         0 # choice again delimiter
6373 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
6374 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
6375 0         0 my %octet = map {$_ => 1} @char;
6376 0         0 if (not $octet{')'}) {
6377             $delimiter = '(';
6378             $end_delimiter = ')';
6379 0         0 }
6380 0         0 elsif (not $octet{'}'}) {
6381             $delimiter = '{';
6382             $end_delimiter = '}';
6383 0         0 }
6384 0         0 elsif (not $octet{']'}) {
6385             $delimiter = '[';
6386             $end_delimiter = ']';
6387 0         0 }
6388 0         0 elsif (not $octet{'>'}) {
6389             $delimiter = '<';
6390             $end_delimiter = '>';
6391 0         0 }
6392 0 0       0 else {
6393 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6394 0         0 if (not $octet{$char}) {
6395 0         0 $delimiter = $char;
6396             $end_delimiter = $char;
6397             last;
6398             }
6399             }
6400             }
6401 0         0 }
6402 0         0  
6403             my $prematch = '';
6404             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6405 0 100       0 }
6406 68         222  
6407             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6408             my $metachar = qr/[\@\\|[\]{^]/oxms;
6409 68         287  
6410             # split regexp
6411             my @char = $string =~ /\G((?>
6412             [^\\\$\@\[\(] |
6413             \\ (?>[1-9][0-9]*) |
6414             \\g (?>\s*) (?>[1-9][0-9]*) |
6415             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6416             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6417             \\x (?>[0-9A-Fa-f]{1,2}) |
6418             \\ (?>[0-7]{2,3}) |
6419             \\c [\x40-\x5F] |
6420             \\x\{ (?>[0-9A-Fa-f]+) \} |
6421             \\o\{ (?>[0-7]+) \} |
6422             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6423             \\ $q_char |
6424             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6425             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6426             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6427             [\$\@] $qq_variable |
6428             \$ (?>\s* [0-9]+) |
6429             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6430             \$ \$ (?![\w\{]) |
6431             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6432             \[\^ |
6433             \[\: (?>[a-z]+) :\] |
6434             \[\:\^ (?>[a-z]+) :\] |
6435             \(\? |
6436             $q_char
6437             ))/oxmsg;
6438 68 50       16653  
6439 68         480 # choice again delimiter
  0         0  
6440 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
6441 0         0 my %octet = map {$_ => 1} @char;
6442 0         0 if (not $octet{')'}) {
6443             $delimiter = '(';
6444             $end_delimiter = ')';
6445 0         0 }
6446 0         0 elsif (not $octet{'}'}) {
6447             $delimiter = '{';
6448             $end_delimiter = '}';
6449 0         0 }
6450 0         0 elsif (not $octet{']'}) {
6451             $delimiter = '[';
6452             $end_delimiter = ']';
6453 0         0 }
6454 0         0 elsif (not $octet{'>'}) {
6455             $delimiter = '<';
6456             $end_delimiter = '>';
6457 0         0 }
6458 0 0       0 else {
6459 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6460 0         0 if (not $octet{$char}) {
6461 0         0 $delimiter = $char;
6462             $end_delimiter = $char;
6463             last;
6464             }
6465             }
6466             }
6467             }
6468 0         0  
  68         134  
6469             # count '('
6470 253         535 my $parens = grep { $_ eq '(' } @char;
6471 68         115  
6472 68         109 my $left_e = 0;
6473             my $right_e = 0;
6474             for (my $i=0; $i <= $#char; $i++) {
6475 68 50 33     195  
    50 33        
    100          
    100          
    50          
    50          
6476 195         1179 # "\L\u" --> "\u\L"
6477             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6478             @char[$i,$i+1] = @char[$i+1,$i];
6479             }
6480              
6481 0         0 # "\U\l" --> "\l\U"
6482             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6483             @char[$i,$i+1] = @char[$i+1,$i];
6484             }
6485              
6486 0         0 # octal escape sequence
6487             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6488             $char[$i] = Elatin1::octchr($1);
6489             }
6490              
6491 1         4 # hexadecimal escape sequence
6492             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6493             $char[$i] = Elatin1::hexchr($1);
6494             }
6495              
6496             # \b{...} --> b\{...}
6497             # \B{...} --> B\{...}
6498             # \N{CHARNAME} --> N\{CHARNAME}
6499             # \p{PROPERTY} --> p\{PROPERTY}
6500 1         3 # \P{PROPERTY} --> P\{PROPERTY}
6501             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6502             $char[$i] = $1 . '\\' . $2;
6503             }
6504              
6505 0         0 # \p, \P, \X --> p, P, X
6506             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6507             $char[$i] = $1;
6508 0 50 66     0 }
    100 66        
    50 100        
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
6509              
6510             if (0) {
6511             }
6512 195         714  
6513 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6514 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6515             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)) {
6516             $char[$i] .= join '', splice @char, $i+1, 3;
6517 0         0 }
6518             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)) {
6519             $char[$i] .= join '', splice @char, $i+1, 2;
6520 0         0 }
6521             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)) {
6522             $char[$i] .= join '', splice @char, $i+1, 1;
6523             }
6524             }
6525              
6526 0         0 # open character class [...]
6527 13 50       18 elsif ($char[$i] eq '[') {
6528 13         53 my $left = $i;
6529             if ($char[$i+1] eq ']') {
6530 0         0 $i++;
6531 13 50       21 }
6532 58         88 while (1) {
6533             if (++$i > $#char) {
6534 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6535 58         143 }
6536             if ($char[$i] eq ']') {
6537             my $right = $i;
6538 13 50       21  
6539 13         80 # [...]
  0         0  
6540             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6541             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin1::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6542 0         0 }
6543             else {
6544             splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
6545 13         56 }
6546 13         29  
6547             $i = $left;
6548             last;
6549             }
6550             }
6551             }
6552              
6553 13         51 # open character class [^...]
6554 0 0       0 elsif ($char[$i] eq '[^') {
6555 0         0 my $left = $i;
6556             if ($char[$i+1] eq ']') {
6557 0         0 $i++;
6558 0 0       0 }
6559 0         0 while (1) {
6560             if (++$i > $#char) {
6561 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6562 0         0 }
6563             if ($char[$i] eq ']') {
6564             my $right = $i;
6565 0 0       0  
6566 0         0 # [^...]
  0         0  
6567             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6568             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin1::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6569 0         0 }
6570             else {
6571             splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6572 0         0 }
6573 0         0  
6574             $i = $left;
6575             last;
6576             }
6577             }
6578             }
6579              
6580 0         0 # rewrite character class or escape character
6581             elsif (my $char = character_class($char[$i],$modifier)) {
6582             $char[$i] = $char;
6583             }
6584              
6585 7 50       15 # /i modifier
6586 3         6 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
6587             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
6588             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
6589 3         6 }
6590             else {
6591             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
6592             }
6593             }
6594              
6595 0 0       0 # \u \l \U \L \F \Q \E
6596 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6597             if ($right_e < $left_e) {
6598             $char[$i] = '\\' . $char[$i];
6599             }
6600 0         0 }
6601 0         0 elsif ($char[$i] eq '\u') {
6602             $char[$i] = '@{[Elatin1::ucfirst qq<';
6603             $left_e++;
6604 0         0 }
6605 0         0 elsif ($char[$i] eq '\l') {
6606             $char[$i] = '@{[Elatin1::lcfirst qq<';
6607             $left_e++;
6608 0         0 }
6609 0         0 elsif ($char[$i] eq '\U') {
6610             $char[$i] = '@{[Elatin1::uc qq<';
6611             $left_e++;
6612 0         0 }
6613 0         0 elsif ($char[$i] eq '\L') {
6614             $char[$i] = '@{[Elatin1::lc qq<';
6615             $left_e++;
6616 0         0 }
6617 0         0 elsif ($char[$i] eq '\F') {
6618             $char[$i] = '@{[Elatin1::fc qq<';
6619             $left_e++;
6620 0         0 }
6621 0         0 elsif ($char[$i] eq '\Q') {
6622             $char[$i] = '@{[CORE::quotemeta qq<';
6623             $left_e++;
6624 0 0       0 }
6625 0         0 elsif ($char[$i] eq '\E') {
6626 0         0 if ($right_e < $left_e) {
6627             $char[$i] = '>]}';
6628             $right_e++;
6629 0         0 }
6630             else {
6631             $char[$i] = '';
6632             }
6633 0         0 }
6634 0 0       0 elsif ($char[$i] eq '\Q') {
6635 0         0 while (1) {
6636             if (++$i > $#char) {
6637 0 0       0 last;
6638 0         0 }
6639             if ($char[$i] eq '\E') {
6640             last;
6641             }
6642             }
6643             }
6644             elsif ($char[$i] eq '\E') {
6645             }
6646              
6647             # \0 --> \0
6648             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6649             }
6650              
6651             # \g{N}, \g{-N}
6652              
6653             # P.108 Using Simple Patterns
6654             # in Chapter 7: In the World of Regular Expressions
6655             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6656              
6657             # P.221 Capturing
6658             # in Chapter 5: Pattern Matching
6659             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6660              
6661             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6662             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6663             }
6664              
6665             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6666             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6667             }
6668              
6669             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6670             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6671             }
6672              
6673             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6674             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6675             }
6676              
6677 0 0       0 # $0 --> $0
6678 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6679             if ($ignorecase) {
6680             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6681             }
6682 0 0       0 }
6683 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6684             if ($ignorecase) {
6685             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6686             }
6687             }
6688              
6689             # $$ --> $$
6690             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6691             }
6692              
6693             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6694 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6695 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6696 0         0 $char[$i] = e_capture($1);
6697             if ($ignorecase) {
6698             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6699             }
6700 0         0 }
6701 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6702 0         0 $char[$i] = e_capture($1);
6703             if ($ignorecase) {
6704             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6705             }
6706             }
6707              
6708 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6709 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
6710 0         0 $char[$i] = e_capture($1.'->'.$2);
6711             if ($ignorecase) {
6712             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6713             }
6714             }
6715              
6716 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6717 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
6718 0         0 $char[$i] = e_capture($1.'->'.$2);
6719             if ($ignorecase) {
6720             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6721             }
6722             }
6723              
6724 0         0 # $$foo
6725 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6726 0         0 $char[$i] = e_capture($1);
6727             if ($ignorecase) {
6728             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6729             }
6730             }
6731              
6732 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
6733 4         14 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6734             if ($ignorecase) {
6735             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::PREMATCH())]}';
6736 0         0 }
6737             else {
6738             $char[$i] = '@{[Elatin1::PREMATCH()]}';
6739             }
6740             }
6741              
6742 4 50       15 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
6743 4         14 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6744             if ($ignorecase) {
6745             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::MATCH())]}';
6746 0         0 }
6747             else {
6748             $char[$i] = '@{[Elatin1::MATCH()]}';
6749             }
6750             }
6751              
6752 4 50       13 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
6753 3         12 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6754             if ($ignorecase) {
6755             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::POSTMATCH())]}';
6756 0         0 }
6757             else {
6758             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
6759             }
6760             }
6761              
6762 3 0       11 # ${ foo }
6763 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
6764             if ($ignorecase) {
6765             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6766             }
6767             }
6768              
6769 0         0 # ${ ... }
6770 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6771 0         0 $char[$i] = e_capture($1);
6772             if ($ignorecase) {
6773             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6774             }
6775             }
6776              
6777 0         0 # $scalar or @array
6778 4 50       22 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6779 4         23 $char[$i] = e_string($char[$i]);
6780             if ($ignorecase) {
6781             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6782             }
6783             }
6784              
6785 0 50       0 # quote character before ? + * {
6786             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6787             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6788 13         70 }
6789             else {
6790             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6791             }
6792             }
6793             }
6794 13         61  
6795 68         155 # make regexp string
6796 68 50       119 my $prematch = '';
6797 68         164 $modifier =~ tr/i//d;
6798             if ($left_e > $right_e) {
6799 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6800             }
6801             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6802             }
6803              
6804             #
6805             # escape regexp (s'here'' or s'here''b)
6806 68     21 0 770 #
6807 21   100     57 sub e_s1_q {
6808             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6809 21         66 $modifier ||= '';
6810 21 50       28  
6811 21         51 $modifier =~ tr/p//d;
6812 0         0 if ($modifier =~ /([adlu])/oxms) {
6813 0 0       0 my $line = 0;
6814 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6815 0         0 if ($filename ne __FILE__) {
6816             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6817             last;
6818 0         0 }
6819             }
6820             die qq{Unsupported modifier "$1" used at line $line.\n};
6821 0         0 }
6822              
6823             $slash = 'div';
6824 21 100       39  
    50          
6825 21         51 # literal null string pattern
6826 8         11 if ($string eq '') {
6827 8         9 $modifier =~ tr/bB//d;
6828             $modifier =~ tr/i//d;
6829             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6830             }
6831              
6832 8         51 # with /b /B modifier
6833             elsif ($modifier =~ tr/bB//d) {
6834             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6835             }
6836              
6837 0         0 # without /b /B modifier
6838             else {
6839             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6840             }
6841             }
6842              
6843             #
6844             # escape regexp (s'here'')
6845 13     13 0 34 #
6846             sub e_s1_qt {
6847 13 50       32 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6848              
6849             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6850 13         29  
6851             # split regexp
6852             my @char = $string =~ /\G((?>
6853             [^\\\[\$\@\/] |
6854             [\x00-\xFF] |
6855             \[\^ |
6856             \[\: (?>[a-z]+) \:\] |
6857             \[\:\^ (?>[a-z]+) \:\] |
6858             [\$\@\/] |
6859             \\ (?:$q_char) |
6860             (?:$q_char)
6861             ))/oxmsg;
6862 13         298  
6863 13 50 33     44 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6864             for (my $i=0; $i <= $#char; $i++) {
6865             if (0) {
6866             }
6867 25         99  
6868 0         0 # open character class [...]
6869 0 0       0 elsif ($char[$i] eq '[') {
6870 0         0 my $left = $i;
6871             if ($char[$i+1] eq ']') {
6872 0         0 $i++;
6873 0 0       0 }
6874 0         0 while (1) {
6875             if (++$i > $#char) {
6876 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6877 0         0 }
6878             if ($char[$i] eq ']') {
6879             my $right = $i;
6880 0         0  
6881             # [...]
6882 0         0 splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
6883 0         0  
6884             $i = $left;
6885             last;
6886             }
6887             }
6888             }
6889              
6890 0         0 # open character class [^...]
6891 0 0       0 elsif ($char[$i] eq '[^') {
6892 0         0 my $left = $i;
6893             if ($char[$i+1] eq ']') {
6894 0         0 $i++;
6895 0 0       0 }
6896 0         0 while (1) {
6897             if (++$i > $#char) {
6898 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6899 0         0 }
6900             if ($char[$i] eq ']') {
6901             my $right = $i;
6902 0         0  
6903             # [^...]
6904 0         0 splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6905 0         0  
6906             $i = $left;
6907             last;
6908             }
6909             }
6910             }
6911              
6912 0         0 # escape $ @ / and \
6913             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6914             $char[$i] = '\\' . $char[$i];
6915             }
6916              
6917 0         0 # rewrite character class or escape character
6918             elsif (my $char = character_class($char[$i],$modifier)) {
6919             $char[$i] = $char;
6920             }
6921              
6922 6 0       13 # /i modifier
6923 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
6924             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
6925             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
6926 0         0 }
6927             else {
6928             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
6929             }
6930             }
6931              
6932 0 0       0 # quote character before ? + * {
6933             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6934             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6935 0         0 }
6936             else {
6937             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6938             }
6939             }
6940 0         0 }
6941 13         23  
6942 13         20 $modifier =~ tr/i//d;
6943 13         16 $delimiter = '/';
6944 13         24 $end_delimiter = '/';
6945             my $prematch = '';
6946             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6947             }
6948              
6949             #
6950             # escape regexp (s'here''b)
6951 13     0 0 102 #
6952             sub e_s1_qb {
6953             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6954 0         0  
6955             # split regexp
6956             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6957 0         0  
6958 0 0       0 # unescape character
    0          
6959             for (my $i=0; $i <= $#char; $i++) {
6960             if (0) {
6961             }
6962 0         0  
6963             # remain \\
6964             elsif ($char[$i] eq '\\\\') {
6965             }
6966              
6967 0         0 # escape $ @ / and \
6968             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6969             $char[$i] = '\\' . $char[$i];
6970             }
6971 0         0 }
6972 0         0  
6973 0         0 $delimiter = '/';
6974 0         0 $end_delimiter = '/';
6975             my $prematch = '';
6976             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6977             }
6978              
6979             #
6980             # escape regexp (s''here')
6981 0     16 0 0 #
6982             sub e_s2_q {
6983 16         31 my($ope,$delimiter,$end_delimiter,$string) = @_;
6984              
6985 16         22 $slash = 'div';
6986 16         91  
6987 16 100       41 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
6988             for (my $i=0; $i <= $#char; $i++) {
6989             if (0) {
6990             }
6991 9         29  
6992             # not escape \\
6993             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
6994             }
6995              
6996 0         0 # escape $ @ / and \
6997             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6998             $char[$i] = '\\' . $char[$i];
6999             }
7000 5         14 }
7001              
7002             return join '', $ope, $delimiter, @char, $end_delimiter;
7003             }
7004              
7005             #
7006             # escape regexp (s/here/and here/modifier)
7007 16     97 0 50 #
7008 97   100     780 sub e_sub {
7009             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
7010 97         393 $modifier ||= '';
7011 97 50       177  
7012 97         256 $modifier =~ tr/p//d;
7013 0         0 if ($modifier =~ /([adlu])/oxms) {
7014 0 0       0 my $line = 0;
7015 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7016 0         0 if ($filename ne __FILE__) {
7017             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7018             last;
7019 0         0 }
7020             }
7021             die qq{Unsupported modifier "$1" used at line $line.\n};
7022 0 100       0 }
7023 97         245  
7024 36         42 if ($variable eq '') {
7025             $variable = '$_';
7026             $bind_operator = ' =~ ';
7027 36         60 }
7028              
7029             $slash = 'div';
7030              
7031             # P.128 Start of match (or end of previous match): \G
7032             # P.130 Advanced Use of \G with Perl
7033             # in Chapter 3: Overview of Regular Expression Features and Flavors
7034             # P.312 Iterative Matching: Scalar Context, with /g
7035             # in Chapter 7: Perl
7036             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
7037              
7038             # P.181 Where You Left Off: The \G Assertion
7039             # in Chapter 5: Pattern Matching
7040             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7041              
7042             # P.220 Where You Left Off: The \G Assertion
7043             # in Chapter 5: Pattern Matching
7044 97         153 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7045 97         141  
7046             my $e_modifier = $modifier =~ tr/e//d;
7047 97         144 my $r_modifier = $modifier =~ tr/r//d;
7048 97 50       144  
7049 97         350 my $my = '';
7050 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
7051 0         0 $my = $variable;
7052             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
7053             $variable =~ s/ = .+ \z//oxms;
7054 0         0 }
7055 97         231  
7056             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
7057             $variable_basename =~ s/ \s+ \z//oxms;
7058 97         177  
7059 97 100       142 # quote replacement string
7060 97         245 my $e_replacement = '';
7061 17         47 if ($e_modifier >= 1) {
7062             $e_replacement = e_qq('', '', '', $replacement);
7063             $e_modifier--;
7064 17 100       24 }
7065 80         174 else {
7066             if ($delimiter2 eq "'") {
7067             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
7068 16         34 }
7069             else {
7070             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
7071             }
7072 64         163 }
7073              
7074             my $sub = '';
7075 97 100       161  
7076 97 100       217 # with /r
7077             if ($r_modifier) {
7078             if (0) {
7079             }
7080 8         15  
7081 0 50       0 # s///gr without multibyte anchoring
7082             elsif ($modifier =~ /g/oxms) {
7083             $sub = sprintf(
7084             # 1 2 3 4 5
7085             q,
7086              
7087             $variable, # 1
7088             ($delimiter1 eq "'") ? # 2
7089             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7090             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7091             $s_matched, # 3
7092             $e_replacement, # 4
7093             '$Elatin1::re_r=CORE::eval $Elatin1::re_r; ' x $e_modifier, # 5
7094             );
7095             }
7096              
7097             # s///r
7098 4         13 else {
7099              
7100 4 50       5 my $prematch = q{$`};
7101              
7102             $sub = sprintf(
7103             # 1 2 3 4 5 6 7
7104             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Elatin1::re_r=%s; %s"%s$Elatin1::re_r$'" } : %s>,
7105              
7106             $variable, # 1
7107             ($delimiter1 eq "'") ? # 2
7108             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7109             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7110             $s_matched, # 3
7111             $e_replacement, # 4
7112             '$Elatin1::re_r=CORE::eval $Elatin1::re_r; ' x $e_modifier, # 5
7113             $prematch, # 6
7114             $variable, # 7
7115             );
7116             }
7117 4 50       10  
7118 8         22 # $var !~ s///r doesn't make sense
7119             if ($bind_operator =~ / !~ /oxms) {
7120             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
7121             }
7122             }
7123              
7124 0 100       0 # without /r
7125             else {
7126             if (0) {
7127             }
7128 89         248  
7129 0 100       0 # s///g without multibyte anchoring
    100          
7130             elsif ($modifier =~ /g/oxms) {
7131             $sub = sprintf(
7132             # 1 2 3 4 5 6 7 8
7133             q,
7134              
7135             $variable, # 1
7136             ($delimiter1 eq "'") ? # 2
7137             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7138             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7139             $s_matched, # 3
7140             $e_replacement, # 4
7141             '$Elatin1::re_r=CORE::eval $Elatin1::re_r; ' x $e_modifier, # 5
7142             $variable, # 6
7143             $variable, # 7
7144             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
7145             );
7146             }
7147              
7148             # s///
7149 22         92 else {
7150              
7151 67 100       110 my $prematch = q{$`};
    100          
7152              
7153             $sub = sprintf(
7154              
7155             ($bind_operator =~ / =~ /oxms) ?
7156              
7157             # 1 2 3 4 5 6 7 8
7158             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Elatin1::re_r=%s; %s%s="%s$Elatin1::re_r$'"; 1 } : undef> :
7159              
7160             # 1 2 3 4 5 6 7 8
7161             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Elatin1::re_r=%s; %s%s="%s$Elatin1::re_r$'"; undef }>,
7162              
7163             $variable, # 1
7164             $bind_operator, # 2
7165             ($delimiter1 eq "'") ? # 3
7166             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7167             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7168             $s_matched, # 4
7169             $e_replacement, # 5
7170             '$Elatin1::re_r=CORE::eval $Elatin1::re_r; ' x $e_modifier, # 6
7171             $variable, # 7
7172             $prematch, # 8
7173             );
7174             }
7175             }
7176 67 50       367  
7177 97         273 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
7178             if ($my ne '') {
7179             $sub = "($my, $sub)[1]";
7180             }
7181 0         0  
7182 97         155 # clear s/// variable
7183             $sub_variable = '';
7184 97         141 $bind_operator = '';
7185              
7186             return $sub;
7187             }
7188              
7189             #
7190             # escape regexp of split qr//
7191 97     74 0 663 #
7192 74   100     425 sub e_split {
7193             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7194 74         400 $modifier ||= '';
7195 74 50       141  
7196 74         169 $modifier =~ tr/p//d;
7197 0         0 if ($modifier =~ /([adlu])/oxms) {
7198 0 0       0 my $line = 0;
7199 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7200 0         0 if ($filename ne __FILE__) {
7201             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7202             last;
7203 0         0 }
7204             }
7205             die qq{Unsupported modifier "$1" used at line $line.\n};
7206 0         0 }
7207              
7208             $slash = 'div';
7209 74 50       135  
7210 74         156 # /b /B modifier
7211             if ($modifier =~ tr/bB//d) {
7212             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7213 0 50       0 }
7214 74         177  
7215             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7216             my $metachar = qr/[\@\\|[\]{^]/oxms;
7217 74         307  
7218             # split regexp
7219             my @char = $string =~ /\G((?>
7220             [^\\\$\@\[\(] |
7221             \\x (?>[0-9A-Fa-f]{1,2}) |
7222             \\ (?>[0-7]{2,3}) |
7223             \\c [\x40-\x5F] |
7224             \\x\{ (?>[0-9A-Fa-f]+) \} |
7225             \\o\{ (?>[0-7]+) \} |
7226             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7227             \\ $q_char |
7228             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7229             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7230             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7231             [\$\@] $qq_variable |
7232             \$ (?>\s* [0-9]+) |
7233             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7234             \$ \$ (?![\w\{]) |
7235             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7236             \[\^ |
7237             \[\: (?>[a-z]+) :\] |
7238             \[\:\^ (?>[a-z]+) :\] |
7239             \(\? |
7240             $q_char
7241 74         8826 ))/oxmsg;
7242 74         270  
7243 74         128 my $left_e = 0;
7244             my $right_e = 0;
7245             for (my $i=0; $i <= $#char; $i++) {
7246 74 50 33     350  
    50 33        
    100          
    100          
    50          
    50          
7247 249         1252 # "\L\u" --> "\u\L"
7248             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7249             @char[$i,$i+1] = @char[$i+1,$i];
7250             }
7251              
7252 0         0 # "\U\l" --> "\l\U"
7253             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7254             @char[$i,$i+1] = @char[$i+1,$i];
7255             }
7256              
7257 0         0 # octal escape sequence
7258             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7259             $char[$i] = Elatin1::octchr($1);
7260             }
7261              
7262 1         3 # hexadecimal escape sequence
7263             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7264             $char[$i] = Elatin1::hexchr($1);
7265             }
7266              
7267             # \b{...} --> b\{...}
7268             # \B{...} --> B\{...}
7269             # \N{CHARNAME} --> N\{CHARNAME}
7270             # \p{PROPERTY} --> p\{PROPERTY}
7271 1         4 # \P{PROPERTY} --> P\{PROPERTY}
7272             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7273             $char[$i] = $1 . '\\' . $2;
7274             }
7275              
7276 0         0 # \p, \P, \X --> p, P, X
7277             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7278             $char[$i] = $1;
7279 0 50 100     0 }
    100 33        
    50 33        
    100 100        
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
7280              
7281             if (0) {
7282             }
7283 249         825  
7284 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
7285 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7286             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)) {
7287             $char[$i] .= join '', splice @char, $i+1, 3;
7288 0         0 }
7289             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)) {
7290             $char[$i] .= join '', splice @char, $i+1, 2;
7291 0         0 }
7292             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)) {
7293             $char[$i] .= join '', splice @char, $i+1, 1;
7294             }
7295             }
7296              
7297 0         0 # open character class [...]
7298 3 50       3 elsif ($char[$i] eq '[') {
7299 3         8 my $left = $i;
7300             if ($char[$i+1] eq ']') {
7301 0         0 $i++;
7302 3 50       7 }
7303 7         10 while (1) {
7304             if (++$i > $#char) {
7305 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7306 7         14 }
7307             if ($char[$i] eq ']') {
7308             my $right = $i;
7309 3 50       6  
7310 3         15 # [...]
  0         0  
7311             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7312             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin1::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7313 0         0 }
7314             else {
7315             splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
7316 3         13 }
7317 3         5  
7318             $i = $left;
7319             last;
7320             }
7321             }
7322             }
7323              
7324 3         8 # open character class [^...]
7325 0 0       0 elsif ($char[$i] eq '[^') {
7326 0         0 my $left = $i;
7327             if ($char[$i+1] eq ']') {
7328 0         0 $i++;
7329 0 0       0 }
7330 0         0 while (1) {
7331             if (++$i > $#char) {
7332 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7333 0         0 }
7334             if ($char[$i] eq ']') {
7335             my $right = $i;
7336 0 0       0  
7337 0         0 # [^...]
  0         0  
7338             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7339             splice @char, $left, $right-$left+1, sprintf(q{@{[Elatin1::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7340 0         0 }
7341             else {
7342             splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7343 0         0 }
7344 0         0  
7345             $i = $left;
7346             last;
7347             }
7348             }
7349             }
7350              
7351 0         0 # rewrite character class or escape character
7352             elsif (my $char = character_class($char[$i],$modifier)) {
7353             $char[$i] = $char;
7354             }
7355              
7356             # P.794 29.2.161. split
7357             # in Chapter 29: Functions
7358             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7359              
7360             # P.951 split
7361             # in Chapter 27: Functions
7362             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7363              
7364             # said "The //m modifier is assumed when you split on the pattern /^/",
7365             # but perl5.008 is not so. Therefore, this software adds //m.
7366             # (and so on)
7367              
7368 1         2 # split(m/^/) --> split(m/^/m)
7369             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7370             $modifier .= 'm';
7371             }
7372              
7373 7 0       22 # /i modifier
7374 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
7375             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
7376             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
7377 0         0 }
7378             else {
7379             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
7380             }
7381             }
7382              
7383 0 0       0 # \u \l \U \L \F \Q \E
7384 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7385             if ($right_e < $left_e) {
7386             $char[$i] = '\\' . $char[$i];
7387             }
7388 0         0 }
7389 0         0 elsif ($char[$i] eq '\u') {
7390             $char[$i] = '@{[Elatin1::ucfirst qq<';
7391             $left_e++;
7392 0         0 }
7393 0         0 elsif ($char[$i] eq '\l') {
7394             $char[$i] = '@{[Elatin1::lcfirst qq<';
7395             $left_e++;
7396 0         0 }
7397 0         0 elsif ($char[$i] eq '\U') {
7398             $char[$i] = '@{[Elatin1::uc qq<';
7399             $left_e++;
7400 0         0 }
7401 0         0 elsif ($char[$i] eq '\L') {
7402             $char[$i] = '@{[Elatin1::lc qq<';
7403             $left_e++;
7404 0         0 }
7405 0         0 elsif ($char[$i] eq '\F') {
7406             $char[$i] = '@{[Elatin1::fc qq<';
7407             $left_e++;
7408 0         0 }
7409 0         0 elsif ($char[$i] eq '\Q') {
7410             $char[$i] = '@{[CORE::quotemeta qq<';
7411             $left_e++;
7412 0 0       0 }
7413 0         0 elsif ($char[$i] eq '\E') {
7414 0         0 if ($right_e < $left_e) {
7415             $char[$i] = '>]}';
7416             $right_e++;
7417 0         0 }
7418             else {
7419             $char[$i] = '';
7420             }
7421 0         0 }
7422 0 0       0 elsif ($char[$i] eq '\Q') {
7423 0         0 while (1) {
7424             if (++$i > $#char) {
7425 0 0       0 last;
7426 0         0 }
7427             if ($char[$i] eq '\E') {
7428             last;
7429             }
7430             }
7431             }
7432             elsif ($char[$i] eq '\E') {
7433             }
7434              
7435 0 0       0 # $0 --> $0
7436 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7437             if ($ignorecase) {
7438             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7439             }
7440 0 0       0 }
7441 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7442             if ($ignorecase) {
7443             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7444             }
7445             }
7446              
7447             # $$ --> $$
7448             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7449             }
7450              
7451             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7452 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7453 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7454 0         0 $char[$i] = e_capture($1);
7455             if ($ignorecase) {
7456             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7457             }
7458 0         0 }
7459 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7460 0         0 $char[$i] = e_capture($1);
7461             if ($ignorecase) {
7462             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7463             }
7464             }
7465              
7466 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7467 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7468 0         0 $char[$i] = e_capture($1.'->'.$2);
7469             if ($ignorecase) {
7470             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7471             }
7472             }
7473              
7474 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7475 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
7476 0         0 $char[$i] = e_capture($1.'->'.$2);
7477             if ($ignorecase) {
7478             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7479             }
7480             }
7481              
7482 0         0 # $$foo
7483 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7484 0         0 $char[$i] = e_capture($1);
7485             if ($ignorecase) {
7486             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7487             }
7488             }
7489              
7490 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
7491 12         32 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7492             if ($ignorecase) {
7493             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::PREMATCH())]}';
7494 0         0 }
7495             else {
7496             $char[$i] = '@{[Elatin1::PREMATCH()]}';
7497             }
7498             }
7499              
7500 12 50       58 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
7501 12         33 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7502             if ($ignorecase) {
7503             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::MATCH())]}';
7504 0         0 }
7505             else {
7506             $char[$i] = '@{[Elatin1::MATCH()]}';
7507             }
7508             }
7509              
7510 12 50       50 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
7511 9         26 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7512             if ($ignorecase) {
7513             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::POSTMATCH())]}';
7514 0         0 }
7515             else {
7516             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
7517             }
7518             }
7519              
7520 9 0       40 # ${ foo }
7521 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
7522             if ($ignorecase) {
7523             $char[$i] = '@{[Elatin1::ignorecase(' . $1 . ')]}';
7524             }
7525             }
7526              
7527 0         0 # ${ ... }
7528 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7529 0         0 $char[$i] = e_capture($1);
7530             if ($ignorecase) {
7531             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7532             }
7533             }
7534              
7535 0         0 # $scalar or @array
7536 3 50       10 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7537 3         13 $char[$i] = e_string($char[$i]);
7538             if ($ignorecase) {
7539             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7540             }
7541             }
7542              
7543 0 50       0 # quote character before ? + * {
7544             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7545             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7546 1         8 }
7547             else {
7548             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7549             }
7550             }
7551             }
7552 0         0  
7553 74 50       206 # make regexp string
7554 74         160 $modifier =~ tr/i//d;
7555             if ($left_e > $right_e) {
7556 0         0 return join '', 'Elatin1::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7557             }
7558             return join '', 'Elatin1::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7559             }
7560              
7561             #
7562             # escape regexp of split qr''
7563 74     0 0 759 #
7564 0   0       sub e_split_q {
7565             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7566 0           $modifier ||= '';
7567 0 0          
7568 0           $modifier =~ tr/p//d;
7569 0           if ($modifier =~ /([adlu])/oxms) {
7570 0 0         my $line = 0;
7571 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7572 0           if ($filename ne __FILE__) {
7573             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7574             last;
7575 0           }
7576             }
7577             die qq{Unsupported modifier "$1" used at line $line.\n};
7578 0           }
7579              
7580             $slash = 'div';
7581 0 0          
7582 0           # /b /B modifier
7583             if ($modifier =~ tr/bB//d) {
7584             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7585 0 0         }
7586              
7587             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7588 0            
7589             # split regexp
7590             my @char = $string =~ /\G((?>
7591             [^\\\[] |
7592             [\x00-\xFF] |
7593             \[\^ |
7594             \[\: (?>[a-z]+) \:\] |
7595             \[\:\^ (?>[a-z]+) \:\] |
7596             \\ (?:$q_char) |
7597             (?:$q_char)
7598             ))/oxmsg;
7599 0            
7600 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7601             for (my $i=0; $i <= $#char; $i++) {
7602             if (0) {
7603             }
7604 0            
7605 0           # open character class [...]
7606 0 0         elsif ($char[$i] eq '[') {
7607 0           my $left = $i;
7608             if ($char[$i+1] eq ']') {
7609 0           $i++;
7610 0 0         }
7611 0           while (1) {
7612             if (++$i > $#char) {
7613 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7614 0           }
7615             if ($char[$i] eq ']') {
7616             my $right = $i;
7617 0            
7618             # [...]
7619 0           splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
7620 0            
7621             $i = $left;
7622             last;
7623             }
7624             }
7625             }
7626              
7627 0           # open character class [^...]
7628 0 0         elsif ($char[$i] eq '[^') {
7629 0           my $left = $i;
7630             if ($char[$i+1] eq ']') {
7631 0           $i++;
7632 0 0         }
7633 0           while (1) {
7634             if (++$i > $#char) {
7635 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7636 0           }
7637             if ($char[$i] eq ']') {
7638             my $right = $i;
7639 0            
7640             # [^...]
7641 0           splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7642 0            
7643             $i = $left;
7644             last;
7645             }
7646             }
7647             }
7648              
7649 0           # rewrite character class or escape character
7650             elsif (my $char = character_class($char[$i],$modifier)) {
7651             $char[$i] = $char;
7652             }
7653              
7654 0           # split(m/^/) --> split(m/^/m)
7655             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7656             $modifier .= 'm';
7657             }
7658              
7659 0 0         # /i modifier
7660 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
7661             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
7662             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
7663 0           }
7664             else {
7665             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
7666             }
7667             }
7668              
7669 0 0         # quote character before ? + * {
7670             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7671             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7672 0           }
7673             else {
7674             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7675             }
7676             }
7677 0           }
7678 0            
7679             $modifier =~ tr/i//d;
7680             return join '', 'Elatin1::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7681             }
7682              
7683             #
7684             # instead of Carp::carp
7685 0     0 0   #
7686 0           sub carp {
7687             my($package,$filename,$line) = caller(1);
7688             print STDERR "@_ at $filename line $line.\n";
7689             }
7690              
7691             #
7692             # instead of Carp::croak
7693 0     0 0   #
7694 0           sub croak {
7695 0           my($package,$filename,$line) = caller(1);
7696             print STDERR "@_ at $filename line $line.\n";
7697             die "\n";
7698             }
7699              
7700             #
7701             # instead of Carp::cluck
7702 0     0 0   #
7703 0           sub cluck {
7704 0           my $i = 0;
7705 0           my @cluck = ();
7706 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7707             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7708 0           $i++;
7709 0           }
7710 0           print STDERR CORE::reverse @cluck;
7711             print STDERR "\n";
7712             print STDERR @_;
7713             }
7714              
7715             #
7716             # instead of Carp::confess
7717 0     0 0   #
7718 0           sub confess {
7719 0           my $i = 0;
7720 0           my @confess = ();
7721 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7722             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7723 0           $i++;
7724 0           }
7725 0           print STDERR CORE::reverse @confess;
7726 0           print STDERR "\n";
7727             print STDERR @_;
7728             die "\n";
7729             }
7730              
7731             1;
7732              
7733             __END__