File Coverage

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


line stmt bran cond sub pod time code
1             package Egreek;
2 204     204   1205 use strict;
  204         1246  
  204         9073  
3             ######################################################################
4             #
5             # Egreek - Run-time routines for Greek.pm
6             #
7             # http://search.cpan.org/dist/Char-Greek/
8             #
9             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
10             ######################################################################
11              
12 204     204   3175 use 5.00503; # Galapagos Consensus 1998 for primetools
  204         860  
13             # use 5.008001; # Lancaster Consensus 2013 for toolchains
14              
15             # 12.3. Delaying use Until Runtime
16             # in Chapter 12. Packages, Libraries, and Modules
17             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
18             # (and so on)
19              
20             # Version numbers should be boring
21             # http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
22             # For the impatient, the disinterested or those who just want to follow
23             # a recipe, my advice for all modules is this:
24             # our $VERSION = "0.001"; # or "0.001_001" for a dev release
25             # $VERSION = eval $VERSION; # No!! because '1.10' makes '1.1'
26              
27 204     204   1286 use vars qw($VERSION);
  204         480  
  204         31061  
28             $VERSION = '1.13';
29             $VERSION = $VERSION;
30              
31             BEGIN {
32 204 50   204   1753 if ($^X =~ / jperl /oxmsi) {
33 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
34             }
35 204         468 if (CORE::ord('A') == 193) {
36             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
37             }
38 204         27474 if (CORE::ord('A') != 0x41) {
39             die __FILE__, ": is not US-ASCII script (must be US-ASCII script).\n";
40             }
41             }
42              
43             BEGIN {
44              
45             # instead of utf8.pm
46 204     204   17630 CORE::eval q{
  204     204   1404  
  204     68   378  
  204         28054  
  0         0  
  0         0  
  0         0  
  0         0  
47             no warnings qw(redefine);
48             *utf8::upgrade = sub { CORE::length $_[0] };
49             *utf8::downgrade = sub { 1 };
50             *utf8::encode = sub { };
51             *utf8::decode = sub { 1 };
52             *utf8::is_utf8 = sub { };
53             *utf8::valid = sub { 1 };
54             };
55 204 50       91046 if ($@) {
56 0         0 *utf8::upgrade = sub { CORE::length $_[0] };
  0         0  
57 0         0 *utf8::downgrade = sub { 1 };
  0         0  
58 0         0 *utf8::encode = sub { };
59 0         0 *utf8::decode = sub { 1 };
  0         0  
60 0         0 *utf8::is_utf8 = sub { };
61 0         0 *utf8::valid = sub { 1 };
  0         0  
62             }
63             }
64              
65             # instead of Symbol.pm
66 0         0 BEGIN {
67             sub gensym () {
68 0     0 0 0 return \do { local *_ };
  0         0  
69             }
70              
71             sub qualify ($$) {
72 0     0 0 0 my($name) = @_;
73              
74 0 0       0 if (ref $name) {
    0          
    0          
    0          
    0          
    0          
    0          
75 0         0 return $name;
76             }
77             elsif (Egreek::index($name,'::') >= 0) {
78 0         0 return $name;
79             }
80             elsif (Egreek::index($name,"'") >= 0) {
81 0         0 return $name;
82             }
83              
84             # special character, "^xyz"
85             elsif ($name =~ /\A \^ [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+ \z/x) {
86              
87             # RGS 2001-11-05 : translate leading ^X to control-char
88 0         0 $name =~ s{\A \^ ([ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]) }{'qq(\c'.$1.')'}xee;
  0         0  
89 0         0 return 'main::' . $name;
90             }
91              
92             # Global names
93             elsif ($name =~ /\A (?: ARGV | ARGVOUT | ENV | INC | SIG | STDERR | STDIN | STDOUT ) \z/x) {
94 0         0 return 'main::' . $name;
95             }
96              
97             # or other
98             elsif ($name =~ /\A [^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz] \z/x) {
99 0         0 return 'main::' . $name;
100             }
101              
102             elsif (defined $_[1]) {
103 0         0 return $_[1] . '::' . $name;
104             }
105             else {
106 0         0 return (caller)[0] . '::' . $name;
107             }
108             }
109              
110             sub qualify_to_ref ($;$) {
111 0 0   0 0 0 if (defined $_[1]) {
112 204     204   2119 no strict qw(refs);
  204         382  
  204         16328  
113 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
114             }
115             else {
116 204     204   2542 no strict qw(refs);
  204     0   1455  
  204         38246  
117 0         0 return \*{ qualify $_[0], (caller)[0] };
  0         0  
118             }
119             }
120             }
121              
122             # P.714 29.2.39. flock
123             # in Chapter 29: Functions
124             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
125              
126             # P.863 flock
127             # in Chapter 27: Functions
128             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
129              
130             sub LOCK_SH() {1}
131             sub LOCK_EX() {2}
132             sub LOCK_UN() {8}
133             sub LOCK_NB() {4}
134              
135             # instead of Carp.pm
136             sub carp;
137             sub croak;
138             sub cluck;
139             sub confess;
140              
141             # 6.18. Matching Multiple-Byte Characters
142             # in Chapter 6. Pattern Matching
143             # of ISBN 978-1-56592-243-3 Perl Perl Cookbook.
144             # (and so on)
145              
146             # regexp of character
147             my $your_char = q{[\x00-\xFF]};
148 204     204   1833 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  204         361  
  204         13824  
149 204     204   1156 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  204         551  
  204         415796  
150              
151             #
152             # Greek character range per length
153             #
154             my %range_tr = ();
155              
156             #
157             # Greek case conversion
158             #
159             my %lc = ();
160             @lc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
161             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
162             my %uc = ();
163             @uc{qw(a b c d e f g h i j k l m n o p q r s t u v w x y z)} =
164             qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
165             my %fc = ();
166             @fc{qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)} =
167             qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
168              
169             if (0) {
170             }
171              
172             elsif (__PACKAGE__ =~ / \b Egreek \z/oxms) {
173             %range_tr = (
174             1 => [ [0x00..0xFF],
175             ],
176             );
177              
178             %lc = (%lc,
179             "\xB6" => "\xDC", # GREEK LETTER ALPHA WITH TONOS
180             "\xB8" => "\xDD", # GREEK LETTER EPSILON WITH TONOS
181             "\xB9" => "\xDE", # GREEK LETTER ETA WITH TONOS
182             "\xBA" => "\xDF", # GREEK LETTER IOTA WITH TONOS
183             "\xBC" => "\xFC", # GREEK LETTER OMICRON WITH TONOS
184             "\xBE" => "\xFD", # GREEK LETTER UPSILON WITH TONOS
185             "\xBF" => "\xFE", # GREEK LETTER OMEGA WITH TONOS
186             "\xC1" => "\xE1", # GREEK LETTER ALPHA
187             "\xC2" => "\xE2", # GREEK LETTER BETA
188             "\xC3" => "\xE3", # GREEK LETTER GAMMA
189             "\xC4" => "\xE4", # GREEK LETTER DELTA
190             "\xC5" => "\xE5", # GREEK LETTER EPSILON
191             "\xC6" => "\xE6", # GREEK LETTER ZETA
192             "\xC7" => "\xE7", # GREEK LETTER ETA
193             "\xC8" => "\xE8", # GREEK LETTER THETA
194             "\xC9" => "\xE9", # GREEK LETTER IOTA
195             "\xCA" => "\xEA", # GREEK LETTER KAPPA
196             "\xCB" => "\xEB", # GREEK LETTER LAMDA
197             "\xCC" => "\xEC", # GREEK LETTER MU
198             "\xCD" => "\xED", # GREEK LETTER NU
199             "\xCE" => "\xEE", # GREEK LETTER XI
200             "\xCF" => "\xEF", # GREEK LETTER OMICRON
201             "\xD0" => "\xF0", # GREEK LETTER PI
202             "\xD1" => "\xF1", # GREEK LETTER RHO
203             "\xD3" => "\xF3", # GREEK LETTER SIGMA
204             "\xD4" => "\xF4", # GREEK LETTER TAU
205             "\xD5" => "\xF5", # GREEK LETTER UPSILON
206             "\xD6" => "\xF6", # GREEK LETTER PHI
207             "\xD7" => "\xF7", # GREEK LETTER CHI
208             "\xD8" => "\xF8", # GREEK LETTER PSI
209             "\xD9" => "\xF9", # GREEK LETTER OMEGA
210             "\xDA" => "\xFA", # GREEK LETTER IOTA WITH DIALYTIKA
211             "\xDB" => "\xFB", # GREEK LETTER UPSILON WITH DIALYTIKA
212             );
213              
214             %uc = (%uc,
215             "\xDC" => "\xB6", # GREEK LETTER ALPHA WITH TONOS
216             "\xDD" => "\xB8", # GREEK LETTER EPSILON WITH TONOS
217             "\xDE" => "\xB9", # GREEK LETTER ETA WITH TONOS
218             "\xDF" => "\xBA", # GREEK LETTER IOTA WITH TONOS
219             "\xE1" => "\xC1", # GREEK LETTER ALPHA
220             "\xE2" => "\xC2", # GREEK LETTER BETA
221             "\xE3" => "\xC3", # GREEK LETTER GAMMA
222             "\xE4" => "\xC4", # GREEK LETTER DELTA
223             "\xE5" => "\xC5", # GREEK LETTER EPSILON
224             "\xE6" => "\xC6", # GREEK LETTER ZETA
225             "\xE7" => "\xC7", # GREEK LETTER ETA
226             "\xE8" => "\xC8", # GREEK LETTER THETA
227             "\xE9" => "\xC9", # GREEK LETTER IOTA
228             "\xEA" => "\xCA", # GREEK LETTER KAPPA
229             "\xEB" => "\xCB", # GREEK LETTER LAMDA
230             "\xEC" => "\xCC", # GREEK LETTER MU
231             "\xED" => "\xCD", # GREEK LETTER NU
232             "\xEE" => "\xCE", # GREEK LETTER XI
233             "\xEF" => "\xCF", # GREEK LETTER OMICRON
234             "\xF0" => "\xD0", # GREEK LETTER PI
235             "\xF1" => "\xD1", # GREEK LETTER RHO
236             "\xF3" => "\xD3", # GREEK LETTER SIGMA
237             "\xF4" => "\xD4", # GREEK LETTER TAU
238             "\xF5" => "\xD5", # GREEK LETTER UPSILON
239             "\xF6" => "\xD6", # GREEK LETTER PHI
240             "\xF7" => "\xD7", # GREEK LETTER CHI
241             "\xF8" => "\xD8", # GREEK LETTER PSI
242             "\xF9" => "\xD9", # GREEK LETTER OMEGA
243             "\xFA" => "\xDA", # GREEK LETTER IOTA WITH DIALYTIKA
244             "\xFB" => "\xDB", # GREEK LETTER UPSILON WITH DIALYTIKA
245             "\xFC" => "\xBC", # GREEK LETTER OMICRON WITH TONOS
246             "\xFD" => "\xBE", # GREEK LETTER UPSILON WITH TONOS
247             "\xFE" => "\xBF", # GREEK LETTER OMEGA WITH TONOS
248             );
249              
250             %fc = (%fc,
251             "\xB6" => "\xDC", # GREEK CAPITAL LETTER ALPHA WITH TONOS --> GREEK SMALL LETTER ALPHA WITH TONOS
252             "\xB8" => "\xDD", # GREEK CAPITAL LETTER EPSILON WITH TONOS --> GREEK SMALL LETTER EPSILON WITH TONOS
253             "\xB9" => "\xDE", # GREEK CAPITAL LETTER ETA WITH TONOS --> GREEK SMALL LETTER ETA WITH TONOS
254             "\xBA" => "\xDF", # GREEK CAPITAL LETTER IOTA WITH TONOS --> GREEK SMALL LETTER IOTA WITH TONOS
255             "\xBC" => "\xFC", # GREEK CAPITAL LETTER OMICRON WITH TONOS --> GREEK SMALL LETTER OMICRON WITH TONOS
256             "\xBE" => "\xFD", # GREEK CAPITAL LETTER UPSILON WITH TONOS --> GREEK SMALL LETTER UPSILON WITH TONOS
257             "\xBF" => "\xFE", # GREEK CAPITAL LETTER OMEGA WITH TONOS --> GREEK SMALL LETTER OMEGA WITH TONOS
258             "\xC1" => "\xE1", # GREEK CAPITAL LETTER ALPHA --> GREEK SMALL LETTER ALPHA
259             "\xC2" => "\xE2", # GREEK CAPITAL LETTER BETA --> GREEK SMALL LETTER BETA
260             "\xC3" => "\xE3", # GREEK CAPITAL LETTER GAMMA --> GREEK SMALL LETTER GAMMA
261             "\xC4" => "\xE4", # GREEK CAPITAL LETTER DELTA --> GREEK SMALL LETTER DELTA
262             "\xC5" => "\xE5", # GREEK CAPITAL LETTER EPSILON --> GREEK SMALL LETTER EPSILON
263             "\xC6" => "\xE6", # GREEK CAPITAL LETTER ZETA --> GREEK SMALL LETTER ZETA
264             "\xC7" => "\xE7", # GREEK CAPITAL LETTER ETA --> GREEK SMALL LETTER ETA
265             "\xC8" => "\xE8", # GREEK CAPITAL LETTER THETA --> GREEK SMALL LETTER THETA
266             "\xC9" => "\xE9", # GREEK CAPITAL LETTER IOTA --> GREEK SMALL LETTER IOTA
267             "\xCA" => "\xEA", # GREEK CAPITAL LETTER KAPPA --> GREEK SMALL LETTER KAPPA
268             "\xCB" => "\xEB", # GREEK CAPITAL LETTER LAMDA --> GREEK SMALL LETTER LAMDA
269             "\xCC" => "\xEC", # GREEK CAPITAL LETTER MU --> GREEK SMALL LETTER MU
270             "\xCD" => "\xED", # GREEK CAPITAL LETTER NU --> GREEK SMALL LETTER NU
271             "\xCE" => "\xEE", # GREEK CAPITAL LETTER XI --> GREEK SMALL LETTER XI
272             "\xCF" => "\xEF", # GREEK CAPITAL LETTER OMICRON --> GREEK SMALL LETTER OMICRON
273             "\xD0" => "\xF0", # GREEK CAPITAL LETTER PI --> GREEK SMALL LETTER PI
274             "\xD1" => "\xF1", # GREEK CAPITAL LETTER RHO --> GREEK SMALL LETTER RHO
275             "\xD3" => "\xF3", # GREEK CAPITAL LETTER SIGMA --> GREEK SMALL LETTER SIGMA
276             "\xD4" => "\xF4", # GREEK CAPITAL LETTER TAU --> GREEK SMALL LETTER TAU
277             "\xD5" => "\xF5", # GREEK CAPITAL LETTER UPSILON --> GREEK SMALL LETTER UPSILON
278             "\xD6" => "\xF6", # GREEK CAPITAL LETTER PHI --> GREEK SMALL LETTER PHI
279             "\xD7" => "\xF7", # GREEK CAPITAL LETTER CHI --> GREEK SMALL LETTER CHI
280             "\xD8" => "\xF8", # GREEK CAPITAL LETTER PSI --> GREEK SMALL LETTER PSI
281             "\xD9" => "\xF9", # GREEK CAPITAL LETTER OMEGA --> GREEK SMALL LETTER OMEGA
282             "\xDA" => "\xFA", # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA --> GREEK SMALL LETTER IOTA WITH DIALYTIKA
283             "\xDB" => "\xFB", # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA --> GREEK SMALL LETTER UPSILON WITH DIALYTIKA
284             "\xF2" => "\xF3", # GREEK SMALL LETTER FINAL SIGMA --> GREEK SMALL LETTER SIGMA
285             );
286             }
287              
288             else {
289             croak "Don't know my package name '@{[__PACKAGE__]}'";
290             }
291              
292             #
293             # @ARGV wildcard globbing
294             #
295             sub import {
296              
297 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
298 0         0 my @argv = ();
299 0         0 for (@ARGV) {
300              
301             # has space
302 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
303 0 0       0 if (my @glob = Egreek::glob(qq{"$_"})) {
304 0         0 push @argv, @glob;
305             }
306             else {
307 0         0 push @argv, $_;
308             }
309             }
310              
311             # has wildcard metachar
312             elsif (/\A (?:$q_char)*? [*?] /oxms) {
313 0 0       0 if (my @glob = Egreek::glob($_)) {
314 0         0 push @argv, @glob;
315             }
316             else {
317 0         0 push @argv, $_;
318             }
319             }
320              
321             # no wildcard globbing
322             else {
323 0         0 push @argv, $_;
324             }
325             }
326 0         0 @ARGV = @argv;
327             }
328              
329 0         0 *Char::ord = \&Greek::ord;
330 0         0 *Char::ord_ = \&Greek::ord_;
331 0         0 *Char::reverse = \&Greek::reverse;
332 0         0 *Char::getc = \&Greek::getc;
333 0         0 *Char::length = \&Greek::length;
334 0         0 *Char::substr = \&Greek::substr;
335 0         0 *Char::index = \&Greek::index;
336 0         0 *Char::rindex = \&Greek::rindex;
337 0         0 *Char::eval = \&Greek::eval;
338 0         0 *Char::escape = \&Greek::escape;
339 0         0 *Char::escape_token = \&Greek::escape_token;
340 0         0 *Char::escape_script = \&Greek::escape_script;
341             }
342              
343             # P.230 Care with Prototypes
344             # in Chapter 6: Subroutines
345             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
346             #
347             # If you aren't careful, you can get yourself into trouble with prototypes.
348             # But if you are careful, you can do a lot of neat things with them. This is
349             # all very powerful, of course, and should only be used in moderation to make
350             # the world a better place.
351              
352             # P.332 Care with Prototypes
353             # in Chapter 7: Subroutines
354             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
355             #
356             # If you aren't careful, you can get yourself into trouble with prototypes.
357             # But if you are careful, you can do a lot of neat things with them. This is
358             # all very powerful, of course, and should only be used in moderation to make
359             # the world a better place.
360              
361             #
362             # Prototypes of subroutines
363             #
364       0     sub unimport {}
365             sub Egreek::split(;$$$);
366             sub Egreek::tr($$$$;$);
367             sub Egreek::chop(@);
368             sub Egreek::index($$;$);
369             sub Egreek::rindex($$;$);
370             sub Egreek::lcfirst(@);
371             sub Egreek::lcfirst_();
372             sub Egreek::lc(@);
373             sub Egreek::lc_();
374             sub Egreek::ucfirst(@);
375             sub Egreek::ucfirst_();
376             sub Egreek::uc(@);
377             sub Egreek::uc_();
378             sub Egreek::fc(@);
379             sub Egreek::fc_();
380             sub Egreek::ignorecase;
381             sub Egreek::classic_character_class;
382             sub Egreek::capture;
383             sub Egreek::chr(;$);
384             sub Egreek::chr_();
385             sub Egreek::glob($);
386             sub Egreek::glob_();
387              
388             sub Greek::ord(;$);
389             sub Greek::ord_();
390             sub Greek::reverse(@);
391             sub Greek::getc(;*@);
392             sub Greek::length(;$);
393             sub Greek::substr($$;$$);
394             sub Greek::index($$;$);
395             sub Greek::rindex($$;$);
396             sub Greek::escape(;$);
397              
398             #
399             # Regexp work
400             #
401 204         19247 use vars qw(
402             $re_a
403             $re_t
404             $re_n
405             $re_r
406 204     204   5137 );
  204         374  
407              
408             #
409             # Character class
410             #
411 204         2189389 use vars qw(
412             $dot
413             $dot_s
414             $eD
415             $eS
416             $eW
417             $eH
418             $eV
419             $eR
420             $eN
421             $not_alnum
422             $not_alpha
423             $not_ascii
424             $not_blank
425             $not_cntrl
426             $not_digit
427             $not_graph
428             $not_lower
429             $not_lower_i
430             $not_print
431             $not_punct
432             $not_space
433             $not_upper
434             $not_upper_i
435             $not_word
436             $not_xdigit
437             $eb
438             $eB
439 204     204   1343 );
  204         532  
440              
441             ${Egreek::dot} = qr{(?>[^\x0A])};
442             ${Egreek::dot_s} = qr{(?>[\x00-\xFF])};
443             ${Egreek::eD} = qr{(?>[^0-9])};
444              
445             # Vertical tabs are now whitespace
446             # \s in a regex now matches a vertical tab in all circumstances.
447             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
448             # ${Egreek::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
449             # ${Egreek::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
450             ${Egreek::eS} = qr{(?>[^\s])};
451              
452             ${Egreek::eW} = qr{(?>[^0-9A-Z_a-z])};
453             ${Egreek::eH} = qr{(?>[^\x09\x20])};
454             ${Egreek::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
455             ${Egreek::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
456             ${Egreek::eN} = qr{(?>[^\x0A])};
457             ${Egreek::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
458             ${Egreek::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
459             ${Egreek::not_ascii} = qr{(?>[^\x00-\x7F])};
460             ${Egreek::not_blank} = qr{(?>[^\x09\x20])};
461             ${Egreek::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
462             ${Egreek::not_digit} = qr{(?>[^\x30-\x39])};
463             ${Egreek::not_graph} = qr{(?>[^\x21-\x7F])};
464             ${Egreek::not_lower} = qr{(?>[^\x61-\x7A])};
465             ${Egreek::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
466             # ${Egreek::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
467             ${Egreek::not_print} = qr{(?>[^\x20-\x7F])};
468             ${Egreek::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
469             ${Egreek::not_space} = qr{(?>[^\s\x0B])};
470             ${Egreek::not_upper} = qr{(?>[^\x41-\x5A])};
471             ${Egreek::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
472             # ${Egreek::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
473             ${Egreek::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
474             ${Egreek::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
475             ${Egreek::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))};
476             ${Egreek::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]))};
477              
478             # avoid: Name "Egreek::foo" used only once: possible typo at here.
479             ${Egreek::dot} = ${Egreek::dot};
480             ${Egreek::dot_s} = ${Egreek::dot_s};
481             ${Egreek::eD} = ${Egreek::eD};
482             ${Egreek::eS} = ${Egreek::eS};
483             ${Egreek::eW} = ${Egreek::eW};
484             ${Egreek::eH} = ${Egreek::eH};
485             ${Egreek::eV} = ${Egreek::eV};
486             ${Egreek::eR} = ${Egreek::eR};
487             ${Egreek::eN} = ${Egreek::eN};
488             ${Egreek::not_alnum} = ${Egreek::not_alnum};
489             ${Egreek::not_alpha} = ${Egreek::not_alpha};
490             ${Egreek::not_ascii} = ${Egreek::not_ascii};
491             ${Egreek::not_blank} = ${Egreek::not_blank};
492             ${Egreek::not_cntrl} = ${Egreek::not_cntrl};
493             ${Egreek::not_digit} = ${Egreek::not_digit};
494             ${Egreek::not_graph} = ${Egreek::not_graph};
495             ${Egreek::not_lower} = ${Egreek::not_lower};
496             ${Egreek::not_lower_i} = ${Egreek::not_lower_i};
497             ${Egreek::not_print} = ${Egreek::not_print};
498             ${Egreek::not_punct} = ${Egreek::not_punct};
499             ${Egreek::not_space} = ${Egreek::not_space};
500             ${Egreek::not_upper} = ${Egreek::not_upper};
501             ${Egreek::not_upper_i} = ${Egreek::not_upper_i};
502             ${Egreek::not_word} = ${Egreek::not_word};
503             ${Egreek::not_xdigit} = ${Egreek::not_xdigit};
504             ${Egreek::eb} = ${Egreek::eb};
505             ${Egreek::eB} = ${Egreek::eB};
506              
507             #
508             # Greek split
509             #
510             sub Egreek::split(;$$$) {
511              
512             # P.794 29.2.161. split
513             # in Chapter 29: Functions
514             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
515              
516             # P.951 split
517             # in Chapter 27: Functions
518             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
519              
520 0     0 0 0 my $pattern = $_[0];
521 0         0 my $string = $_[1];
522 0         0 my $limit = $_[2];
523              
524             # if $pattern is also omitted or is the literal space, " "
525 0 0       0 if (not defined $pattern) {
526 0         0 $pattern = ' ';
527             }
528              
529             # if $string is omitted, the function splits the $_ string
530 0 0       0 if (not defined $string) {
531 0 0       0 if (defined $_) {
532 0         0 $string = $_;
533             }
534             else {
535 0         0 $string = '';
536             }
537             }
538              
539 0         0 my @split = ();
540              
541             # when string is empty
542 0 0       0 if ($string eq '') {
    0          
543              
544             # resulting list value in list context
545 0 0       0 if (wantarray) {
546 0         0 return @split;
547             }
548              
549             # count of substrings in scalar context
550             else {
551 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
552 0         0 @_ = @split;
553 0         0 return scalar @_;
554             }
555             }
556              
557             # split's first argument is more consistently interpreted
558             #
559             # After some changes earlier in v5.17, split's behavior has been simplified:
560             # if the PATTERN argument evaluates to a string containing one space, it is
561             # treated the way that a literal string containing one space once was.
562             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
563              
564             # if $pattern is also omitted or is the literal space, " ", the function splits
565             # on whitespace, /\s+/, after skipping any leading whitespace
566             # (and so on)
567              
568             elsif ($pattern eq ' ') {
569 0 0       0 if (not defined $limit) {
570 0         0 return CORE::split(' ', $string);
571             }
572             else {
573 0         0 return CORE::split(' ', $string, $limit);
574             }
575             }
576              
577             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
578 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
579              
580             # a pattern capable of matching either the null string or something longer than the
581             # null string will split the value of $string into separate characters wherever it
582             # matches the null string between characters
583             # (and so on)
584              
585 0 0       0 if ('' =~ / \A $pattern \z /xms) {
586 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
587 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
588              
589             # P.1024 Appendix W.10 Multibyte Processing
590             # of ISBN 1-56592-224-7 CJKV Information Processing
591             # (and so on)
592              
593             # the //m modifier is assumed when you split on the pattern /^/
594             # (and so on)
595              
596             # V
597 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
598              
599             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
600             # is included in the resulting list, interspersed with the fields that are ordinarily returned
601             # (and so on)
602              
603 0         0 local $@;
604 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
605 0         0 push @split, CORE::eval('$' . $digit);
606             }
607             }
608             }
609              
610             else {
611 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
612              
613             # V
614 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
615 0         0 local $@;
616 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
617 0         0 push @split, CORE::eval('$' . $digit);
618             }
619             }
620             }
621             }
622              
623             elsif ($limit > 0) {
624 0 0       0 if ('' =~ / \A $pattern \z /xms) {
625 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
626 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
627              
628             # V
629 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
630 0         0 local $@;
631 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
632 0         0 push @split, CORE::eval('$' . $digit);
633             }
634             }
635             }
636             }
637             else {
638 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
639 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
640              
641             # V
642 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
643 0         0 local $@;
644 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
645 0         0 push @split, CORE::eval('$' . $digit);
646             }
647             }
648             }
649             }
650             }
651              
652 0 0       0 if (CORE::length($string) > 0) {
653 0         0 push @split, $string;
654             }
655              
656             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
657 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
658 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
659 0         0 pop @split;
660             }
661             }
662              
663             # resulting list value in list context
664 0 0       0 if (wantarray) {
665 0         0 return @split;
666             }
667              
668             # count of substrings in scalar context
669             else {
670 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
671 0         0 @_ = @split;
672 0         0 return scalar @_;
673             }
674             }
675              
676             #
677             # get last subexpression offsets
678             #
679             sub _last_subexpression_offsets {
680 0     0   0 my $pattern = $_[0];
681              
682             # remove comment
683 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
684              
685 0         0 my $modifier = '';
686 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
687 0         0 $modifier = $1;
688 0         0 $modifier =~ s/-[A-Za-z]*//;
689             }
690              
691             # with /x modifier
692 0         0 my @char = ();
693 0 0       0 if ($modifier =~ /x/oxms) {
694 0         0 @char = $pattern =~ /\G((?>
695             [^\\\#\[\(] |
696             \\ $q_char |
697             \# (?>[^\n]*) $ |
698             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
699             \(\? |
700             $q_char
701             ))/oxmsg;
702             }
703              
704             # without /x modifier
705             else {
706 0         0 @char = $pattern =~ /\G((?>
707             [^\\\[\(] |
708             \\ $q_char |
709             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
710             \(\? |
711             $q_char
712             ))/oxmsg;
713             }
714              
715 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
716             }
717              
718             #
719             # Greek transliteration (tr///)
720             #
721             sub Egreek::tr($$$$;$) {
722              
723 0     0 0 0 my $bind_operator = $_[1];
724 0         0 my $searchlist = $_[2];
725 0         0 my $replacementlist = $_[3];
726 0   0     0 my $modifier = $_[4] || '';
727              
728 0 0       0 if ($modifier =~ /r/oxms) {
729 0 0       0 if ($bind_operator =~ / !~ /oxms) {
730 0         0 croak "Using !~ with tr///r doesn't make sense";
731             }
732             }
733              
734 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
735 0         0 my @searchlist = _charlist_tr($searchlist);
736 0         0 my @replacementlist = _charlist_tr($replacementlist);
737              
738 0         0 my %tr = ();
739 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
740 0 0       0 if (not exists $tr{$searchlist[$i]}) {
741 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
742 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
743             }
744             elsif ($modifier =~ /d/oxms) {
745 0         0 $tr{$searchlist[$i]} = '';
746             }
747             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
748 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
749             }
750             else {
751 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
752             }
753             }
754             }
755              
756 0         0 my $tr = 0;
757 0         0 my $replaced = '';
758 0 0       0 if ($modifier =~ /c/oxms) {
759 0         0 while (defined(my $char = shift @char)) {
760 0 0       0 if (not exists $tr{$char}) {
761 0 0       0 if (defined $replacementlist[0]) {
762 0         0 $replaced .= $replacementlist[0];
763             }
764 0         0 $tr++;
765 0 0       0 if ($modifier =~ /s/oxms) {
766 0   0     0 while (@char and (not exists $tr{$char[0]})) {
767 0         0 shift @char;
768 0         0 $tr++;
769             }
770             }
771             }
772             else {
773 0         0 $replaced .= $char;
774             }
775             }
776             }
777             else {
778 0         0 while (defined(my $char = shift @char)) {
779 0 0       0 if (exists $tr{$char}) {
780 0         0 $replaced .= $tr{$char};
781 0         0 $tr++;
782 0 0       0 if ($modifier =~ /s/oxms) {
783 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
784 0         0 shift @char;
785 0         0 $tr++;
786             }
787             }
788             }
789             else {
790 0         0 $replaced .= $char;
791             }
792             }
793             }
794              
795 0 0       0 if ($modifier =~ /r/oxms) {
796 0         0 return $replaced;
797             }
798             else {
799 0         0 $_[0] = $replaced;
800 0 0       0 if ($bind_operator =~ / !~ /oxms) {
801 0         0 return not $tr;
802             }
803             else {
804 0         0 return $tr;
805             }
806             }
807             }
808              
809             #
810             # Greek chop
811             #
812             sub Egreek::chop(@) {
813              
814 0     0 0 0 my $chop;
815 0 0       0 if (@_ == 0) {
816 0         0 my @char = /\G (?>$q_char) /oxmsg;
817 0         0 $chop = pop @char;
818 0         0 $_ = join '', @char;
819             }
820             else {
821 0         0 for (@_) {
822 0         0 my @char = /\G (?>$q_char) /oxmsg;
823 0         0 $chop = pop @char;
824 0         0 $_ = join '', @char;
825             }
826             }
827 0         0 return $chop;
828             }
829              
830             #
831             # Greek index by octet
832             #
833             sub Egreek::index($$;$) {
834              
835 0     0 1 0 my($str,$substr,$position) = @_;
836 0   0     0 $position ||= 0;
837 0         0 my $pos = 0;
838              
839 0         0 while ($pos < CORE::length($str)) {
840 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
841 0 0       0 if ($pos >= $position) {
842 0         0 return $pos;
843             }
844             }
845 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
846 0         0 $pos += CORE::length($1);
847             }
848             else {
849 0         0 $pos += 1;
850             }
851             }
852 0         0 return -1;
853             }
854              
855             #
856             # Greek reverse index
857             #
858             sub Egreek::rindex($$;$) {
859              
860 0     0 0 0 my($str,$substr,$position) = @_;
861 0   0     0 $position ||= CORE::length($str) - 1;
862 0         0 my $pos = 0;
863 0         0 my $rindex = -1;
864              
865 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
866 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
867 0         0 $rindex = $pos;
868             }
869 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
870 0         0 $pos += CORE::length($1);
871             }
872             else {
873 0         0 $pos += 1;
874             }
875             }
876 0         0 return $rindex;
877             }
878              
879             #
880             # Greek lower case first with parameter
881             #
882             sub Egreek::lcfirst(@) {
883 0 0   0 0 0 if (@_) {
884 0         0 my $s = shift @_;
885 0 0 0     0 if (@_ and wantarray) {
886 0         0 return Egreek::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
887             }
888             else {
889 0         0 return Egreek::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
890             }
891             }
892             else {
893 0         0 return Egreek::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
894             }
895             }
896              
897             #
898             # Greek lower case first without parameter
899             #
900             sub Egreek::lcfirst_() {
901 0     0 0 0 return Egreek::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
902             }
903              
904             #
905             # Greek lower case with parameter
906             #
907             sub Egreek::lc(@) {
908 0 0   0 0 0 if (@_) {
909 0         0 my $s = shift @_;
910 0 0 0     0 if (@_ and wantarray) {
911 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
912             }
913             else {
914 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
915             }
916             }
917             else {
918 0         0 return Egreek::lc_();
919             }
920             }
921              
922             #
923             # Greek lower case without parameter
924             #
925             sub Egreek::lc_() {
926 0     0 0 0 my $s = $_;
927 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
928             }
929              
930             #
931             # Greek upper case first with parameter
932             #
933             sub Egreek::ucfirst(@) {
934 0 0   0 0 0 if (@_) {
935 0         0 my $s = shift @_;
936 0 0 0     0 if (@_ and wantarray) {
937 0         0 return Egreek::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
938             }
939             else {
940 0         0 return Egreek::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
941             }
942             }
943             else {
944 0         0 return Egreek::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
945             }
946             }
947              
948             #
949             # Greek upper case first without parameter
950             #
951             sub Egreek::ucfirst_() {
952 0     0 0 0 return Egreek::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
953             }
954              
955             #
956             # Greek upper case with parameter
957             #
958             sub Egreek::uc(@) {
959 0 50   174 0 0 if (@_) {
960 174         270 my $s = shift @_;
961 174 50 33     301 if (@_ and wantarray) {
962 174 0       327 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
963             }
964             else {
965 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         538  
966             }
967             }
968             else {
969 174         633 return Egreek::uc_();
970             }
971             }
972              
973             #
974             # Greek upper case without parameter
975             #
976             sub Egreek::uc_() {
977 0     0 0 0 my $s = $_;
978 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
979             }
980              
981             #
982             # Greek fold case with parameter
983             #
984             sub Egreek::fc(@) {
985 0 50   197 0 0 if (@_) {
986 197         268 my $s = shift @_;
987 197 50 33     218 if (@_ and wantarray) {
988 197 0       333 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
989             }
990             else {
991 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         466  
992             }
993             }
994             else {
995 197         1163 return Egreek::fc_();
996             }
997             }
998              
999             #
1000             # Greek fold case without parameter
1001             #
1002             sub Egreek::fc_() {
1003 0     0 0 0 my $s = $_;
1004 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1005             }
1006              
1007             #
1008             # Greek regexp capture
1009             #
1010             {
1011             sub Egreek::capture {
1012 0     0 1 0 return $_[0];
1013             }
1014             }
1015              
1016             #
1017             # Greek regexp ignore case modifier
1018             #
1019             sub Egreek::ignorecase {
1020              
1021 0     0 0 0 my @string = @_;
1022 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1023              
1024             # ignore case of $scalar or @array
1025 0         0 for my $string (@string) {
1026              
1027             # split regexp
1028 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1029              
1030             # unescape character
1031 0         0 for (my $i=0; $i <= $#char; $i++) {
1032 0 0       0 next if not defined $char[$i];
1033              
1034             # open character class [...]
1035 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1036 0         0 my $left = $i;
1037              
1038             # [] make die "unmatched [] in regexp ...\n"
1039              
1040 0 0       0 if ($char[$i+1] eq ']') {
1041 0         0 $i++;
1042             }
1043              
1044 0         0 while (1) {
1045 0 0       0 if (++$i > $#char) {
1046 0         0 croak "Unmatched [] in regexp";
1047             }
1048 0 0       0 if ($char[$i] eq ']') {
1049 0         0 my $right = $i;
1050 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1051              
1052             # escape character
1053 0         0 for my $char (@charlist) {
1054 0 0       0 if (0) {
1055             }
1056              
1057 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1058 0         0 $char = '\\' . $char;
1059             }
1060             }
1061              
1062             # [...]
1063 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1064              
1065 0         0 $i = $left;
1066 0         0 last;
1067             }
1068             }
1069             }
1070              
1071             # open character class [^...]
1072             elsif ($char[$i] eq '[^') {
1073 0         0 my $left = $i;
1074              
1075             # [^] make die "unmatched [] in regexp ...\n"
1076              
1077 0 0       0 if ($char[$i+1] eq ']') {
1078 0         0 $i++;
1079             }
1080              
1081 0         0 while (1) {
1082 0 0       0 if (++$i > $#char) {
1083 0         0 croak "Unmatched [] in regexp";
1084             }
1085 0 0       0 if ($char[$i] eq ']') {
1086 0         0 my $right = $i;
1087 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1088              
1089             # escape character
1090 0         0 for my $char (@charlist) {
1091 0 0       0 if (0) {
1092             }
1093              
1094 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1095 0         0 $char = '\\' . $char;
1096             }
1097             }
1098              
1099             # [^...]
1100 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1101              
1102 0         0 $i = $left;
1103 0         0 last;
1104             }
1105             }
1106             }
1107              
1108             # rewrite classic character class or escape character
1109             elsif (my $char = classic_character_class($char[$i])) {
1110 0         0 $char[$i] = $char;
1111             }
1112              
1113             # with /i modifier
1114             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1115 0         0 my $uc = Egreek::uc($char[$i]);
1116 0         0 my $fc = Egreek::fc($char[$i]);
1117 0 0       0 if ($uc ne $fc) {
1118 0 0       0 if (CORE::length($fc) == 1) {
1119 0         0 $char[$i] = '[' . $uc . $fc . ']';
1120             }
1121             else {
1122 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1123             }
1124             }
1125             }
1126             }
1127              
1128             # characterize
1129 0         0 for (my $i=0; $i <= $#char; $i++) {
1130 0 0       0 next if not defined $char[$i];
1131              
1132 0 0       0 if (0) {
1133             }
1134              
1135             # quote character before ? + * {
1136 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1137 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1138 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1139             }
1140             }
1141             }
1142              
1143 0         0 $string = join '', @char;
1144             }
1145              
1146             # make regexp string
1147 0         0 return @string;
1148             }
1149              
1150             #
1151             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1152             #
1153             sub Egreek::classic_character_class {
1154 0     1867 0 0 my($char) = @_;
1155              
1156             return {
1157             '\D' => '${Egreek::eD}',
1158             '\S' => '${Egreek::eS}',
1159             '\W' => '${Egreek::eW}',
1160             '\d' => '[0-9]',
1161              
1162             # Before Perl 5.6, \s only matched the five whitespace characters
1163             # tab, newline, form-feed, carriage return, and the space character
1164             # itself, which, taken together, is the character class [\t\n\f\r ].
1165              
1166             # Vertical tabs are now whitespace
1167             # \s in a regex now matches a vertical tab in all circumstances.
1168             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1169             # \t \n \v \f \r space
1170             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1171             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1172             '\s' => '\s',
1173              
1174             '\w' => '[0-9A-Z_a-z]',
1175             '\C' => '[\x00-\xFF]',
1176             '\X' => 'X',
1177              
1178             # \h \v \H \V
1179              
1180             # P.114 Character Class Shortcuts
1181             # in Chapter 7: In the World of Regular Expressions
1182             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1183              
1184             # P.357 13.2.3 Whitespace
1185             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1186             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1187             #
1188             # 0x00009 CHARACTER TABULATION h s
1189             # 0x0000a LINE FEED (LF) vs
1190             # 0x0000b LINE TABULATION v
1191             # 0x0000c FORM FEED (FF) vs
1192             # 0x0000d CARRIAGE RETURN (CR) vs
1193             # 0x00020 SPACE h s
1194              
1195             # P.196 Table 5-9. Alphanumeric regex metasymbols
1196             # in Chapter 5. Pattern Matching
1197             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1198              
1199             # (and so on)
1200              
1201             '\H' => '${Egreek::eH}',
1202             '\V' => '${Egreek::eV}',
1203             '\h' => '[\x09\x20]',
1204             '\v' => '[\x0A\x0B\x0C\x0D]',
1205             '\R' => '${Egreek::eR}',
1206              
1207             # \N
1208             #
1209             # http://perldoc.perl.org/perlre.html
1210             # Character Classes and other Special Escapes
1211             # Any character but \n (experimental). Not affected by /s modifier
1212              
1213             '\N' => '${Egreek::eN}',
1214              
1215             # \b \B
1216              
1217             # P.180 Boundaries: The \b and \B Assertions
1218             # in Chapter 5: Pattern Matching
1219             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1220              
1221             # P.219 Boundaries: The \b and \B Assertions
1222             # in Chapter 5: Pattern Matching
1223             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1224              
1225             # \b really means (?:(?<=\w)(?!\w)|(?
1226             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1227             '\b' => '${Egreek::eb}',
1228              
1229             # \B really means (?:(?<=\w)(?=\w)|(?
1230             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1231             '\B' => '${Egreek::eB}',
1232              
1233 1867   100     2665 }->{$char} || '';
1234             }
1235              
1236             #
1237             # prepare Greek characters per length
1238             #
1239              
1240             # 1 octet characters
1241             my @chars1 = ();
1242             sub chars1 {
1243 1867 0   0 0 76905 if (@chars1) {
1244 0         0 return @chars1;
1245             }
1246 0 0       0 if (exists $range_tr{1}) {
1247 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1248 0         0 while (my @range = splice(@ranges,0,1)) {
1249 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1250 0         0 push @chars1, pack 'C', $oct0;
1251             }
1252             }
1253             }
1254 0         0 return @chars1;
1255             }
1256              
1257             # 2 octets characters
1258             my @chars2 = ();
1259             sub chars2 {
1260 0 0   0 0 0 if (@chars2) {
1261 0         0 return @chars2;
1262             }
1263 0 0       0 if (exists $range_tr{2}) {
1264 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1265 0         0 while (my @range = splice(@ranges,0,2)) {
1266 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1267 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1268 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1269             }
1270             }
1271             }
1272             }
1273 0         0 return @chars2;
1274             }
1275              
1276             # 3 octets characters
1277             my @chars3 = ();
1278             sub chars3 {
1279 0 0   0 0 0 if (@chars3) {
1280 0         0 return @chars3;
1281             }
1282 0 0       0 if (exists $range_tr{3}) {
1283 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1284 0         0 while (my @range = splice(@ranges,0,3)) {
1285 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1286 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1287 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1288 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1289             }
1290             }
1291             }
1292             }
1293             }
1294 0         0 return @chars3;
1295             }
1296              
1297             # 4 octets characters
1298             my @chars4 = ();
1299             sub chars4 {
1300 0 0   0 0 0 if (@chars4) {
1301 0         0 return @chars4;
1302             }
1303 0 0       0 if (exists $range_tr{4}) {
1304 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1305 0         0 while (my @range = splice(@ranges,0,4)) {
1306 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1307 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1308 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1309 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1310 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1311             }
1312             }
1313             }
1314             }
1315             }
1316             }
1317 0         0 return @chars4;
1318             }
1319              
1320             #
1321             # Greek open character list for tr
1322             #
1323             sub _charlist_tr {
1324              
1325 0     0   0 local $_ = shift @_;
1326              
1327             # unescape character
1328 0         0 my @char = ();
1329 0         0 while (not /\G \z/oxmsgc) {
1330 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1331 0         0 push @char, '\-';
1332             }
1333             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1334 0         0 push @char, CORE::chr(oct $1);
1335             }
1336             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1337 0         0 push @char, CORE::chr(hex $1);
1338             }
1339             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1340 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1341             }
1342             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1343             push @char, {
1344             '\0' => "\0",
1345             '\n' => "\n",
1346             '\r' => "\r",
1347             '\t' => "\t",
1348             '\f' => "\f",
1349             '\b' => "\x08", # \b means backspace in character class
1350             '\a' => "\a",
1351             '\e' => "\e",
1352 0         0 }->{$1};
1353             }
1354             elsif (/\G \\ ($q_char) /oxmsgc) {
1355 0         0 push @char, $1;
1356             }
1357             elsif (/\G ($q_char) /oxmsgc) {
1358 0         0 push @char, $1;
1359             }
1360             }
1361              
1362             # join separated multiple-octet
1363 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1364              
1365             # unescape '-'
1366 0         0 my @i = ();
1367 0         0 for my $i (0 .. $#char) {
1368 0 0       0 if ($char[$i] eq '\-') {
    0          
1369 0         0 $char[$i] = '-';
1370             }
1371             elsif ($char[$i] eq '-') {
1372 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1373 0         0 push @i, $i;
1374             }
1375             }
1376             }
1377              
1378             # open character list (reverse for splice)
1379 0         0 for my $i (CORE::reverse @i) {
1380 0         0 my @range = ();
1381              
1382             # range error
1383 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1384 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1385             }
1386              
1387             # range of multiple-octet code
1388 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1389 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1390 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1391             }
1392             elsif (CORE::length($char[$i+1]) == 2) {
1393 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1394 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1395             }
1396             elsif (CORE::length($char[$i+1]) == 3) {
1397 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1398 0         0 push @range, chars2();
1399 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1400             }
1401             elsif (CORE::length($char[$i+1]) == 4) {
1402 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1403 0         0 push @range, chars2();
1404 0         0 push @range, chars3();
1405 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1406             }
1407             else {
1408 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1409             }
1410             }
1411             elsif (CORE::length($char[$i-1]) == 2) {
1412 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1413 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1414             }
1415             elsif (CORE::length($char[$i+1]) == 3) {
1416 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1417 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1418             }
1419             elsif (CORE::length($char[$i+1]) == 4) {
1420 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1421 0         0 push @range, chars3();
1422 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1423             }
1424             else {
1425 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1426             }
1427             }
1428             elsif (CORE::length($char[$i-1]) == 3) {
1429 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1430 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1431             }
1432             elsif (CORE::length($char[$i+1]) == 4) {
1433 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1434 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1435             }
1436             else {
1437 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1438             }
1439             }
1440             elsif (CORE::length($char[$i-1]) == 4) {
1441 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1442 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1443             }
1444             else {
1445 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1446             }
1447             }
1448             else {
1449 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1450             }
1451              
1452 0         0 splice @char, $i-1, 3, @range;
1453             }
1454              
1455 0         0 return @char;
1456             }
1457              
1458             #
1459             # Greek open character class
1460             #
1461             sub _cc {
1462 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1463 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1464             }
1465             elsif (scalar(@_) == 1) {
1466 0         0 return sprintf('\x%02X',$_[0]);
1467             }
1468             elsif (scalar(@_) == 2) {
1469 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1470 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1471             }
1472             elsif ($_[0] == $_[1]) {
1473 0         0 return sprintf('\x%02X',$_[0]);
1474             }
1475             elsif (($_[0]+1) == $_[1]) {
1476 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1477             }
1478             else {
1479 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1480             }
1481             }
1482             else {
1483 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1484             }
1485             }
1486              
1487             #
1488             # Greek octet range
1489             #
1490             sub _octets {
1491 0     182   0 my $length = shift @_;
1492              
1493 182 50       320 if ($length == 1) {
1494 182         377 my($a1) = unpack 'C', $_[0];
1495 182         500 my($z1) = unpack 'C', $_[1];
1496              
1497 182 50       319 if ($a1 > $z1) {
1498 182         353 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1499             }
1500              
1501 0 50       0 if ($a1 == $z1) {
    50          
1502 182         509 return sprintf('\x%02X',$a1);
1503             }
1504             elsif (($a1+1) == $z1) {
1505 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1506             }
1507             else {
1508 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1509             }
1510             }
1511             else {
1512 182         1174 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1513             }
1514             }
1515              
1516             #
1517             # Greek range regexp
1518             #
1519             sub _range_regexp {
1520 0     182   0 my($length,$first,$last) = @_;
1521              
1522 182         398 my @range_regexp = ();
1523 182 50       248 if (not exists $range_tr{$length}) {
1524 182         509 return @range_regexp;
1525             }
1526              
1527 0         0 my @ranges = @{ $range_tr{$length} };
  182         448  
1528 182         479 while (my @range = splice(@ranges,0,$length)) {
1529 182         537 my $min = '';
1530 182         270 my $max = '';
1531 182         237 for (my $i=0; $i < $length; $i++) {
1532 182         514 $min .= pack 'C', $range[$i][0];
1533 182         663 $max .= pack 'C', $range[$i][-1];
1534             }
1535              
1536             # min___max
1537             # FIRST_____________LAST
1538             # (nothing)
1539              
1540 182 50 33     434 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1541             }
1542              
1543             # **********
1544             # min_________max
1545             # FIRST_____________LAST
1546             # **********
1547              
1548             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1549 182         1959 push @range_regexp, _octets($length,$first,$max,$min,$max);
1550             }
1551              
1552             # **********************
1553             # min________________max
1554             # FIRST_____________LAST
1555             # **********************
1556              
1557             elsif (($min eq $first) and ($max eq $last)) {
1558 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1559             }
1560              
1561             # *********
1562             # min___max
1563             # FIRST_____________LAST
1564             # *********
1565              
1566             elsif (($first le $min) and ($max le $last)) {
1567 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1568             }
1569              
1570             # **********************
1571             # min__________________________max
1572             # FIRST_____________LAST
1573             # **********************
1574              
1575             elsif (($min le $first) and ($last le $max)) {
1576 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1577             }
1578              
1579             # *********
1580             # min________max
1581             # FIRST_____________LAST
1582             # *********
1583              
1584             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1585 182         467 push @range_regexp, _octets($length,$min,$last,$min,$max);
1586             }
1587              
1588             # min___max
1589             # FIRST_____________LAST
1590             # (nothing)
1591              
1592             elsif ($last lt $min) {
1593             }
1594              
1595             else {
1596 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1597             }
1598             }
1599              
1600 0         0 return @range_regexp;
1601             }
1602              
1603             #
1604             # Greek open character list for qr and not qr
1605             #
1606             sub _charlist {
1607              
1608 182     358   388 my $modifier = pop @_;
1609 358         696 my @char = @_;
1610              
1611 358 100       746 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1612              
1613             # unescape character
1614 358         838 for (my $i=0; $i <= $#char; $i++) {
1615              
1616             # escape - to ...
1617 358 100 100     1262 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1618 1125 100 100     9113 if ((0 < $i) and ($i < $#char)) {
1619 206         976 $char[$i] = '...';
1620             }
1621             }
1622              
1623             # octal escape sequence
1624             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1625 182         498 $char[$i] = octchr($1);
1626             }
1627              
1628             # hexadecimal escape sequence
1629             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1630 0         0 $char[$i] = hexchr($1);
1631             }
1632              
1633             # \b{...} --> b\{...}
1634             # \B{...} --> B\{...}
1635             # \N{CHARNAME} --> N\{CHARNAME}
1636             # \p{PROPERTY} --> p\{PROPERTY}
1637             # \P{PROPERTY} --> P\{PROPERTY}
1638             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1639 0         0 $char[$i] = $1 . '\\' . $2;
1640             }
1641              
1642             # \p, \P, \X --> p, P, X
1643             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1644 0         0 $char[$i] = $1;
1645             }
1646              
1647             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1648 0         0 $char[$i] = CORE::chr oct $1;
1649             }
1650             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1651 0         0 $char[$i] = CORE::chr hex $1;
1652             }
1653             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1654 22         100 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1655             }
1656             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1657             $char[$i] = {
1658             '\0' => "\0",
1659             '\n' => "\n",
1660             '\r' => "\r",
1661             '\t' => "\t",
1662             '\f' => "\f",
1663             '\b' => "\x08", # \b means backspace in character class
1664             '\a' => "\a",
1665             '\e' => "\e",
1666             '\d' => '[0-9]',
1667              
1668             # Vertical tabs are now whitespace
1669             # \s in a regex now matches a vertical tab in all circumstances.
1670             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1671             # \t \n \v \f \r space
1672             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1673             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1674             '\s' => '\s',
1675              
1676             '\w' => '[0-9A-Z_a-z]',
1677             '\D' => '${Egreek::eD}',
1678             '\S' => '${Egreek::eS}',
1679             '\W' => '${Egreek::eW}',
1680              
1681             '\H' => '${Egreek::eH}',
1682             '\V' => '${Egreek::eV}',
1683             '\h' => '[\x09\x20]',
1684             '\v' => '[\x0A\x0B\x0C\x0D]',
1685             '\R' => '${Egreek::eR}',
1686              
1687 0         0 }->{$1};
1688             }
1689              
1690             # POSIX-style character classes
1691             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1692             $char[$i] = {
1693              
1694             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1695             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1696             '[:^lower:]' => '${Egreek::not_lower_i}',
1697             '[:^upper:]' => '${Egreek::not_upper_i}',
1698              
1699 25         400 }->{$1};
1700             }
1701             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1702             $char[$i] = {
1703              
1704             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1705             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1706             '[:ascii:]' => '[\x00-\x7F]',
1707             '[:blank:]' => '[\x09\x20]',
1708             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1709             '[:digit:]' => '[\x30-\x39]',
1710             '[:graph:]' => '[\x21-\x7F]',
1711             '[:lower:]' => '[\x61-\x7A]',
1712             '[:print:]' => '[\x20-\x7F]',
1713             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1714              
1715             # P.174 POSIX-Style Character Classes
1716             # in Chapter 5: Pattern Matching
1717             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1718              
1719             # P.311 11.2.4 Character Classes and other Special Escapes
1720             # in Chapter 11: perlre: Perl regular expressions
1721             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1722              
1723             # P.210 POSIX-Style Character Classes
1724             # in Chapter 5: Pattern Matching
1725             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1726              
1727             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1728              
1729             '[:upper:]' => '[\x41-\x5A]',
1730             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1731             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1732             '[:^alnum:]' => '${Egreek::not_alnum}',
1733             '[:^alpha:]' => '${Egreek::not_alpha}',
1734             '[:^ascii:]' => '${Egreek::not_ascii}',
1735             '[:^blank:]' => '${Egreek::not_blank}',
1736             '[:^cntrl:]' => '${Egreek::not_cntrl}',
1737             '[:^digit:]' => '${Egreek::not_digit}',
1738             '[:^graph:]' => '${Egreek::not_graph}',
1739             '[:^lower:]' => '${Egreek::not_lower}',
1740             '[:^print:]' => '${Egreek::not_print}',
1741             '[:^punct:]' => '${Egreek::not_punct}',
1742             '[:^space:]' => '${Egreek::not_space}',
1743             '[:^upper:]' => '${Egreek::not_upper}',
1744             '[:^word:]' => '${Egreek::not_word}',
1745             '[:^xdigit:]' => '${Egreek::not_xdigit}',
1746              
1747 8         56 }->{$1};
1748             }
1749             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1750 70         1311 $char[$i] = $1;
1751             }
1752             }
1753              
1754             # open character list
1755 7         33 my @singleoctet = ();
1756 358         657 my @multipleoctet = ();
1757 358         511 for (my $i=0; $i <= $#char; ) {
1758              
1759             # escaped -
1760 358 100 100     984 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1761 943         4233 $i += 1;
1762 182         231 next;
1763             }
1764              
1765             # make range regexp
1766             elsif ($char[$i] eq '...') {
1767              
1768             # range error
1769 182 50       344 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1770 182         686 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1771             }
1772             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1773 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1774 182         468 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1775             }
1776             }
1777              
1778             # make range regexp per length
1779 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1780 182         544 my @regexp = ();
1781              
1782             # is first and last
1783 182 50 33     16347 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1784 182         671 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1785             }
1786              
1787             # is first
1788             elsif ($length == CORE::length($char[$i-1])) {
1789 182         520 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1790             }
1791              
1792             # is inside in first and last
1793             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1794 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1795             }
1796              
1797             # is last
1798             elsif ($length == CORE::length($char[$i+1])) {
1799 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1800             }
1801              
1802             else {
1803 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1804             }
1805              
1806 0 50       0 if ($length == 1) {
1807 182         431 push @singleoctet, @regexp;
1808             }
1809             else {
1810 182         444 push @multipleoctet, @regexp;
1811             }
1812             }
1813              
1814 0         0 $i += 2;
1815             }
1816              
1817             # with /i modifier
1818             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1819 182 100       491 if ($modifier =~ /i/oxms) {
1820 493         745 my $uc = Egreek::uc($char[$i]);
1821 24         46 my $fc = Egreek::fc($char[$i]);
1822 24 100       54 if ($uc ne $fc) {
1823 24 50       46 if (CORE::length($fc) == 1) {
1824 12         27 push @singleoctet, $uc, $fc;
1825             }
1826             else {
1827 12         24 push @singleoctet, $uc;
1828 0         0 push @multipleoctet, $fc;
1829             }
1830             }
1831             else {
1832 0         0 push @singleoctet, $char[$i];
1833             }
1834             }
1835             else {
1836 12         24 push @singleoctet, $char[$i];
1837             }
1838 469         676 $i += 1;
1839             }
1840              
1841             # single character of single octet code
1842             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1843 493         787 push @singleoctet, "\t", "\x20";
1844 0         0 $i += 1;
1845             }
1846             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1847 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1848 0         0 $i += 1;
1849             }
1850             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1851 0         0 push @singleoctet, $char[$i];
1852 2         6 $i += 1;
1853             }
1854              
1855             # single character of multiple-octet code
1856             else {
1857 2         5 push @multipleoctet, $char[$i];
1858 84         156 $i += 1;
1859             }
1860             }
1861              
1862             # quote metachar
1863 84         167 for (@singleoctet) {
1864 358 50       717 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1865 689         2966 $_ = '-';
1866             }
1867             elsif (/\A \n \z/oxms) {
1868 0         0 $_ = '\n';
1869             }
1870             elsif (/\A \r \z/oxms) {
1871 8         15 $_ = '\r';
1872             }
1873             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1874 8         28 $_ = sprintf('\x%02X', CORE::ord $1);
1875             }
1876             elsif (/\A [\x00-\xFF] \z/oxms) {
1877 60         194 $_ = quotemeta $_;
1878             }
1879             }
1880              
1881             # return character list
1882 429         697 return \@singleoctet, \@multipleoctet;
1883             }
1884              
1885             #
1886             # Greek octal escape sequence
1887             #
1888             sub octchr {
1889 358     5 0 1228 my($octdigit) = @_;
1890              
1891 5         13 my @binary = ();
1892 5         12 for my $octal (split(//,$octdigit)) {
1893             push @binary, {
1894             '0' => '000',
1895             '1' => '001',
1896             '2' => '010',
1897             '3' => '011',
1898             '4' => '100',
1899             '5' => '101',
1900             '6' => '110',
1901             '7' => '111',
1902 5         22 }->{$octal};
1903             }
1904 50         177 my $binary = join '', @binary;
1905              
1906             my $octchr = {
1907             # 1234567
1908             1 => pack('B*', "0000000$binary"),
1909             2 => pack('B*', "000000$binary"),
1910             3 => pack('B*', "00000$binary"),
1911             4 => pack('B*', "0000$binary"),
1912             5 => pack('B*', "000$binary"),
1913             6 => pack('B*', "00$binary"),
1914             7 => pack('B*', "0$binary"),
1915             0 => pack('B*', "$binary"),
1916              
1917 5         15 }->{CORE::length($binary) % 8};
1918              
1919 5         68 return $octchr;
1920             }
1921              
1922             #
1923             # Greek hexadecimal escape sequence
1924             #
1925             sub hexchr {
1926 5     5 0 19 my($hexdigit) = @_;
1927              
1928             my $hexchr = {
1929             1 => pack('H*', "0$hexdigit"),
1930             0 => pack('H*', "$hexdigit"),
1931              
1932 5         14 }->{CORE::length($_[0]) % 2};
1933              
1934 5         47 return $hexchr;
1935             }
1936              
1937             #
1938             # Greek open character list for qr
1939             #
1940             sub charlist_qr {
1941              
1942 5     314 0 16 my $modifier = pop @_;
1943 314         730 my @char = @_;
1944              
1945 314         763 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1946 314         1279 my @singleoctet = @$singleoctet;
1947 314         747 my @multipleoctet = @$multipleoctet;
1948              
1949             # return character list
1950 314 100       536 if (scalar(@singleoctet) >= 1) {
1951              
1952             # with /i modifier
1953 314 100       701 if ($modifier =~ m/i/oxms) {
1954 236         595 my %singleoctet_ignorecase = ();
1955 22         30 for (@singleoctet) {
1956 22   100     38 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1957 46         196 for my $ord (hex($1) .. hex($2)) {
1958 46         130 my $char = CORE::chr($ord);
1959 66         107 my $uc = Egreek::uc($char);
1960 66         95 my $fc = Egreek::fc($char);
1961 66 100       106 if ($uc eq $fc) {
1962 66         108 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1963             }
1964             else {
1965 12 50       83 if (CORE::length($fc) == 1) {
1966 54         83 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1967 54         111 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1968             }
1969             else {
1970 54         182 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1971 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1972             }
1973             }
1974             }
1975             }
1976 0 50       0 if ($_ ne '') {
1977 46         102 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1978             }
1979             }
1980 0         0 my $i = 0;
1981 22         28 my @singleoctet_ignorecase = ();
1982 22         32 for my $ord (0 .. 255) {
1983 22 100       32 if (exists $singleoctet_ignorecase{$ord}) {
1984 5632         6515 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         90  
1985             }
1986             else {
1987 96         217 $i++;
1988             }
1989             }
1990 5536         5529 @singleoctet = ();
1991 22         33 for my $range (@singleoctet_ignorecase) {
1992 22 100       61 if (ref $range) {
1993 3648 100       21609 if (scalar(@{$range}) == 1) {
  56 50       56  
1994 56         88 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         64  
1995             }
1996 36         126 elsif (scalar(@{$range}) == 2) {
1997 20         28 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
1998             }
1999             else {
2000 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         23  
  20         24  
2001             }
2002             }
2003             }
2004             }
2005              
2006 20         75 my $not_anchor = '';
2007              
2008 236         357 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2009             }
2010 236 100       640 if (scalar(@multipleoctet) >= 2) {
2011 314         702 return '(?:' . join('|', @multipleoctet) . ')';
2012             }
2013             else {
2014 6         34 return $multipleoctet[0];
2015             }
2016             }
2017              
2018             #
2019             # Greek open character list for not qr
2020             #
2021             sub charlist_not_qr {
2022              
2023 308     44 0 1322 my $modifier = pop @_;
2024 44         89 my @char = @_;
2025              
2026 44         102 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2027 44         122 my @singleoctet = @$singleoctet;
2028 44         240 my @multipleoctet = @$multipleoctet;
2029              
2030             # with /i modifier
2031 44 100       63 if ($modifier =~ m/i/oxms) {
2032 44         119 my %singleoctet_ignorecase = ();
2033 10         17 for (@singleoctet) {
2034 10   66     13 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2035 10         45 for my $ord (hex($1) .. hex($2)) {
2036 10         31 my $char = CORE::chr($ord);
2037 30         48 my $uc = Egreek::uc($char);
2038 30         46 my $fc = Egreek::fc($char);
2039 30 50       49 if ($uc eq $fc) {
2040 30         51 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2041             }
2042             else {
2043 0 50       0 if (CORE::length($fc) == 1) {
2044 30         48 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2045 30         65 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2046             }
2047             else {
2048 30         87 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2049 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2050             }
2051             }
2052             }
2053             }
2054 0 50       0 if ($_ ne '') {
2055 10         34 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2056             }
2057             }
2058 0         0 my $i = 0;
2059 10         11 my @singleoctet_ignorecase = ();
2060 10         16 for my $ord (0 .. 255) {
2061 10 100       25 if (exists $singleoctet_ignorecase{$ord}) {
2062 2560         2976 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         54  
2063             }
2064             else {
2065 60         99 $i++;
2066             }
2067             }
2068 2500         2543 @singleoctet = ();
2069 10         15 for my $range (@singleoctet_ignorecase) {
2070 10 100       28 if (ref $range) {
2071 960 50       1759 if (scalar(@{$range}) == 1) {
  20 50       20  
2072 20         30 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2073             }
2074 0         0 elsif (scalar(@{$range}) == 2) {
2075 20         31 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2076             }
2077             else {
2078 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         26  
  20         24  
2079             }
2080             }
2081             }
2082             }
2083              
2084             # return character list
2085 20 50       96 if (scalar(@multipleoctet) >= 1) {
2086 44 0       142 if (scalar(@singleoctet) >= 1) {
2087              
2088             # any character other than multiple-octet and single octet character class
2089 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2090             }
2091             else {
2092              
2093             # any character other than multiple-octet character class
2094 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2095             }
2096             }
2097             else {
2098 0 50       0 if (scalar(@singleoctet) >= 1) {
2099              
2100             # any character other than single octet character class
2101 44         1363 return '(?:[^' . join('', @singleoctet) . '])';
2102             }
2103             else {
2104              
2105             # any character
2106 44         268 return "(?:$your_char)";
2107             }
2108             }
2109             }
2110              
2111             #
2112             # open file in read mode
2113             #
2114             sub _open_r {
2115 0     408   0 my(undef,$file) = @_;
2116 204     204   2241 use Fcntl qw(O_RDONLY);
  204         529  
  204         30032  
2117 408         1186 return CORE::sysopen($_[0], $file, &O_RDONLY);
2118             }
2119              
2120             #
2121             # open file in append mode
2122             #
2123             sub _open_a {
2124 408     204   21899 my(undef,$file) = @_;
2125 204     204   1575 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  204         559  
  204         649233  
2126 204         706 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2127             }
2128              
2129             #
2130             # safe system
2131             #
2132             sub _systemx {
2133              
2134             # P.707 29.2.33. exec
2135             # in Chapter 29: Functions
2136             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2137             #
2138             # Be aware that in older releases of Perl, exec (and system) did not flush
2139             # your output buffer, so you needed to enable command buffering by setting $|
2140             # on one or more filehandles to avoid lost output in the case of exec, or
2141             # misordererd output in the case of system. This situation was largely remedied
2142             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2143              
2144             # P.855 exec
2145             # in Chapter 27: Functions
2146             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2147             #
2148             # In very old release of Perl (before v5.6), exec (and system) did not flush
2149             # your output buffer, so you needed to enable command buffering by setting $|
2150             # on one or more filehandles to avoid lost output with exec or misordered
2151             # output with system.
2152              
2153 204     204   41468 $| = 1;
2154              
2155             # P.565 23.1.2. Cleaning Up Your Environment
2156             # in Chapter 23: Security
2157             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2158              
2159             # P.656 Cleaning Up Your Environment
2160             # in Chapter 20: Security
2161             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2162              
2163             # local $ENV{'PATH'} = '.';
2164 204         1086 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2165              
2166             # P.707 29.2.33. exec
2167             # in Chapter 29: Functions
2168             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2169             #
2170             # As we mentioned earlier, exec treats a discrete list of arguments as an
2171             # indication that it should bypass shell processing. However, there is one
2172             # place where you might still get tripped up. The exec call (and system, too)
2173             # will not distinguish between a single scalar argument and an array containing
2174             # only one element.
2175             #
2176             # @args = ("echo surprise"); # just one element in list
2177             # exec @args # still subject to shell escapes
2178             # or die "exec: $!"; # because @args == 1
2179             #
2180             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2181             # first argument as the pathname, which forces the rest of the arguments to be
2182             # interpreted as a list, even if there is only one of them:
2183             #
2184             # exec { $args[0] } @args # safe even with one-argument list
2185             # or die "can't exec @args: $!";
2186              
2187             # P.855 exec
2188             # in Chapter 27: Functions
2189             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2190             #
2191             # As we mentioned earlier, exec treats a discrete list of arguments as a
2192             # directive to bypass shell processing. However, there is one place where
2193             # you might still get tripped up. The exec call (and system, too) cannot
2194             # distinguish between a single scalar argument and an array containing
2195             # only one element.
2196             #
2197             # @args = ("echo surprise"); # just one element in list
2198             # exec @args # still subject to shell escapes
2199             # || die "exec: $!"; # because @args == 1
2200             #
2201             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2202             # argument as the pathname, which forces the rest of the arguments to be
2203             # interpreted as a list, even if there is only one of them:
2204             #
2205             # exec { $args[0] } @args # safe even with one-argument list
2206             # || die "can't exec @args: $!";
2207              
2208 204         1870 return CORE::system { $_[0] } @_; # safe even with one-argument list
  204         443  
2209             }
2210              
2211             #
2212             # Greek order to character (with parameter)
2213             #
2214             sub Egreek::chr(;$) {
2215              
2216 204 0   0 0 20170731 my $c = @_ ? $_[0] : $_;
2217              
2218 0 0       0 if ($c == 0x00) {
2219 0         0 return "\x00";
2220             }
2221             else {
2222 0         0 my @chr = ();
2223 0         0 while ($c > 0) {
2224 0         0 unshift @chr, ($c % 0x100);
2225 0         0 $c = int($c / 0x100);
2226             }
2227 0         0 return pack 'C*', @chr;
2228             }
2229             }
2230              
2231             #
2232             # Greek order to character (without parameter)
2233             #
2234             sub Egreek::chr_() {
2235              
2236 0     0 0 0 my $c = $_;
2237              
2238 0 0       0 if ($c == 0x00) {
2239 0         0 return "\x00";
2240             }
2241             else {
2242 0         0 my @chr = ();
2243 0         0 while ($c > 0) {
2244 0         0 unshift @chr, ($c % 0x100);
2245 0         0 $c = int($c / 0x100);
2246             }
2247 0         0 return pack 'C*', @chr;
2248             }
2249             }
2250              
2251             #
2252             # Greek path globbing (with parameter)
2253             #
2254             sub Egreek::glob($) {
2255              
2256 0 0   0 0 0 if (wantarray) {
2257 0         0 my @glob = _DOS_like_glob(@_);
2258 0         0 for my $glob (@glob) {
2259 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2260             }
2261 0         0 return @glob;
2262             }
2263             else {
2264 0         0 my $glob = _DOS_like_glob(@_);
2265 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2266 0         0 return $glob;
2267             }
2268             }
2269              
2270             #
2271             # Greek path globbing (without parameter)
2272             #
2273             sub Egreek::glob_() {
2274              
2275 0 0   0 0 0 if (wantarray) {
2276 0         0 my @glob = _DOS_like_glob();
2277 0         0 for my $glob (@glob) {
2278 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2279             }
2280 0         0 return @glob;
2281             }
2282             else {
2283 0         0 my $glob = _DOS_like_glob();
2284 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2285 0         0 return $glob;
2286             }
2287             }
2288              
2289             #
2290             # Greek path globbing via File::DosGlob 1.10
2291             #
2292             # Often I confuse "_dosglob" and "_doglob".
2293             # So, I renamed "_dosglob" to "_DOS_like_glob".
2294             #
2295             my %iter;
2296             my %entries;
2297             sub _DOS_like_glob {
2298              
2299             # context (keyed by second cxix argument provided by core)
2300 0     0   0 my($expr,$cxix) = @_;
2301              
2302             # glob without args defaults to $_
2303 0 0       0 $expr = $_ if not defined $expr;
2304              
2305             # represents the current user's home directory
2306             #
2307             # 7.3. Expanding Tildes in Filenames
2308             # in Chapter 7. File Access
2309             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2310             #
2311             # and File::HomeDir, File::HomeDir::Windows module
2312              
2313             # DOS-like system
2314 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2315 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2316             { my_home_MSWin32() }oxmse;
2317             }
2318              
2319             # UNIX-like system
2320 0 0 0     0 else {
  0         0  
2321             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2322             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2323             }
2324 0 0       0  
2325 0 0       0 # assume global context if not provided one
2326             $cxix = '_G_' if not defined $cxix;
2327             $iter{$cxix} = 0 if not exists $iter{$cxix};
2328 0 0       0  
2329 0         0 # if we're just beginning, do it all first
2330             if ($iter{$cxix} == 0) {
2331             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2332             }
2333 0 0       0  
2334 0         0 # chuck it all out, quick or slow
2335 0         0 if (wantarray) {
  0         0  
2336             delete $iter{$cxix};
2337             return @{delete $entries{$cxix}};
2338 0 0       0 }
  0         0  
2339 0         0 else {
  0         0  
2340             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2341             return shift @{$entries{$cxix}};
2342             }
2343 0         0 else {
2344 0         0 # return undef for EOL
2345 0         0 delete $iter{$cxix};
2346             delete $entries{$cxix};
2347             return undef;
2348             }
2349             }
2350             }
2351              
2352             #
2353             # Greek path globbing subroutine
2354             #
2355 0     0   0 sub _do_glob {
2356 0         0  
2357 0         0 my($cond,@expr) = @_;
2358             my @glob = ();
2359             my $fix_drive_relative_paths = 0;
2360 0         0  
2361 0 0       0 OUTER:
2362 0 0       0 for my $expr (@expr) {
2363             next OUTER if not defined $expr;
2364 0         0 next OUTER if $expr eq '';
2365 0         0  
2366 0         0 my @matched = ();
2367 0         0 my @globdir = ();
2368 0         0 my $head = '.';
2369             my $pathsep = '/';
2370             my $tail;
2371 0 0       0  
2372 0         0 # if argument is within quotes strip em and do no globbing
2373 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2374 0 0       0 $expr = $1;
2375 0         0 if ($cond eq 'd') {
2376             if (-d $expr) {
2377             push @glob, $expr;
2378             }
2379 0 0       0 }
2380 0         0 else {
2381             if (-e $expr) {
2382             push @glob, $expr;
2383 0         0 }
2384             }
2385             next OUTER;
2386             }
2387              
2388 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2389 0 0       0 # to h:./*.pm to expand correctly
2390 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2391             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2392             $fix_drive_relative_paths = 1;
2393             }
2394 0 0       0 }
2395 0 0       0  
2396 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2397 0         0 if ($tail eq '') {
2398             push @glob, $expr;
2399 0 0       0 next OUTER;
2400 0 0       0 }
2401 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2402 0         0 if (@globdir = _do_glob('d', $head)) {
2403             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2404             next OUTER;
2405 0 0 0     0 }
2406 0         0 }
2407             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2408 0         0 $head .= $pathsep;
2409             }
2410             $expr = $tail;
2411             }
2412 0 0       0  
2413 0 0       0 # If file component has no wildcards, we can avoid opendir
2414 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2415             if ($head eq '.') {
2416 0 0 0     0 $head = '';
2417 0         0 }
2418             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2419 0         0 $head .= $pathsep;
2420 0 0       0 }
2421 0 0       0 $head .= $expr;
2422 0         0 if ($cond eq 'd') {
2423             if (-d $head) {
2424             push @glob, $head;
2425             }
2426 0 0       0 }
2427 0         0 else {
2428             if (-e $head) {
2429             push @glob, $head;
2430 0         0 }
2431             }
2432 0 0       0 next OUTER;
2433 0         0 }
2434 0         0 opendir(*DIR, $head) or next OUTER;
2435             my @leaf = readdir DIR;
2436 0 0       0 closedir DIR;
2437 0         0  
2438             if ($head eq '.') {
2439 0 0 0     0 $head = '';
2440 0         0 }
2441             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2442             $head .= $pathsep;
2443 0         0 }
2444 0         0  
2445 0         0 my $pattern = '';
2446             while ($expr =~ / \G ($q_char) /oxgc) {
2447             my $char = $1;
2448              
2449             # 6.9. Matching Shell Globs as Regular Expressions
2450             # in Chapter 6. Pattern Matching
2451             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2452 0 0       0 # (and so on)
    0          
    0          
2453 0         0  
2454             if ($char eq '*') {
2455             $pattern .= "(?:$your_char)*",
2456 0         0 }
2457             elsif ($char eq '?') {
2458             $pattern .= "(?:$your_char)?", # DOS style
2459             # $pattern .= "(?:$your_char)", # UNIX style
2460 0         0 }
2461             elsif ((my $fc = Egreek::fc($char)) ne $char) {
2462             $pattern .= $fc;
2463 0         0 }
2464             else {
2465             $pattern .= quotemeta $char;
2466 0     0   0 }
  0         0  
2467             }
2468             my $matchsub = sub { Egreek::fc($_[0]) =~ /\A $pattern \z/xms };
2469              
2470             # if ($@) {
2471             # print STDERR "$0: $@\n";
2472             # next OUTER;
2473             # }
2474 0         0  
2475 0 0 0     0 INNER:
2476 0         0 for my $leaf (@leaf) {
2477             if ($leaf eq '.' or $leaf eq '..') {
2478 0 0 0     0 next INNER;
2479 0         0 }
2480             if ($cond eq 'd' and not -d "$head$leaf") {
2481             next INNER;
2482 0 0       0 }
2483 0         0  
2484 0         0 if (&$matchsub($leaf)) {
2485             push @matched, "$head$leaf";
2486             next INNER;
2487             }
2488              
2489             # [DOS compatibility special case]
2490 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2491              
2492             if (Egreek::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2493             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2494 0 0       0 Egreek::index($pattern,'\\.') != -1 # pattern has a dot.
2495 0         0 ) {
2496 0         0 if (&$matchsub("$leaf.")) {
2497             push @matched, "$head$leaf";
2498             next INNER;
2499             }
2500 0 0       0 }
2501 0         0 }
2502             if (@matched) {
2503             push @glob, @matched;
2504 0 0       0 }
2505 0         0 }
2506 0         0 if ($fix_drive_relative_paths) {
2507             for my $glob (@glob) {
2508             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2509 0         0 }
2510             }
2511             return @glob;
2512             }
2513              
2514             #
2515             # Greek parse line
2516             #
2517 0     0   0 sub _parse_line {
2518              
2519 0         0 my($line) = @_;
2520 0         0  
2521 0         0 $line .= ' ';
2522             my @piece = ();
2523             while ($line =~ /
2524             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2525             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2526 0 0       0 /oxmsg
2527             ) {
2528 0         0 push @piece, defined($1) ? $1 : $2;
2529             }
2530             return @piece;
2531             }
2532              
2533             #
2534             # Greek parse path
2535             #
2536 0     0   0 sub _parse_path {
2537              
2538 0         0 my($path,$pathsep) = @_;
2539 0         0  
2540 0         0 $path .= '/';
2541             my @subpath = ();
2542             while ($path =~ /
2543             ((?: [^\/\\] )+?) [\/\\]
2544 0         0 /oxmsg
2545             ) {
2546             push @subpath, $1;
2547 0         0 }
2548 0         0  
2549 0         0 my $tail = pop @subpath;
2550             my $head = join $pathsep, @subpath;
2551             return $head, $tail;
2552             }
2553              
2554             #
2555             # via File::HomeDir::Windows 1.00
2556             #
2557             sub my_home_MSWin32 {
2558              
2559             # A lot of unix people and unix-derived tools rely on
2560 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2561 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2562             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2563             return $ENV{'HOME'};
2564             }
2565              
2566 0         0 # Do we have a user profile?
2567             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2568             return $ENV{'USERPROFILE'};
2569             }
2570              
2571 0         0 # Some Windows use something like $ENV{'HOME'}
2572             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2573             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2574 0         0 }
2575              
2576             return undef;
2577             }
2578              
2579             #
2580             # via File::HomeDir::Unix 1.00
2581 0     0 0 0 #
2582             sub my_home {
2583 0 0 0     0 my $home;
    0 0        
2584 0         0  
2585             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2586             $home = $ENV{'HOME'};
2587             }
2588              
2589             # This is from the original code, but I'm guessing
2590 0         0 # it means "login directory" and exists on some Unixes.
2591             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2592             $home = $ENV{'LOGDIR'};
2593             }
2594              
2595             ### More-desperate methods
2596              
2597 0         0 # Light desperation on any (Unixish) platform
2598             else {
2599             $home = CORE::eval q{ (getpwuid($<))[7] };
2600             }
2601              
2602 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2603 0         0 # For example, "nobody"-like users might use /nonexistant
2604             if (defined $home and ! -d($home)) {
2605 0         0 $home = undef;
2606             }
2607             return $home;
2608             }
2609              
2610             #
2611             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2612 0     0 0 0 #
2613             sub Egreek::PREMATCH {
2614             return $`;
2615             }
2616              
2617             #
2618             # ${^MATCH}, $MATCH, $& the string that matched
2619 0     0 0 0 #
2620             sub Egreek::MATCH {
2621             return $&;
2622             }
2623              
2624             #
2625             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2626 0     0 0 0 #
2627             sub Egreek::POSTMATCH {
2628             return $';
2629             }
2630              
2631             #
2632             # Greek character to order (with parameter)
2633             #
2634 0 0   0 1 0 sub Greek::ord(;$) {
2635              
2636 0 0       0 local $_ = shift if @_;
2637 0         0  
2638 0         0 if (/\A ($q_char) /oxms) {
2639 0         0 my @ord = unpack 'C*', $1;
2640 0         0 my $ord = 0;
2641             while (my $o = shift @ord) {
2642 0         0 $ord = $ord * 0x100 + $o;
2643             }
2644             return $ord;
2645 0         0 }
2646             else {
2647             return CORE::ord $_;
2648             }
2649             }
2650              
2651             #
2652             # Greek character to order (without parameter)
2653             #
2654 0 0   0 0 0 sub Greek::ord_() {
2655 0         0  
2656 0         0 if (/\A ($q_char) /oxms) {
2657 0         0 my @ord = unpack 'C*', $1;
2658 0         0 my $ord = 0;
2659             while (my $o = shift @ord) {
2660 0         0 $ord = $ord * 0x100 + $o;
2661             }
2662             return $ord;
2663 0         0 }
2664             else {
2665             return CORE::ord $_;
2666             }
2667             }
2668              
2669             #
2670             # Greek reverse
2671             #
2672 0 0   0 0 0 sub Greek::reverse(@) {
2673 0         0  
2674             if (wantarray) {
2675             return CORE::reverse @_;
2676             }
2677             else {
2678              
2679             # One of us once cornered Larry in an elevator and asked him what
2680             # problem he was solving with this, but he looked as far off into
2681             # the distance as he could in an elevator and said, "It seemed like
2682 0         0 # a good idea at the time."
2683              
2684             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2685             }
2686             }
2687              
2688             #
2689             # Greek getc (with parameter, without parameter)
2690             #
2691 0     0 0 0 sub Greek::getc(;*@) {
2692 0 0       0  
2693 0 0 0     0 my($package) = caller;
2694             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2695 0         0 croak 'Too many arguments for Greek::getc' if @_ and not wantarray;
  0         0  
2696 0         0  
2697 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2698 0         0 my $getc = '';
2699 0 0       0 for my $length ($length[0] .. $length[-1]) {
2700 0 0       0 $getc .= CORE::getc($fh);
2701 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2702             if ($getc =~ /\A ${Egreek::dot_s} \z/oxms) {
2703             return wantarray ? ($getc,@_) : $getc;
2704             }
2705 0 0       0 }
2706             }
2707             return wantarray ? ($getc,@_) : $getc;
2708             }
2709              
2710             #
2711             # Greek length by character
2712             #
2713 0 0   0 1 0 sub Greek::length(;$) {
2714              
2715 0         0 local $_ = shift if @_;
2716 0         0  
2717             local @_ = /\G ($q_char) /oxmsg;
2718             return scalar @_;
2719             }
2720              
2721             #
2722             # Greek substr by character
2723             #
2724             BEGIN {
2725              
2726             # P.232 The lvalue Attribute
2727             # in Chapter 6: Subroutines
2728             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2729              
2730             # P.336 The lvalue Attribute
2731             # in Chapter 7: Subroutines
2732             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2733              
2734             # P.144 8.4 Lvalue subroutines
2735             # in Chapter 8: perlsub: Perl subroutines
2736 204 50 0 204 1 118225 # 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  
2737              
2738             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2739             # vv----------------------*******
2740             sub Greek::substr($$;$$) %s {
2741              
2742             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2743              
2744             # If the substring is beyond either end of the string, substr() returns the undefined
2745             # value and produces a warning. When used as an lvalue, specifying a substring that
2746             # is entirely outside the string raises an exception.
2747             # http://perldoc.perl.org/functions/substr.html
2748              
2749             # A return with no argument returns the scalar value undef in scalar context,
2750             # an empty list () in list context, and (naturally) nothing at all in void
2751             # context.
2752              
2753             my $offset = $_[1];
2754             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2755             return;
2756             }
2757              
2758             # substr($string,$offset,$length,$replacement)
2759             if (@_ == 4) {
2760             my(undef,undef,$length,$replacement) = @_;
2761             my $substr = join '', splice(@char, $offset, $length, $replacement);
2762             $_[0] = join '', @char;
2763              
2764             # return $substr; this doesn't work, don't say "return"
2765             $substr;
2766             }
2767              
2768             # substr($string,$offset,$length)
2769             elsif (@_ == 3) {
2770             my(undef,undef,$length) = @_;
2771             my $octet_offset = 0;
2772             my $octet_length = 0;
2773             if ($offset == 0) {
2774             $octet_offset = 0;
2775             }
2776             elsif ($offset > 0) {
2777             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2778             }
2779             else {
2780             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2781             }
2782             if ($length == 0) {
2783             $octet_length = 0;
2784             }
2785             elsif ($length > 0) {
2786             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2787             }
2788             else {
2789             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2790             }
2791             CORE::substr($_[0], $octet_offset, $octet_length);
2792             }
2793              
2794             # substr($string,$offset)
2795             else {
2796             my $octet_offset = 0;
2797             if ($offset == 0) {
2798             $octet_offset = 0;
2799             }
2800             elsif ($offset > 0) {
2801             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2802             }
2803             else {
2804             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2805             }
2806             CORE::substr($_[0], $octet_offset);
2807             }
2808             }
2809             END
2810             }
2811              
2812             #
2813             # Greek index by character
2814             #
2815 0     0 1 0 sub Greek::index($$;$) {
2816 0 0       0  
2817 0         0 my $index;
2818             if (@_ == 3) {
2819             $index = Egreek::index($_[0], $_[1], CORE::length(Greek::substr($_[0], 0, $_[2])));
2820 0         0 }
2821             else {
2822             $index = Egreek::index($_[0], $_[1]);
2823 0 0       0 }
2824 0         0  
2825             if ($index == -1) {
2826             return -1;
2827 0         0 }
2828             else {
2829             return Greek::length(CORE::substr $_[0], 0, $index);
2830             }
2831             }
2832              
2833             #
2834             # Greek rindex by character
2835             #
2836 0     0 1 0 sub Greek::rindex($$;$) {
2837 0 0       0  
2838 0         0 my $rindex;
2839             if (@_ == 3) {
2840             $rindex = Egreek::rindex($_[0], $_[1], CORE::length(Greek::substr($_[0], 0, $_[2])));
2841 0         0 }
2842             else {
2843             $rindex = Egreek::rindex($_[0], $_[1]);
2844 0 0       0 }
2845 0         0  
2846             if ($rindex == -1) {
2847             return -1;
2848 0         0 }
2849             else {
2850             return Greek::length(CORE::substr $_[0], 0, $rindex);
2851             }
2852             }
2853              
2854 204     204   2502 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  204         434  
  204         44570  
2855             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2856             use vars qw($slash); $slash = 'm//';
2857              
2858             # ord() to ord() or Greek::ord()
2859             my $function_ord = 'ord';
2860              
2861             # ord to ord or Greek::ord_
2862             my $function_ord_ = 'ord';
2863              
2864             # reverse to reverse or Greek::reverse
2865             my $function_reverse = 'reverse';
2866              
2867             # getc to getc or Greek::getc
2868             my $function_getc = 'getc';
2869              
2870             # P.1023 Appendix W.9 Multibyte Anchoring
2871             # of ISBN 1-56592-224-7 CJKV Information Processing
2872              
2873 204     204   1515 my $anchor = '';
  204     0   411  
  204         10057562  
2874              
2875             use vars qw($nest);
2876              
2877             # regexp of nested parens in qqXX
2878              
2879             # P.340 Matching Nested Constructs with Embedded Code
2880             # in Chapter 7: Perl
2881             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2882              
2883             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2884             [^\\()] |
2885             \( (?{$nest++}) |
2886             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2887             \\ [^c] |
2888             \\c[\x40-\x5F] |
2889             [\x00-\xFF]
2890             }xms;
2891              
2892             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2893             [^\\{}] |
2894             \{ (?{$nest++}) |
2895             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2896             \\ [^c] |
2897             \\c[\x40-\x5F] |
2898             [\x00-\xFF]
2899             }xms;
2900              
2901             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2902             [^\\\[\]] |
2903             \[ (?{$nest++}) |
2904             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2905             \\ [^c] |
2906             \\c[\x40-\x5F] |
2907             [\x00-\xFF]
2908             }xms;
2909              
2910             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2911             [^\\<>] |
2912             \< (?{$nest++}) |
2913             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2914             \\ [^c] |
2915             \\c[\x40-\x5F] |
2916             [\x00-\xFF]
2917             }xms;
2918              
2919             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2920             (?: ::)? (?:
2921             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2922             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2923             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2924             ))
2925             }xms;
2926              
2927             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2928             (?: ::)? (?:
2929             (?>[0-9]+) |
2930             [^a-zA-Z_0-9\[\]] |
2931             ^[A-Z] |
2932             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2933             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2934             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2935             ))
2936             }xms;
2937              
2938             my $qq_substr = qr{(?> Char::substr | Greek::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2939             }xms;
2940              
2941             # regexp of nested parens in qXX
2942             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2943             [^()] |
2944             \( (?{$nest++}) |
2945             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2946             [\x00-\xFF]
2947             }xms;
2948              
2949             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2950             [^\{\}] |
2951             \{ (?{$nest++}) |
2952             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2953             [\x00-\xFF]
2954             }xms;
2955              
2956             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2957             [^\[\]] |
2958             \[ (?{$nest++}) |
2959             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2960             [\x00-\xFF]
2961             }xms;
2962              
2963             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2964             [^<>] |
2965             \< (?{$nest++}) |
2966             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2967             [\x00-\xFF]
2968             }xms;
2969              
2970             my $matched = '';
2971             my $s_matched = '';
2972              
2973             my $tr_variable = ''; # variable of tr///
2974             my $sub_variable = ''; # variable of s///
2975             my $bind_operator = ''; # =~ or !~
2976              
2977             my @heredoc = (); # here document
2978             my @heredoc_delimiter = ();
2979             my $here_script = ''; # here script
2980              
2981             #
2982             # escape Greek script
2983 0 50   204 0 0 #
2984             sub Greek::escape(;$) {
2985             local($_) = $_[0] if @_;
2986              
2987             # P.359 The Study Function
2988             # in Chapter 7: Perl
2989 204         688 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2990              
2991             study $_; # Yes, I studied study yesterday.
2992              
2993             # while all script
2994              
2995             # 6.14. Matching from Where the Last Pattern Left Off
2996             # in Chapter 6. Pattern Matching
2997             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2998             # (and so on)
2999              
3000             # one member of Tag-team
3001             #
3002             # P.128 Start of match (or end of previous match): \G
3003             # P.130 Advanced Use of \G with Perl
3004             # in Chapter 3: Overview of Regular Expression Features and Flavors
3005             # P.255 Use leading anchors
3006             # P.256 Expose ^ and \G at the front expressions
3007             # in Chapter 6: Crafting an Efficient Expression
3008             # P.315 "Tag-team" matching with /gc
3009             # in Chapter 7: Perl
3010 204         403 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3011 204         348  
3012 204         793 my $e_script = '';
3013             while (not /\G \z/oxgc) { # member
3014             $e_script .= Greek::escape_token();
3015 74567         130146 }
3016              
3017             return $e_script;
3018             }
3019              
3020             #
3021             # escape Greek token of script
3022             #
3023             sub Greek::escape_token {
3024              
3025 204     74567 0 2967 # \n output here document
3026              
3027             my $ignore_modules = join('|', qw(
3028             utf8
3029             bytes
3030             charnames
3031             I18N::Japanese
3032             I18N::Collate
3033             I18N::JExt
3034             File::DosGlob
3035             Wild
3036             Wildcard
3037             Japanese
3038             ));
3039              
3040             # another member of Tag-team
3041             #
3042             # P.315 "Tag-team" matching with /gc
3043             # in Chapter 7: Perl
3044 74567 100 100     93398 # 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          
3045 74567         3020027  
3046 12500 100       15179 if (/\G ( \n ) /oxgc) { # another member (and so on)
3047 12500         23578 my $heredoc = '';
3048             if (scalar(@heredoc_delimiter) >= 1) {
3049 174         217 $slash = 'm//';
3050 174         337  
3051             $heredoc = join '', @heredoc;
3052             @heredoc = ();
3053 174         302  
3054 174         297 # skip here document
3055             for my $heredoc_delimiter (@heredoc_delimiter) {
3056 174         1261 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3057             }
3058 174         595 @heredoc_delimiter = ();
3059              
3060 174         240 $here_script = '';
3061             }
3062             return "\n" . $heredoc;
3063             }
3064 12500         56498  
3065             # ignore space, comment
3066             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3067              
3068             # if (, elsif (, unless (, while (, until (, given (, and when (
3069              
3070             # given, when
3071              
3072             # P.225 The given Statement
3073             # in Chapter 15: Smart Matching and given-when
3074             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3075              
3076             # P.133 The given Statement
3077             # in Chapter 4: Statements and Declarations
3078             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3079 17907         57869  
3080 1400         2255 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3081             $slash = 'm//';
3082             return $1;
3083             }
3084              
3085             # scalar variable ($scalar = ...) =~ tr///;
3086             # scalar variable ($scalar = ...) =~ s///;
3087              
3088             # state
3089              
3090             # P.68 Persistent, Private Variables
3091             # in Chapter 4: Subroutines
3092             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3093              
3094             # P.160 Persistent Lexically Scoped Variables: state
3095             # in Chapter 4: Statements and Declarations
3096             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3097              
3098             # (and so on)
3099 1400         12340  
3100             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3101 86 50       182 my $e_string = e_string($1);
    50          
3102 86         4319  
3103 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3104 0         0 $tr_variable = $e_string . e_string($1);
3105 0         0 $bind_operator = $2;
3106             $slash = 'm//';
3107             return '';
3108 0         0 }
3109 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3110 0         0 $sub_variable = $e_string . e_string($1);
3111 0         0 $bind_operator = $2;
3112             $slash = 'm//';
3113             return '';
3114 0         0 }
3115 86         162 else {
3116             $slash = 'div';
3117             return $e_string;
3118             }
3119             }
3120              
3121 86         275 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egreek::PREMATCH()
3122 4         7 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3123             $slash = 'div';
3124             return q{Egreek::PREMATCH()};
3125             }
3126              
3127 4         14 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egreek::MATCH()
3128 28         56 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3129             $slash = 'div';
3130             return q{Egreek::MATCH()};
3131             }
3132              
3133 28         79 # $', ${'} --> $', ${'}
3134 1         3 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3135             $slash = 'div';
3136             return $1;
3137             }
3138              
3139 1         3 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egreek::POSTMATCH()
3140 3         7 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3141             $slash = 'div';
3142             return q{Egreek::POSTMATCH()};
3143             }
3144              
3145             # scalar variable $scalar =~ tr///;
3146             # scalar variable $scalar =~ s///;
3147             # substr() =~ tr///;
3148 3         10 # substr() =~ s///;
3149             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3150 1671 100       3796 my $scalar = e_string($1);
    100          
3151 1671         12957  
3152 1         3 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3153 1         2 $tr_variable = $scalar;
3154 1         2 $bind_operator = $1;
3155             $slash = 'm//';
3156             return '';
3157 1         3 }
3158 61         121 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3159 61         116 $sub_variable = $scalar;
3160 61         96 $bind_operator = $1;
3161             $slash = 'm//';
3162             return '';
3163 61         165 }
3164 1609         14997 else {
3165             $slash = 'div';
3166             return $scalar;
3167             }
3168             }
3169              
3170 1609         4684 # end of statement
3171             elsif (/\G ( [,;] ) /oxgc) {
3172             $slash = 'm//';
3173 4982         8509  
3174             # clear tr/// variable
3175             $tr_variable = '';
3176 4982         6010  
3177             # clear s/// variable
3178 4982         6356 $sub_variable = '';
3179              
3180 4982         5746 $bind_operator = '';
3181              
3182             return $1;
3183             }
3184              
3185 4982         17363 # bareword
3186             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3187             return $1;
3188             }
3189              
3190 0         0 # $0 --> $0
3191 2         4 elsif (/\G ( \$ 0 ) /oxmsgc) {
3192             $slash = 'div';
3193             return $1;
3194 2         6 }
3195 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3196             $slash = 'div';
3197             return $1;
3198             }
3199              
3200 0         0 # $$ --> $$
3201 1         2 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3202             $slash = 'div';
3203             return $1;
3204             }
3205              
3206             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3207 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
3208 4         7 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3209             $slash = 'div';
3210             return e_capture($1);
3211 4         11 }
3212 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3213             $slash = 'div';
3214             return e_capture($1);
3215             }
3216              
3217 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3218 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3219             $slash = 'div';
3220             return e_capture($1.'->'.$2);
3221             }
3222              
3223 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3224 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3225             $slash = 'div';
3226             return e_capture($1.'->'.$2);
3227             }
3228              
3229 0         0 # $$foo
3230 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3231             $slash = 'div';
3232             return e_capture($1);
3233             }
3234              
3235 0         0 # ${ foo }
3236 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3237             $slash = 'div';
3238             return '${' . $1 . '}';
3239             }
3240              
3241 0         0 # ${ ... }
3242 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3243             $slash = 'div';
3244             return e_capture($1);
3245             }
3246              
3247             # variable or function
3248 0         0 # $ @ % & * $ #
3249 42         74 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) {
3250             $slash = 'div';
3251             return $1;
3252             }
3253             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3254 42         185 # $ @ # \ ' " / ? ( ) [ ] < >
3255 61         208 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3256             $slash = 'div';
3257             return $1;
3258             }
3259              
3260 61         235 # while ()
3261             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3262             return $1;
3263             }
3264              
3265             # while () --- glob
3266              
3267             # avoid "Error: Runtime exception" of perl version 5.005_03
3268 0         0  
3269             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3270             return 'while ($_ = Egreek::glob("' . $1 . '"))';
3271             }
3272              
3273 0         0 # while (glob)
3274             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3275             return 'while ($_ = Egreek::glob_)';
3276             }
3277              
3278 0         0 # while (glob(WILDCARD))
3279             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3280             return 'while ($_ = Egreek::glob';
3281             }
3282 0         0  
  247         672  
3283             # doit if, doit unless, doit while, doit until, doit for, doit when
3284             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3285 247         899  
  18         31  
3286 18         59 # subroutines of package Egreek
  0         0  
3287 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         24  
3288 13         40 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3289 0         0 elsif (/\G \b Greek::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         272  
3290 114         452 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         4  
3291 2         6 elsif (/\G \b Greek::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Greek::escape'; }
  0         0  
3292 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         5  
3293 2         5 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::chop'; }
  0         0  
3294 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3295 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3296 0         0 elsif (/\G \b Greek::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Greek::index'; }
  2         5  
3297 2         6 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::index'; }
  0         0  
3298 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3299 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3300 0         0 elsif (/\G \b Greek::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Greek::rindex'; }
  1         3  
3301 1         5 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::rindex'; }
  0         0  
3302 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egreek::lc'; }
  1         3  
3303 1         4 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egreek::lcfirst'; }
  0         0  
3304 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egreek::uc'; }
  6         15  
3305             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egreek::ucfirst'; }
3306             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egreek::fc'; }
3307 6         96  
  0         0  
3308 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3309 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3310 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3311 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3312 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3313 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3314             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3315 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  
3316 0         0  
  0         0  
3317 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3318 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3319 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3320 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3321 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3322             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3323             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3324 0         0  
  0         0  
3325 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3326 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3327 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3328             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3329 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         5  
3330 2         6  
  2         5  
3331 2         7 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         70  
3332 36         112 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         4  
3333 2         7 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egreek::chr'; }
  8         16  
3334 8         25 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3335 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3336 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egreek::glob'; }
  0         0  
3337 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::lc_'; }
  0         0  
3338 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::lcfirst_'; }
  0         0  
3339 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::uc_'; }
  0         0  
3340 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::ucfirst_'; }
  0         0  
3341             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::fc_'; }
3342 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3343 0         0  
  0         0  
3344 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3345 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3346 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::chr_'; }
  0         0  
3347 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3348 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3349 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egreek::glob_'; }
  8         22  
3350             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3351             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3352 8         31 # split
3353             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3354 87         182 $slash = 'm//';
3355 87         125  
3356 87         354 my $e = '';
3357             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3358             $e .= $1;
3359             }
3360 85 100       339  
  87 100       6183  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3361             # end of split
3362             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Egreek::split' . $e; }
3363 2         10  
3364             # split scalar value
3365             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Egreek::split' . $e . e_string($1); }
3366 1         5  
3367 0         0 # split literal space
3368 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Egreek::split' . $e . qq {qq$1 $2}; }
3369 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Egreek::split' . $e . qq{$1qq$2 $3}; }
3370 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Egreek::split' . $e . qq{$1qq$2 $3}; }
3371 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Egreek::split' . $e . qq{$1qq$2 $3}; }
3372 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Egreek::split' . $e . qq{$1qq$2 $3}; }
3373 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Egreek::split' . $e . qq{$1qq$2 $3}; }
3374 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Egreek::split' . $e . qq {q$1 $2}; }
3375 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Egreek::split' . $e . qq {$1q$2 $3}; }
3376 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Egreek::split' . $e . qq {$1q$2 $3}; }
3377 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Egreek::split' . $e . qq {$1q$2 $3}; }
3378 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Egreek::split' . $e . qq {$1q$2 $3}; }
3379 10         42 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Egreek::split' . $e . qq {$1q$2 $3}; }
3380             elsif (/\G ' [ ] ' /oxgc) { return 'Egreek::split' . $e . qq {' '}; }
3381             elsif (/\G " [ ] " /oxgc) { return 'Egreek::split' . $e . qq {" "}; }
3382              
3383 0 0       0 # split qq//
  0         0  
3384             elsif (/\G \b (qq) \b /oxgc) {
3385 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3386 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3387 0         0 while (not /\G \z/oxgc) {
3388 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3389 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3390 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3391 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3392 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3393             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3394 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3395             }
3396             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3397             }
3398             }
3399              
3400 0 50       0 # split qr//
  12         424  
3401             elsif (/\G \b (qr) \b /oxgc) {
3402 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3403 12 50       64 else {
  12 50       3566  
    50          
    50          
    50          
    50          
    50          
    50          
3404 0         0 while (not /\G \z/oxgc) {
3405 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3406 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3407 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3408 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3409 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3410 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3411             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3412 12         94 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3413             }
3414             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3415             }
3416             }
3417              
3418 0 0       0 # split q//
  0         0  
3419             elsif (/\G \b (q) \b /oxgc) {
3420 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3421 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3422 0         0 while (not /\G \z/oxgc) {
3423 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3424 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3425 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3426 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3427 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3428             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3429 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3430             }
3431             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3432             }
3433             }
3434              
3435 0 50       0 # split m//
  18         472  
3436             elsif (/\G \b (m) \b /oxgc) {
3437 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3438 18 50       76 else {
  18 50       3970  
    50          
    50          
    50          
    50          
    50          
    50          
3439 0         0 while (not /\G \z/oxgc) {
3440 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3441 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3442 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3443 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3444 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3445 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3446             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3447 18         107 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3448             }
3449             die __FILE__, ": Search pattern not terminated\n";
3450             }
3451             }
3452              
3453 0         0 # split ''
3454 0         0 elsif (/\G (\') /oxgc) {
3455 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3456 0         0 while (not /\G \z/oxgc) {
3457 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3458 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3459             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3460 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3461             }
3462             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3463             }
3464              
3465 0         0 # split ""
3466 0         0 elsif (/\G (\") /oxgc) {
3467 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3468 0         0 while (not /\G \z/oxgc) {
3469 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3470 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3471             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3472 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3473             }
3474             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3475             }
3476              
3477 0         0 # split //
3478 44         123 elsif (/\G (\/) /oxgc) {
3479 44 50       148 my $regexp = '';
  381 50       1561  
    100          
    50          
3480 0         0 while (not /\G \z/oxgc) {
3481 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3482 44         188 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3483             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3484 337         686 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3485             }
3486             die __FILE__, ": Search pattern not terminated\n";
3487             }
3488             }
3489              
3490             # tr/// or y///
3491              
3492             # about [cdsrbB]* (/B modifier)
3493             #
3494             # P.559 appendix C
3495             # of ISBN 4-89052-384-7 Programming perl
3496             # (Japanese title is: Perl puroguramingu)
3497 0         0  
3498             elsif (/\G \b ( tr | y ) \b /oxgc) {
3499             my $ope = $1;
3500 3 50       7  
3501 3         42 # $1 $2 $3 $4 $5 $6
3502 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3503             my @tr = ($tr_variable,$2);
3504             return e_tr(@tr,'',$4,$6);
3505 0         0 }
3506 3         6 else {
3507 3 50       8 my $e = '';
  3 50       372  
    50          
    50          
    50          
    50          
3508             while (not /\G \z/oxgc) {
3509 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3510 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3511 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3512 0         0 while (not /\G \z/oxgc) {
3513 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3514 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3515 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3516 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3517             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3518 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3519             }
3520             die __FILE__, ": Transliteration replacement not terminated\n";
3521 0         0 }
3522 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3523 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3524 0         0 while (not /\G \z/oxgc) {
3525 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3526 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3527 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3528 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3529             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3530 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3531             }
3532             die __FILE__, ": Transliteration replacement not terminated\n";
3533 0         0 }
3534 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3535 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3536 0         0 while (not /\G \z/oxgc) {
3537 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3538 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3539 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3540 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3541             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3542 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3543             }
3544             die __FILE__, ": Transliteration replacement not terminated\n";
3545 0         0 }
3546 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3547 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3548 0         0 while (not /\G \z/oxgc) {
3549 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3550 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3551 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3552 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3553             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3554 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3555             }
3556             die __FILE__, ": Transliteration replacement not terminated\n";
3557             }
3558 0         0 # $1 $2 $3 $4 $5 $6
3559 3         12 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3560             my @tr = ($tr_variable,$2);
3561             return e_tr(@tr,'',$4,$6);
3562 3         8 }
3563             }
3564             die __FILE__, ": Transliteration pattern not terminated\n";
3565             }
3566             }
3567              
3568 0         0 # qq//
3569             elsif (/\G \b (qq) \b /oxgc) {
3570             my $ope = $1;
3571 2179 50       5265  
3572 2179         4401 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3573 0         0 if (/\G (\#) /oxgc) { # qq# #
3574 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3575 0         0 while (not /\G \z/oxgc) {
3576 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3577 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3578             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3579 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3580             }
3581             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3582             }
3583 0         0  
3584 2179         3043 else {
3585 2179 50       14731 my $e = '';
  2179 50       9110  
    100          
    50          
    50          
    0          
3586             while (not /\G \z/oxgc) {
3587             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3588              
3589 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3590 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3591 0         0 my $qq_string = '';
3592 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3593 0         0 while (not /\G \z/oxgc) {
3594 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3595             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3596 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3597 0         0 elsif (/\G (\)) /oxgc) {
3598             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3599 0         0 else { $qq_string .= $1; }
3600             }
3601 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3602             }
3603             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3604             }
3605              
3606 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3607 2149         2730 elsif (/\G (\{) /oxgc) { # qq { }
3608 2149         3099 my $qq_string = '';
3609 2149 100       4327 local $nest = 1;
  83963 50       255372  
    100          
    100          
    50          
3610 722         1533 while (not /\G \z/oxgc) {
3611 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         1514  
3612             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3613 1153 100       2021 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3302         5148  
3614 2149         4370 elsif (/\G (\}) /oxgc) {
3615             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3616 1153         2269 else { $qq_string .= $1; }
3617             }
3618 78786         157270 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3619             }
3620             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3621             }
3622              
3623 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3624 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3625 0         0 my $qq_string = '';
3626 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3627 0         0 while (not /\G \z/oxgc) {
3628 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3629             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3630 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3631 0         0 elsif (/\G (\]) /oxgc) {
3632             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3633 0         0 else { $qq_string .= $1; }
3634             }
3635 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3636             }
3637             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3638             }
3639              
3640 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3641 30         49 elsif (/\G (\<) /oxgc) { # qq < >
3642 30         55 my $qq_string = '';
3643 30 100       95 local $nest = 1;
  1166 50       4565  
    50          
    100          
    50          
3644 22         51 while (not /\G \z/oxgc) {
3645 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3646             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3647 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         68  
3648 30         78 elsif (/\G (\>) /oxgc) {
3649             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3650 0         0 else { $qq_string .= $1; }
3651             }
3652 1114         2114 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3653             }
3654             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3655             }
3656              
3657 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3658 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3659 0         0 my $delimiter = $1;
3660 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3661 0         0 while (not /\G \z/oxgc) {
3662 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3663 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3664             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3665 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3666             }
3667             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3668 0         0 }
3669             }
3670             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3671             }
3672             }
3673              
3674 0         0 # qr//
3675 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3676 0         0 my $ope = $1;
3677             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3678             return e_qr($ope,$1,$3,$2,$4);
3679 0         0 }
3680 0         0 else {
3681 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3682 0         0 while (not /\G \z/oxgc) {
3683 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3684 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3685 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3686 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3687 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3688 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3689             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3690 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3691             }
3692             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3693             }
3694             }
3695              
3696 0         0 # qw//
3697 16 50       50 elsif (/\G \b (qw) \b /oxgc) {
3698 16         69 my $ope = $1;
3699             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3700             return e_qw($ope,$1,$3,$2);
3701 0         0 }
3702 16         29 else {
3703 16 50       53 my $e = '';
  16 50       116  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3704             while (not /\G \z/oxgc) {
3705 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3706 16         54  
3707             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3708 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3709 0         0  
3710             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3711 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3712 0         0  
3713             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3714 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3715 0         0  
3716             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3717 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3718 0         0  
3719             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3720 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3721             }
3722             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3723             }
3724             }
3725              
3726 0         0 # qx//
3727 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3728 0         0 my $ope = $1;
3729             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3730             return e_qq($ope,$1,$3,$2);
3731 0         0 }
3732 0         0 else {
3733 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3734 0         0 while (not /\G \z/oxgc) {
3735 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3736 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3737 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3738 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3739 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3740             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3741 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3742             }
3743             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3744             }
3745             }
3746              
3747 0         0 # q//
3748             elsif (/\G \b (q) \b /oxgc) {
3749             my $ope = $1;
3750              
3751             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3752              
3753             # avoid "Error: Runtime exception" of perl version 5.005_03
3754 410 50       1235 # (and so on)
3755 410         1527  
3756 0         0 if (/\G (\#) /oxgc) { # q# #
3757 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3758 0         0 while (not /\G \z/oxgc) {
3759 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3760 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3761             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3762 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3763             }
3764             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3765             }
3766 0         0  
3767 410         653 else {
3768 410 50       1173 my $e = '';
  410 50       2046  
    100          
    50          
    100          
    50          
3769             while (not /\G \z/oxgc) {
3770             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3771              
3772 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3773 0         0 elsif (/\G (\() /oxgc) { # q ( )
3774 0         0 my $q_string = '';
3775 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3776 0         0 while (not /\G \z/oxgc) {
3777 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3778 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3779             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3780 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3781 0         0 elsif (/\G (\)) /oxgc) {
3782             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3783 0         0 else { $q_string .= $1; }
3784             }
3785 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3786             }
3787             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3788             }
3789              
3790 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3791 404         655 elsif (/\G (\{) /oxgc) { # q { }
3792 404         708 my $q_string = '';
3793 404 50       1184 local $nest = 1;
  6757 50       25464  
    50          
    100          
    100          
    50          
3794 0         0 while (not /\G \z/oxgc) {
3795 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3796 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         160  
3797             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3798 107 100       281 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         1073  
3799 404         1104 elsif (/\G (\}) /oxgc) {
3800             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3801 107         210 else { $q_string .= $1; }
3802             }
3803 6139         11878 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3804             }
3805             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3806             }
3807              
3808 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3809 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3810 0         0 my $q_string = '';
3811 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3812 0         0 while (not /\G \z/oxgc) {
3813 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3814 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3815             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3816 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3817 0         0 elsif (/\G (\]) /oxgc) {
3818             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3819 0         0 else { $q_string .= $1; }
3820             }
3821 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3822             }
3823             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3824             }
3825              
3826 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3827 5         10 elsif (/\G (\<) /oxgc) { # q < >
3828 5         9 my $q_string = '';
3829 5 50       17 local $nest = 1;
  88 50       367  
    50          
    50          
    100          
    50          
3830 0         0 while (not /\G \z/oxgc) {
3831 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3832 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3833             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3834 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         14  
3835 5         13 elsif (/\G (\>) /oxgc) {
3836             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3837 0         0 else { $q_string .= $1; }
3838             }
3839 83         221 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3840             }
3841             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3842             }
3843              
3844 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3845 1         3 elsif (/\G (\S) /oxgc) { # q * *
3846 1         1 my $delimiter = $1;
3847 1 50       3 my $q_string = '';
  14 50       89  
    100          
    50          
3848 0         0 while (not /\G \z/oxgc) {
3849 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3850 1         111 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3851             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3852 13         29 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3853             }
3854             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3855 0         0 }
3856             }
3857             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3858             }
3859             }
3860              
3861 0         0 # m//
3862 209 50       482 elsif (/\G \b (m) \b /oxgc) {
3863 209         1421 my $ope = $1;
3864             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3865             return e_qr($ope,$1,$3,$2,$4);
3866 0         0 }
3867 209         336 else {
3868 209 50       537 my $e = '';
  209 50       10920  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3869 0         0 while (not /\G \z/oxgc) {
3870 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3871 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3872 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3873 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3874 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3875 10         28 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3876 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3877             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3878 199         611 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3879             }
3880             die __FILE__, ": Search pattern not terminated\n";
3881             }
3882             }
3883              
3884             # s///
3885              
3886             # about [cegimosxpradlunbB]* (/cg modifier)
3887             #
3888             # P.67 Pattern-Matching Operators
3889             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3890 0         0  
3891             elsif (/\G \b (s) \b /oxgc) {
3892             my $ope = $1;
3893 97 100       271  
3894 97         1812 # $1 $2 $3 $4 $5 $6
3895             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3896             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3897 1         4 }
3898 96         180 else {
3899 96 50       288 my $e = '';
  96 50       12105  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3900             while (not /\G \z/oxgc) {
3901 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3902 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3903 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3904             while (not /\G \z/oxgc) {
3905 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3906 0         0 # $1 $2 $3 $4
3907 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3908 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3909 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3910 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3911 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3912 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3913 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3914             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3915 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3916             }
3917             die __FILE__, ": Substitution replacement not terminated\n";
3918 0         0 }
3919 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3920 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3921             while (not /\G \z/oxgc) {
3922 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3923 0         0 # $1 $2 $3 $4
3924 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3925 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3926 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3927 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3928 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3929 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3930 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3931             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3932 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3933             }
3934             die __FILE__, ": Substitution replacement not terminated\n";
3935 0         0 }
3936 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3937 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3938             while (not /\G \z/oxgc) {
3939 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3940 0         0 # $1 $2 $3 $4
3941 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3942 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3943 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3944 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3945 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3946             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3947 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3948             }
3949             die __FILE__, ": Substitution replacement not terminated\n";
3950 0         0 }
3951 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3952 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3953             while (not /\G \z/oxgc) {
3954 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3955 0         0 # $1 $2 $3 $4
3956 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3957 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3958 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3960 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3961 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3962 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3963             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3964 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3965             }
3966             die __FILE__, ": Substitution replacement not terminated\n";
3967             }
3968 0         0 # $1 $2 $3 $4 $5 $6
3969             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3970             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3971             }
3972 21         55 # $1 $2 $3 $4 $5 $6
3973             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3974             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3975             }
3976 0         0 # $1 $2 $3 $4 $5 $6
3977             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3978             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3979             }
3980 0         0 # $1 $2 $3 $4 $5 $6
3981             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3982             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3983 75         327 }
3984             }
3985             die __FILE__, ": Substitution pattern not terminated\n";
3986             }
3987             }
3988 0         0  
3989 0         0 # require ignore module
3990 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
3991             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
3992             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
3993 0         0  
3994 37         294 # use strict; --> use strict; no strict qw(refs);
3995 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
3996             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
3997             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
3998              
3999 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
4000 2         21 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4001             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4002             return "use $1; no strict qw(refs);";
4003 0         0 }
4004             else {
4005             return "use $1;";
4006             }
4007 2 0 0     11 }
      0        
4008 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4009             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4010             return "use $1; no strict qw(refs);";
4011 0         0 }
4012             else {
4013             return "use $1;";
4014             }
4015             }
4016 0         0  
4017 2         13 # ignore use module
4018 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4019             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4020             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4021 0         0  
4022 0         0 # ignore no module
4023 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4024             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4025             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4026 0         0  
4027             # use else
4028             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4029 0         0  
4030             # use else
4031             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4032              
4033 2         8 # ''
4034 848         1748 elsif (/\G (?
4035 848 100       2099 my $q_string = '';
  8241 100       25179  
    100          
    50          
4036 4         9 while (not /\G \z/oxgc) {
4037 48         92 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4038 848         1990 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4039             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4040 7341         14331 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4041             }
4042             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4043             }
4044              
4045 0         0 # ""
4046 1782         3487 elsif (/\G (\") /oxgc) {
4047 1782 100       4604 my $qq_string = '';
  34702 100       108950  
    100          
    50          
4048 67         152 while (not /\G \z/oxgc) {
4049 12         22 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4050 1782         3972 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4051             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4052 32841         79501 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4053             }
4054             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4055             }
4056              
4057 0         0 # ``
4058 1         2 elsif (/\G (\`) /oxgc) {
4059 1 50       4 my $qx_string = '';
  19 50       64  
    100          
    50          
4060 0         0 while (not /\G \z/oxgc) {
4061 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4062 1         3 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4063             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4064 18         31 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4065             }
4066             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4067             }
4068              
4069 0         0 # // --- not divide operator (num / num), not defined-or
4070 453         1445 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4071 453 50       1268 my $regexp = '';
  4496 50       26105  
    100          
    50          
4072 0         0 while (not /\G \z/oxgc) {
4073 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4074 453         2047 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4075             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4076 4043         15625 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4077             }
4078             die __FILE__, ": Search pattern not terminated\n";
4079             }
4080              
4081 0         0 # ?? --- not conditional operator (condition ? then : else)
4082 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4083 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4084 0         0 while (not /\G \z/oxgc) {
4085 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4086 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4087             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4088 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4089             }
4090             die __FILE__, ": Search pattern not terminated\n";
4091             }
4092 0         0  
  0         0  
4093             # <<>> (a safer ARGV)
4094             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4095 0         0  
  0         0  
4096             # << (bit shift) --- not here document
4097             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4098              
4099 0         0 # <<~'HEREDOC'
4100 6         12 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4101 6         12 $slash = 'm//';
4102             my $here_quote = $1;
4103             my $delimiter = $2;
4104 6 50       8  
4105 6         12 # get here document
4106 6         39 if ($here_script eq '') {
4107             $here_script = CORE::substr $_, pos $_;
4108 6 50       30 $here_script =~ s/.*?\n//oxm;
4109 6         54 }
4110 6         10 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4111 6         9 my $heredoc = $1;
4112 6         42 my $indent = $2;
4113 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4114             push @heredoc, $heredoc . qq{\n$delimiter\n};
4115             push @heredoc_delimiter, qq{\\s*$delimiter};
4116 6         13 }
4117             else {
4118 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4119             }
4120             return qq{<<'$delimiter'};
4121             }
4122              
4123             # <<~\HEREDOC
4124              
4125             # P.66 2.6.6. "Here" Documents
4126             # in Chapter 2: Bits and Pieces
4127             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4128              
4129             # P.73 "Here" Documents
4130             # in Chapter 2: Bits and Pieces
4131             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4132 6         23  
4133 3         6 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4134 3         6 $slash = 'm//';
4135             my $here_quote = $1;
4136             my $delimiter = $2;
4137 3 50       5  
4138 3         8 # get here document
4139 3         9 if ($here_script eq '') {
4140             $here_script = CORE::substr $_, pos $_;
4141 3 50       26 $here_script =~ s/.*?\n//oxm;
4142 3         37 }
4143 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4144 3         5 my $heredoc = $1;
4145 3         40 my $indent = $2;
4146 3         11 $heredoc =~ s{^$indent}{}msg; # no /ox
4147             push @heredoc, $heredoc . qq{\n$delimiter\n};
4148             push @heredoc_delimiter, qq{\\s*$delimiter};
4149 3         6 }
4150             else {
4151 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4152             }
4153             return qq{<<\\$delimiter};
4154             }
4155              
4156 3         14 # <<~"HEREDOC"
4157 6         13 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4158 6         11 $slash = 'm//';
4159             my $here_quote = $1;
4160             my $delimiter = $2;
4161 6 50       9  
4162 6         12 # get here document
4163 6         27 if ($here_script eq '') {
4164             $here_script = CORE::substr $_, pos $_;
4165 6 50       31 $here_script =~ s/.*?\n//oxm;
4166 6         67 }
4167 6         12 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4168 6         8 my $heredoc = $1;
4169 6         48 my $indent = $2;
4170 6         15 $heredoc =~ s{^$indent}{}msg; # no /ox
4171             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4172             push @heredoc_delimiter, qq{\\s*$delimiter};
4173 6         13 }
4174             else {
4175 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4176             }
4177             return qq{<<"$delimiter"};
4178             }
4179              
4180 6         45 # <<~HEREDOC
4181 3         7 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4182 3         7 $slash = 'm//';
4183             my $here_quote = $1;
4184             my $delimiter = $2;
4185 3 50       6  
4186 3         8 # get here document
4187 3         10 if ($here_script eq '') {
4188             $here_script = CORE::substr $_, pos $_;
4189 3 50       27 $here_script =~ s/.*?\n//oxm;
4190 3         41 }
4191 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4192 3         4 my $heredoc = $1;
4193 3         44 my $indent = $2;
4194 3         12 $heredoc =~ s{^$indent}{}msg; # no /ox
4195             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4196             push @heredoc_delimiter, qq{\\s*$delimiter};
4197 3         10 }
4198             else {
4199 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4200             }
4201             return qq{<<$delimiter};
4202             }
4203              
4204 3         10 # <<~`HEREDOC`
4205 6         61 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4206 6         19 $slash = 'm//';
4207             my $here_quote = $1;
4208             my $delimiter = $2;
4209 6 50       11  
4210 6         17 # get here document
4211 6         20 if ($here_script eq '') {
4212             $here_script = CORE::substr $_, pos $_;
4213 6 50       83 $here_script =~ s/.*?\n//oxm;
4214 6         65 }
4215 6         15 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4216 6         10 my $heredoc = $1;
4217 6         62 my $indent = $2;
4218 6         20 $heredoc =~ s{^$indent}{}msg; # no /ox
4219             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4220             push @heredoc_delimiter, qq{\\s*$delimiter};
4221 6         15 }
4222             else {
4223 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4224             }
4225             return qq{<<`$delimiter`};
4226             }
4227              
4228 6         27 # <<'HEREDOC'
4229 72         141 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4230 72         368 $slash = 'm//';
4231             my $here_quote = $1;
4232             my $delimiter = $2;
4233 72 50       116  
4234 72         143 # get here document
4235 72         496 if ($here_script eq '') {
4236             $here_script = CORE::substr $_, pos $_;
4237 72 50       400 $here_script =~ s/.*?\n//oxm;
4238 72         807 }
4239 72         290 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4240             push @heredoc, $1 . qq{\n$delimiter\n};
4241             push @heredoc_delimiter, $delimiter;
4242 72         105 }
4243             else {
4244 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4245             }
4246             return $here_quote;
4247             }
4248              
4249             # <<\HEREDOC
4250              
4251             # P.66 2.6.6. "Here" Documents
4252             # in Chapter 2: Bits and Pieces
4253             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4254              
4255             # P.73 "Here" Documents
4256             # in Chapter 2: Bits and Pieces
4257             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4258 72         281  
4259 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4260 0         0 $slash = 'm//';
4261             my $here_quote = $1;
4262             my $delimiter = $2;
4263 0 0       0  
4264 0         0 # get here document
4265 0         0 if ($here_script eq '') {
4266             $here_script = CORE::substr $_, pos $_;
4267 0 0       0 $here_script =~ s/.*?\n//oxm;
4268 0         0 }
4269 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4270             push @heredoc, $1 . qq{\n$delimiter\n};
4271             push @heredoc_delimiter, $delimiter;
4272 0         0 }
4273             else {
4274 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4275             }
4276             return $here_quote;
4277             }
4278              
4279 0         0 # <<"HEREDOC"
4280 36         85 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4281 36         83 $slash = 'm//';
4282             my $here_quote = $1;
4283             my $delimiter = $2;
4284 36 50       66  
4285 36         94 # get here document
4286 36         261 if ($here_script eq '') {
4287             $here_script = CORE::substr $_, pos $_;
4288 36 50       209 $here_script =~ s/.*?\n//oxm;
4289 36         505 }
4290 36         116 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4291             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4292             push @heredoc_delimiter, $delimiter;
4293 36         87 }
4294             else {
4295 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4296             }
4297             return $here_quote;
4298             }
4299              
4300 36         136 # <
4301 42         98 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4302 42         92 $slash = 'm//';
4303             my $here_quote = $1;
4304             my $delimiter = $2;
4305 42 50       80  
4306 42         126 # get here document
4307 42         279 if ($here_script eq '') {
4308             $here_script = CORE::substr $_, pos $_;
4309 42 50       298 $here_script =~ s/.*?\n//oxm;
4310 42         593 }
4311 42         137 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4312             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4313             push @heredoc_delimiter, $delimiter;
4314 42         101 }
4315             else {
4316 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4317             }
4318             return $here_quote;
4319             }
4320              
4321 42         177 # <<`HEREDOC`
4322 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4323 0         0 $slash = 'm//';
4324             my $here_quote = $1;
4325             my $delimiter = $2;
4326 0 0       0  
4327 0         0 # get here document
4328 0         0 if ($here_script eq '') {
4329             $here_script = CORE::substr $_, pos $_;
4330 0 0       0 $here_script =~ s/.*?\n//oxm;
4331 0         0 }
4332 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4333             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4334             push @heredoc_delimiter, $delimiter;
4335 0         0 }
4336             else {
4337 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4338             }
4339             return $here_quote;
4340             }
4341              
4342 0         0 # <<= <=> <= < operator
4343             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4344             return $1;
4345             }
4346              
4347 12         64 #
4348             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4349             return $1;
4350             }
4351              
4352             # --- glob
4353              
4354             # avoid "Error: Runtime exception" of perl version 5.005_03
4355 0         0  
4356             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4357             return 'Egreek::glob("' . $1 . '")';
4358             }
4359 0         0  
4360             # __DATA__
4361             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4362 0         0  
4363             # __END__
4364             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4365              
4366             # \cD Control-D
4367              
4368             # P.68 2.6.8. Other Literal Tokens
4369             # in Chapter 2: Bits and Pieces
4370             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4371              
4372             # P.76 Other Literal Tokens
4373             # in Chapter 2: Bits and Pieces
4374 204         1449 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4375              
4376             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4377 0         0  
4378             # \cZ Control-Z
4379             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4380              
4381             # any operator before div
4382             elsif (/\G (
4383             -- | \+\+ |
4384 0         0 [\)\}\]]
  5076         10660  
4385              
4386             ) /oxgc) { $slash = 'div'; return $1; }
4387              
4388             # yada-yada or triple-dot operator
4389             elsif (/\G (
4390 5076         22456 \.\.\.
  7         14  
4391              
4392             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4393              
4394             # any operator before m//
4395              
4396             # //, //= (defined-or)
4397              
4398             # P.164 Logical Operators
4399             # in Chapter 10: More Control Structures
4400             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4401              
4402             # P.119 C-Style Logical (Short-Circuit) Operators
4403             # in Chapter 3: Unary and Binary Operators
4404             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4405              
4406             # (and so on)
4407              
4408             # ~~
4409              
4410             # P.221 The Smart Match Operator
4411             # in Chapter 15: Smart Matching and given-when
4412             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4413              
4414             # P.112 Smartmatch Operator
4415             # in Chapter 3: Unary and Binary Operators
4416             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4417              
4418             # (and so on)
4419              
4420             elsif (/\G ((?>
4421              
4422             !~~ | !~ | != | ! |
4423             %= | % |
4424             &&= | && | &= | &\.= | &\. | & |
4425             -= | -> | - |
4426             :(?>\s*)= |
4427             : |
4428             <<>> |
4429             <<= | <=> | <= | < |
4430             == | => | =~ | = |
4431             >>= | >> | >= | > |
4432             \*\*= | \*\* | \*= | \* |
4433             \+= | \+ |
4434             \.\. | \.= | \. |
4435             \/\/= | \/\/ |
4436             \/= | \/ |
4437             \? |
4438             \\ |
4439             \^= | \^\.= | \^\. | \^ |
4440             \b x= |
4441             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4442             ~~ | ~\. | ~ |
4443             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4444             \b(?: print )\b |
4445              
4446 7         24 [,;\(\{\[]
  8829         16673  
4447              
4448             )) /oxgc) { $slash = 'm//'; return $1; }
4449 8829         39873  
  14981         28600  
4450             # other any character
4451             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4452              
4453 14981         67877 # system error
4454             else {
4455             die __FILE__, ": Oops, this shouldn't happen!\n";
4456             }
4457             }
4458              
4459 0     1786 0 0 # escape Greek string
4460 1786         4107 sub e_string {
4461             my($string) = @_;
4462 1786         2791 my $e_string = '';
4463              
4464             local $slash = 'm//';
4465              
4466             # P.1024 Appendix W.10 Multibyte Processing
4467             # of ISBN 1-56592-224-7 CJKV Information Processing
4468 1786         2545 # (and so on)
4469              
4470             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4471 1786 100 66     15468  
4472 1786 50       7788 # without { ... }
4473 1769         3950 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4474             if ($string !~ /<
4475             return $string;
4476             }
4477             }
4478 1769         4144  
4479 17 50       69 E_STRING_LOOP:
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
4480             while ($string !~ /\G \z/oxgc) {
4481             if (0) {
4482             }
4483 190         11898  
4484 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Egreek::PREMATCH()]}
4485 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4486             $e_string .= q{Egreek::PREMATCH()};
4487             $slash = 'div';
4488             }
4489              
4490 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Egreek::MATCH()]}
4491 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4492             $e_string .= q{Egreek::MATCH()};
4493             $slash = 'div';
4494             }
4495              
4496 0         0 # $', ${'} --> $', ${'}
4497 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4498             $e_string .= $1;
4499             $slash = 'div';
4500             }
4501              
4502 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Egreek::POSTMATCH()]}
4503 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4504             $e_string .= q{Egreek::POSTMATCH()};
4505             $slash = 'div';
4506             }
4507              
4508 0         0 # bareword
4509 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4510             $e_string .= $1;
4511             $slash = 'div';
4512             }
4513              
4514 0         0 # $0 --> $0
4515 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4516             $e_string .= $1;
4517             $slash = 'div';
4518 0         0 }
4519 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4520             $e_string .= $1;
4521             $slash = 'div';
4522             }
4523              
4524 0         0 # $$ --> $$
4525 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4526             $e_string .= $1;
4527             $slash = 'div';
4528             }
4529              
4530             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4531 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4532 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4533             $e_string .= e_capture($1);
4534             $slash = 'div';
4535 0         0 }
4536 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4537             $e_string .= e_capture($1);
4538             $slash = 'div';
4539             }
4540              
4541 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4542 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4543             $e_string .= e_capture($1.'->'.$2);
4544             $slash = 'div';
4545             }
4546              
4547 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4548 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4549             $e_string .= e_capture($1.'->'.$2);
4550             $slash = 'div';
4551             }
4552              
4553 0         0 # $$foo
4554 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4555             $e_string .= e_capture($1);
4556             $slash = 'div';
4557             }
4558              
4559 0         0 # ${ foo }
4560 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4561             $e_string .= '${' . $1 . '}';
4562             $slash = 'div';
4563             }
4564              
4565 0         0 # ${ ... }
4566 3         10 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4567             $e_string .= e_capture($1);
4568             $slash = 'div';
4569             }
4570              
4571             # variable or function
4572 3         14 # $ @ % & * $ #
4573 7         21 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) {
4574             $e_string .= $1;
4575             $slash = 'div';
4576             }
4577             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4578 7         23 # $ @ # \ ' " / ? ( ) [ ] < >
4579 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4580             $e_string .= $1;
4581             $slash = 'div';
4582             }
4583 0         0  
  0         0  
4584 0         0 # subroutines of package Egreek
  0         0  
4585 0         0 elsif ($string =~ /\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $e_string .= $1; $slash = 'm//'; }
  0         0  
4586 0         0 elsif ($string =~ /\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4587 0         0 elsif ($string =~ /\G \b Greek::eval (?= (?>\s*) \{ ) /oxgc) { $e_string .= 'eval'; $slash = 'm//'; }
  0         0  
4588 0         0 elsif ($string =~ /\G \b Char::eval \b /oxgc) { $e_string .= 'eval Char::escape'; $slash = 'm//'; }
  0         0  
4589 0         0 elsif ($string =~ /\G \b Greek::eval \b /oxgc) { $e_string .= 'eval Greek::escape'; $slash = 'm//'; }
  0         0  
4590 0         0 elsif ($string =~ /\G \b bytes::substr \b /oxgc) { $e_string .= 'substr'; $slash = 'm//'; }
  0         0  
4591 0         0 elsif ($string =~ /\G \b chop \b /oxgc) { $e_string .= 'Egreek::chop'; $slash = 'm//'; }
  0         0  
4592 0         0 elsif ($string =~ /\G \b bytes::index \b /oxgc) { $e_string .= 'index'; $slash = 'm//'; }
  0         0  
4593 0         0 elsif ($string =~ /\G \b Char::index \b /oxgc) { $e_string .= 'Char::index'; $slash = 'm//'; }
  0         0  
4594 0         0 elsif ($string =~ /\G \b Greek::index \b /oxgc) { $e_string .= 'Greek::index'; $slash = 'm//'; }
  0         0  
4595 0         0 elsif ($string =~ /\G \b index \b /oxgc) { $e_string .= 'Egreek::index'; $slash = 'm//'; }
  0         0  
4596 0         0 elsif ($string =~ /\G \b bytes::rindex \b /oxgc) { $e_string .= 'rindex'; $slash = 'm//'; }
  0         0  
4597 0         0 elsif ($string =~ /\G \b Char::rindex \b /oxgc) { $e_string .= 'Char::rindex'; $slash = 'm//'; }
  0         0  
4598 0         0 elsif ($string =~ /\G \b Greek::rindex \b /oxgc) { $e_string .= 'Greek::rindex'; $slash = 'm//'; }
  0         0  
4599 0         0 elsif ($string =~ /\G \b rindex \b /oxgc) { $e_string .= 'Egreek::rindex'; $slash = 'm//'; }
  0         0  
4600 0         0 elsif ($string =~ /\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Egreek::lc'; $slash = 'm//'; }
  0         0  
4601 0         0 elsif ($string =~ /\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Egreek::lcfirst'; $slash = 'm//'; }
  0         0  
4602 0         0 elsif ($string =~ /\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Egreek::uc'; $slash = 'm//'; }
  0         0  
4603             elsif ($string =~ /\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Egreek::ucfirst'; $slash = 'm//'; }
4604             elsif ($string =~ /\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Egreek::fc'; $slash = 'm//'; }
4605 0         0  
  0         0  
4606 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
4607 0         0 elsif ($string =~ /\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= '-s ' . e_qq('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4608 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4609 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4610 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4611 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4612             elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
4613 0         0 elsif ($string =~ /\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_qq('qq',$1,$3,$2); $slash = 'm//'; }
  0         0  
4614 0         0  
  0         0  
4615 0         0 elsif ($string =~ /\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= '-s ' . e_q ('', $1,$3,$2); $slash = 'm//'; }
  0         0  
4616 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4617 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4618 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4619 0         0 elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
  0         0  
4620             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4621             elsif ($string =~ /\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $e_string .= '-s ' . e_q ('q', $1,$3,$2); $slash = 'm//'; }
4622 0         0  
  0         0  
4623 0         0 elsif ($string =~ /\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ))*) /oxgc)
  0         0  
4624 0         0 { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4625 0         0 elsif ($string =~ /\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "-s ($1)"; $slash = 'm//'; }
  0         0  
4626             elsif ($string =~ /\G -s (?= (?>\s+) [a-z]+) /oxgc) { $e_string .= '-s'; $slash = 'm//'; }
4627 0         0 elsif ($string =~ /\G -s (?>\s+) ((?>\w+)) /oxgc) { $e_string .= "-s $1"; $slash = 'm//'; }
  0         0  
4628 0         0  
  0         0  
4629 0         0 elsif ($string =~ /\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4630 0         0 elsif ($string =~ /\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4631 0         0 elsif ($string =~ /\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Egreek::chr'; $slash = 'm//'; }
  0         0  
4632 0         0 elsif ($string =~ /\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4633 0         0 elsif ($string =~ /\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= $function_ord; $slash = 'div'; }
  0         0  
4634 0         0 elsif ($string =~ /\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $e_string .= 'Egreek::glob'; $slash = 'm//'; }
  0         0  
4635 0         0 elsif ($string =~ /\G \b lc \b /oxgc) { $e_string .= 'Egreek::lc_'; $slash = 'm//'; }
  0         0  
4636 0         0 elsif ($string =~ /\G \b lcfirst \b /oxgc) { $e_string .= 'Egreek::lcfirst_'; $slash = 'm//'; }
  0         0  
4637 0         0 elsif ($string =~ /\G \b uc \b /oxgc) { $e_string .= 'Egreek::uc_'; $slash = 'm//'; }
  0         0  
4638 0         0 elsif ($string =~ /\G \b ucfirst \b /oxgc) { $e_string .= 'Egreek::ucfirst_'; $slash = 'm//'; }
  0         0  
4639             elsif ($string =~ /\G \b fc \b /oxgc) { $e_string .= 'Egreek::fc_'; $slash = 'm//'; }
4640 0         0 elsif ($string =~ /\G -s \b /oxgc) { $e_string .= '-s '; $slash = 'm//'; }
  0         0  
4641 0         0  
  0         0  
4642 0         0 elsif ($string =~ /\G \b bytes::length \b /oxgc) { $e_string .= 'length'; $slash = 'm//'; }
  0         0  
4643 0         0 elsif ($string =~ /\G \b bytes::chr \b /oxgc) { $e_string .= 'chr'; $slash = 'm//'; }
  0         0  
4644 0         0 elsif ($string =~ /\G \b chr \b /oxgc) { $e_string .= 'Egreek::chr_'; $slash = 'm//'; }
  0         0  
4645 0         0 elsif ($string =~ /\G \b bytes::ord \b /oxgc) { $e_string .= 'ord'; $slash = 'div'; }
  0         0  
4646 0         0 elsif ($string =~ /\G \b ord \b /oxgc) { $e_string .= $function_ord_; $slash = 'div'; }
  0         0  
4647 0         0 elsif ($string =~ /\G \b glob \b /oxgc) { $e_string .= 'Egreek::glob_'; $slash = 'm//'; }
  0         0  
4648             elsif ($string =~ /\G \b reverse \b /oxgc) { $e_string .= $function_reverse; $slash = 'm//'; }
4649             elsif ($string =~ /\G \b getc \b /oxgc) { $e_string .= $function_getc; $slash = 'm//'; }
4650 0         0 # split
4651             elsif ($string =~ /\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
4652 0         0 $slash = 'm//';
4653 0         0  
4654 0         0 my $e = '';
4655             while ($string =~ /\G ( (?>\s+) | \( | \#.* ) /oxgc) {
4656             $e .= $1;
4657             }
4658 0 0       0  
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
4659             # end of split
4660             if ($string =~ /\G (?= [,;\)\}\]] ) /oxgc) { return 'Egreek::split' . $e; }
4661 0         0  
  0         0  
4662             # split scalar value
4663             elsif ($string =~ /\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { $e_string .= 'Egreek::split' . $e . e_string($1); next E_STRING_LOOP; }
4664 0         0  
  0         0  
4665 0         0 # split literal space
  0         0  
4666 0         0 elsif ($string =~ /\G \b qq (\#) [ ] (\#) /oxgc) { $e_string .= 'Egreek::split' . $e . qq {qq$1 $2}; next E_STRING_LOOP; }
  0         0  
4667 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Egreek::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4668 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Egreek::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4669 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Egreek::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4670 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Egreek::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4671 0         0 elsif ($string =~ /\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Egreek::split' . $e . qq{$1qq$2 $3}; next E_STRING_LOOP; }
  0         0  
4672 0         0 elsif ($string =~ /\G \b q (\#) [ ] (\#) /oxgc) { $e_string .= 'Egreek::split' . $e . qq {q$1 $2}; next E_STRING_LOOP; }
  0         0  
4673 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { $e_string .= 'Egreek::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4674 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { $e_string .= 'Egreek::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4675 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { $e_string .= 'Egreek::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4676 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { $e_string .= 'Egreek::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4677 0         0 elsif ($string =~ /\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { $e_string .= 'Egreek::split' . $e . qq {$1q$2 $3}; next E_STRING_LOOP; }
  0         0  
4678             elsif ($string =~ /\G ' [ ] ' /oxgc) { $e_string .= 'Egreek::split' . $e . qq {' '}; next E_STRING_LOOP; }
4679             elsif ($string =~ /\G " [ ] " /oxgc) { $e_string .= 'Egreek::split' . $e . qq {" "}; next E_STRING_LOOP; }
4680              
4681 0 0       0 # split qq//
  0         0  
  0         0  
4682             elsif ($string =~ /\G \b (qq) \b /oxgc) {
4683 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq# # --> qr # #
4684 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4685 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4686 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4687 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq ( ) --> qr ( )
  0         0  
4688 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq { } --> qr { }
  0         0  
4689 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq [ ] --> qr [ ]
  0         0  
4690 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq < > --> qr < >
  0         0  
4691             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # qq | | --> qr { }
4692 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= e_split($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # qq * * --> qr * *
4693             }
4694             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4695             }
4696             }
4697              
4698 0 0       0 # split qr//
  0         0  
  0         0  
4699             elsif ($string =~ /\G \b (qr) \b /oxgc) {
4700 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # qr# #
4701 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4702 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4703 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4704 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ( )
  0         0  
4705 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr { }
  0         0  
4706 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr [ ]
  0         0  
4707 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr < >
  0         0  
4708 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr ' '
  0         0  
4709             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # qr | | --> qr { }
4710 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # qr * *
4711             }
4712             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4713             }
4714             }
4715              
4716 0 0       0 # split q//
  0         0  
  0         0  
4717             elsif ($string =~ /\G \b (q) \b /oxgc) {
4718 0         0 if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q# # --> qr # #
4719 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4720 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4721 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4722 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q ( ) --> qr ( )
  0         0  
4723 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q { } --> qr { }
  0         0  
4724 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q [ ] --> qr [ ]
  0         0  
4725 0         0 elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q < > --> qr < >
  0         0  
4726             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr','{','}',$2,''); next E_STRING_LOOP; } # q | | --> qr { }
4727 0         0 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= e_split_q($e.'qr',$1,$3,$2,''); next E_STRING_LOOP; } # q * * --> qr * *
4728             }
4729             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4730             }
4731             }
4732              
4733 0 0       0 # split m//
  0         0  
  0         0  
4734             elsif ($string =~ /\G \b (m) \b /oxgc) {
4735 0         0 if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1,$3,$2,$4); next E_STRING_LOOP; } # m# # --> qr # #
4736 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
4737 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4738 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e_string .= $e . $1; }
  0         0  
4739 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ( ) --> qr ( )
  0         0  
4740 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m { } --> qr { }
  0         0  
4741 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m [ ] --> qr [ ]
  0         0  
4742 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m < > --> qr < >
  0         0  
4743 0         0 elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split_q($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m ' ' --> qr ' '
  0         0  
4744             elsif ($string =~ /\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr','{','}',$2,$4); next E_STRING_LOOP; } # m | | --> qr { }
4745 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split ($e.'qr',$1, $3, $2,$4); next E_STRING_LOOP; } # m * * --> qr * *
4746             }
4747             die __FILE__, ": Search pattern not terminated\n";
4748             }
4749             }
4750              
4751 0         0 # split ''
4752 0         0 elsif ($string =~ /\G (\') /oxgc) {
4753 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
4754 0         0 while ($string !~ /\G \z/oxgc) {
4755 0         0 if ($string =~ /\G (\\\\) /oxgc) { $q_string .= $1; }
  0         0  
4756 0         0 elsif ($string =~ /\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
4757             elsif ($string =~ /\G \' /oxgc) { $e_string .= e_split_q($e.q{ qr},"'","'",$q_string,''); next E_STRING_LOOP; } # ' ' --> qr ' '
4758 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $q_string .= $1; }
4759             }
4760             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4761             }
4762              
4763 0         0 # split ""
4764 0         0 elsif ($string =~ /\G (\") /oxgc) {
4765 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
4766 0         0 while ($string !~ /\G \z/oxgc) {
4767 0         0 if ($string =~ /\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
4768 0         0 elsif ($string =~ /\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
4769             elsif ($string =~ /\G \" /oxgc) { $e_string .= e_split($e.q{ qr},'"','"',$qq_string,''); next E_STRING_LOOP; } # " " --> qr " "
4770 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $qq_string .= $1; }
4771             }
4772             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4773             }
4774              
4775 0         0 # split //
4776 0         0 elsif ($string =~ /\G (\/) /oxgc) {
4777 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4778 0         0 while ($string !~ /\G \z/oxgc) {
4779 0         0 if ($string =~ /\G (\\\\) /oxgc) { $regexp .= $1; }
  0         0  
4780 0         0 elsif ($string =~ /\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
4781             elsif ($string =~ /\G \/ ([cgimosxpadlunbB]*) /oxgc) { $e_string .= e_split($e.q{ qr}, '/','/',$regexp,$1); next E_STRING_LOOP; } # / / --> qr / /
4782 0         0 elsif ($string =~ /\G ($q_char) /oxgc) { $regexp .= $1; }
4783             }
4784             die __FILE__, ": Search pattern not terminated\n";
4785             }
4786             }
4787              
4788 0         0 # qq//
4789 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4790 0         0 my $ope = $1;
4791             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4792             $e_string .= e_qq($ope,$1,$3,$2);
4793 0         0 }
4794 0         0 else {
4795 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4796 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4797 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4798 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4799 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4800 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4801             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4802 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4803             }
4804             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4805             }
4806             }
4807              
4808 0         0 # qx//
4809 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4810 0         0 my $ope = $1;
4811             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4812             $e_string .= e_qq($ope,$1,$3,$2);
4813 0         0 }
4814 0         0 else {
4815 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4816 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4817 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4818 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4819 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4820 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4821 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4822             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4823 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4824             }
4825             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4826             }
4827             }
4828              
4829 0         0 # q//
4830 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4831 0         0 my $ope = $1;
4832             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4833             $e_string .= e_q($ope,$1,$3,$2);
4834 0         0 }
4835 0         0 else {
4836 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4837 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4838 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4839 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4840 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4841 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4842             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4843 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 * *
4844             }
4845             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4846             }
4847             }
4848 0         0  
4849             # ''
4850             elsif ($string =~ /\G (?
4851 0         0  
4852             # ""
4853             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4854 0         0  
4855             # ``
4856             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4857 0         0  
4858             # <<>> (a safer ARGV)
4859             elsif ($string =~ /\G ( <<>> ) /oxgc) { $e_string .= $1; }
4860 0         0  
4861             # <<= <=> <= < operator
4862             elsif ($string =~ /\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) { $e_string .= $1; }
4863 0         0  
4864             #
4865             elsif ($string =~ /\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) { $e_string .= $1; }
4866              
4867 0         0 # --- glob
4868             elsif ($string =~ /\G < ((?:$q_char)+?) > /oxgc) {
4869             $e_string .= 'Egreek::glob("' . $1 . '")';
4870             }
4871              
4872 0         0 # << (bit shift) --- not here document
4873 0         0 elsif ($string =~ /\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) {
4874             $slash = 'm//';
4875             $e_string .= $1;
4876             }
4877              
4878 0         0 # <<~'HEREDOC'
4879 0         0 elsif ($string =~ /\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4880 0         0 $slash = 'm//';
4881             my $here_quote = $1;
4882             my $delimiter = $2;
4883 0 0       0  
4884 0         0 # get here document
4885 0         0 if ($here_script eq '') {
4886             $here_script = CORE::substr $_, pos $_;
4887 0 0       0 $here_script =~ s/.*?\n//oxm;
4888 0         0 }
4889 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4890 0         0 my $heredoc = $1;
4891 0         0 my $indent = $2;
4892 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4893             push @heredoc, $heredoc . qq{\n$delimiter\n};
4894             push @heredoc_delimiter, qq{\\s*$delimiter};
4895 0         0 }
4896             else {
4897 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4898             }
4899             $e_string .= qq{<<'$delimiter'};
4900             }
4901              
4902 0         0 # <<~\HEREDOC
4903 0         0 elsif ($string =~ /\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4904 0         0 $slash = 'm//';
4905             my $here_quote = $1;
4906             my $delimiter = $2;
4907 0 0       0  
4908 0         0 # get here document
4909 0         0 if ($here_script eq '') {
4910             $here_script = CORE::substr $_, pos $_;
4911 0 0       0 $here_script =~ s/.*?\n//oxm;
4912 0         0 }
4913 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4914 0         0 my $heredoc = $1;
4915 0         0 my $indent = $2;
4916 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4917             push @heredoc, $heredoc . qq{\n$delimiter\n};
4918             push @heredoc_delimiter, qq{\\s*$delimiter};
4919 0         0 }
4920             else {
4921 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4922             }
4923             $e_string .= qq{<<\\$delimiter};
4924             }
4925              
4926 0         0 # <<~"HEREDOC"
4927 0         0 elsif ($string =~ /\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4928 0         0 $slash = 'm//';
4929             my $here_quote = $1;
4930             my $delimiter = $2;
4931 0 0       0  
4932 0         0 # get here document
4933 0         0 if ($here_script eq '') {
4934             $here_script = CORE::substr $_, pos $_;
4935 0 0       0 $here_script =~ s/.*?\n//oxm;
4936 0         0 }
4937 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4938 0         0 my $heredoc = $1;
4939 0         0 my $indent = $2;
4940 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4941             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4942             push @heredoc_delimiter, qq{\\s*$delimiter};
4943 0         0 }
4944             else {
4945 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4946             }
4947             $e_string .= qq{<<"$delimiter"};
4948             }
4949              
4950 0         0 # <<~HEREDOC
4951 0         0 elsif ($string =~ /\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4952 0         0 $slash = 'm//';
4953             my $here_quote = $1;
4954             my $delimiter = $2;
4955 0 0       0  
4956 0         0 # get here document
4957 0         0 if ($here_script eq '') {
4958             $here_script = CORE::substr $_, pos $_;
4959 0 0       0 $here_script =~ s/.*?\n//oxm;
4960 0         0 }
4961 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4962 0         0 my $heredoc = $1;
4963 0         0 my $indent = $2;
4964 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4965             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4966             push @heredoc_delimiter, qq{\\s*$delimiter};
4967 0         0 }
4968             else {
4969 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4970             }
4971             $e_string .= qq{<<$delimiter};
4972             }
4973              
4974 0         0 # <<~`HEREDOC`
4975 0         0 elsif ($string =~ /\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4976 0         0 $slash = 'm//';
4977             my $here_quote = $1;
4978             my $delimiter = $2;
4979 0 0       0  
4980 0         0 # get here document
4981 0         0 if ($here_script eq '') {
4982             $here_script = CORE::substr $_, pos $_;
4983 0 0       0 $here_script =~ s/.*?\n//oxm;
4984 0         0 }
4985 0         0 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4986 0         0 my $heredoc = $1;
4987 0         0 my $indent = $2;
4988 0         0 $heredoc =~ s{^$indent}{}msg; # no /ox
4989             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4990             push @heredoc_delimiter, qq{\\s*$delimiter};
4991 0         0 }
4992             else {
4993 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4994             }
4995             $e_string .= qq{<<`$delimiter`};
4996             }
4997              
4998 0         0 # <<'HEREDOC'
4999 0         0 elsif ($string =~ /\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
5000 0         0 $slash = 'm//';
5001             my $here_quote = $1;
5002             my $delimiter = $2;
5003 0 0       0  
5004 0         0 # get here document
5005 0         0 if ($here_script eq '') {
5006             $here_script = CORE::substr $_, pos $_;
5007 0 0       0 $here_script =~ s/.*?\n//oxm;
5008 0         0 }
5009 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5010             push @heredoc, $1 . qq{\n$delimiter\n};
5011             push @heredoc_delimiter, $delimiter;
5012 0         0 }
5013             else {
5014 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5015             }
5016             $e_string .= $here_quote;
5017             }
5018              
5019 0         0 # <<\HEREDOC
5020 0         0 elsif ($string =~ /\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
5021 0         0 $slash = 'm//';
5022             my $here_quote = $1;
5023             my $delimiter = $2;
5024 0 0       0  
5025 0         0 # get here document
5026 0         0 if ($here_script eq '') {
5027             $here_script = CORE::substr $_, pos $_;
5028 0 0       0 $here_script =~ s/.*?\n//oxm;
5029 0         0 }
5030 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5031             push @heredoc, $1 . qq{\n$delimiter\n};
5032             push @heredoc_delimiter, $delimiter;
5033 0         0 }
5034             else {
5035 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5036             }
5037             $e_string .= $here_quote;
5038             }
5039              
5040 0         0 # <<"HEREDOC"
5041 0         0 elsif ($string =~ /\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
5042 0         0 $slash = 'm//';
5043             my $here_quote = $1;
5044             my $delimiter = $2;
5045 0 0       0  
5046 0         0 # get here document
5047 0         0 if ($here_script eq '') {
5048             $here_script = CORE::substr $_, pos $_;
5049 0 0       0 $here_script =~ s/.*?\n//oxm;
5050 0         0 }
5051 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5052             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5053             push @heredoc_delimiter, $delimiter;
5054 0         0 }
5055             else {
5056 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5057             }
5058             $e_string .= $here_quote;
5059             }
5060              
5061 0         0 # <
5062 0         0 elsif ($string =~ /\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
5063 0         0 $slash = 'm//';
5064             my $here_quote = $1;
5065             my $delimiter = $2;
5066 0 0       0  
5067 0         0 # get here document
5068 0         0 if ($here_script eq '') {
5069             $here_script = CORE::substr $_, pos $_;
5070 0 0       0 $here_script =~ s/.*?\n//oxm;
5071 0         0 }
5072 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5073             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5074             push @heredoc_delimiter, $delimiter;
5075 0         0 }
5076             else {
5077 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5078             }
5079             $e_string .= $here_quote;
5080             }
5081              
5082 0         0 # <<`HEREDOC`
5083 0         0 elsif ($string =~ /\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
5084 0         0 $slash = 'm//';
5085             my $here_quote = $1;
5086             my $delimiter = $2;
5087 0 0       0  
5088 0         0 # get here document
5089 0         0 if ($here_script eq '') {
5090             $here_script = CORE::substr $_, pos $_;
5091 0 0       0 $here_script =~ s/.*?\n//oxm;
5092 0         0 }
5093 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
5094             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
5095             push @heredoc_delimiter, $delimiter;
5096 0         0 }
5097             else {
5098 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
5099             }
5100             $e_string .= $here_quote;
5101             }
5102              
5103             # any operator before div
5104             elsif ($string =~ /\G (
5105             -- | \+\+ |
5106 0         0 [\)\}\]]
  18         33  
5107              
5108             ) /oxgc) { $slash = 'div'; $e_string .= $1; }
5109              
5110             # yada-yada or triple-dot operator
5111             elsif ($string =~ /\G (
5112 18         55 \.\.\.
  0         0  
5113              
5114             ) /oxgc) { $slash = 'm//'; $e_string .= q{die('Unimplemented')}; }
5115              
5116             # any operator before m//
5117             elsif ($string =~ /\G ((?>
5118              
5119             !~~ | !~ | != | ! |
5120             %= | % |
5121             &&= | && | &= | &\.= | &\. | & |
5122             -= | -> | - |
5123             :(?>\s*)= |
5124             : |
5125             <<>> |
5126             <<= | <=> | <= | < |
5127             == | => | =~ | = |
5128             >>= | >> | >= | > |
5129             \*\*= | \*\* | \*= | \* |
5130             \+= | \+ |
5131             \.\. | \.= | \. |
5132             \/\/= | \/\/ |
5133             \/= | \/ |
5134             \? |
5135             \\ |
5136             \^= | \^\.= | \^\. | \^ |
5137             \b x= |
5138             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
5139             ~~ | ~\. | ~ |
5140             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
5141             \b(?: print )\b |
5142              
5143 0         0 [,;\(\{\[]
  31         77  
5144              
5145             )) /oxgc) { $slash = 'm//'; $e_string .= $1; }
5146 31         116  
5147             # other any character
5148             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
5149              
5150 131         466 # system error
5151             else {
5152             die __FILE__, ": Oops, this shouldn't happen!\n";
5153             }
5154 0         0 }
5155              
5156             return $e_string;
5157             }
5158              
5159             #
5160             # character class
5161 17     1919 0 73 #
5162             sub character_class {
5163 1919 100       3555 my($char,$modifier) = @_;
5164 1919 100       3069  
5165 52         176 if ($char eq '.') {
5166             if ($modifier =~ /s/) {
5167             return '${Egreek::dot_s}';
5168 17         39 }
5169             else {
5170             return '${Egreek::dot}';
5171             }
5172 35         82 }
5173             else {
5174             return Egreek::classic_character_class($char);
5175             }
5176             }
5177              
5178             #
5179             # escape capture ($1, $2, $3, ...)
5180             #
5181 1867     212 0 3160 sub e_capture {
5182              
5183             return join '', '${', $_[0], '}';
5184             }
5185              
5186             #
5187             # escape transliteration (tr/// or y///)
5188 212     3 0 788 #
5189 3         11 sub e_tr {
5190 3   50     5 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
5191             my $e_tr = '';
5192 3         11 $modifier ||= '';
5193              
5194             $slash = 'div';
5195 3         6  
5196             # quote character class 1
5197             $charclass = q_tr($charclass);
5198 3         6  
5199             # quote character class 2
5200             $charclass2 = q_tr($charclass2);
5201 3 50       5  
5202 3 0       8 # /b /B modifier
5203 0         0 if ($modifier =~ tr/bB//d) {
5204             if ($variable eq '') {
5205             $e_tr = qq{tr$charclass$e$charclass2$modifier};
5206 0         0 }
5207             else {
5208             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
5209             }
5210 0 100       0 }
5211 3         6 else {
5212             if ($variable eq '') {
5213             $e_tr = qq{Egreek::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
5214 2         6 }
5215             else {
5216             $e_tr = qq{Egreek::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
5217             }
5218             }
5219 1         5  
5220 3         5 # clear tr/// variable
5221             $tr_variable = '';
5222 3         4 $bind_operator = '';
5223              
5224             return $e_tr;
5225             }
5226              
5227             #
5228             # quote for escape transliteration (tr/// or y///)
5229 3     6 0 16 #
5230             sub q_tr {
5231             my($charclass) = @_;
5232 6 50       8  
    0          
    0          
    0          
    0          
    0          
5233 6         13 # quote character class
5234             if ($charclass !~ /'/oxms) {
5235             return e_q('', "'", "'", $charclass); # --> q' '
5236 6         8 }
5237             elsif ($charclass !~ /\//oxms) {
5238             return e_q('q', '/', '/', $charclass); # --> q/ /
5239 0         0 }
5240             elsif ($charclass !~ /\#/oxms) {
5241             return e_q('q', '#', '#', $charclass); # --> q# #
5242 0         0 }
5243             elsif ($charclass !~ /[\<\>]/oxms) {
5244             return e_q('q', '<', '>', $charclass); # --> q< >
5245 0         0 }
5246             elsif ($charclass !~ /[\(\)]/oxms) {
5247             return e_q('q', '(', ')', $charclass); # --> q( )
5248 0         0 }
5249             elsif ($charclass !~ /[\{\}]/oxms) {
5250             return e_q('q', '{', '}', $charclass); # --> q{ }
5251 0         0 }
5252 0 0       0 else {
5253 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5254             if ($charclass !~ /\Q$char\E/xms) {
5255             return e_q('q', $char, $char, $charclass);
5256             }
5257             }
5258 0         0 }
5259              
5260             return e_q('q', '{', '}', $charclass);
5261             }
5262              
5263             #
5264             # escape q string (q//, '')
5265 0     1264 0 0 #
5266             sub e_q {
5267 1264         3440 my($ope,$delimiter,$end_delimiter,$string) = @_;
5268              
5269 1264         1652 $slash = 'div';
5270              
5271             return join '', $ope, $delimiter, $string, $end_delimiter;
5272             }
5273              
5274             #
5275             # escape qq string (qq//, "", qx//, ``)
5276 1264     4043 0 6201 #
5277             sub e_qq {
5278 4043         9545 my($ope,$delimiter,$end_delimiter,$string) = @_;
5279              
5280 4043         5330 $slash = 'div';
5281 4043         4603  
5282             my $left_e = 0;
5283             my $right_e = 0;
5284 4043         4503  
5285             # split regexp
5286             my @char = $string =~ /\G((?>
5287             [^\\\$] |
5288             \\x\{ (?>[0-9A-Fa-f]+) \} |
5289             \\o\{ (?>[0-7]+) \} |
5290             \\N\{ (?>[^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             \$ (?>\s* [0-9]+) |
5296             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5297             \$ \$ (?![\w\{]) |
5298             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5299             $q_char
5300 4043         153127 ))/oxmsg;
5301              
5302             for (my $i=0; $i <= $#char; $i++) {
5303 4043 50 33     13232  
    50 33        
    100          
    100          
    50          
5304 113357         376038 # "\L\u" --> "\u\L"
5305             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5306             @char[$i,$i+1] = @char[$i+1,$i];
5307             }
5308              
5309 0         0 # "\U\l" --> "\l\U"
5310             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5311             @char[$i,$i+1] = @char[$i+1,$i];
5312             }
5313              
5314 0         0 # octal escape sequence
5315             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5316             $char[$i] = Egreek::octchr($1);
5317             }
5318              
5319 1         4 # hexadecimal escape sequence
5320             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5321             $char[$i] = Egreek::hexchr($1);
5322             }
5323              
5324 1         3 # \N{CHARNAME} --> N{CHARNAME}
5325             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5326             $char[$i] = $1;
5327 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          
5328              
5329             if (0) {
5330             }
5331              
5332             # \F
5333             #
5334             # P.69 Table 2-6. Translation escapes
5335             # in Chapter 2: Bits and Pieces
5336             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5337             # (and so on)
5338 113357         933337  
5339 0 50       0 # \u \l \U \L \F \Q \E
5340 484         1013 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5341             if ($right_e < $left_e) {
5342             $char[$i] = '\\' . $char[$i];
5343             }
5344             }
5345             elsif ($char[$i] eq '\u') {
5346              
5347             # "STRING @{[ LIST EXPR ]} MORE STRING"
5348              
5349             # P.257 Other Tricks You Can Do with Hard References
5350             # in Chapter 8: References
5351             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5352              
5353             # P.353 Other Tricks You Can Do with Hard References
5354             # in Chapter 8: References
5355             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5356              
5357 0         0 # (and so on)
5358 0         0  
5359             $char[$i] = '@{[Egreek::ucfirst qq<';
5360             $left_e++;
5361 0         0 }
5362 0         0 elsif ($char[$i] eq '\l') {
5363             $char[$i] = '@{[Egreek::lcfirst qq<';
5364             $left_e++;
5365 0         0 }
5366 0         0 elsif ($char[$i] eq '\U') {
5367             $char[$i] = '@{[Egreek::uc qq<';
5368             $left_e++;
5369 0         0 }
5370 0         0 elsif ($char[$i] eq '\L') {
5371             $char[$i] = '@{[Egreek::lc qq<';
5372             $left_e++;
5373 0         0 }
5374 24         39 elsif ($char[$i] eq '\F') {
5375             $char[$i] = '@{[Egreek::fc qq<';
5376             $left_e++;
5377 24         44 }
5378 0         0 elsif ($char[$i] eq '\Q') {
5379             $char[$i] = '@{[CORE::quotemeta qq<';
5380             $left_e++;
5381 0 50       0 }
5382 24         89 elsif ($char[$i] eq '\E') {
5383 24         28 if ($right_e < $left_e) {
5384             $char[$i] = '>]}';
5385             $right_e++;
5386 24         47 }
5387             else {
5388             $char[$i] = '';
5389             }
5390 0         0 }
5391 0 0       0 elsif ($char[$i] eq '\Q') {
5392 0         0 while (1) {
5393             if (++$i > $#char) {
5394 0 0       0 last;
5395 0         0 }
5396             if ($char[$i] eq '\E') {
5397             last;
5398             }
5399             }
5400             }
5401             elsif ($char[$i] eq '\E') {
5402             }
5403              
5404             # $0 --> $0
5405             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5406             }
5407             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5408             }
5409              
5410             # $$ --> $$
5411             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5412             }
5413              
5414             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5415 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5416             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5417             $char[$i] = e_capture($1);
5418 205         406 }
5419             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5420             $char[$i] = e_capture($1);
5421             }
5422              
5423 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5424             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5425             $char[$i] = e_capture($1.'->'.$2);
5426             }
5427              
5428 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5429             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5430             $char[$i] = e_capture($1.'->'.$2);
5431             }
5432              
5433 0         0 # $$foo
5434             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5435             $char[$i] = e_capture($1);
5436             }
5437              
5438 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egreek::PREMATCH()
5439             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5440             $char[$i] = '@{[Egreek::PREMATCH()]}';
5441             }
5442              
5443 44         254 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egreek::MATCH()
5444             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5445             $char[$i] = '@{[Egreek::MATCH()]}';
5446             }
5447              
5448 45         163 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egreek::POSTMATCH()
5449             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5450             $char[$i] = '@{[Egreek::POSTMATCH()]}';
5451             }
5452              
5453             # ${ foo } --> ${ foo }
5454             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5455             }
5456              
5457 33         86 # ${ ... }
5458             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5459             $char[$i] = e_capture($1);
5460             }
5461             }
5462 0 50       0  
5463 4043         7283 # return string
5464             if ($left_e > $right_e) {
5465 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
5466             }
5467             return join '', $ope, $delimiter, @char, $end_delimiter;
5468             }
5469              
5470             #
5471             # escape qw string (qw//)
5472 4043     16 0 33924 #
5473             sub e_qw {
5474 16         103 my($ope,$delimiter,$end_delimiter,$string) = @_;
5475              
5476             $slash = 'div';
5477 16         35  
  16         212  
5478 483 50       739 # choice again delimiter
    0          
    0          
    0          
    0          
5479 16         104 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5480             if (not $octet{$end_delimiter}) {
5481             return join '', $ope, $delimiter, $string, $end_delimiter;
5482 16         139 }
5483             elsif (not $octet{')'}) {
5484             return join '', $ope, '(', $string, ')';
5485 0         0 }
5486             elsif (not $octet{'}'}) {
5487             return join '', $ope, '{', $string, '}';
5488 0         0 }
5489             elsif (not $octet{']'}) {
5490             return join '', $ope, '[', $string, ']';
5491 0         0 }
5492             elsif (not $octet{'>'}) {
5493             return join '', $ope, '<', $string, '>';
5494 0         0 }
5495 0 0       0 else {
5496 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5497             if (not $octet{$char}) {
5498             return join '', $ope, $char, $string, $char;
5499             }
5500             }
5501             }
5502 0         0  
5503 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5504 0         0 my @string = CORE::split(/\s+/, $string);
5505 0         0 for my $string (@string) {
5506 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5507 0         0 for my $octet (@octet) {
5508             if ($octet =~ /\A (['\\]) \z/oxms) {
5509             $octet = '\\' . $1;
5510 0         0 }
5511             }
5512 0         0 $string = join '', @octet;
  0         0  
5513             }
5514             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5515             }
5516              
5517             #
5518             # escape here document (<<"HEREDOC", <
5519 0     93 0 0 #
5520             sub e_heredoc {
5521 93         238 my($string) = @_;
5522              
5523 93         154 $slash = 'm//';
5524              
5525 93         292 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5526 93         153  
5527             my $left_e = 0;
5528             my $right_e = 0;
5529 93         117  
5530             # split regexp
5531             my @char = $string =~ /\G((?>
5532             [^\\\$] |
5533             \\x\{ (?>[0-9A-Fa-f]+) \} |
5534             \\o\{ (?>[0-7]+) \} |
5535             \\N\{ (?>[^0-9\}][^\}]*) \} |
5536             \\ $q_char |
5537             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5538             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5539             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5540             \$ (?>\s* [0-9]+) |
5541             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5542             \$ \$ (?![\w\{]) |
5543             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5544             $q_char
5545 93         7757 ))/oxmsg;
5546              
5547             for (my $i=0; $i <= $#char; $i++) {
5548 93 50 33     457  
    50 33        
    100          
    100          
    50          
5549 3151         8981 # "\L\u" --> "\u\L"
5550             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5551             @char[$i,$i+1] = @char[$i+1,$i];
5552             }
5553              
5554 0         0 # "\U\l" --> "\l\U"
5555             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5556             @char[$i,$i+1] = @char[$i+1,$i];
5557             }
5558              
5559 0         0 # octal escape sequence
5560             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5561             $char[$i] = Egreek::octchr($1);
5562             }
5563              
5564 1         4 # hexadecimal escape sequence
5565             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5566             $char[$i] = Egreek::hexchr($1);
5567             }
5568              
5569 1         3 # \N{CHARNAME} --> N{CHARNAME}
5570             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5571             $char[$i] = $1;
5572 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          
5573              
5574             if (0) {
5575             }
5576 3151         24834  
5577 0 0       0 # \u \l \U \L \F \Q \E
5578 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5579             if ($right_e < $left_e) {
5580             $char[$i] = '\\' . $char[$i];
5581             }
5582 0         0 }
5583 0         0 elsif ($char[$i] eq '\u') {
5584             $char[$i] = '@{[Egreek::ucfirst qq<';
5585             $left_e++;
5586 0         0 }
5587 0         0 elsif ($char[$i] eq '\l') {
5588             $char[$i] = '@{[Egreek::lcfirst qq<';
5589             $left_e++;
5590 0         0 }
5591 0         0 elsif ($char[$i] eq '\U') {
5592             $char[$i] = '@{[Egreek::uc qq<';
5593             $left_e++;
5594 0         0 }
5595 0         0 elsif ($char[$i] eq '\L') {
5596             $char[$i] = '@{[Egreek::lc qq<';
5597             $left_e++;
5598 0         0 }
5599 0         0 elsif ($char[$i] eq '\F') {
5600             $char[$i] = '@{[Egreek::fc qq<';
5601             $left_e++;
5602 0         0 }
5603 0         0 elsif ($char[$i] eq '\Q') {
5604             $char[$i] = '@{[CORE::quotemeta qq<';
5605             $left_e++;
5606 0 0       0 }
5607 0         0 elsif ($char[$i] eq '\E') {
5608 0         0 if ($right_e < $left_e) {
5609             $char[$i] = '>]}';
5610             $right_e++;
5611 0         0 }
5612             else {
5613             $char[$i] = '';
5614             }
5615 0         0 }
5616 0 0       0 elsif ($char[$i] eq '\Q') {
5617 0         0 while (1) {
5618             if (++$i > $#char) {
5619 0 0       0 last;
5620 0         0 }
5621             if ($char[$i] eq '\E') {
5622             last;
5623             }
5624             }
5625             }
5626             elsif ($char[$i] eq '\E') {
5627             }
5628              
5629             # $0 --> $0
5630             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5631             }
5632             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5633             }
5634              
5635             # $$ --> $$
5636             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5637             }
5638              
5639             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5640 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5641             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5642             $char[$i] = e_capture($1);
5643 0         0 }
5644             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5645             $char[$i] = e_capture($1);
5646             }
5647              
5648 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5649             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5650             $char[$i] = e_capture($1.'->'.$2);
5651             }
5652              
5653 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5654             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5655             $char[$i] = e_capture($1.'->'.$2);
5656             }
5657              
5658 0         0 # $$foo
5659             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5660             $char[$i] = e_capture($1);
5661             }
5662              
5663 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egreek::PREMATCH()
5664             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5665             $char[$i] = '@{[Egreek::PREMATCH()]}';
5666             }
5667              
5668 8         46 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egreek::MATCH()
5669             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5670             $char[$i] = '@{[Egreek::MATCH()]}';
5671             }
5672              
5673 8         50 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egreek::POSTMATCH()
5674             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5675             $char[$i] = '@{[Egreek::POSTMATCH()]}';
5676             }
5677              
5678             # ${ foo } --> ${ foo }
5679             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5680             }
5681              
5682 6         38 # ${ ... }
5683             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5684             $char[$i] = e_capture($1);
5685             }
5686             }
5687 0 50       0  
5688 93         237 # return string
5689             if ($left_e > $right_e) {
5690 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5691             }
5692             return join '', @char;
5693             }
5694              
5695             #
5696             # escape regexp (m//, qr//)
5697 93     652 0 703 #
5698 652   100     3375 sub e_qr {
5699             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5700 652         2882 $modifier ||= '';
5701 652 50       1190  
5702 652         1962 $modifier =~ tr/p//d;
5703 0         0 if ($modifier =~ /([adlu])/oxms) {
5704 0 0       0 my $line = 0;
5705 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5706 0         0 if ($filename ne __FILE__) {
5707             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5708             last;
5709 0         0 }
5710             }
5711             die qq{Unsupported modifier "$1" used at line $line.\n};
5712 0         0 }
5713              
5714             $slash = 'div';
5715 652 100       1016  
    100          
5716 652         2372 # literal null string pattern
5717 8         10 if ($string eq '') {
5718 8         12 $modifier =~ tr/bB//d;
5719             $modifier =~ tr/i//d;
5720             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5721             }
5722              
5723             # /b /B modifier
5724             elsif ($modifier =~ tr/bB//d) {
5725 8 50       36  
5726 2         6 # choice again delimiter
5727 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5728 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5729 0         0 my %octet = map {$_ => 1} @char;
5730 0         0 if (not $octet{')'}) {
5731             $delimiter = '(';
5732             $end_delimiter = ')';
5733 0         0 }
5734 0         0 elsif (not $octet{'}'}) {
5735             $delimiter = '{';
5736             $end_delimiter = '}';
5737 0         0 }
5738 0         0 elsif (not $octet{']'}) {
5739             $delimiter = '[';
5740             $end_delimiter = ']';
5741 0         0 }
5742 0         0 elsif (not $octet{'>'}) {
5743             $delimiter = '<';
5744             $end_delimiter = '>';
5745 0         0 }
5746 0 0       0 else {
5747 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5748 0         0 if (not $octet{$char}) {
5749 0         0 $delimiter = $char;
5750             $end_delimiter = $char;
5751             last;
5752             }
5753             }
5754             }
5755 0 50 33     0 }
5756 2         10  
5757             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5758             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5759 0         0 }
5760             else {
5761             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5762             }
5763 2 100       11 }
5764 642         1925  
5765             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5766             my $metachar = qr/[\@\\|[\]{^]/oxms;
5767 642         2314  
5768             # split regexp
5769             my @char = $string =~ /\G((?>
5770             [^\\\$\@\[\(] |
5771             \\x (?>[0-9A-Fa-f]{1,2}) |
5772             \\ (?>[0-7]{2,3}) |
5773             \\c [\x40-\x5F] |
5774             \\x\{ (?>[0-9A-Fa-f]+) \} |
5775             \\o\{ (?>[0-7]+) \} |
5776             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5777             \\ $q_char |
5778             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5779             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5780             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5781             [\$\@] $qq_variable |
5782             \$ (?>\s* [0-9]+) |
5783             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5784             \$ \$ (?![\w\{]) |
5785             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5786             \[\^ |
5787             \[\: (?>[a-z]+) :\] |
5788             \[\:\^ (?>[a-z]+) :\] |
5789             \(\? |
5790             $q_char
5791             ))/oxmsg;
5792 642 50       79478  
5793 642         2890 # choice again delimiter
  0         0  
5794 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5795 0         0 my %octet = map {$_ => 1} @char;
5796 0         0 if (not $octet{')'}) {
5797             $delimiter = '(';
5798             $end_delimiter = ')';
5799 0         0 }
5800 0         0 elsif (not $octet{'}'}) {
5801             $delimiter = '{';
5802             $end_delimiter = '}';
5803 0         0 }
5804 0         0 elsif (not $octet{']'}) {
5805             $delimiter = '[';
5806             $end_delimiter = ']';
5807 0         0 }
5808 0         0 elsif (not $octet{'>'}) {
5809             $delimiter = '<';
5810             $end_delimiter = '>';
5811 0         0 }
5812 0 0       0 else {
5813 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5814 0         0 if (not $octet{$char}) {
5815 0         0 $delimiter = $char;
5816             $end_delimiter = $char;
5817             last;
5818             }
5819             }
5820             }
5821 0         0 }
5822 642         1246  
5823 642         836 my $left_e = 0;
5824             my $right_e = 0;
5825             for (my $i=0; $i <= $#char; $i++) {
5826 642 50 66     1909  
    50 66        
    100          
    100          
    100          
    100          
5827 1872         14096 # "\L\u" --> "\u\L"
5828             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5829             @char[$i,$i+1] = @char[$i+1,$i];
5830             }
5831              
5832 0         0 # "\U\l" --> "\l\U"
5833             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5834             @char[$i,$i+1] = @char[$i+1,$i];
5835             }
5836              
5837 0         0 # octal escape sequence
5838             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5839             $char[$i] = Egreek::octchr($1);
5840             }
5841              
5842 1         4 # hexadecimal escape sequence
5843             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5844             $char[$i] = Egreek::hexchr($1);
5845             }
5846              
5847             # \b{...} --> b\{...}
5848             # \B{...} --> B\{...}
5849             # \N{CHARNAME} --> N\{CHARNAME}
5850             # \p{PROPERTY} --> p\{PROPERTY}
5851 1         3 # \P{PROPERTY} --> P\{PROPERTY}
5852             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5853             $char[$i] = $1 . '\\' . $2;
5854             }
5855              
5856 6         25 # \p, \P, \X --> p, P, X
5857             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5858             $char[$i] = $1;
5859 4 100 100     14 }
    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          
5860              
5861             if (0) {
5862             }
5863 1872         5909  
5864 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5865 6         191 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5866             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)) {
5867             $char[$i] .= join '', splice @char, $i+1, 3;
5868 0         0 }
5869             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)) {
5870             $char[$i] .= join '', splice @char, $i+1, 2;
5871 0         0 }
5872             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)) {
5873             $char[$i] .= join '', splice @char, $i+1, 1;
5874             }
5875             }
5876              
5877 0         0 # open character class [...]
5878             elsif ($char[$i] eq '[') {
5879             my $left = $i;
5880              
5881             # [] make die "Unmatched [] in regexp ...\n"
5882 328 100       440 # (and so on)
5883 328         722  
5884             if ($char[$i+1] eq ']') {
5885             $i++;
5886 3         5 }
5887 328 50       427  
5888 1379         2163 while (1) {
5889             if (++$i > $#char) {
5890 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5891 1379         2300 }
5892             if ($char[$i] eq ']') {
5893             my $right = $i;
5894 328 100       420  
5895 328         1691 # [...]
  30         68  
5896             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5897             splice @char, $left, $right-$left+1, sprintf(q{@{[Egreek::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5898 90         159 }
5899             else {
5900             splice @char, $left, $right-$left+1, Egreek::charlist_qr(@char[$left+1..$right-1], $modifier);
5901 298         1146 }
5902 328         647  
5903             $i = $left;
5904             last;
5905             }
5906             }
5907             }
5908              
5909 328         825 # open character class [^...]
5910             elsif ($char[$i] eq '[^') {
5911             my $left = $i;
5912              
5913             # [^] make die "Unmatched [] in regexp ...\n"
5914 74 100       97 # (and so on)
5915 74         166  
5916             if ($char[$i+1] eq ']') {
5917             $i++;
5918 4         7 }
5919 74 50       89  
5920 272         422 while (1) {
5921             if (++$i > $#char) {
5922 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5923 272         399 }
5924             if ($char[$i] eq ']') {
5925             my $right = $i;
5926 74 100       95  
5927 74         370 # [^...]
  30         66  
5928             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5929             splice @char, $left, $right-$left+1, sprintf(q{@{[Egreek::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5930 90         150 }
5931             else {
5932             splice @char, $left, $right-$left+1, Egreek::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5933 44         173 }
5934 74         143  
5935             $i = $left;
5936             last;
5937             }
5938             }
5939             }
5940              
5941 74         183 # rewrite character class or escape character
5942             elsif (my $char = character_class($char[$i],$modifier)) {
5943             $char[$i] = $char;
5944             }
5945              
5946 139 50       341 # /i modifier
5947 20         32 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egreek::uc($char[$i]) ne Egreek::fc($char[$i]))) {
5948             if (CORE::length(Egreek::fc($char[$i])) == 1) {
5949             $char[$i] = '[' . Egreek::uc($char[$i]) . Egreek::fc($char[$i]) . ']';
5950 20         37 }
5951             else {
5952             $char[$i] = '(?:' . Egreek::uc($char[$i]) . '|' . Egreek::fc($char[$i]) . ')';
5953             }
5954             }
5955              
5956 0 50       0 # \u \l \U \L \F \Q \E
5957 1         6 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5958             if ($right_e < $left_e) {
5959             $char[$i] = '\\' . $char[$i];
5960             }
5961 0         0 }
5962 0         0 elsif ($char[$i] eq '\u') {
5963             $char[$i] = '@{[Egreek::ucfirst qq<';
5964             $left_e++;
5965 0         0 }
5966 0         0 elsif ($char[$i] eq '\l') {
5967             $char[$i] = '@{[Egreek::lcfirst qq<';
5968             $left_e++;
5969 0         0 }
5970 1         2 elsif ($char[$i] eq '\U') {
5971             $char[$i] = '@{[Egreek::uc qq<';
5972             $left_e++;
5973 1         2 }
5974 1         3 elsif ($char[$i] eq '\L') {
5975             $char[$i] = '@{[Egreek::lc qq<';
5976             $left_e++;
5977 1         2 }
5978 18         32 elsif ($char[$i] eq '\F') {
5979             $char[$i] = '@{[Egreek::fc qq<';
5980             $left_e++;
5981 18         41 }
5982 1         2 elsif ($char[$i] eq '\Q') {
5983             $char[$i] = '@{[CORE::quotemeta qq<';
5984             $left_e++;
5985 1 50       3 }
5986 21         43 elsif ($char[$i] eq '\E') {
5987 21         85 if ($right_e < $left_e) {
5988             $char[$i] = '>]}';
5989             $right_e++;
5990 21         48 }
5991             else {
5992             $char[$i] = '';
5993             }
5994 0         0 }
5995 0 0       0 elsif ($char[$i] eq '\Q') {
5996 0         0 while (1) {
5997             if (++$i > $#char) {
5998 0 0       0 last;
5999 0         0 }
6000             if ($char[$i] eq '\E') {
6001             last;
6002             }
6003             }
6004             }
6005             elsif ($char[$i] eq '\E') {
6006             }
6007              
6008 0 0       0 # $0 --> $0
6009 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6010             if ($ignorecase) {
6011             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6012             }
6013 0 0       0 }
6014 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6015             if ($ignorecase) {
6016             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6017             }
6018             }
6019              
6020             # $$ --> $$
6021             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6022             }
6023              
6024             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6025 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6026 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6027 0         0 $char[$i] = e_capture($1);
6028             if ($ignorecase) {
6029             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6030             }
6031 0         0 }
6032 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6033 0         0 $char[$i] = e_capture($1);
6034             if ($ignorecase) {
6035             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6036             }
6037             }
6038              
6039 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6040 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) {
6041 0         0 $char[$i] = e_capture($1.'->'.$2);
6042             if ($ignorecase) {
6043             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6044             }
6045             }
6046              
6047 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6048 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) {
6049 0         0 $char[$i] = e_capture($1.'->'.$2);
6050             if ($ignorecase) {
6051             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6052             }
6053             }
6054              
6055 0         0 # $$foo
6056 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6057 0         0 $char[$i] = e_capture($1);
6058             if ($ignorecase) {
6059             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6060             }
6061             }
6062              
6063 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egreek::PREMATCH()
6064 8         21 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6065             if ($ignorecase) {
6066             $char[$i] = '@{[Egreek::ignorecase(Egreek::PREMATCH())]}';
6067 0         0 }
6068             else {
6069             $char[$i] = '@{[Egreek::PREMATCH()]}';
6070             }
6071             }
6072              
6073 8 50       24 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egreek::MATCH()
6074 8         21 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6075             if ($ignorecase) {
6076             $char[$i] = '@{[Egreek::ignorecase(Egreek::MATCH())]}';
6077 0         0 }
6078             else {
6079             $char[$i] = '@{[Egreek::MATCH()]}';
6080             }
6081             }
6082              
6083 8 50       23 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egreek::POSTMATCH()
6084 6         16 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6085             if ($ignorecase) {
6086             $char[$i] = '@{[Egreek::ignorecase(Egreek::POSTMATCH())]}';
6087 0         0 }
6088             else {
6089             $char[$i] = '@{[Egreek::POSTMATCH()]}';
6090             }
6091             }
6092              
6093 6 0       17 # ${ foo }
6094 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) {
6095             if ($ignorecase) {
6096             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6097             }
6098             }
6099              
6100 0         0 # ${ ... }
6101 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6102 0         0 $char[$i] = e_capture($1);
6103             if ($ignorecase) {
6104             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6105             }
6106             }
6107              
6108 0         0 # $scalar or @array
6109 21 100       56 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6110 21         147 $char[$i] = e_string($char[$i]);
6111             if ($ignorecase) {
6112             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6113             }
6114             }
6115              
6116 11 100 33     39 # quote character before ? + * {
    50          
6117             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6118             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6119 138         1015 }
6120 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6121 0         0 my $char = $char[$i-1];
6122             if ($char[$i] eq '{') {
6123             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
6124 0         0 }
6125             else {
6126             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
6127             }
6128 0         0 }
6129             else {
6130             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6131             }
6132             }
6133             }
6134 127         496  
6135 642 50       1338 # make regexp string
6136 642 0 0     1311 $modifier =~ tr/i//d;
6137 0         0 if ($left_e > $right_e) {
6138             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6139             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
6140 0         0 }
6141             else {
6142             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6143 0 50 33     0 }
6144 642         3492 }
6145             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
6146             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
6147 0         0 }
6148             else {
6149             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6150             }
6151             }
6152              
6153             #
6154             # double quote stuff
6155 642     180 0 5565 #
6156             sub qq_stuff {
6157             my($delimiter,$end_delimiter,$stuff) = @_;
6158 180 100       254  
6159 180         352 # scalar variable or array variable
6160             if ($stuff =~ /\A [\$\@] /oxms) {
6161             return $stuff;
6162             }
6163 100         700  
  80         172  
6164 80         217 # quote by delimiter
6165 80 50       182 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
6166 80 50       136 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6167 80 50       120 next if $char eq $delimiter;
6168 80         127 next if $char eq $end_delimiter;
6169             if (not $octet{$char}) {
6170             return join '', 'qq', $char, $stuff, $char;
6171 80         313 }
6172             }
6173             return join '', 'qq', '<', $stuff, '>';
6174             }
6175              
6176             #
6177             # escape regexp (m'', qr'', and m''b, qr''b)
6178 0     10 0 0 #
6179 10   50     40 sub e_qr_q {
6180             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6181 10         47 $modifier ||= '';
6182 10 50       16  
6183 10         18 $modifier =~ tr/p//d;
6184 0         0 if ($modifier =~ /([adlu])/oxms) {
6185 0 0       0 my $line = 0;
6186 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6187 0         0 if ($filename ne __FILE__) {
6188             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6189             last;
6190 0         0 }
6191             }
6192             die qq{Unsupported modifier "$1" used at line $line.\n};
6193 0         0 }
6194              
6195             $slash = 'div';
6196 10 100       14  
    50          
6197 10         21 # literal null string pattern
6198 8         9 if ($string eq '') {
6199 8         8 $modifier =~ tr/bB//d;
6200             $modifier =~ tr/i//d;
6201             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6202             }
6203              
6204 8         35 # with /b /B modifier
6205             elsif ($modifier =~ tr/bB//d) {
6206             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6207             }
6208              
6209 0         0 # without /b /B modifier
6210             else {
6211             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6212             }
6213             }
6214              
6215             #
6216             # escape regexp (m'', qr'')
6217 2     2 0 6 #
6218             sub e_qr_qt {
6219 2 50       5 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6220              
6221             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6222 2         6  
6223             # split regexp
6224             my @char = $string =~ /\G((?>
6225             [^\\\[\$\@\/] |
6226             [\x00-\xFF] |
6227             \[\^ |
6228             \[\: (?>[a-z]+) \:\] |
6229             \[\:\^ (?>[a-z]+) \:\] |
6230             [\$\@\/] |
6231             \\ (?:$q_char) |
6232             (?:$q_char)
6233             ))/oxmsg;
6234 2         61  
6235 2 50 33     9 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
6236             for (my $i=0; $i <= $#char; $i++) {
6237             if (0) {
6238             }
6239 2         16  
6240 0         0 # open character class [...]
6241 0 0       0 elsif ($char[$i] eq '[') {
6242 0         0 my $left = $i;
6243             if ($char[$i+1] eq ']') {
6244 0         0 $i++;
6245 0 0       0 }
6246 0         0 while (1) {
6247             if (++$i > $#char) {
6248 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6249 0         0 }
6250             if ($char[$i] eq ']') {
6251             my $right = $i;
6252 0         0  
6253             # [...]
6254 0         0 splice @char, $left, $right-$left+1, Egreek::charlist_qr(@char[$left+1..$right-1], $modifier);
6255 0         0  
6256             $i = $left;
6257             last;
6258             }
6259             }
6260             }
6261              
6262 0         0 # open character class [^...]
6263 0 0       0 elsif ($char[$i] eq '[^') {
6264 0         0 my $left = $i;
6265             if ($char[$i+1] eq ']') {
6266 0         0 $i++;
6267 0 0       0 }
6268 0         0 while (1) {
6269             if (++$i > $#char) {
6270 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6271 0         0 }
6272             if ($char[$i] eq ']') {
6273             my $right = $i;
6274 0         0  
6275             # [^...]
6276 0         0 splice @char, $left, $right-$left+1, Egreek::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6277 0         0  
6278             $i = $left;
6279             last;
6280             }
6281             }
6282             }
6283              
6284 0         0 # escape $ @ / and \
6285             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6286             $char[$i] = '\\' . $char[$i];
6287             }
6288              
6289 0         0 # rewrite character class or escape character
6290             elsif (my $char = character_class($char[$i],$modifier)) {
6291             $char[$i] = $char;
6292             }
6293              
6294 0 0       0 # /i modifier
6295 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egreek::uc($char[$i]) ne Egreek::fc($char[$i]))) {
6296             if (CORE::length(Egreek::fc($char[$i])) == 1) {
6297             $char[$i] = '[' . Egreek::uc($char[$i]) . Egreek::fc($char[$i]) . ']';
6298 0         0 }
6299             else {
6300             $char[$i] = '(?:' . Egreek::uc($char[$i]) . '|' . Egreek::fc($char[$i]) . ')';
6301             }
6302             }
6303              
6304 0 0       0 # quote character before ? + * {
6305             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6306             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6307 0         0 }
6308             else {
6309             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6310             }
6311             }
6312 0         0 }
6313 2         5  
6314             $delimiter = '/';
6315 2         4 $end_delimiter = '/';
6316 2         3  
6317             $modifier =~ tr/i//d;
6318             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6319             }
6320              
6321             #
6322             # escape regexp (m''b, qr''b)
6323 2     0 0 14 #
6324             sub e_qr_qb {
6325             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6326 0         0  
6327             # split regexp
6328             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
6329 0         0  
6330 0 0       0 # unescape character
    0          
6331             for (my $i=0; $i <= $#char; $i++) {
6332             if (0) {
6333             }
6334 0         0  
6335             # remain \\
6336             elsif ($char[$i] eq '\\\\') {
6337             }
6338              
6339 0         0 # escape $ @ / and \
6340             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6341             $char[$i] = '\\' . $char[$i];
6342             }
6343 0         0 }
6344 0         0  
6345 0         0 $delimiter = '/';
6346             $end_delimiter = '/';
6347             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6348             }
6349              
6350             #
6351             # escape regexp (s/here//)
6352 0     76 0 0 #
6353 76   100     217 sub e_s1 {
6354             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6355 76         346 $modifier ||= '';
6356 76 50       160  
6357 76         381 $modifier =~ tr/p//d;
6358 0         0 if ($modifier =~ /([adlu])/oxms) {
6359 0 0       0 my $line = 0;
6360 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6361 0         0 if ($filename ne __FILE__) {
6362             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6363             last;
6364 0         0 }
6365             }
6366             die qq{Unsupported modifier "$1" used at line $line.\n};
6367 0         0 }
6368              
6369             $slash = 'div';
6370 76 100       172  
    50          
6371 76         296 # literal null string pattern
6372 8         10 if ($string eq '') {
6373 8         8 $modifier =~ tr/bB//d;
6374             $modifier =~ tr/i//d;
6375             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6376             }
6377              
6378             # /b /B modifier
6379             elsif ($modifier =~ tr/bB//d) {
6380 8 0       45  
6381 0         0 # choice again delimiter
6382 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
6383 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
6384 0         0 my %octet = map {$_ => 1} @char;
6385 0         0 if (not $octet{')'}) {
6386             $delimiter = '(';
6387             $end_delimiter = ')';
6388 0         0 }
6389 0         0 elsif (not $octet{'}'}) {
6390             $delimiter = '{';
6391             $end_delimiter = '}';
6392 0         0 }
6393 0         0 elsif (not $octet{']'}) {
6394             $delimiter = '[';
6395             $end_delimiter = ']';
6396 0         0 }
6397 0         0 elsif (not $octet{'>'}) {
6398             $delimiter = '<';
6399             $end_delimiter = '>';
6400 0         0 }
6401 0 0       0 else {
6402 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6403 0         0 if (not $octet{$char}) {
6404 0         0 $delimiter = $char;
6405             $end_delimiter = $char;
6406             last;
6407             }
6408             }
6409             }
6410 0         0 }
6411 0         0  
6412             my $prematch = '';
6413             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
6414 0 100       0 }
6415 68         187  
6416             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6417             my $metachar = qr/[\@\\|[\]{^]/oxms;
6418 68         277  
6419             # split regexp
6420             my @char = $string =~ /\G((?>
6421             [^\\\$\@\[\(] |
6422             \\ (?>[1-9][0-9]*) |
6423             \\g (?>\s*) (?>[1-9][0-9]*) |
6424             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6425             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
6426             \\x (?>[0-9A-Fa-f]{1,2}) |
6427             \\ (?>[0-7]{2,3}) |
6428             \\c [\x40-\x5F] |
6429             \\x\{ (?>[0-9A-Fa-f]+) \} |
6430             \\o\{ (?>[0-7]+) \} |
6431             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6432             \\ $q_char |
6433             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6434             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6435             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6436             [\$\@] $qq_variable |
6437             \$ (?>\s* [0-9]+) |
6438             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6439             \$ \$ (?![\w\{]) |
6440             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6441             \[\^ |
6442             \[\: (?>[a-z]+) :\] |
6443             \[\:\^ (?>[a-z]+) :\] |
6444             \(\? |
6445             $q_char
6446             ))/oxmsg;
6447 68 50       17268  
6448 68         486 # choice again delimiter
  0         0  
6449 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
6450 0         0 my %octet = map {$_ => 1} @char;
6451 0         0 if (not $octet{')'}) {
6452             $delimiter = '(';
6453             $end_delimiter = ')';
6454 0         0 }
6455 0         0 elsif (not $octet{'}'}) {
6456             $delimiter = '{';
6457             $end_delimiter = '}';
6458 0         0 }
6459 0         0 elsif (not $octet{']'}) {
6460             $delimiter = '[';
6461             $end_delimiter = ']';
6462 0         0 }
6463 0         0 elsif (not $octet{'>'}) {
6464             $delimiter = '<';
6465             $end_delimiter = '>';
6466 0         0 }
6467 0 0       0 else {
6468 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
6469 0         0 if (not $octet{$char}) {
6470 0         0 $delimiter = $char;
6471             $end_delimiter = $char;
6472             last;
6473             }
6474             }
6475             }
6476             }
6477 0         0  
  68         221  
6478             # count '('
6479 253         442 my $parens = grep { $_ eq '(' } @char;
6480 68         101  
6481 68         97 my $left_e = 0;
6482             my $right_e = 0;
6483             for (my $i=0; $i <= $#char; $i++) {
6484 68 50 33     194  
    50 33        
    100          
    100          
    50          
    50          
6485 195         1142 # "\L\u" --> "\u\L"
6486             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6487             @char[$i,$i+1] = @char[$i+1,$i];
6488             }
6489              
6490 0         0 # "\U\l" --> "\l\U"
6491             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6492             @char[$i,$i+1] = @char[$i+1,$i];
6493             }
6494              
6495 0         0 # octal escape sequence
6496             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6497             $char[$i] = Egreek::octchr($1);
6498             }
6499              
6500 1         3 # hexadecimal escape sequence
6501             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6502             $char[$i] = Egreek::hexchr($1);
6503             }
6504              
6505             # \b{...} --> b\{...}
6506             # \B{...} --> B\{...}
6507             # \N{CHARNAME} --> N\{CHARNAME}
6508             # \p{PROPERTY} --> p\{PROPERTY}
6509 1         4 # \P{PROPERTY} --> P\{PROPERTY}
6510             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6511             $char[$i] = $1 . '\\' . $2;
6512             }
6513              
6514 0         0 # \p, \P, \X --> p, P, X
6515             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6516             $char[$i] = $1;
6517 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          
6518              
6519             if (0) {
6520             }
6521 195         862  
6522 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6523 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6524             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)) {
6525             $char[$i] .= join '', splice @char, $i+1, 3;
6526 0         0 }
6527             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)) {
6528             $char[$i] .= join '', splice @char, $i+1, 2;
6529 0         0 }
6530             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)) {
6531             $char[$i] .= join '', splice @char, $i+1, 1;
6532             }
6533             }
6534              
6535 0         0 # open character class [...]
6536 13 50       22 elsif ($char[$i] eq '[') {
6537 13         47 my $left = $i;
6538             if ($char[$i+1] eq ']') {
6539 0         0 $i++;
6540 13 50       20 }
6541 58         94 while (1) {
6542             if (++$i > $#char) {
6543 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6544 58         124 }
6545             if ($char[$i] eq ']') {
6546             my $right = $i;
6547 13 50       23  
6548 13         87 # [...]
  0         0  
6549             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6550             splice @char, $left, $right-$left+1, sprintf(q{@{[Egreek::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6551 0         0 }
6552             else {
6553             splice @char, $left, $right-$left+1, Egreek::charlist_qr(@char[$left+1..$right-1], $modifier);
6554 13         68 }
6555 13         25  
6556             $i = $left;
6557             last;
6558             }
6559             }
6560             }
6561              
6562 13         38 # open character class [^...]
6563 0 0       0 elsif ($char[$i] eq '[^') {
6564 0         0 my $left = $i;
6565             if ($char[$i+1] eq ']') {
6566 0         0 $i++;
6567 0 0       0 }
6568 0         0 while (1) {
6569             if (++$i > $#char) {
6570 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6571 0         0 }
6572             if ($char[$i] eq ']') {
6573             my $right = $i;
6574 0 0       0  
6575 0         0 # [^...]
  0         0  
6576             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6577             splice @char, $left, $right-$left+1, sprintf(q{@{[Egreek::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6578 0         0 }
6579             else {
6580             splice @char, $left, $right-$left+1, Egreek::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6581 0         0 }
6582 0         0  
6583             $i = $left;
6584             last;
6585             }
6586             }
6587             }
6588              
6589 0         0 # rewrite character class or escape character
6590             elsif (my $char = character_class($char[$i],$modifier)) {
6591             $char[$i] = $char;
6592             }
6593              
6594 7 50       16 # /i modifier
6595 3         6 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egreek::uc($char[$i]) ne Egreek::fc($char[$i]))) {
6596             if (CORE::length(Egreek::fc($char[$i])) == 1) {
6597             $char[$i] = '[' . Egreek::uc($char[$i]) . Egreek::fc($char[$i]) . ']';
6598 3         15 }
6599             else {
6600             $char[$i] = '(?:' . Egreek::uc($char[$i]) . '|' . Egreek::fc($char[$i]) . ')';
6601             }
6602             }
6603              
6604 0 0       0 # \u \l \U \L \F \Q \E
6605 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6606             if ($right_e < $left_e) {
6607             $char[$i] = '\\' . $char[$i];
6608             }
6609 0         0 }
6610 0         0 elsif ($char[$i] eq '\u') {
6611             $char[$i] = '@{[Egreek::ucfirst qq<';
6612             $left_e++;
6613 0         0 }
6614 0         0 elsif ($char[$i] eq '\l') {
6615             $char[$i] = '@{[Egreek::lcfirst qq<';
6616             $left_e++;
6617 0         0 }
6618 0         0 elsif ($char[$i] eq '\U') {
6619             $char[$i] = '@{[Egreek::uc qq<';
6620             $left_e++;
6621 0         0 }
6622 0         0 elsif ($char[$i] eq '\L') {
6623             $char[$i] = '@{[Egreek::lc qq<';
6624             $left_e++;
6625 0         0 }
6626 0         0 elsif ($char[$i] eq '\F') {
6627             $char[$i] = '@{[Egreek::fc qq<';
6628             $left_e++;
6629 0         0 }
6630 0         0 elsif ($char[$i] eq '\Q') {
6631             $char[$i] = '@{[CORE::quotemeta qq<';
6632             $left_e++;
6633 0 0       0 }
6634 0         0 elsif ($char[$i] eq '\E') {
6635 0         0 if ($right_e < $left_e) {
6636             $char[$i] = '>]}';
6637             $right_e++;
6638 0         0 }
6639             else {
6640             $char[$i] = '';
6641             }
6642 0         0 }
6643 0 0       0 elsif ($char[$i] eq '\Q') {
6644 0         0 while (1) {
6645             if (++$i > $#char) {
6646 0 0       0 last;
6647 0         0 }
6648             if ($char[$i] eq '\E') {
6649             last;
6650             }
6651             }
6652             }
6653             elsif ($char[$i] eq '\E') {
6654             }
6655              
6656             # \0 --> \0
6657             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6658             }
6659              
6660             # \g{N}, \g{-N}
6661              
6662             # P.108 Using Simple Patterns
6663             # in Chapter 7: In the World of Regular Expressions
6664             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6665              
6666             # P.221 Capturing
6667             # in Chapter 5: Pattern Matching
6668             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6669              
6670             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6671             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6672             }
6673              
6674             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6675             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6676             }
6677              
6678             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6679             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6680             }
6681              
6682             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6683             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6684             }
6685              
6686 0 0       0 # $0 --> $0
6687 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6688             if ($ignorecase) {
6689             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6690             }
6691 0 0       0 }
6692 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6693             if ($ignorecase) {
6694             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6695             }
6696             }
6697              
6698             # $$ --> $$
6699             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6700             }
6701              
6702             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6703 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6704 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6705 0         0 $char[$i] = e_capture($1);
6706             if ($ignorecase) {
6707             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6708             }
6709 0         0 }
6710 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6711 0         0 $char[$i] = e_capture($1);
6712             if ($ignorecase) {
6713             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6714             }
6715             }
6716              
6717 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6718 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) {
6719 0         0 $char[$i] = e_capture($1.'->'.$2);
6720             if ($ignorecase) {
6721             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6722             }
6723             }
6724              
6725 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6726 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) {
6727 0         0 $char[$i] = e_capture($1.'->'.$2);
6728             if ($ignorecase) {
6729             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6730             }
6731             }
6732              
6733 0         0 # $$foo
6734 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6735 0         0 $char[$i] = e_capture($1);
6736             if ($ignorecase) {
6737             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6738             }
6739             }
6740              
6741 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egreek::PREMATCH()
6742 4         13 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6743             if ($ignorecase) {
6744             $char[$i] = '@{[Egreek::ignorecase(Egreek::PREMATCH())]}';
6745 0         0 }
6746             else {
6747             $char[$i] = '@{[Egreek::PREMATCH()]}';
6748             }
6749             }
6750              
6751 4 50       14 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egreek::MATCH()
6752 4         15 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6753             if ($ignorecase) {
6754             $char[$i] = '@{[Egreek::ignorecase(Egreek::MATCH())]}';
6755 0         0 }
6756             else {
6757             $char[$i] = '@{[Egreek::MATCH()]}';
6758             }
6759             }
6760              
6761 4 50       14 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egreek::POSTMATCH()
6762 3         10 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6763             if ($ignorecase) {
6764             $char[$i] = '@{[Egreek::ignorecase(Egreek::POSTMATCH())]}';
6765 0         0 }
6766             else {
6767             $char[$i] = '@{[Egreek::POSTMATCH()]}';
6768             }
6769             }
6770              
6771 3 0       10 # ${ foo }
6772 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) {
6773             if ($ignorecase) {
6774             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6775             }
6776             }
6777              
6778 0         0 # ${ ... }
6779 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6780 0         0 $char[$i] = e_capture($1);
6781             if ($ignorecase) {
6782             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6783             }
6784             }
6785              
6786 0         0 # $scalar or @array
6787 4 50       30 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6788 4         22 $char[$i] = e_string($char[$i]);
6789             if ($ignorecase) {
6790             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
6791             }
6792             }
6793              
6794 0 50       0 # quote character before ? + * {
6795             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6796             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6797 13         69 }
6798             else {
6799             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6800             }
6801             }
6802             }
6803 13         65  
6804 68         153 # make regexp string
6805 68 50       121 my $prematch = '';
6806 68         180 $modifier =~ tr/i//d;
6807             if ($left_e > $right_e) {
6808 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6809             }
6810             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6811             }
6812              
6813             #
6814             # escape regexp (s'here'' or s'here''b)
6815 68     21 0 801 #
6816 21   100     44 sub e_s1_q {
6817             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6818 21         60 $modifier ||= '';
6819 21 50       34  
6820 21         37 $modifier =~ tr/p//d;
6821 0         0 if ($modifier =~ /([adlu])/oxms) {
6822 0 0       0 my $line = 0;
6823 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6824 0         0 if ($filename ne __FILE__) {
6825             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6826             last;
6827 0         0 }
6828             }
6829             die qq{Unsupported modifier "$1" used at line $line.\n};
6830 0         0 }
6831              
6832             $slash = 'div';
6833 21 100       25  
    50          
6834 21         55 # literal null string pattern
6835 8         10 if ($string eq '') {
6836 8         9 $modifier =~ tr/bB//d;
6837             $modifier =~ tr/i//d;
6838             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6839             }
6840              
6841 8         40 # with /b /B modifier
6842             elsif ($modifier =~ tr/bB//d) {
6843             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6844             }
6845              
6846 0         0 # without /b /B modifier
6847             else {
6848             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6849             }
6850             }
6851              
6852             #
6853             # escape regexp (s'here'')
6854 13     13 0 24 #
6855             sub e_s1_qt {
6856 13 50       30 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6857              
6858             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6859 13         22  
6860             # split regexp
6861             my @char = $string =~ /\G((?>
6862             [^\\\[\$\@\/] |
6863             [\x00-\xFF] |
6864             \[\^ |
6865             \[\: (?>[a-z]+) \:\] |
6866             \[\:\^ (?>[a-z]+) \:\] |
6867             [\$\@\/] |
6868             \\ (?:$q_char) |
6869             (?:$q_char)
6870             ))/oxmsg;
6871 13         263  
6872 13 50 33     39 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6873             for (my $i=0; $i <= $#char; $i++) {
6874             if (0) {
6875             }
6876 25         92  
6877 0         0 # open character class [...]
6878 0 0       0 elsif ($char[$i] eq '[') {
6879 0         0 my $left = $i;
6880             if ($char[$i+1] eq ']') {
6881 0         0 $i++;
6882 0 0       0 }
6883 0         0 while (1) {
6884             if (++$i > $#char) {
6885 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6886 0         0 }
6887             if ($char[$i] eq ']') {
6888             my $right = $i;
6889 0         0  
6890             # [...]
6891 0         0 splice @char, $left, $right-$left+1, Egreek::charlist_qr(@char[$left+1..$right-1], $modifier);
6892 0         0  
6893             $i = $left;
6894             last;
6895             }
6896             }
6897             }
6898              
6899 0         0 # open character class [^...]
6900 0 0       0 elsif ($char[$i] eq '[^') {
6901 0         0 my $left = $i;
6902             if ($char[$i+1] eq ']') {
6903 0         0 $i++;
6904 0 0       0 }
6905 0         0 while (1) {
6906             if (++$i > $#char) {
6907 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6908 0         0 }
6909             if ($char[$i] eq ']') {
6910             my $right = $i;
6911 0         0  
6912             # [^...]
6913 0         0 splice @char, $left, $right-$left+1, Egreek::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6914 0         0  
6915             $i = $left;
6916             last;
6917             }
6918             }
6919             }
6920              
6921 0         0 # escape $ @ / and \
6922             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6923             $char[$i] = '\\' . $char[$i];
6924             }
6925              
6926 0         0 # rewrite character class or escape character
6927             elsif (my $char = character_class($char[$i],$modifier)) {
6928             $char[$i] = $char;
6929             }
6930              
6931 6 0       13 # /i modifier
6932 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egreek::uc($char[$i]) ne Egreek::fc($char[$i]))) {
6933             if (CORE::length(Egreek::fc($char[$i])) == 1) {
6934             $char[$i] = '[' . Egreek::uc($char[$i]) . Egreek::fc($char[$i]) . ']';
6935 0         0 }
6936             else {
6937             $char[$i] = '(?:' . Egreek::uc($char[$i]) . '|' . Egreek::fc($char[$i]) . ')';
6938             }
6939             }
6940              
6941 0 0       0 # quote character before ? + * {
6942             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6943             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6944 0         0 }
6945             else {
6946             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6947             }
6948             }
6949 0         0 }
6950 13         23  
6951 13         19 $modifier =~ tr/i//d;
6952 13         16 $delimiter = '/';
6953 13         15 $end_delimiter = '/';
6954             my $prematch = '';
6955             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6956             }
6957              
6958             #
6959             # escape regexp (s'here''b)
6960 13     0 0 92 #
6961             sub e_s1_qb {
6962             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6963 0         0  
6964             # split regexp
6965             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6966 0         0  
6967 0 0       0 # unescape character
    0          
6968             for (my $i=0; $i <= $#char; $i++) {
6969             if (0) {
6970             }
6971 0         0  
6972             # remain \\
6973             elsif ($char[$i] eq '\\\\') {
6974             }
6975              
6976 0         0 # escape $ @ / and \
6977             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6978             $char[$i] = '\\' . $char[$i];
6979             }
6980 0         0 }
6981 0         0  
6982 0         0 $delimiter = '/';
6983 0         0 $end_delimiter = '/';
6984             my $prematch = '';
6985             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6986             }
6987              
6988             #
6989             # escape regexp (s''here')
6990 0     16 0 0 #
6991             sub e_s2_q {
6992 16         188 my($ope,$delimiter,$end_delimiter,$string) = @_;
6993              
6994 16         22 $slash = 'div';
6995 16         93  
6996 16 100       47 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
6997             for (my $i=0; $i <= $#char; $i++) {
6998             if (0) {
6999             }
7000 9         29  
7001             # not escape \\
7002             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
7003             }
7004              
7005 0         0 # escape $ @ / and \
7006             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
7007             $char[$i] = '\\' . $char[$i];
7008             }
7009 5         15 }
7010              
7011             return join '', $ope, $delimiter, @char, $end_delimiter;
7012             }
7013              
7014             #
7015             # escape regexp (s/here/and here/modifier)
7016 16     97 0 48 #
7017 97   100     859 sub e_sub {
7018             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
7019 97         536 $modifier ||= '';
7020 97 50       228  
7021 97         264 $modifier =~ tr/p//d;
7022 0         0 if ($modifier =~ /([adlu])/oxms) {
7023 0 0       0 my $line = 0;
7024 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7025 0         0 if ($filename ne __FILE__) {
7026             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7027             last;
7028 0         0 }
7029             }
7030             die qq{Unsupported modifier "$1" used at line $line.\n};
7031 0 100       0 }
7032 97         235  
7033 36         45 if ($variable eq '') {
7034             $variable = '$_';
7035             $bind_operator = ' =~ ';
7036 36         44 }
7037              
7038             $slash = 'div';
7039              
7040             # P.128 Start of match (or end of previous match): \G
7041             # P.130 Advanced Use of \G with Perl
7042             # in Chapter 3: Overview of Regular Expression Features and Flavors
7043             # P.312 Iterative Matching: Scalar Context, with /g
7044             # in Chapter 7: Perl
7045             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
7046              
7047             # P.181 Where You Left Off: The \G Assertion
7048             # in Chapter 5: Pattern Matching
7049             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7050              
7051             # P.220 Where You Left Off: The \G Assertion
7052             # in Chapter 5: Pattern Matching
7053 97         208 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7054 97         152  
7055             my $e_modifier = $modifier =~ tr/e//d;
7056 97         146 my $r_modifier = $modifier =~ tr/r//d;
7057 97 50       153  
7058 97         241 my $my = '';
7059 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
7060 0         0 $my = $variable;
7061             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
7062             $variable =~ s/ = .+ \z//oxms;
7063 0         0 }
7064 97         279  
7065             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
7066             $variable_basename =~ s/ \s+ \z//oxms;
7067 97         216  
7068 97 100       142 # quote replacement string
7069 97         236 my $e_replacement = '';
7070 17         30 if ($e_modifier >= 1) {
7071             $e_replacement = e_qq('', '', '', $replacement);
7072             $e_modifier--;
7073 17 100       24 }
7074 80         265 else {
7075             if ($delimiter2 eq "'") {
7076             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
7077 16         31 }
7078             else {
7079             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
7080             }
7081 64         157 }
7082              
7083             my $sub = '';
7084 97 100       168  
7085 97 100       216 # with /r
7086             if ($r_modifier) {
7087             if (0) {
7088             }
7089 8         21  
7090 0 50       0 # s///gr without multibyte anchoring
7091             elsif ($modifier =~ /g/oxms) {
7092             $sub = sprintf(
7093             # 1 2 3 4 5
7094             q,
7095              
7096             $variable, # 1
7097             ($delimiter1 eq "'") ? # 2
7098             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7099             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7100             $s_matched, # 3
7101             $e_replacement, # 4
7102             '$Egreek::re_r=CORE::eval $Egreek::re_r; ' x $e_modifier, # 5
7103             );
7104             }
7105              
7106             # s///r
7107 4         19 else {
7108              
7109 4 50       6 my $prematch = q{$`};
7110              
7111             $sub = sprintf(
7112             # 1 2 3 4 5 6 7
7113             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Egreek::re_r=%s; %s"%s$Egreek::re_r$'" } : %s>,
7114              
7115             $variable, # 1
7116             ($delimiter1 eq "'") ? # 2
7117             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7118             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7119             $s_matched, # 3
7120             $e_replacement, # 4
7121             '$Egreek::re_r=CORE::eval $Egreek::re_r; ' x $e_modifier, # 5
7122             $prematch, # 6
7123             $variable, # 7
7124             );
7125             }
7126 4 50       21  
7127 8         24 # $var !~ s///r doesn't make sense
7128             if ($bind_operator =~ / !~ /oxms) {
7129             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
7130             }
7131             }
7132              
7133 0 100       0 # without /r
7134             else {
7135             if (0) {
7136             }
7137 89         200  
7138 0 100       0 # s///g without multibyte anchoring
    100          
7139             elsif ($modifier =~ /g/oxms) {
7140             $sub = sprintf(
7141             # 1 2 3 4 5 6 7 8
7142             q,
7143              
7144             $variable, # 1
7145             ($delimiter1 eq "'") ? # 2
7146             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7147             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7148             $s_matched, # 3
7149             $e_replacement, # 4
7150             '$Egreek::re_r=CORE::eval $Egreek::re_r; ' x $e_modifier, # 5
7151             $variable, # 6
7152             $variable, # 7
7153             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
7154             );
7155             }
7156              
7157             # s///
7158 22         78 else {
7159              
7160 67 100       101 my $prematch = q{$`};
    100          
7161              
7162             $sub = sprintf(
7163              
7164             ($bind_operator =~ / =~ /oxms) ?
7165              
7166             # 1 2 3 4 5 6 7 8
7167             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Egreek::re_r=%s; %s%s="%s$Egreek::re_r$'"; 1 } : undef> :
7168              
7169             # 1 2 3 4 5 6 7 8
7170             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Egreek::re_r=%s; %s%s="%s$Egreek::re_r$'"; undef }>,
7171              
7172             $variable, # 1
7173             $bind_operator, # 2
7174             ($delimiter1 eq "'") ? # 3
7175             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
7176             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
7177             $s_matched, # 4
7178             $e_replacement, # 5
7179             '$Egreek::re_r=CORE::eval $Egreek::re_r; ' x $e_modifier, # 6
7180             $variable, # 7
7181             $prematch, # 8
7182             );
7183             }
7184             }
7185 67 50       346  
7186 97         268 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
7187             if ($my ne '') {
7188             $sub = "($my, $sub)[1]";
7189             }
7190 0         0  
7191 97         180 # clear s/// variable
7192             $sub_variable = '';
7193 97         133 $bind_operator = '';
7194              
7195             return $sub;
7196             }
7197              
7198             #
7199             # escape regexp of split qr//
7200 97     74 0 806 #
7201 74   100     465 sub e_split {
7202             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7203 74         353 $modifier ||= '';
7204 74 50       121  
7205 74         176 $modifier =~ tr/p//d;
7206 0         0 if ($modifier =~ /([adlu])/oxms) {
7207 0 0       0 my $line = 0;
7208 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7209 0         0 if ($filename ne __FILE__) {
7210             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7211             last;
7212 0         0 }
7213             }
7214             die qq{Unsupported modifier "$1" used at line $line.\n};
7215 0         0 }
7216              
7217             $slash = 'div';
7218 74 50       112  
7219 74         171 # /b /B modifier
7220             if ($modifier =~ tr/bB//d) {
7221             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7222 0 50       0 }
7223 74         197  
7224             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7225             my $metachar = qr/[\@\\|[\]{^]/oxms;
7226 74         297  
7227             # split regexp
7228             my @char = $string =~ /\G((?>
7229             [^\\\$\@\[\(] |
7230             \\x (?>[0-9A-Fa-f]{1,2}) |
7231             \\ (?>[0-7]{2,3}) |
7232             \\c [\x40-\x5F] |
7233             \\x\{ (?>[0-9A-Fa-f]+) \} |
7234             \\o\{ (?>[0-7]+) \} |
7235             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
7236             \\ $q_char |
7237             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7238             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7239             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7240             [\$\@] $qq_variable |
7241             \$ (?>\s* [0-9]+) |
7242             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7243             \$ \$ (?![\w\{]) |
7244             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7245             \[\^ |
7246             \[\: (?>[a-z]+) :\] |
7247             \[\:\^ (?>[a-z]+) :\] |
7248             \(\? |
7249             $q_char
7250 74         9674 ))/oxmsg;
7251 74         343  
7252 74         119 my $left_e = 0;
7253             my $right_e = 0;
7254             for (my $i=0; $i <= $#char; $i++) {
7255 74 50 33     406  
    50 33        
    100          
    100          
    50          
    50          
7256 249         1305 # "\L\u" --> "\u\L"
7257             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7258             @char[$i,$i+1] = @char[$i+1,$i];
7259             }
7260              
7261 0         0 # "\U\l" --> "\l\U"
7262             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7263             @char[$i,$i+1] = @char[$i+1,$i];
7264             }
7265              
7266 0         0 # octal escape sequence
7267             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7268             $char[$i] = Egreek::octchr($1);
7269             }
7270              
7271 1         4 # hexadecimal escape sequence
7272             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7273             $char[$i] = Egreek::hexchr($1);
7274             }
7275              
7276             # \b{...} --> b\{...}
7277             # \B{...} --> B\{...}
7278             # \N{CHARNAME} --> N\{CHARNAME}
7279             # \p{PROPERTY} --> p\{PROPERTY}
7280 1         4 # \P{PROPERTY} --> P\{PROPERTY}
7281             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
7282             $char[$i] = $1 . '\\' . $2;
7283             }
7284              
7285 0         0 # \p, \P, \X --> p, P, X
7286             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
7287             $char[$i] = $1;
7288 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          
7289              
7290             if (0) {
7291             }
7292 249         1378  
7293 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
7294 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
7295             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)) {
7296             $char[$i] .= join '', splice @char, $i+1, 3;
7297 0         0 }
7298             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)) {
7299             $char[$i] .= join '', splice @char, $i+1, 2;
7300 0         0 }
7301             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)) {
7302             $char[$i] .= join '', splice @char, $i+1, 1;
7303             }
7304             }
7305              
7306 0         0 # open character class [...]
7307 3 50       6 elsif ($char[$i] eq '[') {
7308 3         9 my $left = $i;
7309             if ($char[$i+1] eq ']') {
7310 0         0 $i++;
7311 3 50       3 }
7312 7         10 while (1) {
7313             if (++$i > $#char) {
7314 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
7315 7         14 }
7316             if ($char[$i] eq ']') {
7317             my $right = $i;
7318 3 50       4  
7319 3         12 # [...]
  0         0  
7320             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7321             splice @char, $left, $right-$left+1, sprintf(q{@{[Egreek::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7322 0         0 }
7323             else {
7324             splice @char, $left, $right-$left+1, Egreek::charlist_qr(@char[$left+1..$right-1], $modifier);
7325 3         13 }
7326 3         5  
7327             $i = $left;
7328             last;
7329             }
7330             }
7331             }
7332              
7333 3         7 # open character class [^...]
7334 0 0       0 elsif ($char[$i] eq '[^') {
7335 0         0 my $left = $i;
7336             if ($char[$i+1] eq ']') {
7337 0         0 $i++;
7338 0 0       0 }
7339 0         0 while (1) {
7340             if (++$i > $#char) {
7341 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
7342 0         0 }
7343             if ($char[$i] eq ']') {
7344             my $right = $i;
7345 0 0       0  
7346 0         0 # [^...]
  0         0  
7347             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
7348             splice @char, $left, $right-$left+1, sprintf(q{@{[Egreek::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
7349 0         0 }
7350             else {
7351             splice @char, $left, $right-$left+1, Egreek::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7352 0         0 }
7353 0         0  
7354             $i = $left;
7355             last;
7356             }
7357             }
7358             }
7359              
7360 0         0 # rewrite character class or escape character
7361             elsif (my $char = character_class($char[$i],$modifier)) {
7362             $char[$i] = $char;
7363             }
7364              
7365             # P.794 29.2.161. split
7366             # in Chapter 29: Functions
7367             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7368              
7369             # P.951 split
7370             # in Chapter 27: Functions
7371             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7372              
7373             # said "The //m modifier is assumed when you split on the pattern /^/",
7374             # but perl5.008 is not so. Therefore, this software adds //m.
7375             # (and so on)
7376              
7377 1         3 # split(m/^/) --> split(m/^/m)
7378             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7379             $modifier .= 'm';
7380             }
7381              
7382 7 0       20 # /i modifier
7383 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egreek::uc($char[$i]) ne Egreek::fc($char[$i]))) {
7384             if (CORE::length(Egreek::fc($char[$i])) == 1) {
7385             $char[$i] = '[' . Egreek::uc($char[$i]) . Egreek::fc($char[$i]) . ']';
7386 0         0 }
7387             else {
7388             $char[$i] = '(?:' . Egreek::uc($char[$i]) . '|' . Egreek::fc($char[$i]) . ')';
7389             }
7390             }
7391              
7392 0 0       0 # \u \l \U \L \F \Q \E
7393 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
7394             if ($right_e < $left_e) {
7395             $char[$i] = '\\' . $char[$i];
7396             }
7397 0         0 }
7398 0         0 elsif ($char[$i] eq '\u') {
7399             $char[$i] = '@{[Egreek::ucfirst qq<';
7400             $left_e++;
7401 0         0 }
7402 0         0 elsif ($char[$i] eq '\l') {
7403             $char[$i] = '@{[Egreek::lcfirst qq<';
7404             $left_e++;
7405 0         0 }
7406 0         0 elsif ($char[$i] eq '\U') {
7407             $char[$i] = '@{[Egreek::uc qq<';
7408             $left_e++;
7409 0         0 }
7410 0         0 elsif ($char[$i] eq '\L') {
7411             $char[$i] = '@{[Egreek::lc qq<';
7412             $left_e++;
7413 0         0 }
7414 0         0 elsif ($char[$i] eq '\F') {
7415             $char[$i] = '@{[Egreek::fc qq<';
7416             $left_e++;
7417 0         0 }
7418 0         0 elsif ($char[$i] eq '\Q') {
7419             $char[$i] = '@{[CORE::quotemeta qq<';
7420             $left_e++;
7421 0 0       0 }
7422 0         0 elsif ($char[$i] eq '\E') {
7423 0         0 if ($right_e < $left_e) {
7424             $char[$i] = '>]}';
7425             $right_e++;
7426 0         0 }
7427             else {
7428             $char[$i] = '';
7429             }
7430 0         0 }
7431 0 0       0 elsif ($char[$i] eq '\Q') {
7432 0         0 while (1) {
7433             if (++$i > $#char) {
7434 0 0       0 last;
7435 0         0 }
7436             if ($char[$i] eq '\E') {
7437             last;
7438             }
7439             }
7440             }
7441             elsif ($char[$i] eq '\E') {
7442             }
7443              
7444 0 0       0 # $0 --> $0
7445 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
7446             if ($ignorecase) {
7447             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
7448             }
7449 0 0       0 }
7450 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
7451             if ($ignorecase) {
7452             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
7453             }
7454             }
7455              
7456             # $$ --> $$
7457             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
7458             }
7459              
7460             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7461 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7462 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
7463 0         0 $char[$i] = e_capture($1);
7464             if ($ignorecase) {
7465             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
7466             }
7467 0         0 }
7468 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
7469 0         0 $char[$i] = e_capture($1);
7470             if ($ignorecase) {
7471             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
7472             }
7473             }
7474              
7475 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7476 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) {
7477 0         0 $char[$i] = e_capture($1.'->'.$2);
7478             if ($ignorecase) {
7479             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
7480             }
7481             }
7482              
7483 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7484 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) {
7485 0         0 $char[$i] = e_capture($1.'->'.$2);
7486             if ($ignorecase) {
7487             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
7488             }
7489             }
7490              
7491 0         0 # $$foo
7492 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7493 0         0 $char[$i] = e_capture($1);
7494             if ($ignorecase) {
7495             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
7496             }
7497             }
7498              
7499 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egreek::PREMATCH()
7500 12         34 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7501             if ($ignorecase) {
7502             $char[$i] = '@{[Egreek::ignorecase(Egreek::PREMATCH())]}';
7503 0         0 }
7504             else {
7505             $char[$i] = '@{[Egreek::PREMATCH()]}';
7506             }
7507             }
7508              
7509 12 50       56 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egreek::MATCH()
7510 12         43 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7511             if ($ignorecase) {
7512             $char[$i] = '@{[Egreek::ignorecase(Egreek::MATCH())]}';
7513 0         0 }
7514             else {
7515             $char[$i] = '@{[Egreek::MATCH()]}';
7516             }
7517             }
7518              
7519 12 50       53 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egreek::POSTMATCH()
7520 9         28 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7521             if ($ignorecase) {
7522             $char[$i] = '@{[Egreek::ignorecase(Egreek::POSTMATCH())]}';
7523 0         0 }
7524             else {
7525             $char[$i] = '@{[Egreek::POSTMATCH()]}';
7526             }
7527             }
7528              
7529 9 0       40 # ${ foo }
7530 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) {
7531             if ($ignorecase) {
7532             $char[$i] = '@{[Egreek::ignorecase(' . $1 . ')]}';
7533             }
7534             }
7535              
7536 0         0 # ${ ... }
7537 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7538 0         0 $char[$i] = e_capture($1);
7539             if ($ignorecase) {
7540             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
7541             }
7542             }
7543              
7544 0         0 # $scalar or @array
7545 3 50       9 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7546 3         12 $char[$i] = e_string($char[$i]);
7547             if ($ignorecase) {
7548             $char[$i] = '@{[Egreek::ignorecase(' . $char[$i] . ')]}';
7549             }
7550             }
7551              
7552 0 50       0 # quote character before ? + * {
7553             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7554             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7555 1         6 }
7556             else {
7557             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7558             }
7559             }
7560             }
7561 0         0  
7562 74 50       214 # make regexp string
7563 74         158 $modifier =~ tr/i//d;
7564             if ($left_e > $right_e) {
7565 0         0 return join '', 'Egreek::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7566             }
7567             return join '', 'Egreek::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7568             }
7569              
7570             #
7571             # escape regexp of split qr''
7572 74     0 0 686 #
7573 0   0       sub e_split_q {
7574             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7575 0           $modifier ||= '';
7576 0 0          
7577 0           $modifier =~ tr/p//d;
7578 0           if ($modifier =~ /([adlu])/oxms) {
7579 0 0         my $line = 0;
7580 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7581 0           if ($filename ne __FILE__) {
7582             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7583             last;
7584 0           }
7585             }
7586             die qq{Unsupported modifier "$1" used at line $line.\n};
7587 0           }
7588              
7589             $slash = 'div';
7590 0 0          
7591 0           # /b /B modifier
7592             if ($modifier =~ tr/bB//d) {
7593             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7594 0 0         }
7595              
7596             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7597 0            
7598             # split regexp
7599             my @char = $string =~ /\G((?>
7600             [^\\\[] |
7601             [\x00-\xFF] |
7602             \[\^ |
7603             \[\: (?>[a-z]+) \:\] |
7604             \[\:\^ (?>[a-z]+) \:\] |
7605             \\ (?:$q_char) |
7606             (?:$q_char)
7607             ))/oxmsg;
7608 0            
7609 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7610             for (my $i=0; $i <= $#char; $i++) {
7611             if (0) {
7612             }
7613 0            
7614 0           # open character class [...]
7615 0 0         elsif ($char[$i] eq '[') {
7616 0           my $left = $i;
7617             if ($char[$i+1] eq ']') {
7618 0           $i++;
7619 0 0         }
7620 0           while (1) {
7621             if (++$i > $#char) {
7622 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7623 0           }
7624             if ($char[$i] eq ']') {
7625             my $right = $i;
7626 0            
7627             # [...]
7628 0           splice @char, $left, $right-$left+1, Egreek::charlist_qr(@char[$left+1..$right-1], $modifier);
7629 0            
7630             $i = $left;
7631             last;
7632             }
7633             }
7634             }
7635              
7636 0           # open character class [^...]
7637 0 0         elsif ($char[$i] eq '[^') {
7638 0           my $left = $i;
7639             if ($char[$i+1] eq ']') {
7640 0           $i++;
7641 0 0         }
7642 0           while (1) {
7643             if (++$i > $#char) {
7644 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7645 0           }
7646             if ($char[$i] eq ']') {
7647             my $right = $i;
7648 0            
7649             # [^...]
7650 0           splice @char, $left, $right-$left+1, Egreek::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7651 0            
7652             $i = $left;
7653             last;
7654             }
7655             }
7656             }
7657              
7658 0           # rewrite character class or escape character
7659             elsif (my $char = character_class($char[$i],$modifier)) {
7660             $char[$i] = $char;
7661             }
7662              
7663 0           # split(m/^/) --> split(m/^/m)
7664             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7665             $modifier .= 'm';
7666             }
7667              
7668 0 0         # /i modifier
7669 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egreek::uc($char[$i]) ne Egreek::fc($char[$i]))) {
7670             if (CORE::length(Egreek::fc($char[$i])) == 1) {
7671             $char[$i] = '[' . Egreek::uc($char[$i]) . Egreek::fc($char[$i]) . ']';
7672 0           }
7673             else {
7674             $char[$i] = '(?:' . Egreek::uc($char[$i]) . '|' . Egreek::fc($char[$i]) . ')';
7675             }
7676             }
7677              
7678 0 0         # quote character before ? + * {
7679             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7680             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7681 0           }
7682             else {
7683             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7684             }
7685             }
7686 0           }
7687 0            
7688             $modifier =~ tr/i//d;
7689             return join '', 'Egreek::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7690             }
7691              
7692             #
7693             # instead of Carp::carp
7694 0     0 0   #
7695 0           sub carp {
7696             my($package,$filename,$line) = caller(1);
7697             print STDERR "@_ at $filename line $line.\n";
7698             }
7699              
7700             #
7701             # instead of Carp::croak
7702 0     0 0   #
7703 0           sub croak {
7704 0           my($package,$filename,$line) = caller(1);
7705             print STDERR "@_ at $filename line $line.\n";
7706             die "\n";
7707             }
7708              
7709             #
7710             # instead of Carp::cluck
7711 0     0 0   #
7712 0           sub cluck {
7713 0           my $i = 0;
7714 0           my @cluck = ();
7715 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7716             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7717 0           $i++;
7718 0           }
7719 0           print STDERR CORE::reverse @cluck;
7720             print STDERR "\n";
7721             print STDERR @_;
7722             }
7723              
7724             #
7725             # instead of Carp::confess
7726 0     0 0   #
7727 0           sub confess {
7728 0           my $i = 0;
7729 0           my @confess = ();
7730 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7731             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7732 0           $i++;
7733 0           }
7734 0           print STDERR CORE::reverse @confess;
7735 0           print STDERR "\n";
7736             print STDERR @_;
7737             die "\n";
7738             }
7739              
7740             1;
7741              
7742             __END__