File Coverage

blib/lib/Elatin1.pm
Criterion Covered Total %
statement 905 2814 32.1
branch 890 2412 36.9
condition 98 355 27.6
subroutine 54 113 47.7
pod 7 74 9.4
total 1954 5768 33.8


line stmt bran cond sub pod time code
1             package Elatin1;
2 206     206   1292 use strict;
  206         342  
  206         10831  
3 206 50   206   3887 BEGIN { $INC{'warnings.pm'} = '' if $] < 5.006 } use warnings;
  206     206   1116  
  206         315  
  206         7990  
4             ######################################################################
5             #
6             # Elatin1 - Run-time routines for Latin1.pm
7             #
8             # http://search.cpan.org/dist/Char-Latin1/
9             #
10             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
11             ######################################################################
12              
13 206     206   3670 use 5.00503; # Galapagos Consensus 1998 for primetools
  206         944  
14             # use 5.008001; # Lancaster Consensus 2013 for toolchains
15              
16             # 12.3. Delaying use Until Runtime
17             # in Chapter 12. Packages, Libraries, and Modules
18             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
19             # (and so on)
20              
21             # Version numbers should be boring
22             # http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
23             # For the impatient, the disinterested or those who just want to follow
24             # a recipe, my advice for all modules is this:
25             # our $VERSION = "0.001"; # or "0.001_001" for a dev release
26             # $VERSION = eval $VERSION; # No!! because '1.10' makes '1.1'
27              
28 206     206   1145 use vars qw($VERSION);
  206         401  
  206         48272  
29             $VERSION = '1.22';
30             $VERSION = $VERSION;
31              
32             BEGIN {
33 206 50   206   1397 if ($^X =~ / jperl /oxmsi) {
34 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
35             }
36 206         335 if (CORE::ord('A') == 193) {
37             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
38             }
39 206         30718 if (CORE::ord('A') != 0x41) {
40             die __FILE__, ": is not US-ASCII script (must be US-ASCII script).\n";
41             }
42             }
43              
44             BEGIN {
45              
46             # instead of utf8.pm
47 206     206   15507 CORE::eval q{
  206     206   1305  
  206     74   413  
  206         56487  
  0         0  
  0         0  
  0         0  
  0         0  
48             no warnings qw(redefine);
49             *utf8::upgrade = sub { CORE::length $_[0] };
50             *utf8::downgrade = sub { 1 };
51             *utf8::encode = sub { };
52             *utf8::decode = sub { 1 };
53             *utf8::is_utf8 = sub { };
54             *utf8::valid = sub { 1 };
55             };
56 206 50       85031 if ($@) {
57 0         0 *utf8::upgrade = sub { CORE::length $_[0] };
  0         0  
58 0         0 *utf8::downgrade = sub { 1 };
  0         0  
59 0         0 *utf8::encode = sub { };
60 0         0 *utf8::decode = sub { 1 };
  0         0  
61 0         0 *utf8::is_utf8 = sub { };
62 0         0 *utf8::valid = sub { 1 };
  0         0  
63             }
64             }
65              
66             # instead of Symbol.pm
67 0         0 BEGIN {
68             sub gensym () {
69 0 0   0 0 0 if ($] < 5.006) {
70 0         0 return \do { local *_ };
  0         0  
71             }
72             else {
73 0         0 return undef;
74             }
75             }
76              
77             sub qualify ($$) {
78 0     0 0 0 my($name) = @_;
79              
80 0 0       0 if (ref $name) {
    0          
    0          
    0          
    0          
    0          
    0          
81 0         0 return $name;
82             }
83             elsif (Elatin1::index($name,'::') >= 0) {
84 0         0 return $name;
85             }
86             elsif (Elatin1::index($name,"'") >= 0) {
87 0         0 return $name;
88             }
89              
90             # special character, "^xyz"
91             elsif ($name =~ /\A \^ [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+ \z/x) {
92              
93             # RGS 2001-11-05 : translate leading ^X to control-char
94 0         0 $name =~ s{\A \^ ([ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]) }{'qq(\c'.$1.')'}xee;
  0         0  
95 0         0 return 'main::' . $name;
96             }
97              
98             # Global names
99             elsif ($name =~ /\A (?: ARGV | ARGVOUT | ENV | INC | SIG | STDERR | STDIN | STDOUT ) \z/x) {
100 0         0 return 'main::' . $name;
101             }
102              
103             # or other
104             elsif ($name =~ /\A [^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz] \z/x) {
105 0         0 return 'main::' . $name;
106             }
107              
108             elsif (defined $_[1]) {
109 0         0 return $_[1] . '::' . $name;
110             }
111             else {
112 0         0 return (caller)[0] . '::' . $name;
113             }
114             }
115              
116             sub qualify_to_ref ($;$) {
117 0 0   0 0 0 if (defined $_[1]) {
118 206     206   1590 no strict qw(refs);
  206         521  
  206         22457  
119 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
120             }
121             else {
122 206     206   1256 no strict qw(refs);
  206     0   410  
  206         39253  
123 0         0 return \*{ qualify $_[0], (caller)[0] };
  0         0  
124             }
125             }
126             }
127              
128             # P.714 29.2.39. flock
129             # in Chapter 29: Functions
130             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
131              
132             # P.863 flock
133             # in Chapter 27: Functions
134             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
135              
136             sub LOCK_SH() {1}
137             sub LOCK_EX() {2}
138             sub LOCK_UN() {8}
139             sub LOCK_NB() {4}
140              
141             # instead of Carp.pm
142             sub carp;
143             sub croak;
144             sub cluck;
145             sub confess;
146              
147             # 6.18. Matching Multiple-Byte Characters
148             # in Chapter 6. Pattern Matching
149             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
150             # (and so on)
151              
152             # regexp of character
153             my $your_char = q{[\x00-\xFF]};
154 206     206   1522 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  206         355  
  206         11666  
155 206     206   1107 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  206         457  
  206         399254  
156              
157             #
158             # Latin-1 character range per length
159             #
160             my %range_tr = ();
161              
162             #
163             # Latin-1 case conversion
164             #
165             my %lc = ();
166             @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)} =
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             my %uc = ();
169             @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)} =
170             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);
171             my %fc = ();
172             @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)} =
173             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);
174              
175             if (0) {
176             }
177              
178             elsif (__PACKAGE__ =~ / \b Elatin1 \z/oxms) {
179             %range_tr = (
180             1 => [ [0x00..0xFF],
181             ],
182             );
183              
184             %lc = (%lc,
185             "\xC0" => "\xE0", # LATIN LETTER A WITH GRAVE
186             "\xC1" => "\xE1", # LATIN LETTER A WITH ACUTE
187             "\xC2" => "\xE2", # LATIN LETTER A WITH CIRCUMFLEX
188             "\xC3" => "\xE3", # LATIN LETTER A WITH TILDE
189             "\xC4" => "\xE4", # LATIN LETTER A WITH DIAERESIS
190             "\xC5" => "\xE5", # LATIN LETTER A WITH RING ABOVE
191             "\xC6" => "\xE6", # LATIN LETTER AE
192             "\xC7" => "\xE7", # LATIN LETTER C WITH CEDILLA
193             "\xC8" => "\xE8", # LATIN LETTER E WITH GRAVE
194             "\xC9" => "\xE9", # LATIN LETTER E WITH ACUTE
195             "\xCA" => "\xEA", # LATIN LETTER E WITH CIRCUMFLEX
196             "\xCB" => "\xEB", # LATIN LETTER E WITH DIAERESIS
197             "\xCC" => "\xEC", # LATIN LETTER I WITH GRAVE
198             "\xCD" => "\xED", # LATIN LETTER I WITH ACUTE
199             "\xCE" => "\xEE", # LATIN LETTER I WITH CIRCUMFLEX
200             "\xCF" => "\xEF", # LATIN LETTER I WITH DIAERESIS
201             "\xD0" => "\xF0", # LATIN LETTER ETH (Icelandic)
202             "\xD1" => "\xF1", # LATIN LETTER N WITH TILDE
203             "\xD2" => "\xF2", # LATIN LETTER O WITH GRAVE
204             "\xD3" => "\xF3", # LATIN LETTER O WITH ACUTE
205             "\xD4" => "\xF4", # LATIN LETTER O WITH CIRCUMFLEX
206             "\xD5" => "\xF5", # LATIN LETTER O WITH TILDE
207             "\xD6" => "\xF6", # LATIN LETTER O WITH DIAERESIS
208             "\xD8" => "\xF8", # LATIN LETTER O WITH STROKE
209             "\xD9" => "\xF9", # LATIN LETTER U WITH GRAVE
210             "\xDA" => "\xFA", # LATIN LETTER U WITH ACUTE
211             "\xDB" => "\xFB", # LATIN LETTER U WITH CIRCUMFLEX
212             "\xDC" => "\xFC", # LATIN LETTER U WITH DIAERESIS
213             "\xDD" => "\xFD", # LATIN LETTER Y WITH ACUTE
214             "\xDE" => "\xFE", # LATIN LETTER THORN (Icelandic)
215             );
216              
217             %uc = (%uc,
218             "\xE0" => "\xC0", # LATIN LETTER A WITH GRAVE
219             "\xE1" => "\xC1", # LATIN LETTER A WITH ACUTE
220             "\xE2" => "\xC2", # LATIN LETTER A WITH CIRCUMFLEX
221             "\xE3" => "\xC3", # LATIN LETTER A WITH TILDE
222             "\xE4" => "\xC4", # LATIN LETTER A WITH DIAERESIS
223             "\xE5" => "\xC5", # LATIN LETTER A WITH RING ABOVE
224             "\xE6" => "\xC6", # LATIN LETTER AE
225             "\xE7" => "\xC7", # LATIN LETTER C WITH CEDILLA
226             "\xE8" => "\xC8", # LATIN LETTER E WITH GRAVE
227             "\xE9" => "\xC9", # LATIN LETTER E WITH ACUTE
228             "\xEA" => "\xCA", # LATIN LETTER E WITH CIRCUMFLEX
229             "\xEB" => "\xCB", # LATIN LETTER E WITH DIAERESIS
230             "\xEC" => "\xCC", # LATIN LETTER I WITH GRAVE
231             "\xED" => "\xCD", # LATIN LETTER I WITH ACUTE
232             "\xEE" => "\xCE", # LATIN LETTER I WITH CIRCUMFLEX
233             "\xEF" => "\xCF", # LATIN LETTER I WITH DIAERESIS
234             "\xF0" => "\xD0", # LATIN LETTER ETH (Icelandic)
235             "\xF1" => "\xD1", # LATIN LETTER N WITH TILDE
236             "\xF2" => "\xD2", # LATIN LETTER O WITH GRAVE
237             "\xF3" => "\xD3", # LATIN LETTER O WITH ACUTE
238             "\xF4" => "\xD4", # LATIN LETTER O WITH CIRCUMFLEX
239             "\xF5" => "\xD5", # LATIN LETTER O WITH TILDE
240             "\xF6" => "\xD6", # LATIN LETTER O WITH DIAERESIS
241             "\xF8" => "\xD8", # LATIN LETTER O WITH STROKE
242             "\xF9" => "\xD9", # LATIN LETTER U WITH GRAVE
243             "\xFA" => "\xDA", # LATIN LETTER U WITH ACUTE
244             "\xFB" => "\xDB", # LATIN LETTER U WITH CIRCUMFLEX
245             "\xFC" => "\xDC", # LATIN LETTER U WITH DIAERESIS
246             "\xFD" => "\xDD", # LATIN LETTER Y WITH ACUTE
247             "\xFE" => "\xDE", # LATIN LETTER THORN (Icelandic)
248             );
249              
250             %fc = (%fc,
251             "\xC0" => "\xE0", # LATIN CAPITAL LETTER A WITH GRAVE --> LATIN SMALL LETTER A WITH GRAVE
252             "\xC1" => "\xE1", # LATIN CAPITAL LETTER A WITH ACUTE --> LATIN SMALL LETTER A WITH ACUTE
253             "\xC2" => "\xE2", # LATIN CAPITAL LETTER A WITH CIRCUMFLEX --> LATIN SMALL LETTER A WITH CIRCUMFLEX
254             "\xC3" => "\xE3", # LATIN CAPITAL LETTER A WITH TILDE --> LATIN SMALL LETTER A WITH TILDE
255             "\xC4" => "\xE4", # LATIN CAPITAL LETTER A WITH DIAERESIS --> LATIN SMALL LETTER A WITH DIAERESIS
256             "\xC5" => "\xE5", # LATIN CAPITAL LETTER A WITH RING ABOVE --> LATIN SMALL LETTER A WITH RING ABOVE
257             "\xC6" => "\xE6", # LATIN CAPITAL LETTER AE --> LATIN SMALL LETTER AE
258             "\xC7" => "\xE7", # LATIN CAPITAL LETTER C WITH CEDILLA --> LATIN SMALL LETTER C WITH CEDILLA
259             "\xC8" => "\xE8", # LATIN CAPITAL LETTER E WITH GRAVE --> LATIN SMALL LETTER E WITH GRAVE
260             "\xC9" => "\xE9", # LATIN CAPITAL LETTER E WITH ACUTE --> LATIN SMALL LETTER E WITH ACUTE
261             "\xCA" => "\xEA", # LATIN CAPITAL LETTER E WITH CIRCUMFLEX --> LATIN SMALL LETTER E WITH CIRCUMFLEX
262             "\xCB" => "\xEB", # LATIN CAPITAL LETTER E WITH DIAERESIS --> LATIN SMALL LETTER E WITH DIAERESIS
263             "\xCC" => "\xEC", # LATIN CAPITAL LETTER I WITH GRAVE --> LATIN SMALL LETTER I WITH GRAVE
264             "\xCD" => "\xED", # LATIN CAPITAL LETTER I WITH ACUTE --> LATIN SMALL LETTER I WITH ACUTE
265             "\xCE" => "\xEE", # LATIN CAPITAL LETTER I WITH CIRCUMFLEX --> LATIN SMALL LETTER I WITH CIRCUMFLEX
266             "\xCF" => "\xEF", # LATIN CAPITAL LETTER I WITH DIAERESIS --> LATIN SMALL LETTER I WITH DIAERESIS
267             "\xD0" => "\xF0", # LATIN CAPITAL LETTER ETH --> LATIN SMALL LETTER ETH
268             "\xD1" => "\xF1", # LATIN CAPITAL LETTER N WITH TILDE --> LATIN SMALL LETTER N WITH TILDE
269             "\xD2" => "\xF2", # LATIN CAPITAL LETTER O WITH GRAVE --> LATIN SMALL LETTER O WITH GRAVE
270             "\xD3" => "\xF3", # LATIN CAPITAL LETTER O WITH ACUTE --> LATIN SMALL LETTER O WITH ACUTE
271             "\xD4" => "\xF4", # LATIN CAPITAL LETTER O WITH CIRCUMFLEX --> LATIN SMALL LETTER O WITH CIRCUMFLEX
272             "\xD5" => "\xF5", # LATIN CAPITAL LETTER O WITH TILDE --> LATIN SMALL LETTER O WITH TILDE
273             "\xD6" => "\xF6", # LATIN CAPITAL LETTER O WITH DIAERESIS --> LATIN SMALL LETTER O WITH DIAERESIS
274             "\xD8" => "\xF8", # LATIN CAPITAL LETTER O WITH STROKE --> LATIN SMALL LETTER O WITH STROKE
275             "\xD9" => "\xF9", # LATIN CAPITAL LETTER U WITH GRAVE --> LATIN SMALL LETTER U WITH GRAVE
276             "\xDA" => "\xFA", # LATIN CAPITAL LETTER U WITH ACUTE --> LATIN SMALL LETTER U WITH ACUTE
277             "\xDB" => "\xFB", # LATIN CAPITAL LETTER U WITH CIRCUMFLEX --> LATIN SMALL LETTER U WITH CIRCUMFLEX
278             "\xDC" => "\xFC", # LATIN CAPITAL LETTER U WITH DIAERESIS --> LATIN SMALL LETTER U WITH DIAERESIS
279             "\xDD" => "\xFD", # LATIN CAPITAL LETTER Y WITH ACUTE --> LATIN SMALL LETTER Y WITH ACUTE
280             "\xDE" => "\xFE", # LATIN CAPITAL LETTER THORN --> LATIN SMALL LETTER THORN
281             "\xDF" => "\x73\x73", # LATIN SMALL LETTER SHARP S --> LATIN SMALL LETTER S, LATIN SMALL LETTER S
282             );
283             }
284              
285             else {
286             croak "Don't know my package name '@{[__PACKAGE__]}'";
287             }
288              
289             #
290             # @ARGV wildcard globbing
291             #
292             sub import {
293              
294 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
295 0         0 my @argv = ();
296 0         0 for (@ARGV) {
297              
298             # has space
299 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
300 0 0       0 if (my @glob = Elatin1::glob(qq{"$_"})) {
301 0         0 push @argv, @glob;
302             }
303             else {
304 0         0 push @argv, $_;
305             }
306             }
307              
308             # has wildcard metachar
309             elsif (/\A (?:$q_char)*? [*?] /oxms) {
310 0 0       0 if (my @glob = Elatin1::glob($_)) {
311 0         0 push @argv, @glob;
312             }
313             else {
314 0         0 push @argv, $_;
315             }
316             }
317              
318             # no wildcard globbing
319             else {
320 0         0 push @argv, $_;
321             }
322             }
323 0         0 @ARGV = @argv;
324             }
325              
326 0         0 *Char::ord = \&Latin1::ord;
327 0         0 *Char::ord_ = \&Latin1::ord_;
328 0         0 *Char::reverse = \&Latin1::reverse;
329 0         0 *Char::getc = \&Latin1::getc;
330 0         0 *Char::length = \&Latin1::length;
331 0         0 *Char::substr = \&Latin1::substr;
332 0         0 *Char::index = \&Latin1::index;
333 0         0 *Char::rindex = \&Latin1::rindex;
334 0         0 *Char::eval = \&Latin1::eval;
335 0         0 *Char::escape = \&Latin1::escape;
336 0         0 *Char::escape_token = \&Latin1::escape_token;
337 0         0 *Char::escape_script = \&Latin1::escape_script;
338             }
339              
340             # P.230 Care with Prototypes
341             # in Chapter 6: Subroutines
342             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
343             #
344             # If you aren't careful, you can get yourself into trouble with prototypes.
345             # But if you are careful, you can do a lot of neat things with them. This is
346             # all very powerful, of course, and should only be used in moderation to make
347             # the world a better place.
348              
349             # P.332 Care with Prototypes
350             # in Chapter 7: Subroutines
351             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
352             #
353             # If you aren't careful, you can get yourself into trouble with prototypes.
354             # But if you are careful, you can do a lot of neat things with them. This is
355             # all very powerful, of course, and should only be used in moderation to make
356             # the world a better place.
357              
358             #
359             # Prototypes of subroutines
360             #
361       0     sub unimport {}
362             sub Elatin1::split(;$$$);
363             sub Elatin1::tr($$$$;$);
364             sub Elatin1::chop(@);
365             sub Elatin1::index($$;$);
366             sub Elatin1::rindex($$;$);
367             sub Elatin1::lcfirst(@);
368             sub Elatin1::lcfirst_();
369             sub Elatin1::lc(@);
370             sub Elatin1::lc_();
371             sub Elatin1::ucfirst(@);
372             sub Elatin1::ucfirst_();
373             sub Elatin1::uc(@);
374             sub Elatin1::uc_();
375             sub Elatin1::fc(@);
376             sub Elatin1::fc_();
377             sub Elatin1::ignorecase;
378             sub Elatin1::classic_character_class;
379             sub Elatin1::capture;
380             sub Elatin1::chr(;$);
381             sub Elatin1::chr_();
382             sub Elatin1::glob($);
383             sub Elatin1::glob_();
384              
385             sub Latin1::ord(;$);
386             sub Latin1::ord_();
387             sub Latin1::reverse(@);
388             sub Latin1::getc(;*@);
389             sub Latin1::length(;$);
390             sub Latin1::substr($$;$$);
391             sub Latin1::index($$;$);
392             sub Latin1::rindex($$;$);
393             sub Latin1::escape(;$);
394              
395             #
396             # Regexp work
397             #
398 206         16148 use vars qw(
399             $re_a
400             $re_t
401             $re_n
402             $re_r
403 206     206   1670 );
  206         1510  
404              
405             #
406             # Character class
407             #
408 206         2289658 use vars qw(
409             $dot
410             $dot_s
411             $eD
412             $eS
413             $eW
414             $eH
415             $eV
416             $eR
417             $eN
418             $not_alnum
419             $not_alpha
420             $not_ascii
421             $not_blank
422             $not_cntrl
423             $not_digit
424             $not_graph
425             $not_lower
426             $not_lower_i
427             $not_print
428             $not_punct
429             $not_space
430             $not_upper
431             $not_upper_i
432             $not_word
433             $not_xdigit
434             $eb
435             $eB
436 206     206   1427 );
  206         421  
437              
438             ${Elatin1::dot} = qr{(?>[^\x0A])};
439             ${Elatin1::dot_s} = qr{(?>[\x00-\xFF])};
440             ${Elatin1::eD} = qr{(?>[^0-9])};
441              
442             # Vertical tabs are now whitespace
443             # \s in a regex now matches a vertical tab in all circumstances.
444             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
445             # ${Elatin1::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
446             # ${Elatin1::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
447             ${Elatin1::eS} = qr{(?>[^\s])};
448              
449             ${Elatin1::eW} = qr{(?>[^0-9A-Z_a-z])};
450             ${Elatin1::eH} = qr{(?>[^\x09\x20])};
451             ${Elatin1::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
452             ${Elatin1::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
453             ${Elatin1::eN} = qr{(?>[^\x0A])};
454             ${Elatin1::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
455             ${Elatin1::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
456             ${Elatin1::not_ascii} = qr{(?>[^\x00-\x7F])};
457             ${Elatin1::not_blank} = qr{(?>[^\x09\x20])};
458             ${Elatin1::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
459             ${Elatin1::not_digit} = qr{(?>[^\x30-\x39])};
460             ${Elatin1::not_graph} = qr{(?>[^\x21-\x7F])};
461             ${Elatin1::not_lower} = qr{(?>[^\x61-\x7A])};
462             ${Elatin1::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
463             # ${Elatin1::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
464             ${Elatin1::not_print} = qr{(?>[^\x20-\x7F])};
465             ${Elatin1::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
466             ${Elatin1::not_space} = qr{(?>[^\s\x0B])};
467             ${Elatin1::not_upper} = qr{(?>[^\x41-\x5A])};
468             ${Elatin1::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
469             # ${Elatin1::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
470             ${Elatin1::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
471             ${Elatin1::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
472             ${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))};
473             ${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]))};
474              
475             # avoid: Name "Elatin1::foo" used only once: possible typo at here.
476             ${Elatin1::dot} = ${Elatin1::dot};
477             ${Elatin1::dot_s} = ${Elatin1::dot_s};
478             ${Elatin1::eD} = ${Elatin1::eD};
479             ${Elatin1::eS} = ${Elatin1::eS};
480             ${Elatin1::eW} = ${Elatin1::eW};
481             ${Elatin1::eH} = ${Elatin1::eH};
482             ${Elatin1::eV} = ${Elatin1::eV};
483             ${Elatin1::eR} = ${Elatin1::eR};
484             ${Elatin1::eN} = ${Elatin1::eN};
485             ${Elatin1::not_alnum} = ${Elatin1::not_alnum};
486             ${Elatin1::not_alpha} = ${Elatin1::not_alpha};
487             ${Elatin1::not_ascii} = ${Elatin1::not_ascii};
488             ${Elatin1::not_blank} = ${Elatin1::not_blank};
489             ${Elatin1::not_cntrl} = ${Elatin1::not_cntrl};
490             ${Elatin1::not_digit} = ${Elatin1::not_digit};
491             ${Elatin1::not_graph} = ${Elatin1::not_graph};
492             ${Elatin1::not_lower} = ${Elatin1::not_lower};
493             ${Elatin1::not_lower_i} = ${Elatin1::not_lower_i};
494             ${Elatin1::not_print} = ${Elatin1::not_print};
495             ${Elatin1::not_punct} = ${Elatin1::not_punct};
496             ${Elatin1::not_space} = ${Elatin1::not_space};
497             ${Elatin1::not_upper} = ${Elatin1::not_upper};
498             ${Elatin1::not_upper_i} = ${Elatin1::not_upper_i};
499             ${Elatin1::not_word} = ${Elatin1::not_word};
500             ${Elatin1::not_xdigit} = ${Elatin1::not_xdigit};
501             ${Elatin1::eb} = ${Elatin1::eb};
502             ${Elatin1::eB} = ${Elatin1::eB};
503              
504             #
505             # Latin-1 split
506             #
507             sub Elatin1::split(;$$$) {
508              
509             # P.794 29.2.161. split
510             # in Chapter 29: Functions
511             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
512              
513             # P.951 split
514             # in Chapter 27: Functions
515             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
516              
517 0     0 0 0 my $pattern = $_[0];
518 0         0 my $string = $_[1];
519 0         0 my $limit = $_[2];
520              
521             # if $pattern is also omitted or is the literal space, " "
522 0 0       0 if (not defined $pattern) {
523 0         0 $pattern = ' ';
524             }
525              
526             # if $string is omitted, the function splits the $_ string
527 0 0       0 if (not defined $string) {
528 0 0       0 if (defined $_) {
529 0         0 $string = $_;
530             }
531             else {
532 0         0 $string = '';
533             }
534             }
535              
536 0         0 my @split = ();
537              
538             # when string is empty
539 0 0       0 if ($string eq '') {
    0          
540              
541             # resulting list value in list context
542 0 0       0 if (wantarray) {
543 0         0 return @split;
544             }
545              
546             # count of substrings in scalar context
547             else {
548 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
549 0         0 @_ = @split;
550 0         0 return scalar @_;
551             }
552             }
553              
554             # split's first argument is more consistently interpreted
555             #
556             # After some changes earlier in v5.17, split's behavior has been simplified:
557             # if the PATTERN argument evaluates to a string containing one space, it is
558             # treated the way that a literal string containing one space once was.
559             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
560              
561             # if $pattern is also omitted or is the literal space, " ", the function splits
562             # on whitespace, /\s+/, after skipping any leading whitespace
563             # (and so on)
564              
565             elsif ($pattern eq ' ') {
566 0 0       0 if (not defined $limit) {
567 0         0 return CORE::split(' ', $string);
568             }
569             else {
570 0         0 return CORE::split(' ', $string, $limit);
571             }
572             }
573              
574             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
575 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
576              
577             # a pattern capable of matching either the null string or something longer than the
578             # null string will split the value of $string into separate characters wherever it
579             # matches the null string between characters
580             # (and so on)
581              
582 0 0       0 if ('' =~ / \A $pattern \z /xms) {
583 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
584 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
585              
586             # P.1024 Appendix W.10 Multibyte Processing
587             # of ISBN 1-56592-224-7 CJKV Information Processing
588             # (and so on)
589              
590             # the //m modifier is assumed when you split on the pattern /^/
591             # (and so on)
592              
593 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
594             # V
595 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
596              
597             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
598             # is included in the resulting list, interspersed with the fields that are ordinarily returned
599             # (and so on)
600              
601 0         0 local $@;
602 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
603 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
604 0         0 push @split, CORE::eval('$' . $digit);
605             }
606             }
607             }
608              
609             else {
610 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
611              
612 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
613             # V
614 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
615 0         0 local $@;
616 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
617 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
618 0         0 push @split, CORE::eval('$' . $digit);
619             }
620             }
621             }
622             }
623              
624             elsif ($limit > 0) {
625 0 0       0 if ('' =~ / \A $pattern \z /xms) {
626 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
627 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
628              
629 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
630             # V
631 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
632 0         0 local $@;
633 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
634 0         0 push @split, CORE::eval('$' . $digit);
635             }
636             }
637             }
638             }
639             else {
640 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
641 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
642              
643 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
644             # V
645 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
646 0         0 local $@;
647 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
648 0         0 push @split, CORE::eval('$' . $digit);
649             }
650             }
651             }
652             }
653             }
654              
655 0 0       0 if (CORE::length($string) > 0) {
656 0         0 push @split, $string;
657             }
658              
659             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
660 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
661 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
662 0         0 pop @split;
663             }
664             }
665              
666             # resulting list value in list context
667 0 0       0 if (wantarray) {
668 0         0 return @split;
669             }
670              
671             # count of substrings in scalar context
672             else {
673 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
674 0         0 @_ = @split;
675 0         0 return scalar @_;
676             }
677             }
678              
679             #
680             # get last subexpression offsets
681             #
682             sub _last_subexpression_offsets {
683 0     0   0 my $pattern = $_[0];
684              
685             # remove comment
686 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
687              
688 0         0 my $modifier = '';
689 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
690 0         0 $modifier = $1;
691 0         0 $modifier =~ s/-[A-Za-z]*//;
692             }
693              
694             # with /x modifier
695 0         0 my @char = ();
696 0 0       0 if ($modifier =~ /x/oxms) {
697 0         0 @char = $pattern =~ /\G((?>
698             [^\\\#\[\(] |
699             \\ $q_char |
700             \# (?>[^\n]*) $ |
701             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
702             \(\? |
703             $q_char
704             ))/oxmsg;
705             }
706              
707             # without /x modifier
708             else {
709 0         0 @char = $pattern =~ /\G((?>
710             [^\\\[\(] |
711             \\ $q_char |
712             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
713             \(\? |
714             $q_char
715             ))/oxmsg;
716             }
717              
718 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
719             }
720              
721             #
722             # Latin-1 transliteration (tr///)
723             #
724             sub Elatin1::tr($$$$;$) {
725              
726 0     0 0 0 my $bind_operator = $_[1];
727 0         0 my $searchlist = $_[2];
728 0         0 my $replacementlist = $_[3];
729 0   0     0 my $modifier = $_[4] || '';
730              
731 0 0       0 if ($modifier =~ /r/oxms) {
732 0 0       0 if ($bind_operator =~ / !~ /oxms) {
733 0         0 croak "Using !~ with tr///r doesn't make sense";
734             }
735             }
736              
737 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
738 0         0 my @searchlist = _charlist_tr($searchlist);
739 0         0 my @replacementlist = _charlist_tr($replacementlist);
740              
741 0         0 my %tr = ();
742 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
743 0 0       0 if (not exists $tr{$searchlist[$i]}) {
744 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
745 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
746             }
747             elsif ($modifier =~ /d/oxms) {
748 0         0 $tr{$searchlist[$i]} = '';
749             }
750             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
751 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
752             }
753             else {
754 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
755             }
756             }
757             }
758              
759 0         0 my $tr = 0;
760 0         0 my $replaced = '';
761 0 0       0 if ($modifier =~ /c/oxms) {
762 0         0 while (defined(my $char = shift @char)) {
763 0 0       0 if (not exists $tr{$char}) {
764 0 0       0 if (defined $replacementlist[-1]) {
765 0         0 $replaced .= $replacementlist[-1];
766             }
767 0         0 $tr++;
768 0 0       0 if ($modifier =~ /s/oxms) {
769 0   0     0 while (@char and (not exists $tr{$char[0]})) {
770 0         0 shift @char;
771 0         0 $tr++;
772             }
773             }
774             }
775             else {
776 0         0 $replaced .= $char;
777             }
778             }
779             }
780             else {
781 0         0 while (defined(my $char = shift @char)) {
782 0 0       0 if (exists $tr{$char}) {
783 0         0 $replaced .= $tr{$char};
784 0         0 $tr++;
785 0 0       0 if ($modifier =~ /s/oxms) {
786 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
787 0         0 shift @char;
788 0         0 $tr++;
789             }
790             }
791             }
792             else {
793 0         0 $replaced .= $char;
794             }
795             }
796             }
797              
798 0 0       0 if ($modifier =~ /r/oxms) {
799 0         0 return $replaced;
800             }
801             else {
802 0         0 $_[0] = $replaced;
803 0 0       0 if ($bind_operator =~ / !~ /oxms) {
804 0         0 return not $tr;
805             }
806             else {
807 0         0 return $tr;
808             }
809             }
810             }
811              
812             #
813             # Latin-1 chop
814             #
815             sub Elatin1::chop(@) {
816              
817 0     0 0 0 my $chop;
818 0 0       0 if (@_ == 0) {
819 0         0 my @char = /\G (?>$q_char) /oxmsg;
820 0         0 $chop = pop @char;
821 0         0 $_ = join '', @char;
822             }
823             else {
824 0         0 for (@_) {
825 0         0 my @char = /\G (?>$q_char) /oxmsg;
826 0         0 $chop = pop @char;
827 0         0 $_ = join '', @char;
828             }
829             }
830 0         0 return $chop;
831             }
832              
833             #
834             # Latin-1 index by octet
835             #
836             sub Elatin1::index($$;$) {
837              
838 0     0 1 0 my($str,$substr,$position) = @_;
839 0   0     0 $position ||= 0;
840 0         0 my $pos = 0;
841              
842 0         0 while ($pos < CORE::length($str)) {
843 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
844 0 0       0 if ($pos >= $position) {
845 0         0 return $pos;
846             }
847             }
848 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
849 0         0 $pos += CORE::length($1);
850             }
851             else {
852 0         0 $pos += 1;
853             }
854             }
855 0         0 return -1;
856             }
857              
858             #
859             # Latin-1 reverse index
860             #
861             sub Elatin1::rindex($$;$) {
862              
863 0     0 0 0 my($str,$substr,$position) = @_;
864 0   0     0 $position ||= CORE::length($str) - 1;
865 0         0 my $pos = 0;
866 0         0 my $rindex = -1;
867              
868 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
869 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
870 0         0 $rindex = $pos;
871             }
872 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
873 0         0 $pos += CORE::length($1);
874             }
875             else {
876 0         0 $pos += 1;
877             }
878             }
879 0         0 return $rindex;
880             }
881              
882             #
883             # Latin-1 lower case first with parameter
884             #
885             sub Elatin1::lcfirst(@) {
886 0 0   0 0 0 if (@_) {
887 0         0 my $s = shift @_;
888 0 0 0     0 if (@_ and wantarray) {
889 0         0 return Elatin1::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
890             }
891             else {
892 0         0 return Elatin1::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
893             }
894             }
895             else {
896 0         0 return Elatin1::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
897             }
898             }
899              
900             #
901             # Latin-1 lower case first without parameter
902             #
903             sub Elatin1::lcfirst_() {
904 0     0 0 0 return Elatin1::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
905             }
906              
907             #
908             # Latin-1 lower case with parameter
909             #
910             sub Elatin1::lc(@) {
911 0 0   0 0 0 if (@_) {
912 0         0 my $s = shift @_;
913 0 0 0     0 if (@_ and wantarray) {
914 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
915             }
916             else {
917 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
918             }
919             }
920             else {
921 0         0 return Elatin1::lc_();
922             }
923             }
924              
925             #
926             # Latin-1 lower case without parameter
927             #
928             sub Elatin1::lc_() {
929 0     0 0 0 my $s = $_;
930 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
931             }
932              
933             #
934             # Latin-1 upper case first with parameter
935             #
936             sub Elatin1::ucfirst(@) {
937 0 0   0 0 0 if (@_) {
938 0         0 my $s = shift @_;
939 0 0 0     0 if (@_ and wantarray) {
940 0         0 return Elatin1::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
941             }
942             else {
943 0         0 return Elatin1::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
944             }
945             }
946             else {
947 0         0 return Elatin1::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
948             }
949             }
950              
951             #
952             # Latin-1 upper case first without parameter
953             #
954             sub Elatin1::ucfirst_() {
955 0     0 0 0 return Elatin1::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
956             }
957              
958             #
959             # Latin-1 upper case with parameter
960             #
961             sub Elatin1::uc(@) {
962 0 50   174 0 0 if (@_) {
963 174         246 my $s = shift @_;
964 174 50 33     217 if (@_ and wantarray) {
965 174 0       306 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
966             }
967             else {
968 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         509  
969             }
970             }
971             else {
972 174         614 return Elatin1::uc_();
973             }
974             }
975              
976             #
977             # Latin-1 upper case without parameter
978             #
979             sub Elatin1::uc_() {
980 0     0 0 0 my $s = $_;
981 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
982             }
983              
984             #
985             # Latin-1 fold case with parameter
986             #
987             sub Elatin1::fc(@) {
988 0 50   197 0 0 if (@_) {
989 197         280 my $s = shift @_;
990 197 50 33     224 if (@_ and wantarray) {
991 197 0       347 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
992             }
993             else {
994 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         465  
995             }
996             }
997             else {
998 197         1065 return Elatin1::fc_();
999             }
1000             }
1001              
1002             #
1003             # Latin-1 fold case without parameter
1004             #
1005             sub Elatin1::fc_() {
1006 0     0 0 0 my $s = $_;
1007 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1008             }
1009              
1010             #
1011             # Latin-1 regexp capture
1012             #
1013             {
1014             sub Elatin1::capture {
1015 0     0 1 0 return $_[0];
1016             }
1017             }
1018              
1019             #
1020             # Latin-1 regexp ignore case modifier
1021             #
1022             sub Elatin1::ignorecase {
1023              
1024 0     0 0 0 my @string = @_;
1025 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1026              
1027             # ignore case of $scalar or @array
1028 0         0 for my $string (@string) {
1029              
1030             # split regexp
1031 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1032              
1033             # unescape character
1034 0         0 for (my $i=0; $i <= $#char; $i++) {
1035 0 0       0 next if not defined $char[$i];
1036              
1037             # open character class [...]
1038 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1039 0         0 my $left = $i;
1040              
1041             # [] make die "unmatched [] in regexp ...\n"
1042              
1043 0 0       0 if ($char[$i+1] eq ']') {
1044 0         0 $i++;
1045             }
1046              
1047 0         0 while (1) {
1048 0 0       0 if (++$i > $#char) {
1049 0         0 croak "Unmatched [] in regexp";
1050             }
1051 0 0       0 if ($char[$i] eq ']') {
1052 0         0 my $right = $i;
1053 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1054              
1055             # escape character
1056 0         0 for my $char (@charlist) {
1057 0 0       0 if (0) {
1058             }
1059              
1060 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1061 0         0 $char = '\\' . $char;
1062             }
1063             }
1064              
1065             # [...]
1066 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1067              
1068 0         0 $i = $left;
1069 0         0 last;
1070             }
1071             }
1072             }
1073              
1074             # open character class [^...]
1075             elsif ($char[$i] eq '[^') {
1076 0         0 my $left = $i;
1077              
1078             # [^] make die "unmatched [] in regexp ...\n"
1079              
1080 0 0       0 if ($char[$i+1] eq ']') {
1081 0         0 $i++;
1082             }
1083              
1084 0         0 while (1) {
1085 0 0       0 if (++$i > $#char) {
1086 0         0 croak "Unmatched [] in regexp";
1087             }
1088 0 0       0 if ($char[$i] eq ']') {
1089 0         0 my $right = $i;
1090 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1091              
1092             # escape character
1093 0         0 for my $char (@charlist) {
1094 0 0       0 if (0) {
1095             }
1096              
1097 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1098 0         0 $char = '\\' . $char;
1099             }
1100             }
1101              
1102             # [^...]
1103 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1104              
1105 0         0 $i = $left;
1106 0         0 last;
1107             }
1108             }
1109             }
1110              
1111             # rewrite classic character class or escape character
1112             elsif (my $char = classic_character_class($char[$i])) {
1113 0         0 $char[$i] = $char;
1114             }
1115              
1116             # with /i modifier
1117             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1118 0         0 my $uc = Elatin1::uc($char[$i]);
1119 0         0 my $fc = Elatin1::fc($char[$i]);
1120 0 0       0 if ($uc ne $fc) {
1121 0 0       0 if (CORE::length($fc) == 1) {
1122 0         0 $char[$i] = '[' . $uc . $fc . ']';
1123             }
1124             else {
1125 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1126             }
1127             }
1128             }
1129             }
1130              
1131             # characterize
1132 0         0 for (my $i=0; $i <= $#char; $i++) {
1133 0 0       0 next if not defined $char[$i];
1134              
1135 0 0       0 if (0) {
1136             }
1137              
1138             # quote character before ? + * {
1139 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1140 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1141 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1142             }
1143             }
1144             }
1145              
1146 0         0 $string = join '', @char;
1147             }
1148              
1149             # make regexp string
1150 0         0 return @string;
1151             }
1152              
1153             #
1154             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1155             #
1156             sub Elatin1::classic_character_class {
1157 0     1867 0 0 my($char) = @_;
1158              
1159             return {
1160             '\D' => '${Elatin1::eD}',
1161             '\S' => '${Elatin1::eS}',
1162             '\W' => '${Elatin1::eW}',
1163             '\d' => '[0-9]',
1164              
1165             # Before Perl 5.6, \s only matched the five whitespace characters
1166             # tab, newline, form-feed, carriage return, and the space character
1167             # itself, which, taken together, is the character class [\t\n\f\r ].
1168              
1169             # Vertical tabs are now whitespace
1170             # \s in a regex now matches a vertical tab in all circumstances.
1171             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1172             # \t \n \v \f \r space
1173             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1174             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1175             '\s' => '\s',
1176              
1177             '\w' => '[0-9A-Z_a-z]',
1178             '\C' => '[\x00-\xFF]',
1179             '\X' => 'X',
1180              
1181             # \h \v \H \V
1182              
1183             # P.114 Character Class Shortcuts
1184             # in Chapter 7: In the World of Regular Expressions
1185             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1186              
1187             # P.357 13.2.3 Whitespace
1188             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1189             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1190             #
1191             # 0x00009 CHARACTER TABULATION h s
1192             # 0x0000a LINE FEED (LF) vs
1193             # 0x0000b LINE TABULATION v
1194             # 0x0000c FORM FEED (FF) vs
1195             # 0x0000d CARRIAGE RETURN (CR) vs
1196             # 0x00020 SPACE h s
1197              
1198             # P.196 Table 5-9. Alphanumeric regex metasymbols
1199             # in Chapter 5. Pattern Matching
1200             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1201              
1202             # (and so on)
1203              
1204             '\H' => '${Elatin1::eH}',
1205             '\V' => '${Elatin1::eV}',
1206             '\h' => '[\x09\x20]',
1207             '\v' => '[\x0A\x0B\x0C\x0D]',
1208             '\R' => '${Elatin1::eR}',
1209              
1210             # \N
1211             #
1212             # http://perldoc.perl.org/perlre.html
1213             # Character Classes and other Special Escapes
1214             # Any character but \n (experimental). Not affected by /s modifier
1215              
1216             '\N' => '${Elatin1::eN}',
1217              
1218             # \b \B
1219              
1220             # P.180 Boundaries: The \b and \B Assertions
1221             # in Chapter 5: Pattern Matching
1222             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1223              
1224             # P.219 Boundaries: The \b and \B Assertions
1225             # in Chapter 5: Pattern Matching
1226             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1227              
1228             # \b really means (?:(?<=\w)(?!\w)|(?
1229             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1230             '\b' => '${Elatin1::eb}',
1231              
1232             # \B really means (?:(?<=\w)(?=\w)|(?
1233             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1234             '\B' => '${Elatin1::eB}',
1235              
1236 1867   100     2521 }->{$char} || '';
1237             }
1238              
1239             #
1240             # prepare Latin-1 characters per length
1241             #
1242              
1243             # 1 octet characters
1244             my @chars1 = ();
1245             sub chars1 {
1246 1867 0   0 0 66736 if (@chars1) {
1247 0         0 return @chars1;
1248             }
1249 0 0       0 if (exists $range_tr{1}) {
1250 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1251 0         0 while (my @range = splice(@ranges,0,1)) {
1252 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1253 0         0 push @chars1, pack 'C', $oct0;
1254             }
1255             }
1256             }
1257 0         0 return @chars1;
1258             }
1259              
1260             # 2 octets characters
1261             my @chars2 = ();
1262             sub chars2 {
1263 0 0   0 0 0 if (@chars2) {
1264 0         0 return @chars2;
1265             }
1266 0 0       0 if (exists $range_tr{2}) {
1267 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1268 0         0 while (my @range = splice(@ranges,0,2)) {
1269 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1270 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1271 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1272             }
1273             }
1274             }
1275             }
1276 0         0 return @chars2;
1277             }
1278              
1279             # 3 octets characters
1280             my @chars3 = ();
1281             sub chars3 {
1282 0 0   0 0 0 if (@chars3) {
1283 0         0 return @chars3;
1284             }
1285 0 0       0 if (exists $range_tr{3}) {
1286 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1287 0         0 while (my @range = splice(@ranges,0,3)) {
1288 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1289 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1290 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1291 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1292             }
1293             }
1294             }
1295             }
1296             }
1297 0         0 return @chars3;
1298             }
1299              
1300             # 4 octets characters
1301             my @chars4 = ();
1302             sub chars4 {
1303 0 0   0 0 0 if (@chars4) {
1304 0         0 return @chars4;
1305             }
1306 0 0       0 if (exists $range_tr{4}) {
1307 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1308 0         0 while (my @range = splice(@ranges,0,4)) {
1309 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1310 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1311 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1312 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1313 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1314             }
1315             }
1316             }
1317             }
1318             }
1319             }
1320 0         0 return @chars4;
1321             }
1322              
1323             #
1324             # Latin-1 open character list for tr
1325             #
1326             sub _charlist_tr {
1327              
1328 0     0   0 local $_ = shift @_;
1329              
1330             # unescape character
1331 0         0 my @char = ();
1332 0         0 while (not /\G \z/oxmsgc) {
1333 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1334 0         0 push @char, '\-';
1335             }
1336             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1337 0         0 push @char, CORE::chr(oct $1);
1338             }
1339             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1340 0         0 push @char, CORE::chr(hex $1);
1341             }
1342             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1343 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1344             }
1345             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1346             push @char, {
1347             '\0' => "\0",
1348             '\n' => "\n",
1349             '\r' => "\r",
1350             '\t' => "\t",
1351             '\f' => "\f",
1352             '\b' => "\x08", # \b means backspace in character class
1353             '\a' => "\a",
1354             '\e' => "\e",
1355 0         0 }->{$1};
1356             }
1357             elsif (/\G \\ ($q_char) /oxmsgc) {
1358 0         0 push @char, $1;
1359             }
1360             elsif (/\G ($q_char) /oxmsgc) {
1361 0         0 push @char, $1;
1362             }
1363             }
1364              
1365             # join separated multiple-octet
1366 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1367              
1368             # unescape '-'
1369 0         0 my @i = ();
1370 0         0 for my $i (0 .. $#char) {
1371 0 0       0 if ($char[$i] eq '\-') {
    0          
1372 0         0 $char[$i] = '-';
1373             }
1374             elsif ($char[$i] eq '-') {
1375 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1376 0         0 push @i, $i;
1377             }
1378             }
1379             }
1380              
1381             # open character list (reverse for splice)
1382 0         0 for my $i (CORE::reverse @i) {
1383 0         0 my @range = ();
1384              
1385             # range error
1386 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1387 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1388             }
1389              
1390             # range of multiple-octet code
1391 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1392 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1393 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1394             }
1395             elsif (CORE::length($char[$i+1]) == 2) {
1396 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1397 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1398             }
1399             elsif (CORE::length($char[$i+1]) == 3) {
1400 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1401 0         0 push @range, chars2();
1402 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1403             }
1404             elsif (CORE::length($char[$i+1]) == 4) {
1405 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1406 0         0 push @range, chars2();
1407 0         0 push @range, chars3();
1408 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1409             }
1410             else {
1411 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1412             }
1413             }
1414             elsif (CORE::length($char[$i-1]) == 2) {
1415 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1416 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1417             }
1418             elsif (CORE::length($char[$i+1]) == 3) {
1419 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1420 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1421             }
1422             elsif (CORE::length($char[$i+1]) == 4) {
1423 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1424 0         0 push @range, chars3();
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]) == 3) {
1432 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1433 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1434             }
1435             elsif (CORE::length($char[$i+1]) == 4) {
1436 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1437 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
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             elsif (CORE::length($char[$i-1]) == 4) {
1444 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1445 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1446             }
1447             else {
1448 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1449             }
1450             }
1451             else {
1452 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1453             }
1454              
1455 0         0 splice @char, $i-1, 3, @range;
1456             }
1457              
1458 0         0 return @char;
1459             }
1460              
1461             #
1462             # Latin-1 open character class
1463             #
1464             sub _cc {
1465 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1466 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1467             }
1468             elsif (scalar(@_) == 1) {
1469 0         0 return sprintf('\x%02X',$_[0]);
1470             }
1471             elsif (scalar(@_) == 2) {
1472 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1473 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1474             }
1475             elsif ($_[0] == $_[1]) {
1476 0         0 return sprintf('\x%02X',$_[0]);
1477             }
1478             elsif (($_[0]+1) == $_[1]) {
1479 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1480             }
1481             else {
1482 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1483             }
1484             }
1485             else {
1486 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1487             }
1488             }
1489              
1490             #
1491             # Latin-1 octet range
1492             #
1493             sub _octets {
1494 0     182   0 my $length = shift @_;
1495              
1496 182 50       282 if ($length == 1) {
1497 182         364 my($a1) = unpack 'C', $_[0];
1498 182         458 my($z1) = unpack 'C', $_[1];
1499              
1500 182 50       323 if ($a1 > $z1) {
1501 182         336 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1502             }
1503              
1504 0 50       0 if ($a1 == $z1) {
    50          
1505 182         409 return sprintf('\x%02X',$a1);
1506             }
1507             elsif (($a1+1) == $z1) {
1508 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1509             }
1510             else {
1511 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1512             }
1513             }
1514             else {
1515 182         1215 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1516             }
1517             }
1518              
1519             #
1520             # Latin-1 range regexp
1521             #
1522             sub _range_regexp {
1523 0     182   0 my($length,$first,$last) = @_;
1524              
1525 182         399 my @range_regexp = ();
1526 182 50       246 if (not exists $range_tr{$length}) {
1527 182         418 return @range_regexp;
1528             }
1529              
1530 0         0 my @ranges = @{ $range_tr{$length} };
  182         287  
1531 182         413 while (my @range = splice(@ranges,0,$length)) {
1532 182         527 my $min = '';
1533 182         267 my $max = '';
1534 182         214 for (my $i=0; $i < $length; $i++) {
1535 182         471 $min .= pack 'C', $range[$i][0];
1536 182         607 $max .= pack 'C', $range[$i][-1];
1537             }
1538              
1539             # min___max
1540             # FIRST_____________LAST
1541             # (nothing)
1542              
1543 182 50 33     423 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1544             }
1545              
1546             # **********
1547             # min_________max
1548             # FIRST_____________LAST
1549             # **********
1550              
1551             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1552 182         1679 push @range_regexp, _octets($length,$first,$max,$min,$max);
1553             }
1554              
1555             # **********************
1556             # min________________max
1557             # FIRST_____________LAST
1558             # **********************
1559              
1560             elsif (($min eq $first) and ($max eq $last)) {
1561 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1562             }
1563              
1564             # *********
1565             # min___max
1566             # FIRST_____________LAST
1567             # *********
1568              
1569             elsif (($first le $min) and ($max le $last)) {
1570 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1571             }
1572              
1573             # **********************
1574             # min__________________________max
1575             # FIRST_____________LAST
1576             # **********************
1577              
1578             elsif (($min le $first) and ($last le $max)) {
1579 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1580             }
1581              
1582             # *********
1583             # min________max
1584             # FIRST_____________LAST
1585             # *********
1586              
1587             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1588 182         441 push @range_regexp, _octets($length,$min,$last,$min,$max);
1589             }
1590              
1591             # min___max
1592             # FIRST_____________LAST
1593             # (nothing)
1594              
1595             elsif ($last lt $min) {
1596             }
1597              
1598             else {
1599 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1600             }
1601             }
1602              
1603 0         0 return @range_regexp;
1604             }
1605              
1606             #
1607             # Latin-1 open character list for qr and not qr
1608             #
1609             sub _charlist {
1610              
1611 182     358   417 my $modifier = pop @_;
1612 358         1968 my @char = @_;
1613              
1614 358 100       738 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1615              
1616             # unescape character
1617 358         851 for (my $i=0; $i <= $#char; $i++) {
1618              
1619             # escape - to ...
1620 358 100 100     1143 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1621 1125 100 100     7929 if ((0 < $i) and ($i < $#char)) {
1622 206         749 $char[$i] = '...';
1623             }
1624             }
1625              
1626             # octal escape sequence
1627             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1628 182         389 $char[$i] = octchr($1);
1629             }
1630              
1631             # hexadecimal escape sequence
1632             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1633 0         0 $char[$i] = hexchr($1);
1634             }
1635              
1636             # \b{...} --> b\{...}
1637             # \B{...} --> B\{...}
1638             # \N{CHARNAME} --> N\{CHARNAME}
1639             # \p{PROPERTY} --> p\{PROPERTY}
1640             # \P{PROPERTY} --> P\{PROPERTY}
1641             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1642 0         0 $char[$i] = $1 . '\\' . $2;
1643             }
1644              
1645             # \p, \P, \X --> p, P, X
1646             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1647 0         0 $char[$i] = $1;
1648             }
1649              
1650             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1651 0         0 $char[$i] = CORE::chr oct $1;
1652             }
1653             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1654 0         0 $char[$i] = CORE::chr hex $1;
1655             }
1656             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1657 22         99 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1658             }
1659             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1660             $char[$i] = {
1661             '\0' => "\0",
1662             '\n' => "\n",
1663             '\r' => "\r",
1664             '\t' => "\t",
1665             '\f' => "\f",
1666             '\b' => "\x08", # \b means backspace in character class
1667             '\a' => "\a",
1668             '\e' => "\e",
1669             '\d' => '[0-9]',
1670              
1671             # Vertical tabs are now whitespace
1672             # \s in a regex now matches a vertical tab in all circumstances.
1673             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1674             # \t \n \v \f \r space
1675             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1676             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1677             '\s' => '\s',
1678              
1679             '\w' => '[0-9A-Z_a-z]',
1680             '\D' => '${Elatin1::eD}',
1681             '\S' => '${Elatin1::eS}',
1682             '\W' => '${Elatin1::eW}',
1683              
1684             '\H' => '${Elatin1::eH}',
1685             '\V' => '${Elatin1::eV}',
1686             '\h' => '[\x09\x20]',
1687             '\v' => '[\x0A\x0B\x0C\x0D]',
1688             '\R' => '${Elatin1::eR}',
1689              
1690 0         0 }->{$1};
1691             }
1692              
1693             # POSIX-style character classes
1694             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1695             $char[$i] = {
1696              
1697             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1698             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1699             '[:^lower:]' => '${Elatin1::not_lower_i}',
1700             '[:^upper:]' => '${Elatin1::not_upper_i}',
1701              
1702 25         448 }->{$1};
1703             }
1704             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1705             $char[$i] = {
1706              
1707             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1708             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1709             '[:ascii:]' => '[\x00-\x7F]',
1710             '[:blank:]' => '[\x09\x20]',
1711             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1712             '[:digit:]' => '[\x30-\x39]',
1713             '[:graph:]' => '[\x21-\x7F]',
1714             '[:lower:]' => '[\x61-\x7A]',
1715             '[:print:]' => '[\x20-\x7F]',
1716             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1717              
1718             # P.174 POSIX-Style Character Classes
1719             # in Chapter 5: Pattern Matching
1720             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1721              
1722             # P.311 11.2.4 Character Classes and other Special Escapes
1723             # in Chapter 11: perlre: Perl regular expressions
1724             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1725              
1726             # P.210 POSIX-Style Character Classes
1727             # in Chapter 5: Pattern Matching
1728             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1729              
1730             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1731              
1732             '[:upper:]' => '[\x41-\x5A]',
1733             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1734             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1735             '[:^alnum:]' => '${Elatin1::not_alnum}',
1736             '[:^alpha:]' => '${Elatin1::not_alpha}',
1737             '[:^ascii:]' => '${Elatin1::not_ascii}',
1738             '[:^blank:]' => '${Elatin1::not_blank}',
1739             '[:^cntrl:]' => '${Elatin1::not_cntrl}',
1740             '[:^digit:]' => '${Elatin1::not_digit}',
1741             '[:^graph:]' => '${Elatin1::not_graph}',
1742             '[:^lower:]' => '${Elatin1::not_lower}',
1743             '[:^print:]' => '${Elatin1::not_print}',
1744             '[:^punct:]' => '${Elatin1::not_punct}',
1745             '[:^space:]' => '${Elatin1::not_space}',
1746             '[:^upper:]' => '${Elatin1::not_upper}',
1747             '[:^word:]' => '${Elatin1::not_word}',
1748             '[:^xdigit:]' => '${Elatin1::not_xdigit}',
1749              
1750 8         54 }->{$1};
1751             }
1752             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1753 70         1604 $char[$i] = $1;
1754             }
1755             }
1756              
1757             # open character list
1758 7         32 my @singleoctet = ();
1759 358         655 my @multipleoctet = ();
1760 358         481 for (my $i=0; $i <= $#char; ) {
1761              
1762             # escaped -
1763 358 100 100     794 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1764 943         3882 $i += 1;
1765 182         393 next;
1766             }
1767              
1768             # make range regexp
1769             elsif ($char[$i] eq '...') {
1770              
1771             # range error
1772 182 50       308 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1773 182         595 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1774             }
1775             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1776 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1777 182         407 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1778             }
1779             }
1780              
1781             # make range regexp per length
1782 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1783 182         486 my @regexp = ();
1784              
1785             # is first and last
1786 182 50 33     244 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1787 182         567 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1788             }
1789              
1790             # is first
1791             elsif ($length == CORE::length($char[$i-1])) {
1792 182         448 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1793             }
1794              
1795             # is inside in first and last
1796             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1797 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1798             }
1799              
1800             # is last
1801             elsif ($length == CORE::length($char[$i+1])) {
1802 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1803             }
1804              
1805             else {
1806 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1807             }
1808              
1809 0 50       0 if ($length == 1) {
1810 182         339 push @singleoctet, @regexp;
1811             }
1812             else {
1813 182         403 push @multipleoctet, @regexp;
1814             }
1815             }
1816              
1817 0         0 $i += 2;
1818             }
1819              
1820             # with /i modifier
1821             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1822 182 100       370 if ($modifier =~ /i/oxms) {
1823 493         708 my $uc = Elatin1::uc($char[$i]);
1824 24         45 my $fc = Elatin1::fc($char[$i]);
1825 24 100       44 if ($uc ne $fc) {
1826 24 50       43 if (CORE::length($fc) == 1) {
1827 12         23 push @singleoctet, $uc, $fc;
1828             }
1829             else {
1830 12         35 push @singleoctet, $uc;
1831 0         0 push @multipleoctet, $fc;
1832             }
1833             }
1834             else {
1835 0         0 push @singleoctet, $char[$i];
1836             }
1837             }
1838             else {
1839 12         23 push @singleoctet, $char[$i];
1840             }
1841 469         691 $i += 1;
1842             }
1843              
1844             # single character of single octet code
1845             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1846 493         789 push @singleoctet, "\t", "\x20";
1847 0         0 $i += 1;
1848             }
1849             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1850 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1851 0         0 $i += 1;
1852             }
1853             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1854 0         0 push @singleoctet, $char[$i];
1855 2         12 $i += 1;
1856             }
1857              
1858             # single character of multiple-octet code
1859             else {
1860 2         6 push @multipleoctet, $char[$i];
1861 84         165 $i += 1;
1862             }
1863             }
1864              
1865             # quote metachar
1866 84         143 for (@singleoctet) {
1867 358 50       760 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1868 689         3001 $_ = '-';
1869             }
1870             elsif (/\A \n \z/oxms) {
1871 0         0 $_ = '\n';
1872             }
1873             elsif (/\A \r \z/oxms) {
1874 8         19 $_ = '\r';
1875             }
1876             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1877 8         18 $_ = sprintf('\x%02X', CORE::ord $1);
1878             }
1879             elsif (/\A [\x00-\xFF] \z/oxms) {
1880 60         189 $_ = quotemeta $_;
1881             }
1882             }
1883              
1884             # return character list
1885 429         717 return \@singleoctet, \@multipleoctet;
1886             }
1887              
1888             #
1889             # Latin-1 octal escape sequence
1890             #
1891             sub octchr {
1892 358     5 0 1169 my($octdigit) = @_;
1893              
1894 5         13 my @binary = ();
1895 5         8 for my $octal (split(//,$octdigit)) {
1896             push @binary, {
1897             '0' => '000',
1898             '1' => '001',
1899             '2' => '010',
1900             '3' => '011',
1901             '4' => '100',
1902             '5' => '101',
1903             '6' => '110',
1904             '7' => '111',
1905 5         21 }->{$octal};
1906             }
1907 50         176 my $binary = join '', @binary;
1908              
1909             my $octchr = {
1910             # 1234567
1911             1 => pack('B*', "0000000$binary"),
1912             2 => pack('B*', "000000$binary"),
1913             3 => pack('B*', "00000$binary"),
1914             4 => pack('B*', "0000$binary"),
1915             5 => pack('B*', "000$binary"),
1916             6 => pack('B*', "00$binary"),
1917             7 => pack('B*', "0$binary"),
1918             0 => pack('B*', "$binary"),
1919              
1920 5         15 }->{CORE::length($binary) % 8};
1921              
1922 5         63 return $octchr;
1923             }
1924              
1925             #
1926             # Latin-1 hexadecimal escape sequence
1927             #
1928             sub hexchr {
1929 5     5 0 18 my($hexdigit) = @_;
1930              
1931             my $hexchr = {
1932             1 => pack('H*', "0$hexdigit"),
1933             0 => pack('H*', "$hexdigit"),
1934              
1935 5         13 }->{CORE::length($_[0]) % 2};
1936              
1937 5         40 return $hexchr;
1938             }
1939              
1940             #
1941             # Latin-1 open character list for qr
1942             #
1943             sub charlist_qr {
1944              
1945 5     314 0 17 my $modifier = pop @_;
1946 314         580 my @char = @_;
1947              
1948 314         720 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1949 314         903 my @singleoctet = @$singleoctet;
1950 314         723 my @multipleoctet = @$multipleoctet;
1951              
1952             # return character list
1953 314 100       520 if (scalar(@singleoctet) >= 1) {
1954              
1955             # with /i modifier
1956 314 100       677 if ($modifier =~ m/i/oxms) {
1957 236         477 my %singleoctet_ignorecase = ();
1958 22         33 for (@singleoctet) {
1959 22   100     35 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1960 46         197 for my $ord (hex($1) .. hex($2)) {
1961 46         122 my $char = CORE::chr($ord);
1962 66         94 my $uc = Elatin1::uc($char);
1963 66         105 my $fc = Elatin1::fc($char);
1964 66 100       118 if ($uc eq $fc) {
1965 66         329 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1966             }
1967             else {
1968 12 50       78 if (CORE::length($fc) == 1) {
1969 54         83 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1970 54         143 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1971             }
1972             else {
1973 54         184 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1974 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1975             }
1976             }
1977             }
1978             }
1979 0 50       0 if ($_ ne '') {
1980 46         106 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1981             }
1982             }
1983 0         0 my $i = 0;
1984 22         23 my @singleoctet_ignorecase = ();
1985 22         31 for my $ord (0 .. 255) {
1986 22 100       34 if (exists $singleoctet_ignorecase{$ord}) {
1987 5632         6283 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         87  
1988             }
1989             else {
1990 96         185 $i++;
1991             }
1992             }
1993 5536         5458 @singleoctet = ();
1994 22         30 for my $range (@singleoctet_ignorecase) {
1995 22 100       56 if (ref $range) {
1996 3648 100       5394 if (scalar(@{$range}) == 1) {
  56 50       52  
1997 56         78 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         42  
1998             }
1999 36         113 elsif (scalar(@{$range}) == 2) {
2000 20         24 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2001             }
2002             else {
2003 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         22  
  20         22  
2004             }
2005             }
2006             }
2007             }
2008              
2009 20         85 my $not_anchor = '';
2010              
2011 236         342 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2012             }
2013 236 100       597 if (scalar(@multipleoctet) >= 2) {
2014 314         671 return '(?:' . join('|', @multipleoctet) . ')';
2015             }
2016             else {
2017 6         30 return $multipleoctet[0];
2018             }
2019             }
2020              
2021             #
2022             # Latin-1 open character list for not qr
2023             #
2024             sub charlist_not_qr {
2025              
2026 308     44 0 1228 my $modifier = pop @_;
2027 44         91 my @char = @_;
2028              
2029 44         101 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2030 44         111 my @singleoctet = @$singleoctet;
2031 44         106 my @multipleoctet = @$multipleoctet;
2032              
2033             # with /i modifier
2034 44 100       73 if ($modifier =~ m/i/oxms) {
2035 44         119 my %singleoctet_ignorecase = ();
2036 10         13 for (@singleoctet) {
2037 10   66     14 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2038 10         48 for my $ord (hex($1) .. hex($2)) {
2039 10         31 my $char = CORE::chr($ord);
2040 30         46 my $uc = Elatin1::uc($char);
2041 30         43 my $fc = Elatin1::fc($char);
2042 30 50       49 if ($uc eq $fc) {
2043 30         45 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2044             }
2045             else {
2046 0 50       0 if (CORE::length($fc) == 1) {
2047 30         41 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2048 30         61 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2049             }
2050             else {
2051 30         90 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2052 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2053             }
2054             }
2055             }
2056             }
2057 0 50       0 if ($_ ne '') {
2058 10         22 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2059             }
2060             }
2061 0         0 my $i = 0;
2062 10         14 my @singleoctet_ignorecase = ();
2063 10         15 for my $ord (0 .. 255) {
2064 10 100       13 if (exists $singleoctet_ignorecase{$ord}) {
2065 2560         2836 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         57  
2066             }
2067             else {
2068 60         94 $i++;
2069             }
2070             }
2071 2500         2363 @singleoctet = ();
2072 10         12 for my $range (@singleoctet_ignorecase) {
2073 10 100       24 if (ref $range) {
2074 960 50       1416 if (scalar(@{$range}) == 1) {
  20 50       20  
2075 20         30 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2076             }
2077 0         0 elsif (scalar(@{$range}) == 2) {
2078 20         25 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2079             }
2080             else {
2081 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         24  
  20         21  
2082             }
2083             }
2084             }
2085             }
2086              
2087             # return character list
2088 20 50       76 if (scalar(@multipleoctet) >= 1) {
2089 44 0       95 if (scalar(@singleoctet) >= 1) {
2090              
2091             # any character other than multiple-octet and single octet character class
2092 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2093             }
2094             else {
2095              
2096             # any character other than multiple-octet character class
2097 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2098             }
2099             }
2100             else {
2101 0 50       0 if (scalar(@singleoctet) >= 1) {
2102              
2103             # any character other than single octet character class
2104 44         86 return '(?:[^' . join('', @singleoctet) . '])';
2105             }
2106             else {
2107              
2108             # any character
2109 44         243 return "(?:$your_char)";
2110             }
2111             }
2112             }
2113              
2114             #
2115             # open file in read mode
2116             #
2117             sub _open_r {
2118 0     412   0 my(undef,$file) = @_;
2119 206     206   3334 use Fcntl qw(O_RDONLY);
  206         5702  
  206         29564  
2120 412         1233 return CORE::sysopen($_[0], $file, &O_RDONLY);
2121             }
2122              
2123             #
2124             # open file in append mode
2125             #
2126             sub _open_a {
2127 412     206   23065 my(undef,$file) = @_;
2128 206     206   2419 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  206         390  
  206         773369  
2129 206         741 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2130             }
2131              
2132             #
2133             # safe system
2134             #
2135             sub _systemx {
2136              
2137             # P.707 29.2.33. exec
2138             # in Chapter 29: Functions
2139             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2140             #
2141             # Be aware that in older releases of Perl, exec (and system) did not flush
2142             # your output buffer, so you needed to enable command buffering by setting $|
2143             # on one or more filehandles to avoid lost output in the case of exec, or
2144             # misordererd output in the case of system. This situation was largely remedied
2145             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2146              
2147             # P.855 exec
2148             # in Chapter 27: Functions
2149             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2150             #
2151             # In very old release of Perl (before v5.6), exec (and system) did not flush
2152             # your output buffer, so you needed to enable command buffering by setting $|
2153             # on one or more filehandles to avoid lost output with exec or misordered
2154             # output with system.
2155              
2156 206     206   23343 $| = 1;
2157              
2158             # P.565 23.1.2. Cleaning Up Your Environment
2159             # in Chapter 23: Security
2160             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2161              
2162             # P.656 Cleaning Up Your Environment
2163             # in Chapter 20: Security
2164             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2165              
2166             # local $ENV{'PATH'} = '.';
2167 206         786 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2168              
2169             # P.707 29.2.33. exec
2170             # in Chapter 29: Functions
2171             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2172             #
2173             # As we mentioned earlier, exec treats a discrete list of arguments as an
2174             # indication that it should bypass shell processing. However, there is one
2175             # place where you might still get tripped up. The exec call (and system, too)
2176             # will not distinguish between a single scalar argument and an array containing
2177             # only one element.
2178             #
2179             # @args = ("echo surprise"); # just one element in list
2180             # exec @args # still subject to shell escapes
2181             # or die "exec: $!"; # because @args == 1
2182             #
2183             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2184             # first argument as the pathname, which forces the rest of the arguments to be
2185             # interpreted as a list, even if there is only one of them:
2186             #
2187             # exec { $args[0] } @args # safe even with one-argument list
2188             # or die "can't exec @args: $!";
2189              
2190             # P.855 exec
2191             # in Chapter 27: Functions
2192             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2193             #
2194             # As we mentioned earlier, exec treats a discrete list of arguments as a
2195             # directive to bypass shell processing. However, there is one place where
2196             # you might still get tripped up. The exec call (and system, too) cannot
2197             # distinguish between a single scalar argument and an array containing
2198             # only one element.
2199             #
2200             # @args = ("echo surprise"); # just one element in list
2201             # exec @args # still subject to shell escapes
2202             # || die "exec: $!"; # because @args == 1
2203             #
2204             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2205             # argument as the pathname, which forces the rest of the arguments to be
2206             # interpreted as a list, even if there is only one of them:
2207             #
2208             # exec { $args[0] } @args # safe even with one-argument list
2209             # || die "can't exec @args: $!";
2210              
2211 206         2093 return CORE::system { $_[0] } @_; # safe even with one-argument list
  206         481  
2212             }
2213              
2214             #
2215             # Latin-1 order to character (with parameter)
2216             #
2217             sub Elatin1::chr(;$) {
2218              
2219 206 0   0 0 18861366 my $c = @_ ? $_[0] : $_;
2220              
2221 0 0       0 if ($c == 0x00) {
2222 0         0 return "\x00";
2223             }
2224             else {
2225 0         0 my @chr = ();
2226 0         0 while ($c > 0) {
2227 0         0 unshift @chr, ($c % 0x100);
2228 0         0 $c = int($c / 0x100);
2229             }
2230 0         0 return pack 'C*', @chr;
2231             }
2232             }
2233              
2234             #
2235             # Latin-1 order to character (without parameter)
2236             #
2237             sub Elatin1::chr_() {
2238              
2239 0     0 0 0 my $c = $_;
2240              
2241 0 0       0 if ($c == 0x00) {
2242 0         0 return "\x00";
2243             }
2244             else {
2245 0         0 my @chr = ();
2246 0         0 while ($c > 0) {
2247 0         0 unshift @chr, ($c % 0x100);
2248 0         0 $c = int($c / 0x100);
2249             }
2250 0         0 return pack 'C*', @chr;
2251             }
2252             }
2253              
2254             #
2255             # Latin-1 path globbing (with parameter)
2256             #
2257             sub Elatin1::glob($) {
2258              
2259 0 0   0 0 0 if (wantarray) {
2260 0         0 my @glob = _DOS_like_glob(@_);
2261 0         0 for my $glob (@glob) {
2262 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2263             }
2264 0         0 return @glob;
2265             }
2266             else {
2267 0         0 my $glob = _DOS_like_glob(@_);
2268 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2269 0         0 return $glob;
2270             }
2271             }
2272              
2273             #
2274             # Latin-1 path globbing (without parameter)
2275             #
2276             sub Elatin1::glob_() {
2277              
2278 0 0   0 0 0 if (wantarray) {
2279 0         0 my @glob = _DOS_like_glob();
2280 0         0 for my $glob (@glob) {
2281 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2282             }
2283 0         0 return @glob;
2284             }
2285             else {
2286 0         0 my $glob = _DOS_like_glob();
2287 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2288 0         0 return $glob;
2289             }
2290             }
2291              
2292             #
2293             # Latin-1 path globbing via File::DosGlob 1.10
2294             #
2295             # Often I confuse "_dosglob" and "_doglob".
2296             # So, I renamed "_dosglob" to "_DOS_like_glob".
2297             #
2298             my %iter;
2299             my %entries;
2300             sub _DOS_like_glob {
2301              
2302             # context (keyed by second cxix argument provided by core)
2303 0     0   0 my($expr,$cxix) = @_;
2304              
2305             # glob without args defaults to $_
2306 0 0       0 $expr = $_ if not defined $expr;
2307              
2308             # represents the current user's home directory
2309             #
2310             # 7.3. Expanding Tildes in Filenames
2311             # in Chapter 7. File Access
2312             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2313             #
2314             # and File::HomeDir, File::HomeDir::Windows module
2315              
2316             # DOS-like system
2317 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2318 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2319             { my_home_MSWin32() }oxmse;
2320             }
2321              
2322             # UNIX-like system
2323 0 0 0     0 else {
  0         0  
2324             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2325             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2326             }
2327 0 0       0  
2328 0 0       0 # assume global context if not provided one
2329             $cxix = '_G_' if not defined $cxix;
2330             $iter{$cxix} = 0 if not exists $iter{$cxix};
2331 0 0       0  
2332 0         0 # if we're just beginning, do it all first
2333             if ($iter{$cxix} == 0) {
2334             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2335             }
2336 0 0       0  
2337 0         0 # chuck it all out, quick or slow
2338 0         0 if (wantarray) {
  0         0  
2339             delete $iter{$cxix};
2340             return @{delete $entries{$cxix}};
2341 0 0       0 }
  0         0  
2342 0         0 else {
  0         0  
2343             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2344             return shift @{$entries{$cxix}};
2345             }
2346 0         0 else {
2347 0         0 # return undef for EOL
2348 0         0 delete $iter{$cxix};
2349             delete $entries{$cxix};
2350             return undef;
2351             }
2352             }
2353             }
2354              
2355             #
2356             # Latin-1 path globbing subroutine
2357             #
2358 0     0   0 sub _do_glob {
2359 0         0  
2360 0         0 my($cond,@expr) = @_;
2361             my @glob = ();
2362             my $fix_drive_relative_paths = 0;
2363 0         0  
2364 0 0       0 OUTER:
2365 0 0       0 for my $expr (@expr) {
2366             next OUTER if not defined $expr;
2367 0         0 next OUTER if $expr eq '';
2368 0         0  
2369 0         0 my @matched = ();
2370 0         0 my @globdir = ();
2371 0         0 my $head = '.';
2372             my $pathsep = '/';
2373             my $tail;
2374 0 0       0  
2375 0         0 # if argument is within quotes strip em and do no globbing
2376 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2377 0 0       0 $expr = $1;
2378 0         0 if ($cond eq 'd') {
2379             if (-d $expr) {
2380             push @glob, $expr;
2381             }
2382 0 0       0 }
2383 0         0 else {
2384             if (-e $expr) {
2385             push @glob, $expr;
2386 0         0 }
2387             }
2388             next OUTER;
2389             }
2390              
2391 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2392 0 0       0 # to h:./*.pm to expand correctly
2393 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2394             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2395             $fix_drive_relative_paths = 1;
2396             }
2397 0 0       0 }
2398 0 0       0  
2399 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2400 0         0 if ($tail eq '') {
2401             push @glob, $expr;
2402 0 0       0 next OUTER;
2403 0 0       0 }
2404 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2405 0         0 if (@globdir = _do_glob('d', $head)) {
2406             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2407             next OUTER;
2408 0 0 0     0 }
2409 0         0 }
2410             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2411 0         0 $head .= $pathsep;
2412             }
2413             $expr = $tail;
2414             }
2415 0 0       0  
2416 0 0       0 # If file component has no wildcards, we can avoid opendir
2417 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2418             if ($head eq '.') {
2419 0 0 0     0 $head = '';
2420 0         0 }
2421             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2422 0         0 $head .= $pathsep;
2423 0 0       0 }
2424 0 0       0 $head .= $expr;
2425 0         0 if ($cond eq 'd') {
2426             if (-d $head) {
2427             push @glob, $head;
2428             }
2429 0 0       0 }
2430 0         0 else {
2431             if (-e $head) {
2432             push @glob, $head;
2433 0         0 }
2434             }
2435 0 0       0 next OUTER;
2436 0         0 }
2437 0         0 opendir(*DIR, $head) or next OUTER;
2438             my @leaf = readdir DIR;
2439 0 0       0 closedir DIR;
2440 0         0  
2441             if ($head eq '.') {
2442 0 0 0     0 $head = '';
2443 0         0 }
2444             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2445             $head .= $pathsep;
2446 0         0 }
2447 0         0  
2448 0         0 my $pattern = '';
2449             while ($expr =~ / \G ($q_char) /oxgc) {
2450             my $char = $1;
2451              
2452             # 6.9. Matching Shell Globs as Regular Expressions
2453             # in Chapter 6. Pattern Matching
2454             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2455 0 0       0 # (and so on)
    0          
    0          
2456 0         0  
2457             if ($char eq '*') {
2458             $pattern .= "(?:$your_char)*",
2459 0         0 }
2460             elsif ($char eq '?') {
2461             $pattern .= "(?:$your_char)?", # DOS style
2462             # $pattern .= "(?:$your_char)", # UNIX style
2463 0         0 }
2464             elsif ((my $fc = Elatin1::fc($char)) ne $char) {
2465             $pattern .= $fc;
2466 0         0 }
2467             else {
2468             $pattern .= quotemeta $char;
2469 0     0   0 }
  0         0  
2470             }
2471             my $matchsub = sub { Elatin1::fc($_[0]) =~ /\A $pattern \z/xms };
2472              
2473             # if ($@) {
2474             # print STDERR "$0: $@\n";
2475             # next OUTER;
2476             # }
2477 0         0  
2478 0 0 0     0 INNER:
2479 0         0 for my $leaf (@leaf) {
2480             if ($leaf eq '.' or $leaf eq '..') {
2481 0 0 0     0 next INNER;
2482 0         0 }
2483             if ($cond eq 'd' and not -d "$head$leaf") {
2484             next INNER;
2485 0 0       0 }
2486 0         0  
2487 0         0 if (&$matchsub($leaf)) {
2488             push @matched, "$head$leaf";
2489             next INNER;
2490             }
2491              
2492             # [DOS compatibility special case]
2493 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2494              
2495             if (Elatin1::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2496             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2497 0 0       0 Elatin1::index($pattern,'\\.') != -1 # pattern has a dot.
2498 0         0 ) {
2499 0         0 if (&$matchsub("$leaf.")) {
2500             push @matched, "$head$leaf";
2501             next INNER;
2502             }
2503 0 0       0 }
2504 0         0 }
2505             if (@matched) {
2506             push @glob, @matched;
2507 0 0       0 }
2508 0         0 }
2509 0         0 if ($fix_drive_relative_paths) {
2510             for my $glob (@glob) {
2511             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2512 0         0 }
2513             }
2514             return @glob;
2515             }
2516              
2517             #
2518             # Latin-1 parse line
2519             #
2520 0     0   0 sub _parse_line {
2521              
2522 0         0 my($line) = @_;
2523 0         0  
2524 0         0 $line .= ' ';
2525             my @piece = ();
2526             while ($line =~ /
2527             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2528             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2529 0 0       0 /oxmsg
2530             ) {
2531 0         0 push @piece, defined($1) ? $1 : $2;
2532             }
2533             return @piece;
2534             }
2535              
2536             #
2537             # Latin-1 parse path
2538             #
2539 0     0   0 sub _parse_path {
2540              
2541 0         0 my($path,$pathsep) = @_;
2542 0         0  
2543 0         0 $path .= '/';
2544             my @subpath = ();
2545             while ($path =~ /
2546             ((?: [^\/\\] )+?) [\/\\]
2547 0         0 /oxmsg
2548             ) {
2549             push @subpath, $1;
2550 0         0 }
2551 0         0  
2552 0         0 my $tail = pop @subpath;
2553             my $head = join $pathsep, @subpath;
2554             return $head, $tail;
2555             }
2556              
2557             #
2558             # via File::HomeDir::Windows 1.00
2559             #
2560             sub my_home_MSWin32 {
2561              
2562             # A lot of unix people and unix-derived tools rely on
2563 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2564 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2565             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2566             return $ENV{'HOME'};
2567             }
2568              
2569 0         0 # Do we have a user profile?
2570             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2571             return $ENV{'USERPROFILE'};
2572             }
2573              
2574 0         0 # Some Windows use something like $ENV{'HOME'}
2575             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2576             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2577 0         0 }
2578              
2579             return undef;
2580             }
2581              
2582             #
2583             # via File::HomeDir::Unix 1.00
2584 0     0 0 0 #
2585             sub my_home {
2586 0 0 0     0 my $home;
    0 0        
2587 0         0  
2588             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2589             $home = $ENV{'HOME'};
2590             }
2591              
2592             # This is from the original code, but I'm guessing
2593 0         0 # it means "login directory" and exists on some Unixes.
2594             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2595             $home = $ENV{'LOGDIR'};
2596             }
2597              
2598             ### More-desperate methods
2599              
2600 0         0 # Light desperation on any (Unixish) platform
2601             else {
2602             $home = CORE::eval q{ (getpwuid($<))[7] };
2603             }
2604              
2605 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2606 0         0 # For example, "nobody"-like users might use /nonexistant
2607             if (defined $home and ! -d($home)) {
2608 0         0 $home = undef;
2609             }
2610             return $home;
2611             }
2612              
2613             #
2614             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2615 0     0 0 0 #
2616             sub Elatin1::PREMATCH {
2617             return $`;
2618             }
2619              
2620             #
2621             # ${^MATCH}, $MATCH, $& the string that matched
2622 0     0 0 0 #
2623             sub Elatin1::MATCH {
2624             return $&;
2625             }
2626              
2627             #
2628             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2629 0     0 0 0 #
2630             sub Elatin1::POSTMATCH {
2631             return $';
2632             }
2633              
2634             #
2635             # Latin-1 character to order (with parameter)
2636             #
2637 0 0   0 1 0 sub Latin1::ord(;$) {
2638              
2639 0 0       0 local $_ = shift if @_;
2640 0         0  
2641 0         0 if (/\A ($q_char) /oxms) {
2642 0         0 my @ord = unpack 'C*', $1;
2643 0         0 my $ord = 0;
2644             while (my $o = shift @ord) {
2645 0         0 $ord = $ord * 0x100 + $o;
2646             }
2647             return $ord;
2648 0         0 }
2649             else {
2650             return CORE::ord $_;
2651             }
2652             }
2653              
2654             #
2655             # Latin-1 character to order (without parameter)
2656             #
2657 0 0   0 0 0 sub Latin1::ord_() {
2658 0         0  
2659 0         0 if (/\A ($q_char) /oxms) {
2660 0         0 my @ord = unpack 'C*', $1;
2661 0         0 my $ord = 0;
2662             while (my $o = shift @ord) {
2663 0         0 $ord = $ord * 0x100 + $o;
2664             }
2665             return $ord;
2666 0         0 }
2667             else {
2668             return CORE::ord $_;
2669             }
2670             }
2671              
2672             #
2673             # Latin-1 reverse
2674             #
2675 0 0   0 0 0 sub Latin1::reverse(@) {
2676 0         0  
2677             if (wantarray) {
2678             return CORE::reverse @_;
2679             }
2680             else {
2681              
2682             # One of us once cornered Larry in an elevator and asked him what
2683             # problem he was solving with this, but he looked as far off into
2684             # the distance as he could in an elevator and said, "It seemed like
2685 0         0 # a good idea at the time."
2686              
2687             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2688             }
2689             }
2690              
2691             #
2692             # Latin-1 getc (with parameter, without parameter)
2693             #
2694 0     0 0 0 sub Latin1::getc(;*@) {
2695 0 0       0  
2696 0 0 0     0 my($package) = caller;
2697             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2698 0         0 croak 'Too many arguments for Latin1::getc' if @_ and not wantarray;
  0         0  
2699 0         0  
2700 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2701 0         0 my $getc = '';
2702 0 0       0 for my $length ($length[0] .. $length[-1]) {
2703 0 0       0 $getc .= CORE::getc($fh);
2704 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2705             if ($getc =~ /\A ${Elatin1::dot_s} \z/oxms) {
2706             return wantarray ? ($getc,@_) : $getc;
2707             }
2708 0 0       0 }
2709             }
2710             return wantarray ? ($getc,@_) : $getc;
2711             }
2712              
2713             #
2714             # Latin-1 length by character
2715             #
2716 0 0   0 1 0 sub Latin1::length(;$) {
2717              
2718 0         0 local $_ = shift if @_;
2719 0         0  
2720             local @_ = /\G ($q_char) /oxmsg;
2721             return scalar @_;
2722             }
2723              
2724             #
2725             # Latin-1 substr by character
2726             #
2727             BEGIN {
2728              
2729             # P.232 The lvalue Attribute
2730             # in Chapter 6: Subroutines
2731             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2732              
2733             # P.336 The lvalue Attribute
2734             # in Chapter 7: Subroutines
2735             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2736              
2737             # P.144 8.4 Lvalue subroutines
2738             # in Chapter 8: perlsub: Perl subroutines
2739 206 50 0 206 1 151545 # 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         0  
  0         0  
  0         0  
  0         0  
  0         0  
2740              
2741             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2742             # vv----------------------*******
2743             sub Latin1::substr($$;$$) %s {
2744              
2745             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2746              
2747             # If the substring is beyond either end of the string, substr() returns the undefined
2748             # value and produces a warning. When used as an lvalue, specifying a substring that
2749             # is entirely outside the string raises an exception.
2750             # http://perldoc.perl.org/functions/substr.html
2751              
2752             # A return with no argument returns the scalar value undef in scalar context,
2753             # an empty list () in list context, and (naturally) nothing at all in void
2754             # context.
2755              
2756             my $offset = $_[1];
2757             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2758             return;
2759             }
2760              
2761             # substr($string,$offset,$length,$replacement)
2762             if (@_ == 4) {
2763             my(undef,undef,$length,$replacement) = @_;
2764             my $substr = join '', splice(@char, $offset, $length, $replacement);
2765             $_[0] = join '', @char;
2766              
2767             # return $substr; this doesn't work, don't say "return"
2768             $substr;
2769             }
2770              
2771             # substr($string,$offset,$length)
2772             elsif (@_ == 3) {
2773             my(undef,undef,$length) = @_;
2774             my $octet_offset = 0;
2775             my $octet_length = 0;
2776             if ($offset == 0) {
2777             $octet_offset = 0;
2778             }
2779             elsif ($offset > 0) {
2780             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2781             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2782             }
2783             else {
2784             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2785             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2786             }
2787             if ($length == 0) {
2788             $octet_length = 0;
2789             }
2790             elsif ($length > 0) {
2791             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2792             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2793             }
2794             else {
2795             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2796             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2797             }
2798             CORE::substr($_[0], $octet_offset, $octet_length);
2799             }
2800              
2801             # substr($string,$offset)
2802             else {
2803             my $octet_offset = 0;
2804             if ($offset == 0) {
2805             $octet_offset = 0;
2806             }
2807             elsif ($offset > 0) {
2808             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2809             }
2810             else {
2811             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2812             }
2813             CORE::substr($_[0], $octet_offset);
2814             }
2815             }
2816             END
2817             }
2818              
2819             #
2820             # Latin-1 index by character
2821             #
2822 0     0 1 0 sub Latin1::index($$;$) {
2823 0 0       0  
2824 0         0 my $index;
2825             if (@_ == 3) {
2826             $index = Elatin1::index($_[0], $_[1], CORE::length(Latin1::substr($_[0], 0, $_[2])));
2827 0         0 }
2828             else {
2829             $index = Elatin1::index($_[0], $_[1]);
2830 0 0       0 }
2831 0         0  
2832             if ($index == -1) {
2833             return -1;
2834 0         0 }
2835             else {
2836             return Latin1::length(CORE::substr $_[0], 0, $index);
2837             }
2838             }
2839              
2840             #
2841             # Latin-1 rindex by character
2842             #
2843 0     0 1 0 sub Latin1::rindex($$;$) {
2844 0 0       0  
2845 0         0 my $rindex;
2846             if (@_ == 3) {
2847             $rindex = Elatin1::rindex($_[0], $_[1], CORE::length(Latin1::substr($_[0], 0, $_[2])));
2848 0         0 }
2849             else {
2850             $rindex = Elatin1::rindex($_[0], $_[1]);
2851 0 0       0 }
2852 0         0  
2853             if ($rindex == -1) {
2854             return -1;
2855 0         0 }
2856             else {
2857             return Latin1::length(CORE::substr $_[0], 0, $rindex);
2858             }
2859             }
2860              
2861 206     206   1830 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  206         486  
  206         19270  
2862             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2863             use vars qw($slash); $slash = 'm//';
2864              
2865             # ord() to ord() or Latin1::ord()
2866             my $function_ord = 'ord';
2867              
2868             # ord to ord or Latin1::ord_
2869             my $function_ord_ = 'ord';
2870              
2871             # reverse to reverse or Latin1::reverse
2872             my $function_reverse = 'reverse';
2873              
2874             # getc to getc or Latin1::getc
2875             my $function_getc = 'getc';
2876              
2877             # P.1023 Appendix W.9 Multibyte Anchoring
2878             # of ISBN 1-56592-224-7 CJKV Information Processing
2879              
2880 206     206   1341 my $anchor = '';
  206     0   371  
  206         8878513  
2881              
2882             use vars qw($nest);
2883              
2884             # regexp of nested parens in qqXX
2885              
2886             # P.340 Matching Nested Constructs with Embedded Code
2887             # in Chapter 7: Perl
2888             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2889              
2890             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2891             [^\\()] |
2892             \( (?{$nest++}) |
2893             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2894             \\ [^c] |
2895             \\c[\x40-\x5F] |
2896             [\x00-\xFF]
2897             }xms;
2898              
2899             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2900             [^\\{}] |
2901             \{ (?{$nest++}) |
2902             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2903             \\ [^c] |
2904             \\c[\x40-\x5F] |
2905             [\x00-\xFF]
2906             }xms;
2907              
2908             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2909             [^\\\[\]] |
2910             \[ (?{$nest++}) |
2911             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2912             \\ [^c] |
2913             \\c[\x40-\x5F] |
2914             [\x00-\xFF]
2915             }xms;
2916              
2917             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2918             [^\\<>] |
2919             \< (?{$nest++}) |
2920             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2921             \\ [^c] |
2922             \\c[\x40-\x5F] |
2923             [\x00-\xFF]
2924             }xms;
2925              
2926             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2927             (?: ::)? (?:
2928             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2929             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2930             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2931             ))
2932             }xms;
2933              
2934             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2935             (?: ::)? (?:
2936             (?>[0-9]+) |
2937             [^a-zA-Z_0-9\[\]] |
2938             ^[A-Z] |
2939             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2940             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2941             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2942             ))
2943             }xms;
2944              
2945             my $qq_substr = qr{(?> Char::substr | Latin1::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2946             }xms;
2947              
2948             # regexp of nested parens in qXX
2949             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2950             [^()] |
2951             \( (?{$nest++}) |
2952             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2953             [\x00-\xFF]
2954             }xms;
2955              
2956             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2957             [^\{\}] |
2958             \{ (?{$nest++}) |
2959             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2960             [\x00-\xFF]
2961             }xms;
2962              
2963             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2964             [^\[\]] |
2965             \[ (?{$nest++}) |
2966             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2967             [\x00-\xFF]
2968             }xms;
2969              
2970             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2971             [^<>] |
2972             \< (?{$nest++}) |
2973             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2974             [\x00-\xFF]
2975             }xms;
2976              
2977             my $matched = '';
2978             my $s_matched = '';
2979              
2980             my $tr_variable = ''; # variable of tr///
2981             my $sub_variable = ''; # variable of s///
2982             my $bind_operator = ''; # =~ or !~
2983              
2984             my @heredoc = (); # here document
2985             my @heredoc_delimiter = ();
2986             my $here_script = ''; # here script
2987              
2988             #
2989             # escape Latin-1 script
2990 0 50   206 0 0 #
2991             sub Latin1::escape(;$) {
2992             local($_) = $_[0] if @_;
2993              
2994             # P.359 The Study Function
2995             # in Chapter 7: Perl
2996 206         641 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2997              
2998             study $_; # Yes, I studied study yesterday.
2999              
3000             # while all script
3001              
3002             # 6.14. Matching from Where the Last Pattern Left Off
3003             # in Chapter 6. Pattern Matching
3004             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3005             # (and so on)
3006              
3007             # one member of Tag-team
3008             #
3009             # P.128 Start of match (or end of previous match): \G
3010             # P.130 Advanced Use of \G with Perl
3011             # in Chapter 3: Overview of Regular Expression Features and Flavors
3012             # P.255 Use leading anchors
3013             # P.256 Expose ^ and \G at the front expressions
3014             # in Chapter 6: Crafting an Efficient Expression
3015             # P.315 "Tag-team" matching with /gc
3016             # in Chapter 7: Perl
3017 206         398 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3018 206         336  
3019 206         757 my $e_script = '';
3020             while (not /\G \z/oxgc) { # member
3021             $e_script .= Latin1::escape_token();
3022 74766         120464 }
3023              
3024             return $e_script;
3025             }
3026              
3027             #
3028             # escape Latin-1 token of script
3029             #
3030             sub Latin1::escape_token {
3031              
3032 206     74766 0 5141 # \n output here document
3033              
3034             my $ignore_modules = join('|', qw(
3035             utf8
3036             bytes
3037             charnames
3038             I18N::Japanese
3039             I18N::Collate
3040             I18N::JExt
3041             File::DosGlob
3042             Wild
3043             Wildcard
3044             Japanese
3045             ));
3046              
3047             # another member of Tag-team
3048             #
3049             # P.315 "Tag-team" matching with /gc
3050             # in Chapter 7: Perl
3051 74766 100 100     88400 # 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          
3052 74766         3051754  
3053 12515 100       15023 if (/\G ( \n ) /oxgc) { # another member (and so on)
3054 12515         20762 my $heredoc = '';
3055             if (scalar(@heredoc_delimiter) >= 1) {
3056 174         245 $slash = 'm//';
3057 174         445  
3058             $heredoc = join '', @heredoc;
3059             @heredoc = ();
3060 174         321  
3061 174         298 # skip here document
3062             for my $heredoc_delimiter (@heredoc_delimiter) {
3063 174         1128 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3064             }
3065 174         306 @heredoc_delimiter = ();
3066              
3067 174         249 $here_script = '';
3068             }
3069             return "\n" . $heredoc;
3070             }
3071 12515         38292  
3072             # ignore space, comment
3073             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3074              
3075             # if (, elsif (, unless (, while (, until (, given (, and when (
3076              
3077             # given, when
3078              
3079             # P.225 The given Statement
3080             # in Chapter 15: Smart Matching and given-when
3081             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3082              
3083             # P.133 The given Statement
3084             # in Chapter 4: Statements and Declarations
3085             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3086 17892         55348  
3087 1401         2059 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3088             $slash = 'm//';
3089             return $1;
3090             }
3091              
3092             # scalar variable ($scalar = ...) =~ tr///;
3093             # scalar variable ($scalar = ...) =~ s///;
3094              
3095             # state
3096              
3097             # P.68 Persistent, Private Variables
3098             # in Chapter 4: Subroutines
3099             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3100              
3101             # P.160 Persistent Lexically Scoped Variables: state
3102             # in Chapter 4: Statements and Declarations
3103             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3104              
3105             # (and so on)
3106 1401         4345  
3107             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3108 86 50       221 my $e_string = e_string($1);
    50          
3109 86         2305  
3110 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3111 0         0 $tr_variable = $e_string . e_string($1);
3112 0         0 $bind_operator = $2;
3113             $slash = 'm//';
3114             return '';
3115 0         0 }
3116 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3117 0         0 $sub_variable = $e_string . e_string($1);
3118 0         0 $bind_operator = $2;
3119             $slash = 'm//';
3120             return '';
3121 0         0 }
3122 86         212 else {
3123             $slash = 'div';
3124             return $e_string;
3125             }
3126             }
3127              
3128 86         323 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
3129 4         8 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3130             $slash = 'div';
3131             return q{Elatin1::PREMATCH()};
3132             }
3133              
3134 4         13 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
3135 28         56 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3136             $slash = 'div';
3137             return q{Elatin1::MATCH()};
3138             }
3139              
3140 28         89 # $', ${'} --> $', ${'}
3141 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3142             $slash = 'div';
3143             return $1;
3144             }
3145              
3146 1         4 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
3147 3         7 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3148             $slash = 'div';
3149             return q{Elatin1::POSTMATCH()};
3150             }
3151              
3152             # scalar variable $scalar =~ tr///;
3153             # scalar variable $scalar =~ s///;
3154             # substr() =~ tr///;
3155 3         10 # substr() =~ s///;
3156             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3157 1673 100       3753 my $scalar = e_string($1);
    100          
3158 1673         6648  
3159 1         3 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3160 1         2 $tr_variable = $scalar;
3161 1         3 $bind_operator = $1;
3162             $slash = 'm//';
3163             return '';
3164 1         3 }
3165 61         119 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3166 61         117 $sub_variable = $scalar;
3167 61         93 $bind_operator = $1;
3168             $slash = 'm//';
3169             return '';
3170 61         172 }
3171 1611         2304 else {
3172             $slash = 'div';
3173             return $scalar;
3174             }
3175             }
3176              
3177 1611         4230 # end of statement
3178             elsif (/\G ( [,;] ) /oxgc) {
3179             $slash = 'm//';
3180 4988         7055  
3181             # clear tr/// variable
3182             $tr_variable = '';
3183 4988         6023  
3184             # clear s/// variable
3185 4988         5665 $sub_variable = '';
3186              
3187 4988         5954 $bind_operator = '';
3188              
3189             return $1;
3190             }
3191              
3192 4988         17162 # bareword
3193             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3194             return $1;
3195             }
3196              
3197 0         0 # $0 --> $0
3198 2         5 elsif (/\G ( \$ 0 ) /oxmsgc) {
3199             $slash = 'div';
3200             return $1;
3201 2         6 }
3202 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3203             $slash = 'div';
3204             return $1;
3205             }
3206              
3207 0         0 # $$ --> $$
3208 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3209             $slash = 'div';
3210             return $1;
3211             }
3212              
3213             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3214 1         3 # $1, $2, $3 --> $1, $2, $3 otherwise
3215 4         6 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3216             $slash = 'div';
3217             return e_capture($1);
3218 4         9 }
3219 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3220             $slash = 'div';
3221             return e_capture($1);
3222             }
3223              
3224 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3225 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3226             $slash = 'div';
3227             return e_capture($1.'->'.$2);
3228             }
3229              
3230 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3231 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3232             $slash = 'div';
3233             return e_capture($1.'->'.$2);
3234             }
3235              
3236 0         0 # $$foo
3237 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3238             $slash = 'div';
3239             return e_capture($1);
3240             }
3241              
3242 0         0 # ${ foo }
3243 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3244             $slash = 'div';
3245             return '${' . $1 . '}';
3246             }
3247              
3248 0         0 # ${ ... }
3249 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3250             $slash = 'div';
3251             return e_capture($1);
3252             }
3253              
3254             # variable or function
3255 0         0 # $ @ % & * $ #
3256 42         68 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) {
3257             $slash = 'div';
3258             return $1;
3259             }
3260             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3261 42         128 # $ @ # \ ' " / ? ( ) [ ] < >
3262 62         123 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3263             $slash = 'div';
3264             return $1;
3265             }
3266              
3267 62         258 # while ()
3268             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3269             return $1;
3270             }
3271              
3272             # while () --- glob
3273              
3274             # avoid "Error: Runtime exception" of perl version 5.005_03
3275 0         0  
3276             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3277             return 'while ($_ = Elatin1::glob("' . $1 . '"))';
3278             }
3279              
3280 0         0 # while (glob)
3281             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3282             return 'while ($_ = Elatin1::glob_)';
3283             }
3284              
3285 0         0 # while (glob(WILDCARD))
3286             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3287             return 'while ($_ = Elatin1::glob';
3288             }
3289 0         0  
  248         572  
3290             # doit if, doit unless, doit while, doit until, doit for, doit when
3291             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3292 248         890  
  19         32  
3293 19         62 # subroutines of package Elatin1
  0         0  
3294 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         20  
3295 13         38 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3296 0         0 elsif (/\G \b Latin1::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         162  
3297 114         373 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         6  
3298 2         5 elsif (/\G \b Latin1::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Latin1::escape'; }
  0         0  
3299 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         5  
3300 2         6 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::chop'; }
  0         0  
3301 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3302 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3303 0         0 elsif (/\G \b Latin1::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin1::index'; }
  2         4  
3304 2         6 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::index'; }
  0         0  
3305 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3306 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3307 0         0 elsif (/\G \b Latin1::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Latin1::rindex'; }
  1         4  
3308 1         3 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::rindex'; }
  0         0  
3309 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::lc'; }
  1         3  
3310 1         3 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::lcfirst'; }
  0         0  
3311 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::uc'; }
  6         8  
3312             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::ucfirst'; }
3313             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::fc'; }
3314 6         17  
  0         0  
3315 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3316 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3317 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3318 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3319 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3320 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3321             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3322 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  
3323 0         0  
  0         0  
3324 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3325 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3326 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3327 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3328 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3329             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3330             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3331 0         0  
  0         0  
3332 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3333 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3334 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3335             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3336 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         6  
3337 2         6  
  2         3  
3338 2         7 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         72  
3339 36         115 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         5  
3340 2         5 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::chr'; }
  8         13  
3341 8         4689 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3342 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3343 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Elatin1::glob'; }
  0         0  
3344 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::lc_'; }
  0         0  
3345 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::lcfirst_'; }
  0         0  
3346 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::uc_'; }
  0         0  
3347 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::ucfirst_'; }
  0         0  
3348             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::fc_'; }
3349 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3350 0         0  
  0         0  
3351 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3352 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3353 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::chr_'; }
  0         0  
3354 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3355 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3356 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Elatin1::glob_'; }
  8         19  
3357             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3358             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3359 8         26 # split
3360             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3361 87         174 $slash = 'm//';
3362 87         177  
3363 87         299 my $e = '';
3364             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3365             $e .= $1;
3366             }
3367 85 100       341  
  87 100       5721  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3368             # end of split
3369             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Elatin1::split' . $e; }
3370 2         10  
3371             # split scalar value
3372             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Elatin1::split' . $e . e_string($1); }
3373 1         6  
3374 0         0 # split literal space
3375 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Elatin1::split' . $e . qq {qq$1 $2}; }
3376 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3377 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3378 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3379 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3380 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin1::split' . $e . qq{$1qq$2 $3}; }
3381 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Elatin1::split' . $e . qq {q$1 $2}; }
3382 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3383 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3384 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3385 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3386 10         39 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Elatin1::split' . $e . qq {$1q$2 $3}; }
3387             elsif (/\G ' [ ] ' /oxgc) { return 'Elatin1::split' . $e . qq {' '}; }
3388             elsif (/\G " [ ] " /oxgc) { return 'Elatin1::split' . $e . qq {" "}; }
3389              
3390 0 0       0 # split qq//
  0         0  
3391             elsif (/\G \b (qq) \b /oxgc) {
3392 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3393 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3394 0         0 while (not /\G \z/oxgc) {
3395 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3396 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3397 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3398 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3399 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3400             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3401 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3402             }
3403             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3404             }
3405             }
3406              
3407 0 50       0 # split qr//
  12         396  
3408             elsif (/\G \b (qr) \b /oxgc) {
3409 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3410 12 50       62 else {
  12 50       3282  
    50          
    50          
    50          
    50          
    50          
    50          
3411 0         0 while (not /\G \z/oxgc) {
3412 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3413 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3414 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3415 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3416 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3417 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3418             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3419 12         139 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3420             }
3421             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3422             }
3423             }
3424              
3425 0 0       0 # split q//
  0         0  
3426             elsif (/\G \b (q) \b /oxgc) {
3427 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3428 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3429 0         0 while (not /\G \z/oxgc) {
3430 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3431 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3432 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3433 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3434 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3435             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3436 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3437             }
3438             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3439             }
3440             }
3441              
3442 0 50       0 # split m//
  18         464  
3443             elsif (/\G \b (m) \b /oxgc) {
3444 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3445 18 50       79 else {
  18 50       3825  
    50          
    50          
    50          
    50          
    50          
    50          
3446 0         0 while (not /\G \z/oxgc) {
3447 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3448 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3449 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3450 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3451 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3452 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3453             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3454 18         119 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3455             }
3456             die __FILE__, ": Search pattern not terminated\n";
3457             }
3458             }
3459              
3460 0         0 # split ''
3461 0         0 elsif (/\G (\') /oxgc) {
3462 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3463 0         0 while (not /\G \z/oxgc) {
3464 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3465 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3466             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3467 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3468             }
3469             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3470             }
3471              
3472 0         0 # split ""
3473 0         0 elsif (/\G (\") /oxgc) {
3474 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3475 0         0 while (not /\G \z/oxgc) {
3476 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3477 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3478             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3479 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3480             }
3481             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3482             }
3483              
3484 0         0 # split //
3485 44         162 elsif (/\G (\/) /oxgc) {
3486 44 50       171 my $regexp = '';
  381 50       1419  
    100          
    50          
3487 0         0 while (not /\G \z/oxgc) {
3488 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3489 44         236 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3490             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3491 337         622 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3492             }
3493             die __FILE__, ": Search pattern not terminated\n";
3494             }
3495             }
3496              
3497             # tr/// or y///
3498              
3499             # about [cdsrbB]* (/B modifier)
3500             #
3501             # P.559 appendix C
3502             # of ISBN 4-89052-384-7 Programming perl
3503             # (Japanese title is: Perl puroguramingu)
3504 0         0  
3505             elsif (/\G \b ( tr | y ) \b /oxgc) {
3506             my $ope = $1;
3507 3 50       8  
3508 3         41 # $1 $2 $3 $4 $5 $6
3509 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3510             my @tr = ($tr_variable,$2);
3511             return e_tr(@tr,'',$4,$6);
3512 0         0 }
3513 3         5 else {
3514 3 50       9 my $e = '';
  3 50       225  
    50          
    50          
    50          
    50          
3515             while (not /\G \z/oxgc) {
3516 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3517 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3518 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3519 0         0 while (not /\G \z/oxgc) {
3520 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3521 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3522 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3523 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3524             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3525 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3526             }
3527             die __FILE__, ": Transliteration replacement not terminated\n";
3528 0         0 }
3529 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3530 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3531 0         0 while (not /\G \z/oxgc) {
3532 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3533 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3534 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3535 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3536             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3537 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3538             }
3539             die __FILE__, ": Transliteration replacement not terminated\n";
3540 0         0 }
3541 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3542 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3543 0         0 while (not /\G \z/oxgc) {
3544 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3545 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3546 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3547 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3548             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3549 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3550             }
3551             die __FILE__, ": Transliteration replacement not terminated\n";
3552 0         0 }
3553 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3554 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3555 0         0 while (not /\G \z/oxgc) {
3556 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3557 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3558 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3559 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3560             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3561 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3562             }
3563             die __FILE__, ": Transliteration replacement not terminated\n";
3564             }
3565 0         0 # $1 $2 $3 $4 $5 $6
3566 3         11 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3567             my @tr = ($tr_variable,$2);
3568             return e_tr(@tr,'',$4,$6);
3569 3         9 }
3570             }
3571             die __FILE__, ": Transliteration pattern not terminated\n";
3572             }
3573             }
3574              
3575 0         0 # qq//
3576             elsif (/\G \b (qq) \b /oxgc) {
3577             my $ope = $1;
3578 2180 50       4625  
3579 2180         4007 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3580 0         0 if (/\G (\#) /oxgc) { # qq# #
3581 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3582 0         0 while (not /\G \z/oxgc) {
3583 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3584 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3585             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3586 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3587             }
3588             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3589             }
3590 0         0  
3591 2180         2864 else {
3592 2180 50       5091 my $e = '';
  2180 50       8061  
    100          
    50          
    50          
    0          
3593             while (not /\G \z/oxgc) {
3594             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3595              
3596 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3597 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3598 0         0 my $qq_string = '';
3599 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3600 0         0 while (not /\G \z/oxgc) {
3601 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3602             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3603 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3604 0         0 elsif (/\G (\)) /oxgc) {
3605             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3606 0         0 else { $qq_string .= $1; }
3607             }
3608 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3609             }
3610             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3611             }
3612              
3613 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3614 2150         2817 elsif (/\G (\{) /oxgc) { # qq { }
3615 2150         2973 my $qq_string = '';
3616 2150 100       5194 local $nest = 1;
  84006 50       293127  
    100          
    100          
    50          
3617 722         1367 while (not /\G \z/oxgc) {
3618 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         1575  
3619             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3620 1153 100       1908 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         4860  
3621 2150         4113 elsif (/\G (\}) /oxgc) {
3622             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3623 1153         2228 else { $qq_string .= $1; }
3624             }
3625 78828         192573 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3626             }
3627             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3628             }
3629              
3630 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3631 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3632 0         0 my $qq_string = '';
3633 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3634 0         0 while (not /\G \z/oxgc) {
3635 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3636             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3637 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3638 0         0 elsif (/\G (\]) /oxgc) {
3639             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3640 0         0 else { $qq_string .= $1; }
3641             }
3642 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3643             }
3644             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3645             }
3646              
3647 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3648 30         53 elsif (/\G (\<) /oxgc) { # qq < >
3649 30         53 my $qq_string = '';
3650 30 100       87 local $nest = 1;
  1166 50       3783  
    50          
    100          
    50          
3651 22         49 while (not /\G \z/oxgc) {
3652 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3653             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3654 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         57  
3655 30         102 elsif (/\G (\>) /oxgc) {
3656             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3657 0         0 else { $qq_string .= $1; }
3658             }
3659 1114         2830 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3660             }
3661             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3662             }
3663              
3664 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3665 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3666 0         0 my $delimiter = $1;
3667 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3668 0         0 while (not /\G \z/oxgc) {
3669 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3670 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3671             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3672 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3673             }
3674             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3675 0         0 }
3676             }
3677             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3678             }
3679             }
3680              
3681 0         0 # qr//
3682 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3683 0         0 my $ope = $1;
3684             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3685             return e_qr($ope,$1,$3,$2,$4);
3686 0         0 }
3687 0         0 else {
3688 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3689 0         0 while (not /\G \z/oxgc) {
3690 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3691 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3692 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3693 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3694 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3695 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3696             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3697 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3698             }
3699             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3700             }
3701             }
3702              
3703 0         0 # qw//
3704 16 50       53 elsif (/\G \b (qw) \b /oxgc) {
3705 16         82 my $ope = $1;
3706             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3707             return e_qw($ope,$1,$3,$2);
3708 0         0 }
3709 16         32 else {
3710 16 50       57 my $e = '';
  16 50       140  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3711             while (not /\G \z/oxgc) {
3712 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3713 16         70  
3714             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3715 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3716 0         0  
3717             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3718 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3719 0         0  
3720             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3721 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3722 0         0  
3723             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3724 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3725 0         0  
3726             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3727 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3728             }
3729             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3730             }
3731             }
3732              
3733 0         0 # qx//
3734 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3735 0         0 my $ope = $1;
3736             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3737             return e_qq($ope,$1,$3,$2);
3738 0         0 }
3739 0         0 else {
3740 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3741 0         0 while (not /\G \z/oxgc) {
3742 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3743 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3744 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3745 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3746 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3747             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3748 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3749             }
3750             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3751             }
3752             }
3753              
3754 0         0 # q//
3755             elsif (/\G \b (q) \b /oxgc) {
3756             my $ope = $1;
3757              
3758             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3759              
3760             # avoid "Error: Runtime exception" of perl version 5.005_03
3761 410 50       1285 # (and so on)
3762 410         1114  
3763 0         0 if (/\G (\#) /oxgc) { # q# #
3764 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3765 0         0 while (not /\G \z/oxgc) {
3766 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3767 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3768             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3769 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3770             }
3771             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3772             }
3773 0         0  
3774 410         761 else {
3775 410 50       1402 my $e = '';
  410 50       2349  
    100          
    50          
    100          
    50          
3776             while (not /\G \z/oxgc) {
3777             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3778              
3779 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3780 0         0 elsif (/\G (\() /oxgc) { # q ( )
3781 0         0 my $q_string = '';
3782 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3783 0         0 while (not /\G \z/oxgc) {
3784 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3785 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3786             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3787 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3788 0         0 elsif (/\G (\)) /oxgc) {
3789             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3790 0         0 else { $q_string .= $1; }
3791             }
3792 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3793             }
3794             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3795             }
3796              
3797 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3798 404         690 elsif (/\G (\{) /oxgc) { # q { }
3799 404         632 my $q_string = '';
3800 404 50       1169 local $nest = 1;
  6770 50       25109  
    50          
    100          
    100          
    50          
3801 0         0 while (not /\G \z/oxgc) {
3802 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3803 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         152  
3804             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3805 107 100       181 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         937  
3806 404         1236 elsif (/\G (\}) /oxgc) {
3807             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3808 107         218 else { $q_string .= $1; }
3809             }
3810 6152         11980 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3811             }
3812             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3813             }
3814              
3815 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3816 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3817 0         0 my $q_string = '';
3818 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3819 0         0 while (not /\G \z/oxgc) {
3820 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3821 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3822             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3823 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3824 0         0 elsif (/\G (\]) /oxgc) {
3825             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3826 0         0 else { $q_string .= $1; }
3827             }
3828 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3829             }
3830             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3831             }
3832              
3833 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3834 5         12 elsif (/\G (\<) /oxgc) { # q < >
3835 5         17 my $q_string = '';
3836 5 50       22 local $nest = 1;
  88 50       390  
    50          
    50          
    100          
    50          
3837 0         0 while (not /\G \z/oxgc) {
3838 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3839 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3840             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3841 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         13  
3842 5         18 elsif (/\G (\>) /oxgc) {
3843             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3844 0         0 else { $q_string .= $1; }
3845             }
3846 83         219 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3847             }
3848             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3849             }
3850              
3851 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3852 1         3 elsif (/\G (\S) /oxgc) { # q * *
3853 1         16 my $delimiter = $1;
3854 1 50       5 my $q_string = '';
  14 50       73  
    100          
    50          
3855 0         0 while (not /\G \z/oxgc) {
3856 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3857 1         3 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3858             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3859 13         22 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3860             }
3861             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3862 0         0 }
3863             }
3864             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3865             }
3866             }
3867              
3868 0         0 # m//
3869 209 50       454 elsif (/\G \b (m) \b /oxgc) {
3870 209         1266 my $ope = $1;
3871             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3872             return e_qr($ope,$1,$3,$2,$4);
3873 0         0 }
3874 209         326 else {
3875 209 50       573 my $e = '';
  209 50       11794  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3876 0         0 while (not /\G \z/oxgc) {
3877 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3878 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3879 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3880 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3881 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3882 10         29 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3883 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3884             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3885 199         626 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3886             }
3887             die __FILE__, ": Search pattern not terminated\n";
3888             }
3889             }
3890              
3891             # s///
3892              
3893             # about [cegimosxpradlunbB]* (/cg modifier)
3894             #
3895             # P.67 Pattern-Matching Operators
3896             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3897 0         0  
3898             elsif (/\G \b (s) \b /oxgc) {
3899             my $ope = $1;
3900 97 100       247  
3901 97         1615 # $1 $2 $3 $4 $5 $6
3902             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3903             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3904 1         5 }
3905 96         181 else {
3906 96 50       405 my $e = '';
  96 50       12021  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3907             while (not /\G \z/oxgc) {
3908 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3909 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3910 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3911             while (not /\G \z/oxgc) {
3912 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3913 0         0 # $1 $2 $3 $4
3914 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3915 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3916 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3917 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3918 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([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             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3922 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3923             }
3924             die __FILE__, ": Substitution replacement not terminated\n";
3925 0         0 }
3926 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3927 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3928             while (not /\G \z/oxgc) {
3929 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3930 0         0 # $1 $2 $3 $4
3931 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3932 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3933 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3934 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3935 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3936 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3937 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3938             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3939 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3940             }
3941             die __FILE__, ": Substitution replacement not terminated\n";
3942 0         0 }
3943 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3944 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3945             while (not /\G \z/oxgc) {
3946 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3947 0         0 # $1 $2 $3 $4
3948 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3949 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3950 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3951 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([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             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3954 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3955             }
3956             die __FILE__, ": Substitution replacement not terminated\n";
3957 0         0 }
3958 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3959 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3960             while (not /\G \z/oxgc) {
3961 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3962 0         0 # $1 $2 $3 $4
3963 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3964 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3965 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3966 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3967 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3968 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3969 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3970             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3971 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3972             }
3973             die __FILE__, ": Substitution replacement not terminated\n";
3974             }
3975 0         0 # $1 $2 $3 $4 $5 $6
3976             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3977             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3978             }
3979 21         60 # $1 $2 $3 $4 $5 $6
3980             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3981             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3982             }
3983 0         0 # $1 $2 $3 $4 $5 $6
3984             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3985             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3986             }
3987 0         0 # $1 $2 $3 $4 $5 $6
3988             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3989             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3990 75         333 }
3991             }
3992             die __FILE__, ": Substitution pattern not terminated\n";
3993             }
3994             }
3995 0         0  
3996 0         0 # require ignore module
3997 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
3998             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
3999             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4000 0         0  
4001 37         316 # use strict; --> use strict; no strict qw(refs);
4002 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4003             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4004             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4005              
4006 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
4007 2         23 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4008             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4009             return "use $1; no strict qw(refs);";
4010 0         0 }
4011             else {
4012             return "use $1;";
4013             }
4014 2 0 0     12 }
      0        
4015 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4016             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4017             return "use $1; no strict qw(refs);";
4018 0         0 }
4019             else {
4020             return "use $1;";
4021             }
4022             }
4023 0         0  
4024 2         39 # ignore use module
4025 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4026             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4027             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4028 0         0  
4029 0         0 # ignore no module
4030 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4031             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4032             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4033 0         0  
4034             # use else
4035             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4036 0         0  
4037             # use else
4038             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4039              
4040 2         9 # ''
4041 848         1699 elsif (/\G (?
4042 848 100       2163 my $q_string = '';
  8254 100       24321  
    100          
    50          
4043 4         10 while (not /\G \z/oxgc) {
4044 48         92 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4045 848         1837 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4046             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4047 7354         14941 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4048             }
4049             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4050             }
4051              
4052 0         0 # ""
4053 1768         4632 elsif (/\G (\") /oxgc) {
4054 1768 100       5864 my $qq_string = '';
  35021 100       145992  
    100          
    50          
4055 67         227 while (not /\G \z/oxgc) {
4056 12         25 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4057 1768         3913 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4058             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4059 33174         79069 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4060             }
4061             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4062             }
4063              
4064 0         0 # ``
4065 1         2 elsif (/\G (\`) /oxgc) {
4066 1 50       4 my $qx_string = '';
  19 50       65  
    100          
    50          
4067 0         0 while (not /\G \z/oxgc) {
4068 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4069 1         2 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4070             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4071 18         35 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4072             }
4073             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4074             }
4075              
4076 0         0 # // --- not divide operator (num / num), not defined-or
4077 453         991 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4078 453 50       1207 my $regexp = '';
  4496 50       14384  
    100          
    50          
4079 0         0 while (not /\G \z/oxgc) {
4080 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4081 453         1255 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4082             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4083 4043         7942 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4084             }
4085             die __FILE__, ": Search pattern not terminated\n";
4086             }
4087              
4088 0         0 # ?? --- not conditional operator (condition ? then : else)
4089 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4090 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4091 0         0 while (not /\G \z/oxgc) {
4092 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4093 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4094             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4095 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4096             }
4097             die __FILE__, ": Search pattern not terminated\n";
4098             }
4099 0         0  
  0         0  
4100             # <<>> (a safer ARGV)
4101             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4102 0         0  
  0         0  
4103             # << (bit shift) --- not here document
4104             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4105              
4106 0         0 # <<~'HEREDOC'
4107 6         13 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4108 6         12 $slash = 'm//';
4109             my $here_quote = $1;
4110             my $delimiter = $2;
4111 6 50       10  
4112 6         13 # get here document
4113 6         44 if ($here_script eq '') {
4114             $here_script = CORE::substr $_, pos $_;
4115 6 50       31 $here_script =~ s/.*?\n//oxm;
4116 6         57 }
4117 6         15 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4118 6         10 my $heredoc = $1;
4119 6         47 my $indent = $2;
4120 6         20 $heredoc =~ s{^$indent}{}msg; # no /ox
4121             push @heredoc, $heredoc . qq{\n$delimiter\n};
4122             push @heredoc_delimiter, qq{\\s*$delimiter};
4123 6         19 }
4124             else {
4125 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4126             }
4127             return qq{<<'$delimiter'};
4128             }
4129              
4130             # <<~\HEREDOC
4131              
4132             # P.66 2.6.6. "Here" Documents
4133             # in Chapter 2: Bits and Pieces
4134             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4135              
4136             # P.73 "Here" Documents
4137             # in Chapter 2: Bits and Pieces
4138             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4139 6         23  
4140 3         8 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4141 3         6 $slash = 'm//';
4142             my $here_quote = $1;
4143             my $delimiter = $2;
4144 3 50       6  
4145 3         10 # get here document
4146 3         19 if ($here_script eq '') {
4147             $here_script = CORE::substr $_, pos $_;
4148 3 50       23 $here_script =~ s/.*?\n//oxm;
4149 3         40 }
4150 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4151 3         5 my $heredoc = $1;
4152 3         44 my $indent = $2;
4153 3         14 $heredoc =~ s{^$indent}{}msg; # no /ox
4154             push @heredoc, $heredoc . qq{\n$delimiter\n};
4155             push @heredoc_delimiter, qq{\\s*$delimiter};
4156 3         8 }
4157             else {
4158 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4159             }
4160             return qq{<<\\$delimiter};
4161             }
4162              
4163 3         14 # <<~"HEREDOC"
4164 6         12 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4165 6         9 $slash = 'm//';
4166             my $here_quote = $1;
4167             my $delimiter = $2;
4168 6 50       9  
4169 6         11 # get here document
4170 6         24 if ($here_script eq '') {
4171             $here_script = CORE::substr $_, pos $_;
4172 6 50       28 $here_script =~ s/.*?\n//oxm;
4173 6         62 }
4174 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4175 6         8 my $heredoc = $1;
4176 6         41 my $indent = $2;
4177 6         16 $heredoc =~ s{^$indent}{}msg; # no /ox
4178             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4179             push @heredoc_delimiter, qq{\\s*$delimiter};
4180 6         13 }
4181             else {
4182 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4183             }
4184             return qq{<<"$delimiter"};
4185             }
4186              
4187 6         19 # <<~HEREDOC
4188 3         5 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4189 3         7 $slash = 'm//';
4190             my $here_quote = $1;
4191             my $delimiter = $2;
4192 3 50       4  
4193 3         6 # get here document
4194 3         12 if ($here_script eq '') {
4195             $here_script = CORE::substr $_, pos $_;
4196 3 50       20 $here_script =~ s/.*?\n//oxm;
4197 3         35 }
4198 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4199 3         4 my $heredoc = $1;
4200 3         38 my $indent = $2;
4201 3         9 $heredoc =~ s{^$indent}{}msg; # no /ox
4202             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4203             push @heredoc_delimiter, qq{\\s*$delimiter};
4204 3         7 }
4205             else {
4206 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4207             }
4208             return qq{<<$delimiter};
4209             }
4210              
4211 3         12 # <<~`HEREDOC`
4212 6         37 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4213 6         10 $slash = 'm//';
4214             my $here_quote = $1;
4215             my $delimiter = $2;
4216 6 50       23  
4217 6         21 # get here document
4218 6         16 if ($here_script eq '') {
4219             $here_script = CORE::substr $_, pos $_;
4220 6 50       29 $here_script =~ s/.*?\n//oxm;
4221 6         59 }
4222 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4223 6         7 my $heredoc = $1;
4224 6         48 my $indent = $2;
4225 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4226             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4227             push @heredoc_delimiter, qq{\\s*$delimiter};
4228 6         13 }
4229             else {
4230 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4231             }
4232             return qq{<<`$delimiter`};
4233             }
4234              
4235 6         22 # <<'HEREDOC'
4236 72         150 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4237 72         190 $slash = 'm//';
4238             my $here_quote = $1;
4239             my $delimiter = $2;
4240 72 50       125  
4241 72         195 # get here document
4242 72         439 if ($here_script eq '') {
4243             $here_script = CORE::substr $_, pos $_;
4244 72 50       458 $here_script =~ s/.*?\n//oxm;
4245 72         696 }
4246 72         319 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4247             push @heredoc, $1 . qq{\n$delimiter\n};
4248             push @heredoc_delimiter, $delimiter;
4249 72         125 }
4250             else {
4251 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4252             }
4253             return $here_quote;
4254             }
4255              
4256             # <<\HEREDOC
4257              
4258             # P.66 2.6.6. "Here" Documents
4259             # in Chapter 2: Bits and Pieces
4260             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4261              
4262             # P.73 "Here" Documents
4263             # in Chapter 2: Bits and Pieces
4264             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4265 72         313  
4266 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4267 0         0 $slash = 'm//';
4268             my $here_quote = $1;
4269             my $delimiter = $2;
4270 0 0       0  
4271 0         0 # get here document
4272 0         0 if ($here_script eq '') {
4273             $here_script = CORE::substr $_, pos $_;
4274 0 0       0 $here_script =~ s/.*?\n//oxm;
4275 0         0 }
4276 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4277             push @heredoc, $1 . qq{\n$delimiter\n};
4278             push @heredoc_delimiter, $delimiter;
4279 0         0 }
4280             else {
4281 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4282             }
4283             return $here_quote;
4284             }
4285              
4286 0         0 # <<"HEREDOC"
4287 36         88 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4288 36         87 $slash = 'm//';
4289             my $here_quote = $1;
4290             my $delimiter = $2;
4291 36 50       475  
4292 36         103 # get here document
4293 36         271 if ($here_script eq '') {
4294             $here_script = CORE::substr $_, pos $_;
4295 36 50       225 $here_script =~ s/.*?\n//oxm;
4296 36         755 }
4297 36         133 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4298             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4299             push @heredoc_delimiter, $delimiter;
4300 36         153 }
4301             else {
4302 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4303             }
4304             return $here_quote;
4305             }
4306              
4307 36         147 # <
4308 42         97 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4309 42         86 $slash = 'm//';
4310             my $here_quote = $1;
4311             my $delimiter = $2;
4312 42 50       76  
4313 42         101 # get here document
4314 42         276 if ($here_script eq '') {
4315             $here_script = CORE::substr $_, pos $_;
4316 42 50       319 $here_script =~ s/.*?\n//oxm;
4317 42         597 }
4318 42         169 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4319             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4320             push @heredoc_delimiter, $delimiter;
4321 42         99 }
4322             else {
4323 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4324             }
4325             return $here_quote;
4326             }
4327              
4328 42         172 # <<`HEREDOC`
4329 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4330 0         0 $slash = 'm//';
4331             my $here_quote = $1;
4332             my $delimiter = $2;
4333 0 0       0  
4334 0         0 # get here document
4335 0         0 if ($here_script eq '') {
4336             $here_script = CORE::substr $_, pos $_;
4337 0 0       0 $here_script =~ s/.*?\n//oxm;
4338 0         0 }
4339 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4340             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4341             push @heredoc_delimiter, $delimiter;
4342 0         0 }
4343             else {
4344 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4345             }
4346             return $here_quote;
4347             }
4348              
4349 0         0 # <<= <=> <= < operator
4350             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4351             return $1;
4352             }
4353              
4354 12         59 #
4355             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4356             return $1;
4357             }
4358              
4359             # --- glob
4360              
4361             # avoid "Error: Runtime exception" of perl version 5.005_03
4362 0         0  
4363             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4364             return 'Elatin1::glob("' . $1 . '")';
4365             }
4366 0         0  
4367             # __DATA__
4368             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4369 0         0  
4370             # __END__
4371             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4372              
4373             # \cD Control-D
4374              
4375             # P.68 2.6.8. Other Literal Tokens
4376             # in Chapter 2: Bits and Pieces
4377             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4378              
4379             # P.76 Other Literal Tokens
4380             # in Chapter 2: Bits and Pieces
4381 204         1663 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4382              
4383             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4384 0         0  
4385             # \cZ Control-Z
4386             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4387              
4388             # any operator before div
4389             elsif (/\G (
4390             -- | \+\+ |
4391 0         0 [\)\}\]]
  5083         10465  
4392              
4393             ) /oxgc) { $slash = 'div'; return $1; }
4394              
4395             # yada-yada or triple-dot operator
4396             elsif (/\G (
4397 5083         24660 \.\.\.
  7         14  
4398              
4399             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4400              
4401             # any operator before m//
4402              
4403             # //, //= (defined-or)
4404              
4405             # P.164 Logical Operators
4406             # in Chapter 10: More Control Structures
4407             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4408              
4409             # P.119 C-Style Logical (Short-Circuit) Operators
4410             # in Chapter 3: Unary and Binary Operators
4411             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4412              
4413             # (and so on)
4414              
4415             # ~~
4416              
4417             # P.221 The Smart Match Operator
4418             # in Chapter 15: Smart Matching and given-when
4419             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4420              
4421             # P.112 Smartmatch Operator
4422             # in Chapter 3: Unary and Binary Operators
4423             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4424              
4425             # (and so on)
4426              
4427             elsif (/\G ((?>
4428              
4429             !~~ | !~ | != | ! |
4430             %= | % |
4431             &&= | && | &= | &\.= | &\. | & |
4432             -= | -> | - |
4433             :(?>\s*)= |
4434             : |
4435             <<>> |
4436             <<= | <=> | <= | < |
4437             == | => | =~ | = |
4438             >>= | >> | >= | > |
4439             \*\*= | \*\* | \*= | \* |
4440             \+= | \+ |
4441             \.\. | \.= | \. |
4442             \/\/= | \/\/ |
4443             \/= | \/ |
4444             \? |
4445             \\ |
4446             \^= | \^\.= | \^\. | \^ |
4447             \b x= |
4448             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4449             ~~ | ~\. | ~ |
4450             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4451             \b(?: print )\b |
4452              
4453 7         25 [,;\(\{\[]
  8838         16254  
4454              
4455             )) /oxgc) { $slash = 'm//'; return $1; }
4456 8838         38469  
  15165         28323  
4457             # other any character
4458             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4459              
4460 15165         71722 # system error
4461             else {
4462             die __FILE__, ": Oops, this shouldn't happen!\n";
4463             }
4464             }
4465              
4466 0     1788 0 0 # escape Latin-1 string
4467 1788         4289 sub e_string {
4468             my($string) = @_;
4469 1788         2553 my $e_string = '';
4470              
4471             local $slash = 'm//';
4472              
4473             # P.1024 Appendix W.10 Multibyte Processing
4474             # of ISBN 1-56592-224-7 CJKV Information Processing
4475 1788         2513 # (and so on)
4476              
4477             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4478 1788 100 66     13715  
4479 1788 50       7471 # without { ... }
4480 1769         4016 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4481             if ($string !~ /<
4482             return $string;
4483             }
4484             }
4485 1769         4302  
4486 19 50       106 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          
4487             while ($string !~ /\G \z/oxgc) {
4488             if (0) {
4489             }
4490 223         6430  
4491 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Elatin1::PREMATCH()]}
4492 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4493             $e_string .= q{Elatin1::PREMATCH()};
4494             $slash = 'div';
4495             }
4496              
4497 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Elatin1::MATCH()]}
4498 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4499             $e_string .= q{Elatin1::MATCH()};
4500             $slash = 'div';
4501             }
4502              
4503 0         0 # $', ${'} --> $', ${'}
4504 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4505             $e_string .= $1;
4506             $slash = 'div';
4507             }
4508              
4509 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Elatin1::POSTMATCH()]}
4510 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4511             $e_string .= q{Elatin1::POSTMATCH()};
4512             $slash = 'div';
4513             }
4514              
4515 0         0 # bareword
4516 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4517             $e_string .= $1;
4518             $slash = 'div';
4519             }
4520              
4521 0         0 # $0 --> $0
4522 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4523             $e_string .= $1;
4524             $slash = 'div';
4525 0         0 }
4526 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4527             $e_string .= $1;
4528             $slash = 'div';
4529             }
4530              
4531 0         0 # $$ --> $$
4532 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4533             $e_string .= $1;
4534             $slash = 'div';
4535             }
4536              
4537             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4538 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4539 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4540             $e_string .= e_capture($1);
4541             $slash = 'div';
4542 0         0 }
4543 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4544             $e_string .= e_capture($1);
4545             $slash = 'div';
4546             }
4547              
4548 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4549 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4550             $e_string .= e_capture($1.'->'.$2);
4551             $slash = 'div';
4552             }
4553              
4554 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4555 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4556             $e_string .= e_capture($1.'->'.$2);
4557             $slash = 'div';
4558             }
4559              
4560 0         0 # $$foo
4561 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4562             $e_string .= e_capture($1);
4563             $slash = 'div';
4564             }
4565              
4566 0         0 # ${ foo }
4567 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4568             $e_string .= '${' . $1 . '}';
4569             $slash = 'div';
4570             }
4571              
4572 0         0 # ${ ... }
4573 3         24 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4574             $e_string .= e_capture($1);
4575             $slash = 'div';
4576             }
4577              
4578             # variable or function
4579 3         21 # $ @ % & * $ #
4580 7         75 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) {
4581             $e_string .= $1;
4582             $slash = 'div';
4583             }
4584             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4585 7         29 # $ @ # \ ' " / ? ( ) [ ] < >
4586 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4587             $e_string .= $1;
4588             $slash = 'div';
4589             }
4590              
4591 0         0 # qq//
4592 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4593 0         0 my $ope = $1;
4594             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4595             $e_string .= e_qq($ope,$1,$3,$2);
4596 0         0 }
4597 0         0 else {
4598 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4599 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4600 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4601 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4602 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4603 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4604             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4605 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4606             }
4607             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4608             }
4609             }
4610              
4611 0         0 # qx//
4612 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4613 0         0 my $ope = $1;
4614             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4615             $e_string .= e_qq($ope,$1,$3,$2);
4616 0         0 }
4617 0         0 else {
4618 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4619 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4620 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4621 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4622 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4623 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4624 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4625             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4626 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4627             }
4628             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4629             }
4630             }
4631              
4632 0         0 # q//
4633 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4634 0         0 my $ope = $1;
4635             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4636             $e_string .= e_q($ope,$1,$3,$2);
4637 0         0 }
4638 0         0 else {
4639 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4640 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4641 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4642 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4643 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4644 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4645             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4646 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 * *
4647             }
4648             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4649             }
4650             }
4651 0         0  
4652             # ''
4653             elsif ($string =~ /\G (?
4654 0         0  
4655             # ""
4656             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4657 0         0  
4658             # ``
4659             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4660 0         0  
4661             # other any character
4662             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
4663              
4664 213         491 # system error
4665             else {
4666             die __FILE__, ": Oops, this shouldn't happen!\n";
4667             }
4668 0         0 }
4669              
4670             return $e_string;
4671             }
4672              
4673             #
4674             # character class
4675 19     1919 0 123 #
4676             sub character_class {
4677 1919 100       3257 my($char,$modifier) = @_;
4678 1919 100       2808  
4679 52         105 if ($char eq '.') {
4680             if ($modifier =~ /s/) {
4681             return '${Elatin1::dot_s}';
4682 17         38 }
4683             else {
4684             return '${Elatin1::dot}';
4685             }
4686 35         86 }
4687             else {
4688             return Elatin1::classic_character_class($char);
4689             }
4690             }
4691              
4692             #
4693             # escape capture ($1, $2, $3, ...)
4694             #
4695 1867     212 0 3042 sub e_capture {
4696              
4697             return join '', '${', $_[0], '}';
4698             }
4699              
4700             #
4701             # escape transliteration (tr/// or y///)
4702 212     3 0 1414 #
4703 3         11 sub e_tr {
4704 3   50     4 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
4705             my $e_tr = '';
4706 3         7 $modifier ||= '';
4707              
4708             $slash = 'div';
4709 3         4  
4710             # quote character class 1
4711             $charclass = q_tr($charclass);
4712 3         5  
4713             # quote character class 2
4714             $charclass2 = q_tr($charclass2);
4715 3 50       5  
4716 3 0       10 # /b /B modifier
4717 0         0 if ($modifier =~ tr/bB//d) {
4718             if ($variable eq '') {
4719             $e_tr = qq{tr$charclass$e$charclass2$modifier};
4720 0         0 }
4721             else {
4722             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
4723             }
4724 0 100       0 }
4725 3         6 else {
4726             if ($variable eq '') {
4727             $e_tr = qq{Elatin1::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
4728 2         7 }
4729             else {
4730             $e_tr = qq{Elatin1::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
4731             }
4732             }
4733 1         4  
4734 3         4 # clear tr/// variable
4735             $tr_variable = '';
4736 3         4 $bind_operator = '';
4737              
4738             return $e_tr;
4739             }
4740              
4741             #
4742             # quote for escape transliteration (tr/// or y///)
4743 3     6 0 14 #
4744             sub q_tr {
4745             my($charclass) = @_;
4746 6 50       9  
    0          
    0          
    0          
    0          
    0          
4747 6         11 # quote character class
4748             if ($charclass !~ /'/oxms) {
4749             return e_q('', "'", "'", $charclass); # --> q' '
4750 6         9 }
4751             elsif ($charclass !~ /\//oxms) {
4752             return e_q('q', '/', '/', $charclass); # --> q/ /
4753 0         0 }
4754             elsif ($charclass !~ /\#/oxms) {
4755             return e_q('q', '#', '#', $charclass); # --> q# #
4756 0         0 }
4757             elsif ($charclass !~ /[\<\>]/oxms) {
4758             return e_q('q', '<', '>', $charclass); # --> q< >
4759 0         0 }
4760             elsif ($charclass !~ /[\(\)]/oxms) {
4761             return e_q('q', '(', ')', $charclass); # --> q( )
4762 0         0 }
4763             elsif ($charclass !~ /[\{\}]/oxms) {
4764             return e_q('q', '{', '}', $charclass); # --> q{ }
4765 0         0 }
4766 0 0       0 else {
4767 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
4768             if ($charclass !~ /\Q$char\E/xms) {
4769             return e_q('q', $char, $char, $charclass);
4770             }
4771             }
4772 0         0 }
4773              
4774             return e_q('q', '{', '}', $charclass);
4775             }
4776              
4777             #
4778             # escape q string (q//, '')
4779 0     1264 0 0 #
4780             sub e_q {
4781 1264         2898 my($ope,$delimiter,$end_delimiter,$string) = @_;
4782              
4783 1264         1736 $slash = 'div';
4784              
4785             return join '', $ope, $delimiter, $string, $end_delimiter;
4786             }
4787              
4788             #
4789             # escape qq string (qq//, "", qx//, ``)
4790 1264     4030 0 6223 #
4791             sub e_qq {
4792 4030         9458 my($ope,$delimiter,$end_delimiter,$string) = @_;
4793              
4794 4030         5865 $slash = 'div';
4795 4030         5594  
4796             my $left_e = 0;
4797             my $right_e = 0;
4798 4030         4529  
4799             # split regexp
4800             my @char = $string =~ /\G((?>
4801             [^\\\$] |
4802             \\x\{ (?>[0-9A-Fa-f]+) \} |
4803             \\o\{ (?>[0-7]+) \} |
4804             \\N\{ (?>[^0-9\}][^\}]*) \} |
4805             \\ $q_char |
4806             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
4807             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
4808             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
4809             \$ (?>\s* [0-9]+) |
4810             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
4811             \$ \$ (?![\w\{]) |
4812             \$ (?>\s*) \$ (?>\s*) $qq_variable |
4813             $q_char
4814 4030         150004 ))/oxmsg;
4815              
4816             for (my $i=0; $i <= $#char; $i++) {
4817 4030 50 33     12388  
    50 33        
    100          
    100          
    50          
4818 113745         359195 # "\L\u" --> "\u\L"
4819             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
4820             @char[$i,$i+1] = @char[$i+1,$i];
4821             }
4822              
4823 0         0 # "\U\l" --> "\l\U"
4824             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
4825             @char[$i,$i+1] = @char[$i+1,$i];
4826             }
4827              
4828 0         0 # octal escape sequence
4829             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
4830             $char[$i] = Elatin1::octchr($1);
4831             }
4832              
4833 1         4 # hexadecimal escape sequence
4834             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
4835             $char[$i] = Elatin1::hexchr($1);
4836             }
4837              
4838 1         4 # \N{CHARNAME} --> N{CHARNAME}
4839             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
4840             $char[$i] = $1;
4841 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          
4842              
4843             if (0) {
4844             }
4845              
4846             # \F
4847             #
4848             # P.69 Table 2-6. Translation escapes
4849             # in Chapter 2: Bits and Pieces
4850             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4851             # (and so on)
4852 113745         930438  
4853 0 50       0 # \u \l \U \L \F \Q \E
4854 484         1007 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
4855             if ($right_e < $left_e) {
4856             $char[$i] = '\\' . $char[$i];
4857             }
4858             }
4859             elsif ($char[$i] eq '\u') {
4860              
4861             # "STRING @{[ LIST EXPR ]} MORE STRING"
4862              
4863             # P.257 Other Tricks You Can Do with Hard References
4864             # in Chapter 8: References
4865             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4866              
4867             # P.353 Other Tricks You Can Do with Hard References
4868             # in Chapter 8: References
4869             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4870              
4871 0         0 # (and so on)
4872 0         0  
4873             $char[$i] = '@{[Elatin1::ucfirst qq<';
4874             $left_e++;
4875 0         0 }
4876 0         0 elsif ($char[$i] eq '\l') {
4877             $char[$i] = '@{[Elatin1::lcfirst qq<';
4878             $left_e++;
4879 0         0 }
4880 0         0 elsif ($char[$i] eq '\U') {
4881             $char[$i] = '@{[Elatin1::uc qq<';
4882             $left_e++;
4883 0         0 }
4884 0         0 elsif ($char[$i] eq '\L') {
4885             $char[$i] = '@{[Elatin1::lc qq<';
4886             $left_e++;
4887 0         0 }
4888 24         38 elsif ($char[$i] eq '\F') {
4889             $char[$i] = '@{[Elatin1::fc qq<';
4890             $left_e++;
4891 24         40 }
4892 0         0 elsif ($char[$i] eq '\Q') {
4893             $char[$i] = '@{[CORE::quotemeta qq<';
4894             $left_e++;
4895 0 50       0 }
4896 24         32 elsif ($char[$i] eq '\E') {
4897 24         33 if ($right_e < $left_e) {
4898             $char[$i] = '>]}';
4899             $right_e++;
4900 24         38 }
4901             else {
4902             $char[$i] = '';
4903             }
4904 0         0 }
4905 0 0       0 elsif ($char[$i] eq '\Q') {
4906 0         0 while (1) {
4907             if (++$i > $#char) {
4908 0 0       0 last;
4909 0         0 }
4910             if ($char[$i] eq '\E') {
4911             last;
4912             }
4913             }
4914             }
4915             elsif ($char[$i] eq '\E') {
4916             }
4917              
4918             # $0 --> $0
4919             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
4920             }
4921             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
4922             }
4923              
4924             # $$ --> $$
4925             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
4926             }
4927              
4928             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4929 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4930             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
4931             $char[$i] = e_capture($1);
4932 205         389 }
4933             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
4934             $char[$i] = e_capture($1);
4935             }
4936              
4937 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4938             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
4939             $char[$i] = e_capture($1.'->'.$2);
4940             }
4941              
4942 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4943             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
4944             $char[$i] = e_capture($1.'->'.$2);
4945             }
4946              
4947 0         0 # $$foo
4948             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
4949             $char[$i] = e_capture($1);
4950             }
4951              
4952 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
4953             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
4954             $char[$i] = '@{[Elatin1::PREMATCH()]}';
4955             }
4956              
4957 44         106 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
4958             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
4959             $char[$i] = '@{[Elatin1::MATCH()]}';
4960             }
4961              
4962 45         115 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
4963             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
4964             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
4965             }
4966              
4967             # ${ foo } --> ${ foo }
4968             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
4969             }
4970              
4971 33         86 # ${ ... }
4972             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
4973             $char[$i] = e_capture($1);
4974             }
4975             }
4976 0 50       0  
4977 4030         9099 # return string
4978             if ($left_e > $right_e) {
4979 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
4980             }
4981             return join '', $ope, $delimiter, @char, $end_delimiter;
4982             }
4983              
4984             #
4985             # escape qw string (qw//)
4986 4030     16 0 31273 #
4987             sub e_qw {
4988 16         644 my($ope,$delimiter,$end_delimiter,$string) = @_;
4989              
4990             $slash = 'div';
4991 16         40  
  16         240  
4992 483 50       1273 # choice again delimiter
    0          
    0          
    0          
    0          
4993 16         118 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
4994             if (not $octet{$end_delimiter}) {
4995             return join '', $ope, $delimiter, $string, $end_delimiter;
4996 16         142 }
4997             elsif (not $octet{')'}) {
4998             return join '', $ope, '(', $string, ')';
4999 0         0 }
5000             elsif (not $octet{'}'}) {
5001             return join '', $ope, '{', $string, '}';
5002 0         0 }
5003             elsif (not $octet{']'}) {
5004             return join '', $ope, '[', $string, ']';
5005 0         0 }
5006             elsif (not $octet{'>'}) {
5007             return join '', $ope, '<', $string, '>';
5008 0         0 }
5009 0 0       0 else {
5010 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5011             if (not $octet{$char}) {
5012             return join '', $ope, $char, $string, $char;
5013             }
5014             }
5015             }
5016 0         0  
5017 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5018 0         0 my @string = CORE::split(/\s+/, $string);
5019 0         0 for my $string (@string) {
5020 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5021 0         0 for my $octet (@octet) {
5022             if ($octet =~ /\A (['\\]) \z/oxms) {
5023             $octet = '\\' . $1;
5024 0         0 }
5025             }
5026 0         0 $string = join '', @octet;
  0         0  
5027             }
5028             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5029             }
5030              
5031             #
5032             # escape here document (<<"HEREDOC", <
5033 0     93 0 0 #
5034             sub e_heredoc {
5035 93         235 my($string) = @_;
5036              
5037 93         146 $slash = 'm//';
5038              
5039 93         293 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5040 93         138  
5041             my $left_e = 0;
5042             my $right_e = 0;
5043 93         120  
5044             # split regexp
5045             my @char = $string =~ /\G((?>
5046             [^\\\$] |
5047             \\x\{ (?>[0-9A-Fa-f]+) \} |
5048             \\o\{ (?>[0-7]+) \} |
5049             \\N\{ (?>[^0-9\}][^\}]*) \} |
5050             \\ $q_char |
5051             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5052             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5053             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5054             \$ (?>\s* [0-9]+) |
5055             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5056             \$ \$ (?![\w\{]) |
5057             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5058             $q_char
5059 93         7969 ))/oxmsg;
5060              
5061             for (my $i=0; $i <= $#char; $i++) {
5062 93 50 33     388  
    50 33        
    100          
    100          
    50          
5063 3177         9347 # "\L\u" --> "\u\L"
5064             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5065             @char[$i,$i+1] = @char[$i+1,$i];
5066             }
5067              
5068 0         0 # "\U\l" --> "\l\U"
5069             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5070             @char[$i,$i+1] = @char[$i+1,$i];
5071             }
5072              
5073 0         0 # octal escape sequence
5074             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5075             $char[$i] = Elatin1::octchr($1);
5076             }
5077              
5078 1         3 # hexadecimal escape sequence
5079             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5080             $char[$i] = Elatin1::hexchr($1);
5081             }
5082              
5083 1         4 # \N{CHARNAME} --> N{CHARNAME}
5084             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5085             $char[$i] = $1;
5086 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          
5087              
5088             if (0) {
5089             }
5090 3177         25054  
5091 0 0       0 # \u \l \U \L \F \Q \E
5092 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5093             if ($right_e < $left_e) {
5094             $char[$i] = '\\' . $char[$i];
5095             }
5096 0         0 }
5097 0         0 elsif ($char[$i] eq '\u') {
5098             $char[$i] = '@{[Elatin1::ucfirst qq<';
5099             $left_e++;
5100 0         0 }
5101 0         0 elsif ($char[$i] eq '\l') {
5102             $char[$i] = '@{[Elatin1::lcfirst qq<';
5103             $left_e++;
5104 0         0 }
5105 0         0 elsif ($char[$i] eq '\U') {
5106             $char[$i] = '@{[Elatin1::uc qq<';
5107             $left_e++;
5108 0         0 }
5109 0         0 elsif ($char[$i] eq '\L') {
5110             $char[$i] = '@{[Elatin1::lc qq<';
5111             $left_e++;
5112 0         0 }
5113 0         0 elsif ($char[$i] eq '\F') {
5114             $char[$i] = '@{[Elatin1::fc qq<';
5115             $left_e++;
5116 0         0 }
5117 0         0 elsif ($char[$i] eq '\Q') {
5118             $char[$i] = '@{[CORE::quotemeta qq<';
5119             $left_e++;
5120 0 0       0 }
5121 0         0 elsif ($char[$i] eq '\E') {
5122 0         0 if ($right_e < $left_e) {
5123             $char[$i] = '>]}';
5124             $right_e++;
5125 0         0 }
5126             else {
5127             $char[$i] = '';
5128             }
5129 0         0 }
5130 0 0       0 elsif ($char[$i] eq '\Q') {
5131 0         0 while (1) {
5132             if (++$i > $#char) {
5133 0 0       0 last;
5134 0         0 }
5135             if ($char[$i] eq '\E') {
5136             last;
5137             }
5138             }
5139             }
5140             elsif ($char[$i] eq '\E') {
5141             }
5142              
5143             # $0 --> $0
5144             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5145             }
5146             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5147             }
5148              
5149             # $$ --> $$
5150             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5151             }
5152              
5153             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5154 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5155             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5156             $char[$i] = e_capture($1);
5157 0         0 }
5158             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5159             $char[$i] = e_capture($1);
5160             }
5161              
5162 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5163             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5164             $char[$i] = e_capture($1.'->'.$2);
5165             }
5166              
5167 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5168             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5169             $char[$i] = e_capture($1.'->'.$2);
5170             }
5171              
5172 0         0 # $$foo
5173             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5174             $char[$i] = e_capture($1);
5175             }
5176              
5177 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
5178             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5179             $char[$i] = '@{[Elatin1::PREMATCH()]}';
5180             }
5181              
5182 8         44 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
5183             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5184             $char[$i] = '@{[Elatin1::MATCH()]}';
5185             }
5186              
5187 8         49 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
5188             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5189             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
5190             }
5191              
5192             # ${ foo } --> ${ foo }
5193             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5194             }
5195              
5196 6         34 # ${ ... }
5197             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5198             $char[$i] = e_capture($1);
5199             }
5200             }
5201 0 50       0  
5202 93         330 # return string
5203             if ($left_e > $right_e) {
5204 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5205             }
5206             return join '', @char;
5207             }
5208              
5209             #
5210             # escape regexp (m//, qr//)
5211 93     652 0 679 #
5212 652   100     2982 sub e_qr {
5213             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5214 652         2520 $modifier ||= '';
5215 652 50       1105  
5216 652         1480 $modifier =~ tr/p//d;
5217 0         0 if ($modifier =~ /([adlu])/oxms) {
5218 0 0       0 my $line = 0;
5219 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5220 0         0 if ($filename ne __FILE__) {
5221             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5222             last;
5223 0         0 }
5224             }
5225             die qq{Unsupported modifier "$1" used at line $line.\n};
5226 0         0 }
5227              
5228             $slash = 'div';
5229 652 100       1035  
    100          
5230 652         1931 # literal null string pattern
5231 8         9 if ($string eq '') {
5232 8         9 $modifier =~ tr/bB//d;
5233             $modifier =~ tr/i//d;
5234             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5235             }
5236              
5237             # /b /B modifier
5238             elsif ($modifier =~ tr/bB//d) {
5239 8 50       36  
5240 2         5 # choice again delimiter
5241 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5242 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5243 0         0 my %octet = map {$_ => 1} @char;
5244 0         0 if (not $octet{')'}) {
5245             $delimiter = '(';
5246             $end_delimiter = ')';
5247 0         0 }
5248 0         0 elsif (not $octet{'}'}) {
5249             $delimiter = '{';
5250             $end_delimiter = '}';
5251 0         0 }
5252 0         0 elsif (not $octet{']'}) {
5253             $delimiter = '[';
5254             $end_delimiter = ']';
5255 0         0 }
5256 0         0 elsif (not $octet{'>'}) {
5257             $delimiter = '<';
5258             $end_delimiter = '>';
5259 0         0 }
5260 0 0       0 else {
5261 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5262 0         0 if (not $octet{$char}) {
5263 0         0 $delimiter = $char;
5264             $end_delimiter = $char;
5265             last;
5266             }
5267             }
5268             }
5269 0 50 33     0 }
5270 2         11  
5271             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5272             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5273 0         0 }
5274             else {
5275             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5276             }
5277 2 100       10 }
5278 642         1430  
5279             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5280             my $metachar = qr/[\@\\|[\]{^]/oxms;
5281 642         2183  
5282             # split regexp
5283             my @char = $string =~ /\G((?>
5284             [^\\\$\@\[\(] |
5285             \\x (?>[0-9A-Fa-f]{1,2}) |
5286             \\ (?>[0-7]{2,3}) |
5287             \\c [\x40-\x5F] |
5288             \\x\{ (?>[0-9A-Fa-f]+) \} |
5289             \\o\{ (?>[0-7]+) \} |
5290             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5291             \\ $q_char |
5292             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5293             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5294             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5295             [\$\@] $qq_variable |
5296             \$ (?>\s* [0-9]+) |
5297             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5298             \$ \$ (?![\w\{]) |
5299             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5300             \[\^ |
5301             \[\: (?>[a-z]+) :\] |
5302             \[\:\^ (?>[a-z]+) :\] |
5303             \(\? |
5304             $q_char
5305             ))/oxmsg;
5306 642 50       71608  
5307 642         3131 # choice again delimiter
  0         0  
5308 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5309 0         0 my %octet = map {$_ => 1} @char;
5310 0         0 if (not $octet{')'}) {
5311             $delimiter = '(';
5312             $end_delimiter = ')';
5313 0         0 }
5314 0         0 elsif (not $octet{'}'}) {
5315             $delimiter = '{';
5316             $end_delimiter = '}';
5317 0         0 }
5318 0         0 elsif (not $octet{']'}) {
5319             $delimiter = '[';
5320             $end_delimiter = ']';
5321 0         0 }
5322 0         0 elsif (not $octet{'>'}) {
5323             $delimiter = '<';
5324             $end_delimiter = '>';
5325 0         0 }
5326 0 0       0 else {
5327 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5328 0         0 if (not $octet{$char}) {
5329 0         0 $delimiter = $char;
5330             $end_delimiter = $char;
5331             last;
5332             }
5333             }
5334             }
5335 0         0 }
5336 642         962  
5337 642         847 my $left_e = 0;
5338             my $right_e = 0;
5339             for (my $i=0; $i <= $#char; $i++) {
5340 642 50 66     1655  
    50 66        
    100          
    100          
    100          
    100          
5341 1872         9442 # "\L\u" --> "\u\L"
5342             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5343             @char[$i,$i+1] = @char[$i+1,$i];
5344             }
5345              
5346 0         0 # "\U\l" --> "\l\U"
5347             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5348             @char[$i,$i+1] = @char[$i+1,$i];
5349             }
5350              
5351 0         0 # octal escape sequence
5352             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5353             $char[$i] = Elatin1::octchr($1);
5354             }
5355              
5356 1         3 # hexadecimal escape sequence
5357             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5358             $char[$i] = Elatin1::hexchr($1);
5359             }
5360              
5361             # \b{...} --> b\{...}
5362             # \B{...} --> B\{...}
5363             # \N{CHARNAME} --> N\{CHARNAME}
5364             # \p{PROPERTY} --> p\{PROPERTY}
5365 1         3 # \P{PROPERTY} --> P\{PROPERTY}
5366             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5367             $char[$i] = $1 . '\\' . $2;
5368             }
5369              
5370 6         18 # \p, \P, \X --> p, P, X
5371             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5372             $char[$i] = $1;
5373 4 100 100     11 }
    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          
5374              
5375             if (0) {
5376             }
5377 1872         5084  
5378 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5379 6         106 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5380             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)) {
5381             $char[$i] .= join '', splice @char, $i+1, 3;
5382 0         0 }
5383             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)) {
5384             $char[$i] .= join '', splice @char, $i+1, 2;
5385 0         0 }
5386             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)) {
5387             $char[$i] .= join '', splice @char, $i+1, 1;
5388             }
5389             }
5390              
5391 0         0 # open character class [...]
5392             elsif ($char[$i] eq '[') {
5393             my $left = $i;
5394              
5395             # [] make die "Unmatched [] in regexp ...\n"
5396 328 100       440 # (and so on)
5397 328         730  
5398             if ($char[$i+1] eq ']') {
5399             $i++;
5400 3         5 }
5401 328 50       376  
5402 1379         1950 while (1) {
5403             if (++$i > $#char) {
5404 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5405 1379         2035 }
5406             if ($char[$i] eq ']') {
5407             my $right = $i;
5408 328 100       411  
5409 328         1535 # [...]
  30         64  
5410             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5411             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);
5412 90         132 }
5413             else {
5414             splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
5415 298         1091 }
5416 328         576  
5417             $i = $left;
5418             last;
5419             }
5420             }
5421             }
5422              
5423 328         830 # open character class [^...]
5424             elsif ($char[$i] eq '[^') {
5425             my $left = $i;
5426              
5427             # [^] make die "Unmatched [] in regexp ...\n"
5428 74 100       97 # (and so on)
5429 74         163  
5430             if ($char[$i+1] eq ']') {
5431             $i++;
5432 4         8 }
5433 74 50       84  
5434 272         393 while (1) {
5435             if (++$i > $#char) {
5436 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5437 272         464 }
5438             if ($char[$i] eq ']') {
5439             my $right = $i;
5440 74 100       88  
5441 74         329 # [^...]
  30         63  
5442             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5443             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);
5444 90         152 }
5445             else {
5446             splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5447 44         153 }
5448 74         130  
5449             $i = $left;
5450             last;
5451             }
5452             }
5453             }
5454              
5455 74         179 # rewrite character class or escape character
5456             elsif (my $char = character_class($char[$i],$modifier)) {
5457             $char[$i] = $char;
5458             }
5459              
5460 139 50       336 # /i modifier
5461 20         108 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
5462             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
5463             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
5464 20         36 }
5465             else {
5466             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
5467             }
5468             }
5469              
5470 0 50       0 # \u \l \U \L \F \Q \E
5471 1         5 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5472             if ($right_e < $left_e) {
5473             $char[$i] = '\\' . $char[$i];
5474             }
5475 0         0 }
5476 0         0 elsif ($char[$i] eq '\u') {
5477             $char[$i] = '@{[Elatin1::ucfirst qq<';
5478             $left_e++;
5479 0         0 }
5480 0         0 elsif ($char[$i] eq '\l') {
5481             $char[$i] = '@{[Elatin1::lcfirst qq<';
5482             $left_e++;
5483 0         0 }
5484 1         3 elsif ($char[$i] eq '\U') {
5485             $char[$i] = '@{[Elatin1::uc qq<';
5486             $left_e++;
5487 1         2 }
5488 1         3 elsif ($char[$i] eq '\L') {
5489             $char[$i] = '@{[Elatin1::lc qq<';
5490             $left_e++;
5491 1         4 }
5492 18         32 elsif ($char[$i] eq '\F') {
5493             $char[$i] = '@{[Elatin1::fc qq<';
5494             $left_e++;
5495 18         37 }
5496 1         3 elsif ($char[$i] eq '\Q') {
5497             $char[$i] = '@{[CORE::quotemeta qq<';
5498             $left_e++;
5499 1 50       3 }
5500 21         38 elsif ($char[$i] eq '\E') {
5501 21         23 if ($right_e < $left_e) {
5502             $char[$i] = '>]}';
5503             $right_e++;
5504 21         42 }
5505             else {
5506             $char[$i] = '';
5507             }
5508 0         0 }
5509 0 0       0 elsif ($char[$i] eq '\Q') {
5510 0         0 while (1) {
5511             if (++$i > $#char) {
5512 0 0       0 last;
5513 0         0 }
5514             if ($char[$i] eq '\E') {
5515             last;
5516             }
5517             }
5518             }
5519             elsif ($char[$i] eq '\E') {
5520             }
5521              
5522 0 0       0 # $0 --> $0
5523 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5524             if ($ignorecase) {
5525             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5526             }
5527 0 0       0 }
5528 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5529             if ($ignorecase) {
5530             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5531             }
5532             }
5533              
5534             # $$ --> $$
5535             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5536             }
5537              
5538             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5539 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5540 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5541 0         0 $char[$i] = e_capture($1);
5542             if ($ignorecase) {
5543             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5544             }
5545 0         0 }
5546 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5547 0         0 $char[$i] = e_capture($1);
5548             if ($ignorecase) {
5549             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5550             }
5551             }
5552              
5553 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5554 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) {
5555 0         0 $char[$i] = e_capture($1.'->'.$2);
5556             if ($ignorecase) {
5557             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5558             }
5559             }
5560              
5561 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5562 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) {
5563 0         0 $char[$i] = e_capture($1.'->'.$2);
5564             if ($ignorecase) {
5565             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5566             }
5567             }
5568              
5569 0         0 # $$foo
5570 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5571 0         0 $char[$i] = e_capture($1);
5572             if ($ignorecase) {
5573             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5574             }
5575             }
5576              
5577 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
5578 8         20 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5579             if ($ignorecase) {
5580             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::PREMATCH())]}';
5581 0         0 }
5582             else {
5583             $char[$i] = '@{[Elatin1::PREMATCH()]}';
5584             }
5585             }
5586              
5587 8 50       22 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
5588 8         18 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5589             if ($ignorecase) {
5590             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::MATCH())]}';
5591 0         0 }
5592             else {
5593             $char[$i] = '@{[Elatin1::MATCH()]}';
5594             }
5595             }
5596              
5597 8 50       26 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
5598 6         17 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5599             if ($ignorecase) {
5600             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::POSTMATCH())]}';
5601 0         0 }
5602             else {
5603             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
5604             }
5605             }
5606              
5607 6 0       18 # ${ foo }
5608 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) {
5609             if ($ignorecase) {
5610             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5611             }
5612             }
5613              
5614 0         0 # ${ ... }
5615 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5616 0         0 $char[$i] = e_capture($1);
5617             if ($ignorecase) {
5618             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5619             }
5620             }
5621              
5622 0         0 # $scalar or @array
5623 21 100       51 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
5624 21         57 $char[$i] = e_string($char[$i]);
5625             if ($ignorecase) {
5626             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
5627             }
5628             }
5629              
5630 11 100 33     35 # quote character before ? + * {
    50          
5631             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
5632             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
5633 138         912 }
5634 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5635 0         0 my $char = $char[$i-1];
5636             if ($char[$i] eq '{') {
5637             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
5638 0         0 }
5639             else {
5640             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
5641             }
5642 0         0 }
5643             else {
5644             $char[$i-1] = '(?:' . $char[$i-1] . ')';
5645             }
5646             }
5647             }
5648 127         466  
5649 642 50       1068 # make regexp string
5650 642 0 0     1336 $modifier =~ tr/i//d;
5651 0         0 if ($left_e > $right_e) {
5652             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5653             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
5654 0         0 }
5655             else {
5656             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
5657 0 50 33     0 }
5658 642         3233 }
5659             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5660             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
5661 0         0 }
5662             else {
5663             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5664             }
5665             }
5666              
5667             #
5668             # double quote stuff
5669 642     180 0 5051 #
5670             sub qq_stuff {
5671             my($delimiter,$end_delimiter,$stuff) = @_;
5672 180 100       259  
5673 180         330 # scalar variable or array variable
5674             if ($stuff =~ /\A [\$\@] /oxms) {
5675             return $stuff;
5676             }
5677 100         317  
  80         170  
5678 80         223 # quote by delimiter
5679 80 50       182 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
5680 80 50       122 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5681 80 50       125 next if $char eq $delimiter;
5682 80         139 next if $char eq $end_delimiter;
5683             if (not $octet{$char}) {
5684             return join '', 'qq', $char, $stuff, $char;
5685 80         369 }
5686             }
5687             return join '', 'qq', '<', $stuff, '>';
5688             }
5689              
5690             #
5691             # escape regexp (m'', qr'', and m''b, qr''b)
5692 0     10 0 0 #
5693 10   50     40 sub e_qr_q {
5694             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5695 10         39 $modifier ||= '';
5696 10 50       16  
5697 10         48 $modifier =~ tr/p//d;
5698 0         0 if ($modifier =~ /([adlu])/oxms) {
5699 0 0       0 my $line = 0;
5700 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5701 0         0 if ($filename ne __FILE__) {
5702             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5703             last;
5704 0         0 }
5705             }
5706             die qq{Unsupported modifier "$1" used at line $line.\n};
5707 0         0 }
5708              
5709             $slash = 'div';
5710 10 100       16  
    50          
5711 10         25 # literal null string pattern
5712 8         10 if ($string eq '') {
5713 8         12 $modifier =~ tr/bB//d;
5714             $modifier =~ tr/i//d;
5715             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5716             }
5717              
5718 8         37 # with /b /B modifier
5719             elsif ($modifier =~ tr/bB//d) {
5720             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
5721             }
5722              
5723 0         0 # without /b /B modifier
5724             else {
5725             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
5726             }
5727             }
5728              
5729             #
5730             # escape regexp (m'', qr'')
5731 2     2 0 8 #
5732             sub e_qr_qt {
5733 2 50       6 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5734              
5735             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5736 2         6  
5737             # split regexp
5738             my @char = $string =~ /\G((?>
5739             [^\\\[\$\@\/] |
5740             [\x00-\xFF] |
5741             \[\^ |
5742             \[\: (?>[a-z]+) \:\] |
5743             \[\:\^ (?>[a-z]+) \:\] |
5744             [\$\@\/] |
5745             \\ (?:$q_char) |
5746             (?:$q_char)
5747             ))/oxmsg;
5748 2         61  
5749 2 50 33     9 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
5750             for (my $i=0; $i <= $#char; $i++) {
5751             if (0) {
5752             }
5753 2         18  
5754 0         0 # open character class [...]
5755 0 0       0 elsif ($char[$i] eq '[') {
5756 0         0 my $left = $i;
5757             if ($char[$i+1] eq ']') {
5758 0         0 $i++;
5759 0 0       0 }
5760 0         0 while (1) {
5761             if (++$i > $#char) {
5762 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
5763 0         0 }
5764             if ($char[$i] eq ']') {
5765             my $right = $i;
5766 0         0  
5767             # [...]
5768 0         0 splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
5769 0         0  
5770             $i = $left;
5771             last;
5772             }
5773             }
5774             }
5775              
5776 0         0 # open character class [^...]
5777 0 0       0 elsif ($char[$i] eq '[^') {
5778 0         0 my $left = $i;
5779             if ($char[$i+1] eq ']') {
5780 0         0 $i++;
5781 0 0       0 }
5782 0         0 while (1) {
5783             if (++$i > $#char) {
5784 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
5785 0         0 }
5786             if ($char[$i] eq ']') {
5787             my $right = $i;
5788 0         0  
5789             # [^...]
5790 0         0 splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5791 0         0  
5792             $i = $left;
5793             last;
5794             }
5795             }
5796             }
5797              
5798 0         0 # escape $ @ / and \
5799             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
5800             $char[$i] = '\\' . $char[$i];
5801             }
5802              
5803 0         0 # rewrite character class or escape character
5804             elsif (my $char = character_class($char[$i],$modifier)) {
5805             $char[$i] = $char;
5806             }
5807              
5808 0 0       0 # /i modifier
5809 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
5810             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
5811             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
5812 0         0 }
5813             else {
5814             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
5815             }
5816             }
5817              
5818 0 0       0 # quote character before ? + * {
5819             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
5820             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
5821 0         0 }
5822             else {
5823             $char[$i-1] = '(?:' . $char[$i-1] . ')';
5824             }
5825             }
5826 0         0 }
5827 2         6  
5828             $delimiter = '/';
5829 2         3 $end_delimiter = '/';
5830 2         4  
5831             $modifier =~ tr/i//d;
5832             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5833             }
5834              
5835             #
5836             # escape regexp (m''b, qr''b)
5837 2     0 0 14 #
5838             sub e_qr_qb {
5839             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5840 0         0  
5841             # split regexp
5842             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
5843 0         0  
5844 0 0       0 # unescape character
    0          
5845             for (my $i=0; $i <= $#char; $i++) {
5846             if (0) {
5847             }
5848 0         0  
5849             # remain \\
5850             elsif ($char[$i] eq '\\\\') {
5851             }
5852              
5853 0         0 # escape $ @ / and \
5854             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
5855             $char[$i] = '\\' . $char[$i];
5856             }
5857 0         0 }
5858 0         0  
5859 0         0 $delimiter = '/';
5860             $end_delimiter = '/';
5861             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5862             }
5863              
5864             #
5865             # escape regexp (s/here//)
5866 0     76 0 0 #
5867 76   100     251 sub e_s1 {
5868             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5869 76         355 $modifier ||= '';
5870 76 50       157  
5871 76         229 $modifier =~ tr/p//d;
5872 0         0 if ($modifier =~ /([adlu])/oxms) {
5873 0 0       0 my $line = 0;
5874 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5875 0         0 if ($filename ne __FILE__) {
5876             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5877             last;
5878 0         0 }
5879             }
5880             die qq{Unsupported modifier "$1" used at line $line.\n};
5881 0         0 }
5882              
5883             $slash = 'div';
5884 76 100       139  
    50          
5885 76         258 # literal null string pattern
5886 8         10 if ($string eq '') {
5887 8         9 $modifier =~ tr/bB//d;
5888             $modifier =~ tr/i//d;
5889             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5890             }
5891              
5892             # /b /B modifier
5893             elsif ($modifier =~ tr/bB//d) {
5894 8 0       48  
5895 0         0 # choice again delimiter
5896 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5897 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5898 0         0 my %octet = map {$_ => 1} @char;
5899 0         0 if (not $octet{')'}) {
5900             $delimiter = '(';
5901             $end_delimiter = ')';
5902 0         0 }
5903 0         0 elsif (not $octet{'}'}) {
5904             $delimiter = '{';
5905             $end_delimiter = '}';
5906 0         0 }
5907 0         0 elsif (not $octet{']'}) {
5908             $delimiter = '[';
5909             $end_delimiter = ']';
5910 0         0 }
5911 0         0 elsif (not $octet{'>'}) {
5912             $delimiter = '<';
5913             $end_delimiter = '>';
5914 0         0 }
5915 0 0       0 else {
5916 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5917 0         0 if (not $octet{$char}) {
5918 0         0 $delimiter = $char;
5919             $end_delimiter = $char;
5920             last;
5921             }
5922             }
5923             }
5924 0         0 }
5925 0         0  
5926             my $prematch = '';
5927             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5928 0 100       0 }
5929 68         183  
5930             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5931             my $metachar = qr/[\@\\|[\]{^]/oxms;
5932 68         242  
5933             # split regexp
5934             my @char = $string =~ /\G((?>
5935             [^\\\$\@\[\(] |
5936             \\ (?>[1-9][0-9]*) |
5937             \\g (?>\s*) (?>[1-9][0-9]*) |
5938             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
5939             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
5940             \\x (?>[0-9A-Fa-f]{1,2}) |
5941             \\ (?>[0-7]{2,3}) |
5942             \\c [\x40-\x5F] |
5943             \\x\{ (?>[0-9A-Fa-f]+) \} |
5944             \\o\{ (?>[0-7]+) \} |
5945             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5946             \\ $q_char |
5947             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5948             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5949             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5950             [\$\@] $qq_variable |
5951             \$ (?>\s* [0-9]+) |
5952             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5953             \$ \$ (?![\w\{]) |
5954             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5955             \[\^ |
5956             \[\: (?>[a-z]+) :\] |
5957             \[\:\^ (?>[a-z]+) :\] |
5958             \(\? |
5959             $q_char
5960             ))/oxmsg;
5961 68 50       16211  
5962 68         461 # choice again delimiter
  0         0  
5963 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5964 0         0 my %octet = map {$_ => 1} @char;
5965 0         0 if (not $octet{')'}) {
5966             $delimiter = '(';
5967             $end_delimiter = ')';
5968 0         0 }
5969 0         0 elsif (not $octet{'}'}) {
5970             $delimiter = '{';
5971             $end_delimiter = '}';
5972 0         0 }
5973 0         0 elsif (not $octet{']'}) {
5974             $delimiter = '[';
5975             $end_delimiter = ']';
5976 0         0 }
5977 0         0 elsif (not $octet{'>'}) {
5978             $delimiter = '<';
5979             $end_delimiter = '>';
5980 0         0 }
5981 0 0       0 else {
5982 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5983 0         0 if (not $octet{$char}) {
5984 0         0 $delimiter = $char;
5985             $end_delimiter = $char;
5986             last;
5987             }
5988             }
5989             }
5990             }
5991 0         0  
  68         149  
5992             # count '('
5993 253         490 my $parens = grep { $_ eq '(' } @char;
5994 68         106  
5995 68         93 my $left_e = 0;
5996             my $right_e = 0;
5997             for (my $i=0; $i <= $#char; $i++) {
5998 68 50 33     199  
    50 33        
    100          
    100          
    50          
    50          
5999 195         1083 # "\L\u" --> "\u\L"
6000             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6001             @char[$i,$i+1] = @char[$i+1,$i];
6002             }
6003              
6004 0         0 # "\U\l" --> "\l\U"
6005             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6006             @char[$i,$i+1] = @char[$i+1,$i];
6007             }
6008              
6009 0         0 # octal escape sequence
6010             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6011             $char[$i] = Elatin1::octchr($1);
6012             }
6013              
6014 1         5 # hexadecimal escape sequence
6015             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6016             $char[$i] = Elatin1::hexchr($1);
6017             }
6018              
6019             # \b{...} --> b\{...}
6020             # \B{...} --> B\{...}
6021             # \N{CHARNAME} --> N\{CHARNAME}
6022             # \p{PROPERTY} --> p\{PROPERTY}
6023 1         3 # \P{PROPERTY} --> P\{PROPERTY}
6024             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6025             $char[$i] = $1 . '\\' . $2;
6026             }
6027              
6028 0         0 # \p, \P, \X --> p, P, X
6029             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6030             $char[$i] = $1;
6031 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          
6032              
6033             if (0) {
6034             }
6035 195         837  
6036 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6037 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6038             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)) {
6039             $char[$i] .= join '', splice @char, $i+1, 3;
6040 0         0 }
6041             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)) {
6042             $char[$i] .= join '', splice @char, $i+1, 2;
6043 0         0 }
6044             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)) {
6045             $char[$i] .= join '', splice @char, $i+1, 1;
6046             }
6047             }
6048              
6049 0         0 # open character class [...]
6050 13 50       20 elsif ($char[$i] eq '[') {
6051 13         38 my $left = $i;
6052             if ($char[$i+1] eq ']') {
6053 0         0 $i++;
6054 13 50       27 }
6055 58         117 while (1) {
6056             if (++$i > $#char) {
6057 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6058 58         113 }
6059             if ($char[$i] eq ']') {
6060             my $right = $i;
6061 13 50       22  
6062 13         73 # [...]
  0         0  
6063             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6064             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);
6065 0         0 }
6066             else {
6067             splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
6068 13         58 }
6069 13         29  
6070             $i = $left;
6071             last;
6072             }
6073             }
6074             }
6075              
6076 13         36 # open character class [^...]
6077 0 0       0 elsif ($char[$i] eq '[^') {
6078 0         0 my $left = $i;
6079             if ($char[$i+1] eq ']') {
6080 0         0 $i++;
6081 0 0       0 }
6082 0         0 while (1) {
6083             if (++$i > $#char) {
6084 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6085 0         0 }
6086             if ($char[$i] eq ']') {
6087             my $right = $i;
6088 0 0       0  
6089 0         0 # [^...]
  0         0  
6090             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6091             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);
6092 0         0 }
6093             else {
6094             splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6095 0         0 }
6096 0         0  
6097             $i = $left;
6098             last;
6099             }
6100             }
6101             }
6102              
6103 0         0 # rewrite character class or escape character
6104             elsif (my $char = character_class($char[$i],$modifier)) {
6105             $char[$i] = $char;
6106             }
6107              
6108 7 50       14 # /i modifier
6109 3         6 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
6110             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
6111             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
6112 3         5 }
6113             else {
6114             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
6115             }
6116             }
6117              
6118 0 0       0 # \u \l \U \L \F \Q \E
6119 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6120             if ($right_e < $left_e) {
6121             $char[$i] = '\\' . $char[$i];
6122             }
6123 0         0 }
6124 0         0 elsif ($char[$i] eq '\u') {
6125             $char[$i] = '@{[Elatin1::ucfirst qq<';
6126             $left_e++;
6127 0         0 }
6128 0         0 elsif ($char[$i] eq '\l') {
6129             $char[$i] = '@{[Elatin1::lcfirst qq<';
6130             $left_e++;
6131 0         0 }
6132 0         0 elsif ($char[$i] eq '\U') {
6133             $char[$i] = '@{[Elatin1::uc qq<';
6134             $left_e++;
6135 0         0 }
6136 0         0 elsif ($char[$i] eq '\L') {
6137             $char[$i] = '@{[Elatin1::lc qq<';
6138             $left_e++;
6139 0         0 }
6140 0         0 elsif ($char[$i] eq '\F') {
6141             $char[$i] = '@{[Elatin1::fc qq<';
6142             $left_e++;
6143 0         0 }
6144 0         0 elsif ($char[$i] eq '\Q') {
6145             $char[$i] = '@{[CORE::quotemeta qq<';
6146             $left_e++;
6147 0 0       0 }
6148 0         0 elsif ($char[$i] eq '\E') {
6149 0         0 if ($right_e < $left_e) {
6150             $char[$i] = '>]}';
6151             $right_e++;
6152 0         0 }
6153             else {
6154             $char[$i] = '';
6155             }
6156 0         0 }
6157 0 0       0 elsif ($char[$i] eq '\Q') {
6158 0         0 while (1) {
6159             if (++$i > $#char) {
6160 0 0       0 last;
6161 0         0 }
6162             if ($char[$i] eq '\E') {
6163             last;
6164             }
6165             }
6166             }
6167             elsif ($char[$i] eq '\E') {
6168             }
6169              
6170             # \0 --> \0
6171             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6172             }
6173              
6174             # \g{N}, \g{-N}
6175              
6176             # P.108 Using Simple Patterns
6177             # in Chapter 7: In the World of Regular Expressions
6178             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6179              
6180             # P.221 Capturing
6181             # in Chapter 5: Pattern Matching
6182             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6183              
6184             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6185             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6186             }
6187              
6188             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6189             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6190             }
6191              
6192             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6193             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6194             }
6195              
6196             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6197             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6198             }
6199              
6200 0 0       0 # $0 --> $0
6201 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6202             if ($ignorecase) {
6203             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6204             }
6205 0 0       0 }
6206 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6207             if ($ignorecase) {
6208             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6209             }
6210             }
6211              
6212             # $$ --> $$
6213             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6214             }
6215              
6216             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6217 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6218 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6219 0         0 $char[$i] = e_capture($1);
6220             if ($ignorecase) {
6221             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6222             }
6223 0         0 }
6224 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6225 0         0 $char[$i] = e_capture($1);
6226             if ($ignorecase) {
6227             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6228             }
6229             }
6230              
6231 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6232 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) {
6233 0         0 $char[$i] = e_capture($1.'->'.$2);
6234             if ($ignorecase) {
6235             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6236             }
6237             }
6238              
6239 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6240 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) {
6241 0         0 $char[$i] = e_capture($1.'->'.$2);
6242             if ($ignorecase) {
6243             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6244             }
6245             }
6246              
6247 0         0 # $$foo
6248 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6249 0         0 $char[$i] = e_capture($1);
6250             if ($ignorecase) {
6251             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6252             }
6253             }
6254              
6255 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
6256 4         15 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6257             if ($ignorecase) {
6258             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::PREMATCH())]}';
6259 0         0 }
6260             else {
6261             $char[$i] = '@{[Elatin1::PREMATCH()]}';
6262             }
6263             }
6264              
6265 4 50       13 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
6266 4         15 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6267             if ($ignorecase) {
6268             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::MATCH())]}';
6269 0         0 }
6270             else {
6271             $char[$i] = '@{[Elatin1::MATCH()]}';
6272             }
6273             }
6274              
6275 4 50       12 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
6276 3         11 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6277             if ($ignorecase) {
6278             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::POSTMATCH())]}';
6279 0         0 }
6280             else {
6281             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
6282             }
6283             }
6284              
6285 3 0       12 # ${ foo }
6286 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) {
6287             if ($ignorecase) {
6288             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6289             }
6290             }
6291              
6292 0         0 # ${ ... }
6293 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6294 0         0 $char[$i] = e_capture($1);
6295             if ($ignorecase) {
6296             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6297             }
6298             }
6299              
6300 0         0 # $scalar or @array
6301 4 50       16 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6302 4         64 $char[$i] = e_string($char[$i]);
6303             if ($ignorecase) {
6304             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6305             }
6306             }
6307              
6308 0 50       0 # quote character before ? + * {
6309             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6310             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6311 13         62 }
6312             else {
6313             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6314             }
6315             }
6316             }
6317 13         61  
6318 68         151 # make regexp string
6319 68 50       118 my $prematch = '';
6320 68         206 $modifier =~ tr/i//d;
6321             if ($left_e > $right_e) {
6322 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6323             }
6324             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6325             }
6326              
6327             #
6328             # escape regexp (s'here'' or s'here''b)
6329 68     21 0 848 #
6330 21   100     49 sub e_s1_q {
6331             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6332 21         68 $modifier ||= '';
6333 21 50       28  
6334 21         43 $modifier =~ tr/p//d;
6335 0         0 if ($modifier =~ /([adlu])/oxms) {
6336 0 0       0 my $line = 0;
6337 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6338 0         0 if ($filename ne __FILE__) {
6339             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6340             last;
6341 0         0 }
6342             }
6343             die qq{Unsupported modifier "$1" used at line $line.\n};
6344 0         0 }
6345              
6346             $slash = 'div';
6347 21 100       29  
    50          
6348 21         57 # literal null string pattern
6349 8         9 if ($string eq '') {
6350 8         10 $modifier =~ tr/bB//d;
6351             $modifier =~ tr/i//d;
6352             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6353             }
6354              
6355 8         45 # with /b /B modifier
6356             elsif ($modifier =~ tr/bB//d) {
6357             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6358             }
6359              
6360 0         0 # without /b /B modifier
6361             else {
6362             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6363             }
6364             }
6365              
6366             #
6367             # escape regexp (s'here'')
6368 13     13 0 28 #
6369             sub e_s1_qt {
6370 13 50       30 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6371              
6372             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6373 13         25  
6374             # split regexp
6375             my @char = $string =~ /\G((?>
6376             [^\\\[\$\@\/] |
6377             [\x00-\xFF] |
6378             \[\^ |
6379             \[\: (?>[a-z]+) \:\] |
6380             \[\:\^ (?>[a-z]+) \:\] |
6381             [\$\@\/] |
6382             \\ (?:$q_char) |
6383             (?:$q_char)
6384             ))/oxmsg;
6385 13         187  
6386 13 50 33     37 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6387             for (my $i=0; $i <= $#char; $i++) {
6388             if (0) {
6389             }
6390 25         133  
6391 0         0 # open character class [...]
6392 0 0       0 elsif ($char[$i] eq '[') {
6393 0         0 my $left = $i;
6394             if ($char[$i+1] eq ']') {
6395 0         0 $i++;
6396 0 0       0 }
6397 0         0 while (1) {
6398             if (++$i > $#char) {
6399 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6400 0         0 }
6401             if ($char[$i] eq ']') {
6402             my $right = $i;
6403 0         0  
6404             # [...]
6405 0         0 splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
6406 0         0  
6407             $i = $left;
6408             last;
6409             }
6410             }
6411             }
6412              
6413 0         0 # open character class [^...]
6414 0 0       0 elsif ($char[$i] eq '[^') {
6415 0         0 my $left = $i;
6416             if ($char[$i+1] eq ']') {
6417 0         0 $i++;
6418 0 0       0 }
6419 0         0 while (1) {
6420             if (++$i > $#char) {
6421 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6422 0         0 }
6423             if ($char[$i] eq ']') {
6424             my $right = $i;
6425 0         0  
6426             # [^...]
6427 0         0 splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6428 0         0  
6429             $i = $left;
6430             last;
6431             }
6432             }
6433             }
6434              
6435 0         0 # escape $ @ / and \
6436             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6437             $char[$i] = '\\' . $char[$i];
6438             }
6439              
6440 0         0 # rewrite character class or escape character
6441             elsif (my $char = character_class($char[$i],$modifier)) {
6442             $char[$i] = $char;
6443             }
6444              
6445 6 0       12 # /i modifier
6446 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
6447             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
6448             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
6449 0         0 }
6450             else {
6451             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
6452             }
6453             }
6454              
6455 0 0       0 # quote character before ? + * {
6456             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6457             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6458 0         0 }
6459             else {
6460             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6461             }
6462             }
6463 0         0 }
6464 13         25  
6465 13         20 $modifier =~ tr/i//d;
6466 13         15 $delimiter = '/';
6467 13         18 $end_delimiter = '/';
6468             my $prematch = '';
6469             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6470             }
6471              
6472             #
6473             # escape regexp (s'here''b)
6474 13     0 0 90 #
6475             sub e_s1_qb {
6476             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6477 0         0  
6478             # split regexp
6479             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6480 0         0  
6481 0 0       0 # unescape character
    0          
6482             for (my $i=0; $i <= $#char; $i++) {
6483             if (0) {
6484             }
6485 0         0  
6486             # remain \\
6487             elsif ($char[$i] eq '\\\\') {
6488             }
6489              
6490 0         0 # escape $ @ / and \
6491             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6492             $char[$i] = '\\' . $char[$i];
6493             }
6494 0         0 }
6495 0         0  
6496 0         0 $delimiter = '/';
6497 0         0 $end_delimiter = '/';
6498             my $prematch = '';
6499             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6500             }
6501              
6502             #
6503             # escape regexp (s''here')
6504 0     16 0 0 #
6505             sub e_s2_q {
6506 16         31 my($ope,$delimiter,$end_delimiter,$string) = @_;
6507              
6508 16         22 $slash = 'div';
6509 16         95  
6510 16 100       60 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
6511             for (my $i=0; $i <= $#char; $i++) {
6512             if (0) {
6513             }
6514 9         30  
6515             # not escape \\
6516             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
6517             }
6518              
6519 0         0 # escape $ @ / and \
6520             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6521             $char[$i] = '\\' . $char[$i];
6522             }
6523 5         13 }
6524              
6525             return join '', $ope, $delimiter, @char, $end_delimiter;
6526             }
6527              
6528             #
6529             # escape regexp (s/here/and here/modifier)
6530 16     97 0 48 #
6531 97   100     775 sub e_sub {
6532             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
6533 97         373 $modifier ||= '';
6534 97 50       299  
6535 97         271 $modifier =~ tr/p//d;
6536 0         0 if ($modifier =~ /([adlu])/oxms) {
6537 0 0       0 my $line = 0;
6538 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6539 0         0 if ($filename ne __FILE__) {
6540             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6541             last;
6542 0         0 }
6543             }
6544             die qq{Unsupported modifier "$1" used at line $line.\n};
6545 0 100       0 }
6546 97         234  
6547 36         41 if ($variable eq '') {
6548             $variable = '$_';
6549             $bind_operator = ' =~ ';
6550 36         50 }
6551              
6552             $slash = 'div';
6553              
6554             # P.128 Start of match (or end of previous match): \G
6555             # P.130 Advanced Use of \G with Perl
6556             # in Chapter 3: Overview of Regular Expression Features and Flavors
6557             # P.312 Iterative Matching: Scalar Context, with /g
6558             # in Chapter 7: Perl
6559             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
6560              
6561             # P.181 Where You Left Off: The \G Assertion
6562             # in Chapter 5: Pattern Matching
6563             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6564              
6565             # P.220 Where You Left Off: The \G Assertion
6566             # in Chapter 5: Pattern Matching
6567 97         145 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6568 97         141  
6569             my $e_modifier = $modifier =~ tr/e//d;
6570 97         146 my $r_modifier = $modifier =~ tr/r//d;
6571 97 50       134  
6572 97         290 my $my = '';
6573 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
6574 0         0 $my = $variable;
6575             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
6576             $variable =~ s/ = .+ \z//oxms;
6577 0         0 }
6578 97         270  
6579             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
6580             $variable_basename =~ s/ \s+ \z//oxms;
6581 97         175  
6582 97 100       136 # quote replacement string
6583 97         224 my $e_replacement = '';
6584 17         36 if ($e_modifier >= 1) {
6585             $e_replacement = e_qq('', '', '', $replacement);
6586             $e_modifier--;
6587 17 100       27 }
6588 80         213 else {
6589             if ($delimiter2 eq "'") {
6590             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
6591 16         39 }
6592             else {
6593             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
6594             }
6595 64         150 }
6596              
6597             my $sub = '';
6598 97 100       156  
6599 97 100       209 # with /r
6600             if ($r_modifier) {
6601             if (0) {
6602             }
6603 8         25  
6604 0 50       0 # s///gr without multibyte anchoring
6605             elsif ($modifier =~ /g/oxms) {
6606             $sub = sprintf(
6607             # 1 2 3 4 5
6608             q,
6609              
6610             $variable, # 1
6611             ($delimiter1 eq "'") ? # 2
6612             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6613             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6614             $s_matched, # 3
6615             $e_replacement, # 4
6616             '$Elatin1::re_r=CORE::eval $Elatin1::re_r; ' x $e_modifier, # 5
6617             );
6618             }
6619              
6620             # s///r
6621 4         16 else {
6622              
6623 4 50       8 my $prematch = q{$`};
6624              
6625             $sub = sprintf(
6626             # 1 2 3 4 5 6 7
6627             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Elatin1::re_r=%s; %s"%s$Elatin1::re_r$'" } : %s>,
6628              
6629             $variable, # 1
6630             ($delimiter1 eq "'") ? # 2
6631             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6632             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6633             $s_matched, # 3
6634             $e_replacement, # 4
6635             '$Elatin1::re_r=CORE::eval $Elatin1::re_r; ' x $e_modifier, # 5
6636             $prematch, # 6
6637             $variable, # 7
6638             );
6639             }
6640 4 50       58  
6641 8         23 # $var !~ s///r doesn't make sense
6642             if ($bind_operator =~ / !~ /oxms) {
6643             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
6644             }
6645             }
6646              
6647 0 100       0 # without /r
6648             else {
6649             if (0) {
6650             }
6651 89         630  
6652 0 100       0 # s///g without multibyte anchoring
    100          
6653             elsif ($modifier =~ /g/oxms) {
6654             $sub = sprintf(
6655             # 1 2 3 4 5 6 7 8
6656             q,
6657              
6658             $variable, # 1
6659             ($delimiter1 eq "'") ? # 2
6660             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6661             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6662             $s_matched, # 3
6663             $e_replacement, # 4
6664             '$Elatin1::re_r=CORE::eval $Elatin1::re_r; ' x $e_modifier, # 5
6665             $variable, # 6
6666             $variable, # 7
6667             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
6668             );
6669             }
6670              
6671             # s///
6672 22         80 else {
6673              
6674 67 100       180 my $prematch = q{$`};
    100          
6675              
6676             $sub = sprintf(
6677              
6678             ($bind_operator =~ / =~ /oxms) ?
6679              
6680             # 1 2 3 4 5 6 7 8
6681             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Elatin1::re_r=%s; %s%s="%s$Elatin1::re_r$'"; 1 } : undef> :
6682              
6683             # 1 2 3 4 5 6 7 8
6684             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Elatin1::re_r=%s; %s%s="%s$Elatin1::re_r$'"; undef }>,
6685              
6686             $variable, # 1
6687             $bind_operator, # 2
6688             ($delimiter1 eq "'") ? # 3
6689             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6690             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6691             $s_matched, # 4
6692             $e_replacement, # 5
6693             '$Elatin1::re_r=CORE::eval $Elatin1::re_r; ' x $e_modifier, # 6
6694             $variable, # 7
6695             $prematch, # 8
6696             );
6697             }
6698             }
6699 67 50       435  
6700 97         338 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
6701             if ($my ne '') {
6702             $sub = "($my, $sub)[1]";
6703             }
6704 0         0  
6705 97         167 # clear s/// variable
6706             $sub_variable = '';
6707 97         559 $bind_operator = '';
6708              
6709             return $sub;
6710             }
6711              
6712             #
6713             # escape regexp of split qr//
6714 97     74 0 694 #
6715 74   100     722 sub e_split {
6716             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6717 74         355 $modifier ||= '';
6718 74 50       135  
6719 74         350 $modifier =~ tr/p//d;
6720 0         0 if ($modifier =~ /([adlu])/oxms) {
6721 0 0       0 my $line = 0;
6722 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6723 0         0 if ($filename ne __FILE__) {
6724             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6725             last;
6726 0         0 }
6727             }
6728             die qq{Unsupported modifier "$1" used at line $line.\n};
6729 0         0 }
6730              
6731             $slash = 'div';
6732 74 50       137  
6733 74         151 # /b /B modifier
6734             if ($modifier =~ tr/bB//d) {
6735             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
6736 0 50       0 }
6737 74         177  
6738             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6739             my $metachar = qr/[\@\\|[\]{^]/oxms;
6740 74         315  
6741             # split regexp
6742             my @char = $string =~ /\G((?>
6743             [^\\\$\@\[\(] |
6744             \\x (?>[0-9A-Fa-f]{1,2}) |
6745             \\ (?>[0-7]{2,3}) |
6746             \\c [\x40-\x5F] |
6747             \\x\{ (?>[0-9A-Fa-f]+) \} |
6748             \\o\{ (?>[0-7]+) \} |
6749             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6750             \\ $q_char |
6751             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6752             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6753             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6754             [\$\@] $qq_variable |
6755             \$ (?>\s* [0-9]+) |
6756             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6757             \$ \$ (?![\w\{]) |
6758             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6759             \[\^ |
6760             \[\: (?>[a-z]+) :\] |
6761             \[\:\^ (?>[a-z]+) :\] |
6762             \(\? |
6763             $q_char
6764 74         8734 ))/oxmsg;
6765 74         236  
6766 74         111 my $left_e = 0;
6767             my $right_e = 0;
6768             for (my $i=0; $i <= $#char; $i++) {
6769 74 50 33     279  
    50 33        
    100          
    100          
    50          
    50          
6770 249         1205 # "\L\u" --> "\u\L"
6771             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6772             @char[$i,$i+1] = @char[$i+1,$i];
6773             }
6774              
6775 0         0 # "\U\l" --> "\l\U"
6776             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6777             @char[$i,$i+1] = @char[$i+1,$i];
6778             }
6779              
6780 0         0 # octal escape sequence
6781             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6782             $char[$i] = Elatin1::octchr($1);
6783             }
6784              
6785 1         4 # hexadecimal escape sequence
6786             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6787             $char[$i] = Elatin1::hexchr($1);
6788             }
6789              
6790             # \b{...} --> b\{...}
6791             # \B{...} --> B\{...}
6792             # \N{CHARNAME} --> N\{CHARNAME}
6793             # \p{PROPERTY} --> p\{PROPERTY}
6794 1         4 # \P{PROPERTY} --> P\{PROPERTY}
6795             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6796             $char[$i] = $1 . '\\' . $2;
6797             }
6798              
6799 0         0 # \p, \P, \X --> p, P, X
6800             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6801             $char[$i] = $1;
6802 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          
6803              
6804             if (0) {
6805             }
6806 249         746  
6807 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6808 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6809             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)) {
6810             $char[$i] .= join '', splice @char, $i+1, 3;
6811 0         0 }
6812             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)) {
6813             $char[$i] .= join '', splice @char, $i+1, 2;
6814 0         0 }
6815             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)) {
6816             $char[$i] .= join '', splice @char, $i+1, 1;
6817             }
6818             }
6819              
6820 0         0 # open character class [...]
6821 3 50       6 elsif ($char[$i] eq '[') {
6822 3         7 my $left = $i;
6823             if ($char[$i+1] eq ']') {
6824 0         0 $i++;
6825 3 50       4 }
6826 7         14 while (1) {
6827             if (++$i > $#char) {
6828 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6829 7         10 }
6830             if ($char[$i] eq ']') {
6831             my $right = $i;
6832 3 50       4  
6833 3         13 # [...]
  0         0  
6834             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6835             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);
6836 0         0 }
6837             else {
6838             splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
6839 3         12 }
6840 3         5  
6841             $i = $left;
6842             last;
6843             }
6844             }
6845             }
6846              
6847 3         8 # open character class [^...]
6848 0 0       0 elsif ($char[$i] eq '[^') {
6849 0         0 my $left = $i;
6850             if ($char[$i+1] eq ']') {
6851 0         0 $i++;
6852 0 0       0 }
6853 0         0 while (1) {
6854             if (++$i > $#char) {
6855 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6856 0         0 }
6857             if ($char[$i] eq ']') {
6858             my $right = $i;
6859 0 0       0  
6860 0         0 # [^...]
  0         0  
6861             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6862             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);
6863 0         0 }
6864             else {
6865             splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6866 0         0 }
6867 0         0  
6868             $i = $left;
6869             last;
6870             }
6871             }
6872             }
6873              
6874 0         0 # rewrite character class or escape character
6875             elsif (my $char = character_class($char[$i],$modifier)) {
6876             $char[$i] = $char;
6877             }
6878              
6879             # P.794 29.2.161. split
6880             # in Chapter 29: Functions
6881             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6882              
6883             # P.951 split
6884             # in Chapter 27: Functions
6885             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6886              
6887             # said "The //m modifier is assumed when you split on the pattern /^/",
6888             # but perl5.008 is not so. Therefore, this software adds //m.
6889             # (and so on)
6890              
6891 1         4 # split(m/^/) --> split(m/^/m)
6892             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
6893             $modifier .= 'm';
6894             }
6895              
6896 7 0       21 # /i modifier
6897 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
6898             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
6899             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
6900 0         0 }
6901             else {
6902             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
6903             }
6904             }
6905              
6906 0 0       0 # \u \l \U \L \F \Q \E
6907 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
6908             if ($right_e < $left_e) {
6909             $char[$i] = '\\' . $char[$i];
6910             }
6911 0         0 }
6912 0         0 elsif ($char[$i] eq '\u') {
6913             $char[$i] = '@{[Elatin1::ucfirst qq<';
6914             $left_e++;
6915 0         0 }
6916 0         0 elsif ($char[$i] eq '\l') {
6917             $char[$i] = '@{[Elatin1::lcfirst qq<';
6918             $left_e++;
6919 0         0 }
6920 0         0 elsif ($char[$i] eq '\U') {
6921             $char[$i] = '@{[Elatin1::uc qq<';
6922             $left_e++;
6923 0         0 }
6924 0         0 elsif ($char[$i] eq '\L') {
6925             $char[$i] = '@{[Elatin1::lc qq<';
6926             $left_e++;
6927 0         0 }
6928 0         0 elsif ($char[$i] eq '\F') {
6929             $char[$i] = '@{[Elatin1::fc qq<';
6930             $left_e++;
6931 0         0 }
6932 0         0 elsif ($char[$i] eq '\Q') {
6933             $char[$i] = '@{[CORE::quotemeta qq<';
6934             $left_e++;
6935 0 0       0 }
6936 0         0 elsif ($char[$i] eq '\E') {
6937 0         0 if ($right_e < $left_e) {
6938             $char[$i] = '>]}';
6939             $right_e++;
6940 0         0 }
6941             else {
6942             $char[$i] = '';
6943             }
6944 0         0 }
6945 0 0       0 elsif ($char[$i] eq '\Q') {
6946 0         0 while (1) {
6947             if (++$i > $#char) {
6948 0 0       0 last;
6949 0         0 }
6950             if ($char[$i] eq '\E') {
6951             last;
6952             }
6953             }
6954             }
6955             elsif ($char[$i] eq '\E') {
6956             }
6957              
6958 0 0       0 # $0 --> $0
6959 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6960             if ($ignorecase) {
6961             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6962             }
6963 0 0       0 }
6964 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6965             if ($ignorecase) {
6966             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6967             }
6968             }
6969              
6970             # $$ --> $$
6971             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6972             }
6973              
6974             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6975 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6976 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6977 0         0 $char[$i] = e_capture($1);
6978             if ($ignorecase) {
6979             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6980             }
6981 0         0 }
6982 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6983 0         0 $char[$i] = e_capture($1);
6984             if ($ignorecase) {
6985             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6986             }
6987             }
6988              
6989 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6990 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) {
6991 0         0 $char[$i] = e_capture($1.'->'.$2);
6992             if ($ignorecase) {
6993             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
6994             }
6995             }
6996              
6997 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6998 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) {
6999 0         0 $char[$i] = e_capture($1.'->'.$2);
7000             if ($ignorecase) {
7001             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7002             }
7003             }
7004              
7005 0         0 # $$foo
7006 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7007 0         0 $char[$i] = e_capture($1);
7008             if ($ignorecase) {
7009             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7010             }
7011             }
7012              
7013 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Elatin1::PREMATCH()
7014 12         32 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7015             if ($ignorecase) {
7016             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::PREMATCH())]}';
7017 0         0 }
7018             else {
7019             $char[$i] = '@{[Elatin1::PREMATCH()]}';
7020             }
7021             }
7022              
7023 12 50       70 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Elatin1::MATCH()
7024 12         33 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7025             if ($ignorecase) {
7026             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::MATCH())]}';
7027 0         0 }
7028             else {
7029             $char[$i] = '@{[Elatin1::MATCH()]}';
7030             }
7031             }
7032              
7033 12 50       54 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Elatin1::POSTMATCH()
7034 9         26 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7035             if ($ignorecase) {
7036             $char[$i] = '@{[Elatin1::ignorecase(Elatin1::POSTMATCH())]}';
7037 0         0 }
7038             else {
7039             $char[$i] = '@{[Elatin1::POSTMATCH()]}';
7040             }
7041             }
7042              
7043 9 0       40 # ${ foo }
7044 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) {
7045             if ($ignorecase) {
7046             $char[$i] = '@{[Elatin1::ignorecase(' . $1 . ')]}';
7047             }
7048             }
7049              
7050 0         0 # ${ ... }
7051 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7052 0         0 $char[$i] = e_capture($1);
7053             if ($ignorecase) {
7054             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7055             }
7056             }
7057              
7058 0         0 # $scalar or @array
7059 3 50       9 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7060 3         13 $char[$i] = e_string($char[$i]);
7061             if ($ignorecase) {
7062             $char[$i] = '@{[Elatin1::ignorecase(' . $char[$i] . ')]}';
7063             }
7064             }
7065              
7066 0 50       0 # quote character before ? + * {
7067             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7068             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7069 1         7 }
7070             else {
7071             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7072             }
7073             }
7074             }
7075 0         0  
7076 74 50       137 # make regexp string
7077 74         158 $modifier =~ tr/i//d;
7078             if ($left_e > $right_e) {
7079 0         0 return join '', 'Elatin1::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7080             }
7081             return join '', 'Elatin1::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7082             }
7083              
7084             #
7085             # escape regexp of split qr''
7086 74     0 0 733 #
7087 0   0       sub e_split_q {
7088             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7089 0           $modifier ||= '';
7090 0 0          
7091 0           $modifier =~ tr/p//d;
7092 0           if ($modifier =~ /([adlu])/oxms) {
7093 0 0         my $line = 0;
7094 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7095 0           if ($filename ne __FILE__) {
7096             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7097             last;
7098 0           }
7099             }
7100             die qq{Unsupported modifier "$1" used at line $line.\n};
7101 0           }
7102              
7103             $slash = 'div';
7104 0 0          
7105 0           # /b /B modifier
7106             if ($modifier =~ tr/bB//d) {
7107             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7108 0 0         }
7109              
7110             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7111 0            
7112             # split regexp
7113             my @char = $string =~ /\G((?>
7114             [^\\\[] |
7115             [\x00-\xFF] |
7116             \[\^ |
7117             \[\: (?>[a-z]+) \:\] |
7118             \[\:\^ (?>[a-z]+) \:\] |
7119             \\ (?:$q_char) |
7120             (?:$q_char)
7121             ))/oxmsg;
7122 0            
7123 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7124             for (my $i=0; $i <= $#char; $i++) {
7125             if (0) {
7126             }
7127 0            
7128 0           # open character class [...]
7129 0 0         elsif ($char[$i] eq '[') {
7130 0           my $left = $i;
7131             if ($char[$i+1] eq ']') {
7132 0           $i++;
7133 0 0         }
7134 0           while (1) {
7135             if (++$i > $#char) {
7136 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7137 0           }
7138             if ($char[$i] eq ']') {
7139             my $right = $i;
7140 0            
7141             # [...]
7142 0           splice @char, $left, $right-$left+1, Elatin1::charlist_qr(@char[$left+1..$right-1], $modifier);
7143 0            
7144             $i = $left;
7145             last;
7146             }
7147             }
7148             }
7149              
7150 0           # open character class [^...]
7151 0 0         elsif ($char[$i] eq '[^') {
7152 0           my $left = $i;
7153             if ($char[$i+1] eq ']') {
7154 0           $i++;
7155 0 0         }
7156 0           while (1) {
7157             if (++$i > $#char) {
7158 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7159 0           }
7160             if ($char[$i] eq ']') {
7161             my $right = $i;
7162 0            
7163             # [^...]
7164 0           splice @char, $left, $right-$left+1, Elatin1::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7165 0            
7166             $i = $left;
7167             last;
7168             }
7169             }
7170             }
7171              
7172 0           # rewrite character class or escape character
7173             elsif (my $char = character_class($char[$i],$modifier)) {
7174             $char[$i] = $char;
7175             }
7176              
7177 0           # split(m/^/) --> split(m/^/m)
7178             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7179             $modifier .= 'm';
7180             }
7181              
7182 0 0         # /i modifier
7183 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Elatin1::uc($char[$i]) ne Elatin1::fc($char[$i]))) {
7184             if (CORE::length(Elatin1::fc($char[$i])) == 1) {
7185             $char[$i] = '[' . Elatin1::uc($char[$i]) . Elatin1::fc($char[$i]) . ']';
7186 0           }
7187             else {
7188             $char[$i] = '(?:' . Elatin1::uc($char[$i]) . '|' . Elatin1::fc($char[$i]) . ')';
7189             }
7190             }
7191              
7192 0 0         # quote character before ? + * {
7193             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7194             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7195 0           }
7196             else {
7197             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7198             }
7199             }
7200 0           }
7201 0            
7202             $modifier =~ tr/i//d;
7203             return join '', 'Elatin1::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7204             }
7205              
7206             #
7207             # instead of Carp::carp
7208 0     0 0   #
7209 0           sub carp {
7210             my($package,$filename,$line) = caller(1);
7211             print STDERR "@_ at $filename line $line.\n";
7212             }
7213              
7214             #
7215             # instead of Carp::croak
7216 0     0 0   #
7217 0           sub croak {
7218 0           my($package,$filename,$line) = caller(1);
7219             print STDERR "@_ at $filename line $line.\n";
7220             die "\n";
7221             }
7222              
7223             #
7224             # instead of Carp::cluck
7225 0     0 0   #
7226 0           sub cluck {
7227 0           my $i = 0;
7228 0           my @cluck = ();
7229 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7230             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7231 0           $i++;
7232 0           }
7233 0           print STDERR CORE::reverse @cluck;
7234             print STDERR "\n";
7235             print STDERR @_;
7236             }
7237              
7238             #
7239             # instead of Carp::confess
7240 0     0 0   #
7241 0           sub confess {
7242 0           my $i = 0;
7243 0           my @confess = ();
7244 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7245             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7246 0           $i++;
7247 0           }
7248 0           print STDERR CORE::reverse @confess;
7249 0           print STDERR "\n";
7250             print STDERR @_;
7251             die "\n";
7252             }
7253              
7254             1;
7255              
7256             __END__