File Coverage

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


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