File Coverage

blib/lib/Egbk.pm
Criterion Covered Total %
statement 1213 4194 28.9
branch 1266 4236 29.8
condition 162 496 32.6
subroutine 71 196 36.2
pod 8 148 5.4
total 2720 9270 29.3


line stmt bran cond sub pod time code
1             package Egbk;
2 391     391   9577 use strict;
  391         2214  
  391         19159  
3 391 50   391   9437 BEGIN { $INC{'warnings.pm'} = '' if $] < 5.006 } use warnings;
  391     391   4818  
  391         2150  
  391         15863  
4             ######################################################################
5             #
6             # Egbk - Run-time routines for GBK.pm
7             #
8             # http://search.cpan.org/dist/Char-GBK/
9             #
10             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
11             ######################################################################
12              
13 391     391   7723 use 5.00503; # Galapagos Consensus 1998 for primetools
  391         1195  
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 391     391   5525 use vars qw($VERSION);
  391         2316  
  391         55169  
29             $VERSION = '1.22';
30             $VERSION = $VERSION;
31              
32             BEGIN {
33 391 50   391   7529 if ($^X =~ / jperl /oxmsi) {
34 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
35             }
36 391         620 if (CORE::ord('A') == 193) {
37             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
38             }
39 391         55228 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 391     391   26204 CORE::eval q{
  391     391   3730  
  391     126   2247  
  391         50011  
  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 391 50       147837 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     1158 0 0 my($name) = @_;
79              
80 1158 50       2813 if (ref $name) {
    50          
    50          
    50          
    50          
    50          
    50          
81 1158         4797 return $name;
82             }
83             elsif (Egbk::index($name,'::') >= 0) {
84 0         0 return $name;
85             }
86             elsif (Egbk::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 1158         8899 return (caller)[0] . '::' . $name;
113             }
114             }
115              
116             sub qualify_to_ref ($;$) {
117 0 50   1158 0 0 if (defined $_[1]) {
118 391     391   4486 no strict qw(refs);
  391         742  
  391         28318  
119 1158         3421 return \*{ qualify $_[0], $_[1] };
  0         0  
120             }
121             else {
122 391     391   2399 no strict qw(refs);
  391     0   692  
  391         69636  
123 0         0 return \*{ qualify $_[0], (caller)[0] };
  1158         1749  
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{[\x81-\xFE][\x00-\xFF]|[\x00-\xFF]};
154 391     391   4092 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  391         2218  
  391         32181  
155 391     391   3572 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  391         2241  
  391         635659  
156              
157             #
158             # GBK character range per length
159             #
160             my %range_tr = ();
161              
162             #
163             # GBK 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 Egbk \z/oxms) {
179             %range_tr = (
180             1 => [ [0x00..0x80],
181             [0xFF..0xFF],
182             ],
183             2 => [ [0x81..0xFE],[0x40..0x7E],
184             [0x81..0xFE],[0x80..0xFE],
185             ],
186             );
187             }
188              
189             else {
190             croak "Don't know my package name '@{[__PACKAGE__]}'";
191             }
192              
193             #
194             # @ARGV wildcard globbing
195             #
196             sub import {
197              
198 1158 50   5   5987 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
199 5         87 my @argv = ();
200 0         0 for (@ARGV) {
201              
202             # has space
203 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
204 0 0       0 if (my @glob = Egbk::glob(qq{"$_"})) {
205 0         0 push @argv, @glob;
206             }
207             else {
208 0         0 push @argv, $_;
209             }
210             }
211              
212             # has wildcard metachar
213             elsif (/\A (?:$q_char)*? [*?] /oxms) {
214 0 0       0 if (my @glob = Egbk::glob($_)) {
215 0         0 push @argv, @glob;
216             }
217             else {
218 0         0 push @argv, $_;
219             }
220             }
221              
222             # no wildcard globbing
223             else {
224 0         0 push @argv, $_;
225             }
226             }
227 0         0 @ARGV = @argv;
228             }
229              
230 0         0 *Char::ord = \&GBK::ord;
231 5         27 *Char::ord_ = \&GBK::ord_;
232 5         15 *Char::reverse = \&GBK::reverse;
233 5         11 *Char::getc = \&GBK::getc;
234 5         9 *Char::length = \&GBK::length;
235 5         10 *Char::substr = \&GBK::substr;
236 5         127 *Char::index = \&GBK::index;
237 5         11 *Char::rindex = \&GBK::rindex;
238 5         10 *Char::eval = \&GBK::eval;
239 5         18 *Char::escape = \&GBK::escape;
240 5         10 *Char::escape_token = \&GBK::escape_token;
241 5         9 *Char::escape_script = \&GBK::escape_script;
242             }
243              
244             # P.230 Care with Prototypes
245             # in Chapter 6: Subroutines
246             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
247             #
248             # If you aren't careful, you can get yourself into trouble with prototypes.
249             # But if you are careful, you can do a lot of neat things with them. This is
250             # all very powerful, of course, and should only be used in moderation to make
251             # the world a better place.
252              
253             # P.332 Care with Prototypes
254             # in Chapter 7: Subroutines
255             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
256             #
257             # If you aren't careful, you can get yourself into trouble with prototypes.
258             # But if you are careful, you can do a lot of neat things with them. This is
259             # all very powerful, of course, and should only be used in moderation to make
260             # the world a better place.
261              
262             #
263             # Prototypes of subroutines
264             #
265       0     sub unimport {}
266             sub Egbk::split(;$$$);
267             sub Egbk::tr($$$$;$);
268             sub Egbk::chop(@);
269             sub Egbk::index($$;$);
270             sub Egbk::rindex($$;$);
271             sub Egbk::lcfirst(@);
272             sub Egbk::lcfirst_();
273             sub Egbk::lc(@);
274             sub Egbk::lc_();
275             sub Egbk::ucfirst(@);
276             sub Egbk::ucfirst_();
277             sub Egbk::uc(@);
278             sub Egbk::uc_();
279             sub Egbk::fc(@);
280             sub Egbk::fc_();
281             sub Egbk::ignorecase;
282             sub Egbk::classic_character_class;
283             sub Egbk::capture;
284             sub Egbk::chr(;$);
285             sub Egbk::chr_();
286             sub Egbk::filetest;
287             sub Egbk::r(;*@);
288             sub Egbk::w(;*@);
289             sub Egbk::x(;*@);
290             sub Egbk::o(;*@);
291             sub Egbk::R(;*@);
292             sub Egbk::W(;*@);
293             sub Egbk::X(;*@);
294             sub Egbk::O(;*@);
295             sub Egbk::e(;*@);
296             sub Egbk::z(;*@);
297             sub Egbk::s(;*@);
298             sub Egbk::f(;*@);
299             sub Egbk::d(;*@);
300             sub Egbk::l(;*@);
301             sub Egbk::p(;*@);
302             sub Egbk::S(;*@);
303             sub Egbk::b(;*@);
304             sub Egbk::c(;*@);
305             sub Egbk::u(;*@);
306             sub Egbk::g(;*@);
307             sub Egbk::k(;*@);
308             sub Egbk::T(;*@);
309             sub Egbk::B(;*@);
310             sub Egbk::M(;*@);
311             sub Egbk::A(;*@);
312             sub Egbk::C(;*@);
313             sub Egbk::filetest_;
314             sub Egbk::r_();
315             sub Egbk::w_();
316             sub Egbk::x_();
317             sub Egbk::o_();
318             sub Egbk::R_();
319             sub Egbk::W_();
320             sub Egbk::X_();
321             sub Egbk::O_();
322             sub Egbk::e_();
323             sub Egbk::z_();
324             sub Egbk::s_();
325             sub Egbk::f_();
326             sub Egbk::d_();
327             sub Egbk::l_();
328             sub Egbk::p_();
329             sub Egbk::S_();
330             sub Egbk::b_();
331             sub Egbk::c_();
332             sub Egbk::u_();
333             sub Egbk::g_();
334             sub Egbk::k_();
335             sub Egbk::T_();
336             sub Egbk::B_();
337             sub Egbk::M_();
338             sub Egbk::A_();
339             sub Egbk::C_();
340             sub Egbk::glob($);
341             sub Egbk::glob_();
342             sub Egbk::lstat(*);
343             sub Egbk::lstat_();
344             sub Egbk::opendir(*$);
345             sub Egbk::stat(*);
346             sub Egbk::stat_();
347             sub Egbk::unlink(@);
348             sub Egbk::chdir(;$);
349             sub Egbk::do($);
350             sub Egbk::require(;$);
351             sub Egbk::telldir(*);
352              
353             sub GBK::ord(;$);
354             sub GBK::ord_();
355             sub GBK::reverse(@);
356             sub GBK::getc(;*@);
357             sub GBK::length(;$);
358             sub GBK::substr($$;$$);
359             sub GBK::index($$;$);
360             sub GBK::rindex($$;$);
361             sub GBK::escape(;$);
362              
363             #
364             # Regexp work
365             #
366 391         43286 use vars qw(
367             $re_a
368             $re_t
369             $re_n
370             $re_r
371 391     391   5898 );
  391         872  
372              
373             #
374             # Character class
375             #
376 391         100349 use vars qw(
377             $dot
378             $dot_s
379             $eD
380             $eS
381             $eW
382             $eH
383             $eV
384             $eR
385             $eN
386             $not_alnum
387             $not_alpha
388             $not_ascii
389             $not_blank
390             $not_cntrl
391             $not_digit
392             $not_graph
393             $not_lower
394             $not_lower_i
395             $not_print
396             $not_punct
397             $not_space
398             $not_upper
399             $not_upper_i
400             $not_word
401             $not_xdigit
402             $eb
403             $eB
404 391     391   4032 );
  391         2322  
405              
406 391         4202618 use vars qw(
407             $anchor
408             $matched
409 391     391   3740 );
  391         6498  
410             ${Egbk::anchor} = qr{\G(?>[^\x81-\xFE]|[\x81-\xFE][\x00-\xFF])*?}oxms;
411             my $q_char_SADAHIRO_Tomoyuki_2002_01_17 = '';
412              
413             # Quantifiers
414             # {n,m} --- Match at least n but not more than m times
415             #
416             # n and m are limited to non-negative integral values less than a
417             # preset limit defined when perl is built. This is usually 32766 on
418             # the most common platforms.
419             #
420             # The following code is an attempt to solve the above limitations
421             # in a multi-byte anchoring.
422              
423             # avoid "Segmentation fault" and "Error: Parse exception"
424              
425             # perl5101delta
426             # http://perldoc.perl.org/perl5101delta.html
427             # In 5.10.0, the * quantifier in patterns was sometimes treated as {0,32767}
428             # [RT #60034, #60464]. For example, this match would fail:
429             # ("ab" x 32768) =~ /^(ab)*$/
430              
431             # SEE ALSO
432             #
433             # Complex regular subexpression recursion limit
434             # http://www.perlmonks.org/?node_id=810857
435             #
436             # regexp iteration limits
437             # http://www.nntp.perl.org/group/perl.perl5.porters/2009/02/msg144065.html
438             #
439             # latest Perl won't match certain regexes more than 32768 characters long
440             # http://stackoverflow.com/questions/26226630/latest-perl-wont-match-certain-regexes-more-than-32768-characters-long
441             #
442             # Break through the limitations of regular expressions of Perl
443             # http://d.hatena.ne.jp/gfx/20110212/1297512479
444              
445             if (($] >= 5.010001) or
446             # ActivePerl 5.6 or later (include 5.10.0)
447             (defined($ActivePerl::VERSION) and ($ActivePerl::VERSION > 800)) or
448             (($^O eq 'MSWin32') and ($] =~ /\A 5\.006/oxms))
449             ) {
450             my $sbcs = ''; # Single Byte Character Set
451             for my $range (@{ $range_tr{1} }) {
452             $sbcs .= sprintf('\\x%02X-\\x%02X', $range->[0], $range->[-1]);
453             }
454              
455             if (0) {
456             }
457              
458             # other encoding
459             else {
460             ${Egbk::q_char_SADAHIRO_Tomoyuki_2002_01_17} = qr{.*?[$sbcs](?:[^$sbcs][^$sbcs])*?}oxms;
461             # ******* octets not in multiple octet char (always char boundary)
462             # **************** 2 octet chars
463             }
464              
465             ${Egbk::anchor_SADAHIRO_Tomoyuki_2002_01_17} =
466             qr{\G(?(?=.{0,32766}\z)(?:[^\x81-\xFE]|[\x81-\xFE][\x00-\xFF])*?|(?(?=[$sbcs]+\z).*?|(?:${Egbk::q_char_SADAHIRO_Tomoyuki_2002_01_17})))}oxms;
467             # qr{
468             # \G # (1), (2)
469             # (? # (3)
470             # (?=.{0,32766}\z) # (4)
471             # (?:[^\x81-\xFE]|[\x81-\xFE][\x00-\xFF])*?| # (5)
472             # (?(?=[$sbcs]+\z) # (6)
473             # .*?| #(7)
474             # (?:${Egbk::q_char_SADAHIRO_Tomoyuki_2002_01_17}) # (8)
475             # ))}oxms;
476              
477             # avoid: Complex regular subexpression recursion limit (32766) exceeded at here.
478             local $^W = 0;
479             local $SIG{__WARN__} = sub {};
480              
481             if (((('A' x 32768).'B') !~ / ${Egbk::anchor} B /oxms) and
482             ((('A' x 32768).'B') =~ / ${Egbk::anchor_SADAHIRO_Tomoyuki_2002_01_17} B /oxms)
483             ) {
484             ${Egbk::anchor} = ${Egbk::anchor_SADAHIRO_Tomoyuki_2002_01_17};
485             }
486             else {
487             undef ${Egbk::q_char_SADAHIRO_Tomoyuki_2002_01_17};
488             }
489             }
490              
491             # (1)
492             # P.128 Start of match (or end of previous match): \G
493             # P.130 Advanced Use of \G with Perl
494             # in Chapter3: Over view of Regular Expression Features and Flavors
495             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
496              
497             # (2)
498             # P.255 Use leading anchors
499             # P.256 Expose ^ and \G at the front of expressions
500             # in Chapter6: Crafting an Efficient Expression
501             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
502              
503             # (3)
504             # P.138 Conditional: (? if then| else)
505             # in Chapter3: Over view of Regular Expression Features and Flavors
506             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
507              
508             # (4)
509             # perlre
510             # http://perldoc.perl.org/perlre.html
511             # The "*" quantifier is equivalent to {0,} , the "+" quantifier to {1,} ,
512             # and the "?" quantifier to {0,1}, ., n, and m are limited to non-negative
513             # integral values less than a preset limit defined when perl is built.
514             # This is usually 32766 on the most common platforms. The actual limit
515             # can be seen in the error message generated by code such as this:
516             # $_ **= $_ , / {$_} / for 2 .. 42;
517              
518             # (5)
519             # P.1023 Multiple-Byte Anchoring
520             # in Appendix W Perl Code Examples
521             # of ISBN 1-56592-224-7 CJKV Information Processing
522              
523             # (6)
524             # if string has only SBCS (Single Byte Character Set)
525              
526             # (7)
527             # then .*? (isn't limited to 32766)
528              
529             # (8)
530             # else GBK::Regexp::Const (SADAHIRO Tomoyuki)
531             # http://homepage1.nifty.com/nomenclator/perl/shiftjis.htm#long
532             # http://search.cpan.org/~sadahiro/GBK-Regexp/
533             # $PadA = ' (?:\A| [\x00-\x80\xA0-\xDF])(?:[\x81-\xFE]{2})*?';
534             # $PadG = '\G(?: |[\x00-\xFF]*?[\x00-\x80\xA0-\xDF])(?:[\x81-\xFE]{2})*?';
535             # $PadGA = '\G(?:\A|(?:[\x81-\xFE]{2})+?|[\x00-\xFF]*?[\x00-\x80\xA0-\xDF] (?:[\x81-\xFE]{2})*?)';
536              
537             ${Egbk::dot} = qr{(?>[^\x81-\xFE\x0A]|[\x81-\xFE][\x00-\xFF])};
538             ${Egbk::dot_s} = qr{(?>[^\x81-\xFE]|[\x81-\xFE][\x00-\xFF])};
539             ${Egbk::eD} = qr{(?>[^\x81-\xFE0-9]|[\x81-\xFE][\x00-\xFF])};
540              
541             # Vertical tabs are now whitespace
542             # \s in a regex now matches a vertical tab in all circumstances.
543             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
544             # ${Egbk::eS} = qr{(?>[^\x81-\xFE\x09\x0A \x0C\x0D\x20]|[\x81-\xFE][\x00-\xFF])};
545             # ${Egbk::eS} = qr{(?>[^\x81-\xFE\x09\x0A\x0B\x0C\x0D\x20]|[\x81-\xFE][\x00-\xFF])};
546             ${Egbk::eS} = qr{(?>[^\x81-\xFE\s]|[\x81-\xFE][\x00-\xFF])};
547              
548             ${Egbk::eW} = qr{(?>[^\x81-\xFE0-9A-Z_a-z]|[\x81-\xFE][\x00-\xFF])};
549             ${Egbk::eH} = qr{(?>[^\x81-\xFE\x09\x20]|[\x81-\xFE][\x00-\xFF])};
550             ${Egbk::eV} = qr{(?>[^\x81-\xFE\x0A\x0B\x0C\x0D]|[\x81-\xFE][\x00-\xFF])};
551             ${Egbk::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
552             ${Egbk::eN} = qr{(?>[^\x81-\xFE\x0A]|[\x81-\xFE][\x00-\xFF])};
553             ${Egbk::not_alnum} = qr{(?>[^\x81-\xFE\x30-\x39\x41-\x5A\x61-\x7A]|[\x81-\xFE][\x00-\xFF])};
554             ${Egbk::not_alpha} = qr{(?>[^\x81-\xFE\x41-\x5A\x61-\x7A]|[\x81-\xFE][\x00-\xFF])};
555             ${Egbk::not_ascii} = qr{(?>[^\x81-\xFE\x00-\x7F]|[\x81-\xFE][\x00-\xFF])};
556             ${Egbk::not_blank} = qr{(?>[^\x81-\xFE\x09\x20]|[\x81-\xFE][\x00-\xFF])};
557             ${Egbk::not_cntrl} = qr{(?>[^\x81-\xFE\x00-\x1F\x7F]|[\x81-\xFE][\x00-\xFF])};
558             ${Egbk::not_digit} = qr{(?>[^\x81-\xFE\x30-\x39]|[\x81-\xFE][\x00-\xFF])};
559             ${Egbk::not_graph} = qr{(?>[^\x81-\xFE\x21-\x7F]|[\x81-\xFE][\x00-\xFF])};
560             ${Egbk::not_lower} = qr{(?>[^\x81-\xFE\x61-\x7A]|[\x81-\xFE][\x00-\xFF])};
561             ${Egbk::not_lower_i} = qr{(?>[^\x81-\xFE\x41-\x5A\x61-\x7A]|[\x81-\xFE][\x00-\xFF])}; # Perl 5.16 compatible
562             # ${Egbk::not_lower_i} = qr{(?>[^\x81-\xFE]|[\x81-\xFE][\x00-\xFF])}; # older Perl compatible
563             ${Egbk::not_print} = qr{(?>[^\x81-\xFE\x20-\x7F]|[\x81-\xFE][\x00-\xFF])};
564             ${Egbk::not_punct} = qr{(?>[^\x81-\xFE\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]|[\x81-\xFE][\x00-\xFF])};
565             ${Egbk::not_space} = qr{(?>[^\x81-\xFE\s\x0B]|[\x81-\xFE][\x00-\xFF])};
566             ${Egbk::not_upper} = qr{(?>[^\x81-\xFE\x41-\x5A]|[\x81-\xFE][\x00-\xFF])};
567             ${Egbk::not_upper_i} = qr{(?>[^\x81-\xFE\x41-\x5A\x61-\x7A]|[\x81-\xFE][\x00-\xFF])}; # Perl 5.16 compatible
568             # ${Egbk::not_upper_i} = qr{(?>[^\x81-\xFE]|[\x81-\xFE][\x00-\xFF])}; # older Perl compatible
569             ${Egbk::not_word} = qr{(?>[^\x81-\xFE\x30-\x39\x41-\x5A\x5F\x61-\x7A]|[\x81-\xFE][\x00-\xFF])};
570             ${Egbk::not_xdigit} = qr{(?>[^\x81-\xFE\x30-\x39\x41-\x46\x61-\x66]|[\x81-\xFE][\x00-\xFF])};
571             ${Egbk::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))};
572             ${Egbk::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]))};
573              
574             # avoid: Name "Egbk::foo" used only once: possible typo at here.
575             ${Egbk::dot} = ${Egbk::dot};
576             ${Egbk::dot_s} = ${Egbk::dot_s};
577             ${Egbk::eD} = ${Egbk::eD};
578             ${Egbk::eS} = ${Egbk::eS};
579             ${Egbk::eW} = ${Egbk::eW};
580             ${Egbk::eH} = ${Egbk::eH};
581             ${Egbk::eV} = ${Egbk::eV};
582             ${Egbk::eR} = ${Egbk::eR};
583             ${Egbk::eN} = ${Egbk::eN};
584             ${Egbk::not_alnum} = ${Egbk::not_alnum};
585             ${Egbk::not_alpha} = ${Egbk::not_alpha};
586             ${Egbk::not_ascii} = ${Egbk::not_ascii};
587             ${Egbk::not_blank} = ${Egbk::not_blank};
588             ${Egbk::not_cntrl} = ${Egbk::not_cntrl};
589             ${Egbk::not_digit} = ${Egbk::not_digit};
590             ${Egbk::not_graph} = ${Egbk::not_graph};
591             ${Egbk::not_lower} = ${Egbk::not_lower};
592             ${Egbk::not_lower_i} = ${Egbk::not_lower_i};
593             ${Egbk::not_print} = ${Egbk::not_print};
594             ${Egbk::not_punct} = ${Egbk::not_punct};
595             ${Egbk::not_space} = ${Egbk::not_space};
596             ${Egbk::not_upper} = ${Egbk::not_upper};
597             ${Egbk::not_upper_i} = ${Egbk::not_upper_i};
598             ${Egbk::not_word} = ${Egbk::not_word};
599             ${Egbk::not_xdigit} = ${Egbk::not_xdigit};
600             ${Egbk::eb} = ${Egbk::eb};
601             ${Egbk::eB} = ${Egbk::eB};
602              
603             #
604             # GBK split
605             #
606             sub Egbk::split(;$$$) {
607              
608             # P.794 29.2.161. split
609             # in Chapter 29: Functions
610             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
611              
612             # P.951 split
613             # in Chapter 27: Functions
614             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
615              
616 5     0 0 11765 my $pattern = $_[0];
617 0         0 my $string = $_[1];
618 0         0 my $limit = $_[2];
619              
620             # if $pattern is also omitted or is the literal space, " "
621 0 0       0 if (not defined $pattern) {
622 0         0 $pattern = ' ';
623             }
624              
625             # if $string is omitted, the function splits the $_ string
626 0 0       0 if (not defined $string) {
627 0 0       0 if (defined $_) {
628 0         0 $string = $_;
629             }
630             else {
631 0         0 $string = '';
632             }
633             }
634              
635 0         0 my @split = ();
636              
637             # when string is empty
638 0 0       0 if ($string eq '') {
    0          
639              
640             # resulting list value in list context
641 0 0       0 if (wantarray) {
642 0         0 return @split;
643             }
644              
645             # count of substrings in scalar context
646             else {
647 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
648 0         0 @_ = @split;
649 0         0 return scalar @_;
650             }
651             }
652              
653             # split's first argument is more consistently interpreted
654             #
655             # After some changes earlier in v5.17, split's behavior has been simplified:
656             # if the PATTERN argument evaluates to a string containing one space, it is
657             # treated the way that a literal string containing one space once was.
658             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
659              
660             # if $pattern is also omitted or is the literal space, " ", the function splits
661             # on whitespace, /\s+/, after skipping any leading whitespace
662             # (and so on)
663              
664             elsif ($pattern eq ' ') {
665 0 0       0 if (not defined $limit) {
666 0         0 return CORE::split(' ', $string);
667             }
668             else {
669 0         0 return CORE::split(' ', $string, $limit);
670             }
671             }
672              
673 0         0 local $q_char = $q_char;
674 0 0       0 if (CORE::length($string) > 32766) {
675 0 0       0 if ($string =~ /\A [\x00-\x7F]+ \z/oxms) {
    0          
676 0         0 $q_char = qr{.}s;
677             }
678             elsif (defined ${Egbk::q_char_SADAHIRO_Tomoyuki_2002_01_17}) {
679 0         0 $q_char = ${Egbk::q_char_SADAHIRO_Tomoyuki_2002_01_17};
680             }
681             }
682              
683             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
684 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
685              
686             # a pattern capable of matching either the null string or something longer than the
687             # null string will split the value of $string into separate characters wherever it
688             # matches the null string between characters
689             # (and so on)
690              
691 0 0       0 if ('' =~ / \A $pattern \z /xms) {
692 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
693 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
694              
695             # P.1024 Appendix W.10 Multibyte Processing
696             # of ISBN 1-56592-224-7 CJKV Information Processing
697             # (and so on)
698              
699             # the //m modifier is assumed when you split on the pattern /^/
700             # (and so on)
701              
702 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
703             # V
704 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
705              
706             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
707             # is included in the resulting list, interspersed with the fields that are ordinarily returned
708             # (and so on)
709              
710 0         0 local $@;
711 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
712 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
713 0         0 push @split, CORE::eval('$' . $digit);
714             }
715             }
716             }
717              
718             else {
719 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
720              
721 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
722             # V
723 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
724 0         0 local $@;
725 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
726 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
727 0         0 push @split, CORE::eval('$' . $digit);
728             }
729             }
730             }
731             }
732              
733             elsif ($limit > 0) {
734 0 0       0 if ('' =~ / \A $pattern \z /xms) {
735 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
736 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
737              
738 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
739             # V
740 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
741 0         0 local $@;
742 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
743 0         0 push @split, CORE::eval('$' . $digit);
744             }
745             }
746             }
747             }
748             else {
749 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
750 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
751              
752 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
753             # V
754 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
755 0         0 local $@;
756 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
757 0         0 push @split, CORE::eval('$' . $digit);
758             }
759             }
760             }
761             }
762             }
763              
764 0 0       0 if (CORE::length($string) > 0) {
765 0         0 push @split, $string;
766             }
767              
768             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
769 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
770 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
771 0         0 pop @split;
772             }
773             }
774              
775             # resulting list value in list context
776 0 0       0 if (wantarray) {
777 0         0 return @split;
778             }
779              
780             # count of substrings in scalar context
781             else {
782 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
783 0         0 @_ = @split;
784 0         0 return scalar @_;
785             }
786             }
787              
788             #
789             # get last subexpression offsets
790             #
791             sub _last_subexpression_offsets {
792 0     0   0 my $pattern = $_[0];
793              
794             # remove comment
795 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
796              
797 0         0 my $modifier = '';
798 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
799 0         0 $modifier = $1;
800 0         0 $modifier =~ s/-[A-Za-z]*//;
801             }
802              
803             # with /x modifier
804 0         0 my @char = ();
805 0 0       0 if ($modifier =~ /x/oxms) {
806 0         0 @char = $pattern =~ /\G((?>
807             [^\x81-\xFE\\\#\[\(]|[\x81-\xFE][\x00-\xFF] |
808             \\ $q_char |
809             \# (?>[^\n]*) $ |
810             \[ (?>(?:[^\x81-\xFE\\\]]|[\x81-\xFE][\x00-\xFF]|\\\\|\\\]|$q_char)+) \] |
811             \(\? |
812             $q_char
813             ))/oxmsg;
814             }
815              
816             # without /x modifier
817             else {
818 0         0 @char = $pattern =~ /\G((?>
819             [^\x81-\xFE\\\[\(]|[\x81-\xFE][\x00-\xFF] |
820             \\ $q_char |
821             \[ (?>(?:[^\x81-\xFE\\\]]|[\x81-\xFE][\x00-\xFF]|\\\\|\\\]|$q_char)+) \] |
822             \(\? |
823             $q_char
824             ))/oxmsg;
825             }
826              
827 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
828             }
829              
830             #
831             # GBK transliteration (tr///)
832             #
833             sub Egbk::tr($$$$;$) {
834              
835 0     0 0 0 my $bind_operator = $_[1];
836 0         0 my $searchlist = $_[2];
837 0         0 my $replacementlist = $_[3];
838 0   0     0 my $modifier = $_[4] || '';
839              
840 0 0       0 if ($modifier =~ /r/oxms) {
841 0 0       0 if ($bind_operator =~ / !~ /oxms) {
842 0         0 croak "Using !~ with tr///r doesn't make sense";
843             }
844             }
845              
846 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
847 0         0 my @searchlist = _charlist_tr($searchlist);
848 0         0 my @replacementlist = _charlist_tr($replacementlist);
849              
850 0         0 my %tr = ();
851 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
852 0 0       0 if (not exists $tr{$searchlist[$i]}) {
853 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
854 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
855             }
856             elsif ($modifier =~ /d/oxms) {
857 0         0 $tr{$searchlist[$i]} = '';
858             }
859             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
860 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
861             }
862             else {
863 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
864             }
865             }
866             }
867              
868 0         0 my $tr = 0;
869 0         0 my $replaced = '';
870 0 0       0 if ($modifier =~ /c/oxms) {
871 0         0 while (defined(my $char = shift @char)) {
872 0 0       0 if (not exists $tr{$char}) {
873 0 0       0 if (defined $replacementlist[-1]) {
874 0         0 $replaced .= $replacementlist[-1];
875             }
876 0         0 $tr++;
877 0 0       0 if ($modifier =~ /s/oxms) {
878 0   0     0 while (@char and (not exists $tr{$char[0]})) {
879 0         0 shift @char;
880 0         0 $tr++;
881             }
882             }
883             }
884             else {
885 0         0 $replaced .= $char;
886             }
887             }
888             }
889             else {
890 0         0 while (defined(my $char = shift @char)) {
891 0 0       0 if (exists $tr{$char}) {
892 0         0 $replaced .= $tr{$char};
893 0         0 $tr++;
894 0 0       0 if ($modifier =~ /s/oxms) {
895 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
896 0         0 shift @char;
897 0         0 $tr++;
898             }
899             }
900             }
901             else {
902 0         0 $replaced .= $char;
903             }
904             }
905             }
906              
907 0 0       0 if ($modifier =~ /r/oxms) {
908 0         0 return $replaced;
909             }
910             else {
911 0         0 $_[0] = $replaced;
912 0 0       0 if ($bind_operator =~ / !~ /oxms) {
913 0         0 return not $tr;
914             }
915             else {
916 0         0 return $tr;
917             }
918             }
919             }
920              
921             #
922             # GBK chop
923             #
924             sub Egbk::chop(@) {
925              
926 0     0 0 0 my $chop;
927 0 0       0 if (@_ == 0) {
928 0         0 my @char = /\G (?>$q_char) /oxmsg;
929 0         0 $chop = pop @char;
930 0         0 $_ = join '', @char;
931             }
932             else {
933 0         0 for (@_) {
934 0         0 my @char = /\G (?>$q_char) /oxmsg;
935 0         0 $chop = pop @char;
936 0         0 $_ = join '', @char;
937             }
938             }
939 0         0 return $chop;
940             }
941              
942             #
943             # GBK index by octet
944             #
945             sub Egbk::index($$;$) {
946              
947 0     2316 1 0 my($str,$substr,$position) = @_;
948 2316   50     4658 $position ||= 0;
949 2316         8557 my $pos = 0;
950              
951 2316         2643 while ($pos < CORE::length($str)) {
952 2316 50       4748 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
953 40318 0       62187 if ($pos >= $position) {
954 0         0 return $pos;
955             }
956             }
957 0 50       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
958 40318         91159 $pos += CORE::length($1);
959             }
960             else {
961 40318         65397 $pos += 1;
962             }
963             }
964 0         0 return -1;
965             }
966              
967             #
968             # GBK reverse index
969             #
970             sub Egbk::rindex($$;$) {
971              
972 2316     0 0 12504 my($str,$substr,$position) = @_;
973 0   0     0 $position ||= CORE::length($str) - 1;
974 0         0 my $pos = 0;
975 0         0 my $rindex = -1;
976              
977 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
978 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
979 0         0 $rindex = $pos;
980             }
981 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
982 0         0 $pos += CORE::length($1);
983             }
984             else {
985 0         0 $pos += 1;
986             }
987             }
988 0         0 return $rindex;
989             }
990              
991             #
992             # GBK lower case first with parameter
993             #
994             sub Egbk::lcfirst(@) {
995 0 0   0 0 0 if (@_) {
996 0         0 my $s = shift @_;
997 0 0 0     0 if (@_ and wantarray) {
998 0         0 return Egbk::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
999             }
1000             else {
1001 0         0 return Egbk::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
1002             }
1003             }
1004             else {
1005 0         0 return Egbk::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
1006             }
1007             }
1008              
1009             #
1010             # GBK lower case first without parameter
1011             #
1012             sub Egbk::lcfirst_() {
1013 0     0 0 0 return Egbk::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
1014             }
1015              
1016             #
1017             # GBK lower case with parameter
1018             #
1019             sub Egbk::lc(@) {
1020 0 0   0 0 0 if (@_) {
1021 0         0 my $s = shift @_;
1022 0 0 0     0 if (@_ and wantarray) {
1023 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1024             }
1025             else {
1026 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
1027             }
1028             }
1029             else {
1030 0         0 return Egbk::lc_();
1031             }
1032             }
1033              
1034             #
1035             # GBK lower case without parameter
1036             #
1037             sub Egbk::lc_() {
1038 0     0 0 0 my $s = $_;
1039 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1040             }
1041              
1042             #
1043             # GBK upper case first with parameter
1044             #
1045             sub Egbk::ucfirst(@) {
1046 0 0   0 0 0 if (@_) {
1047 0         0 my $s = shift @_;
1048 0 0 0     0 if (@_ and wantarray) {
1049 0         0 return Egbk::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
1050             }
1051             else {
1052 0         0 return Egbk::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
1053             }
1054             }
1055             else {
1056 0         0 return Egbk::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
1057             }
1058             }
1059              
1060             #
1061             # GBK upper case first without parameter
1062             #
1063             sub Egbk::ucfirst_() {
1064 0     0 0 0 return Egbk::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
1065             }
1066              
1067             #
1068             # GBK upper case with parameter
1069             #
1070             sub Egbk::uc(@) {
1071 0 50   2968 0 0 if (@_) {
1072 2968         4634 my $s = shift @_;
1073 2968 50 33     3935 if (@_ and wantarray) {
1074 2968 0       5607 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1075             }
1076             else {
1077 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  2968         8663  
1078             }
1079             }
1080             else {
1081 2968         10692 return Egbk::uc_();
1082             }
1083             }
1084              
1085             #
1086             # GBK upper case without parameter
1087             #
1088             sub Egbk::uc_() {
1089 0     0 0 0 my $s = $_;
1090 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1091             }
1092              
1093             #
1094             # GBK fold case with parameter
1095             #
1096             sub Egbk::fc(@) {
1097 0 50   3271 0 0 if (@_) {
1098 3271         4705 my $s = shift @_;
1099 3271 50 33     4052 if (@_ and wantarray) {
1100 3271 0       5805 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1101             }
1102             else {
1103 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  3271         8513  
1104             }
1105             }
1106             else {
1107 3271         12687 return Egbk::fc_();
1108             }
1109             }
1110              
1111             #
1112             # GBK fold case without parameter
1113             #
1114             sub Egbk::fc_() {
1115 0     0 0 0 my $s = $_;
1116 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1117             }
1118              
1119             #
1120             # GBK regexp capture
1121             #
1122             {
1123             # 10.3. Creating Persistent Private Variables
1124             # in Chapter 10. Subroutines
1125             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
1126              
1127             my $last_s_matched = 0;
1128              
1129             sub Egbk::capture {
1130 0 0 0 0 1 0 if ($last_s_matched and ($_[0] =~ /\A (?>[1-9][0-9]*) \z/oxms)) {
1131 0         0 return $_[0] + 1;
1132             }
1133 0         0 return $_[0];
1134             }
1135              
1136             # GBK mark last regexp matched
1137             sub Egbk::matched() {
1138 0     0 0 0 $last_s_matched = 0;
1139             }
1140              
1141             # GBK mark last s/// matched
1142             sub Egbk::s_matched() {
1143 0     0 0 0 $last_s_matched = 1;
1144             }
1145              
1146             # P.854 31.17. use re
1147             # in Chapter 31. Pragmatic Modules
1148             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1149              
1150             # P.1026 re
1151             # in Chapter 29. Pragmatic Modules
1152             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1153              
1154             $Egbk::matched = qr/(?{Egbk::matched})/;
1155             }
1156              
1157             #
1158             # GBK regexp ignore case modifier
1159             #
1160             sub Egbk::ignorecase {
1161              
1162 0     0 0 0 my @string = @_;
1163 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1164              
1165             # ignore case of $scalar or @array
1166 0         0 for my $string (@string) {
1167              
1168             # split regexp
1169 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1170              
1171             # unescape character
1172 0         0 for (my $i=0; $i <= $#char; $i++) {
1173 0 0       0 next if not defined $char[$i];
1174              
1175             # open character class [...]
1176 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1177 0         0 my $left = $i;
1178              
1179             # [] make die "unmatched [] in regexp ...\n"
1180              
1181 0 0       0 if ($char[$i+1] eq ']') {
1182 0         0 $i++;
1183             }
1184              
1185 0         0 while (1) {
1186 0 0       0 if (++$i > $#char) {
1187 0         0 croak "Unmatched [] in regexp";
1188             }
1189 0 0       0 if ($char[$i] eq ']') {
1190 0         0 my $right = $i;
1191 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1192              
1193             # escape character
1194 0         0 for my $char (@charlist) {
1195 0 0       0 if (0) {
    0          
1196             }
1197              
1198             # do not use quotemeta here
1199 0         0 elsif ($char =~ /\A ([\x80-\xFF].*) ($metachar) \z/oxms) {
1200 0         0 $char = $1 . '\\' . $2;
1201             }
1202             elsif ($char =~ /\A [.|)] \z/oxms) {
1203 0         0 $char = '\\' . $char;
1204             }
1205             }
1206              
1207             # [...]
1208 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1209              
1210 0         0 $i = $left;
1211 0         0 last;
1212             }
1213             }
1214             }
1215              
1216             # open character class [^...]
1217             elsif ($char[$i] eq '[^') {
1218 0         0 my $left = $i;
1219              
1220             # [^] make die "unmatched [] in regexp ...\n"
1221              
1222 0 0       0 if ($char[$i+1] eq ']') {
1223 0         0 $i++;
1224             }
1225              
1226 0         0 while (1) {
1227 0 0       0 if (++$i > $#char) {
1228 0         0 croak "Unmatched [] in regexp";
1229             }
1230 0 0       0 if ($char[$i] eq ']') {
1231 0         0 my $right = $i;
1232 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1233              
1234             # escape character
1235 0         0 for my $char (@charlist) {
1236 0 0       0 if (0) {
    0          
1237             }
1238              
1239             # do not use quotemeta here
1240 0         0 elsif ($char =~ /\A ([\x80-\xFF].*) ($metachar) \z/oxms) {
1241 0         0 $char = $1 . '\\' . $2;
1242             }
1243             elsif ($char =~ /\A [.|)] \z/oxms) {
1244 0         0 $char = '\\' . $char;
1245             }
1246             }
1247              
1248             # [^...]
1249 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1250              
1251 0         0 $i = $left;
1252 0         0 last;
1253             }
1254             }
1255             }
1256              
1257             # rewrite classic character class or escape character
1258             elsif (my $char = classic_character_class($char[$i])) {
1259 0         0 $char[$i] = $char;
1260             }
1261              
1262             # with /i modifier
1263             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1264 0         0 my $uc = Egbk::uc($char[$i]);
1265 0         0 my $fc = Egbk::fc($char[$i]);
1266 0 0       0 if ($uc ne $fc) {
1267 0 0       0 if (CORE::length($fc) == 1) {
1268 0         0 $char[$i] = '[' . $uc . $fc . ']';
1269             }
1270             else {
1271 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1272             }
1273             }
1274             }
1275             }
1276              
1277             # characterize
1278 0         0 for (my $i=0; $i <= $#char; $i++) {
1279 0 0       0 next if not defined $char[$i];
1280              
1281 0 0 0     0 if (0) {
    0          
1282             }
1283              
1284             # escape last octet of multiple-octet
1285 0         0 elsif ($char[$i] =~ /\A ([\x80-\xFF].*) ($metachar) \z/oxms) {
1286 0         0 $char[$i] = $1 . '\\' . $2;
1287             }
1288              
1289             # quote character before ? + * {
1290             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1291 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1292 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1293             }
1294             }
1295             }
1296              
1297 0         0 $string = join '', @char;
1298             }
1299              
1300             # make regexp string
1301 0         0 return @string;
1302             }
1303              
1304             #
1305             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1306             #
1307             sub Egbk::classic_character_class {
1308 0     5319 0 0 my($char) = @_;
1309              
1310             return {
1311             '\D' => '${Egbk::eD}',
1312             '\S' => '${Egbk::eS}',
1313             '\W' => '${Egbk::eW}',
1314             '\d' => '[0-9]',
1315              
1316             # Before Perl 5.6, \s only matched the five whitespace characters
1317             # tab, newline, form-feed, carriage return, and the space character
1318             # itself, which, taken together, is the character class [\t\n\f\r ].
1319              
1320             # Vertical tabs are now whitespace
1321             # \s in a regex now matches a vertical tab in all circumstances.
1322             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1323             # \t \n \v \f \r space
1324             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1325             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1326             '\s' => '\s',
1327              
1328             '\w' => '[0-9A-Z_a-z]',
1329             '\C' => '[\x00-\xFF]',
1330             '\X' => 'X',
1331              
1332             # \h \v \H \V
1333              
1334             # P.114 Character Class Shortcuts
1335             # in Chapter 7: In the World of Regular Expressions
1336             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1337              
1338             # P.357 13.2.3 Whitespace
1339             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1340             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1341             #
1342             # 0x00009 CHARACTER TABULATION h s
1343             # 0x0000a LINE FEED (LF) vs
1344             # 0x0000b LINE TABULATION v
1345             # 0x0000c FORM FEED (FF) vs
1346             # 0x0000d CARRIAGE RETURN (CR) vs
1347             # 0x00020 SPACE h s
1348              
1349             # P.196 Table 5-9. Alphanumeric regex metasymbols
1350             # in Chapter 5. Pattern Matching
1351             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1352              
1353             # (and so on)
1354              
1355             '\H' => '${Egbk::eH}',
1356             '\V' => '${Egbk::eV}',
1357             '\h' => '[\x09\x20]',
1358             '\v' => '[\x0A\x0B\x0C\x0D]',
1359             '\R' => '${Egbk::eR}',
1360              
1361             # \N
1362             #
1363             # http://perldoc.perl.org/perlre.html
1364             # Character Classes and other Special Escapes
1365             # Any character but \n (experimental). Not affected by /s modifier
1366              
1367             '\N' => '${Egbk::eN}',
1368              
1369             # \b \B
1370              
1371             # P.180 Boundaries: The \b and \B Assertions
1372             # in Chapter 5: Pattern Matching
1373             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1374              
1375             # P.219 Boundaries: The \b and \B Assertions
1376             # in Chapter 5: Pattern Matching
1377             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1378              
1379             # \b really means (?:(?<=\w)(?!\w)|(?
1380             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1381             '\b' => '${Egbk::eb}',
1382              
1383             # \B really means (?:(?<=\w)(?=\w)|(?
1384             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1385             '\B' => '${Egbk::eB}',
1386              
1387 5319   100     7067 }->{$char} || '';
1388             }
1389              
1390             #
1391             # prepare GBK characters per length
1392             #
1393              
1394             # 1 octet characters
1395             my @chars1 = ();
1396             sub chars1 {
1397 5319 0   0 0 190955 if (@chars1) {
1398 0         0 return @chars1;
1399             }
1400 0 0       0 if (exists $range_tr{1}) {
1401 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1402 0         0 while (my @range = splice(@ranges,0,1)) {
1403 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1404 0         0 push @chars1, pack 'C', $oct0;
1405             }
1406             }
1407             }
1408 0         0 return @chars1;
1409             }
1410              
1411             # 2 octets characters
1412             my @chars2 = ();
1413             sub chars2 {
1414 0 0   0 0 0 if (@chars2) {
1415 0         0 return @chars2;
1416             }
1417 0 0       0 if (exists $range_tr{2}) {
1418 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1419 0         0 while (my @range = splice(@ranges,0,2)) {
1420 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1421 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1422 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1423             }
1424             }
1425             }
1426             }
1427 0         0 return @chars2;
1428             }
1429              
1430             # 3 octets characters
1431             my @chars3 = ();
1432             sub chars3 {
1433 0 0   0 0 0 if (@chars3) {
1434 0         0 return @chars3;
1435             }
1436 0 0       0 if (exists $range_tr{3}) {
1437 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1438 0         0 while (my @range = splice(@ranges,0,3)) {
1439 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1440 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1441 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1442 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1443             }
1444             }
1445             }
1446             }
1447             }
1448 0         0 return @chars3;
1449             }
1450              
1451             # 4 octets characters
1452             my @chars4 = ();
1453             sub chars4 {
1454 0 0   0 0 0 if (@chars4) {
1455 0         0 return @chars4;
1456             }
1457 0 0       0 if (exists $range_tr{4}) {
1458 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1459 0         0 while (my @range = splice(@ranges,0,4)) {
1460 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1461 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1462 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1463 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1464 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1465             }
1466             }
1467             }
1468             }
1469             }
1470             }
1471 0         0 return @chars4;
1472             }
1473              
1474             #
1475             # GBK open character list for tr
1476             #
1477             sub _charlist_tr {
1478              
1479 0     0   0 local $_ = shift @_;
1480              
1481             # unescape character
1482 0         0 my @char = ();
1483 0         0 while (not /\G \z/oxmsgc) {
1484 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1485 0         0 push @char, '\-';
1486             }
1487             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1488 0         0 push @char, CORE::chr(oct $1);
1489             }
1490             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1491 0         0 push @char, CORE::chr(hex $1);
1492             }
1493             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1494 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1495             }
1496             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1497             push @char, {
1498             '\0' => "\0",
1499             '\n' => "\n",
1500             '\r' => "\r",
1501             '\t' => "\t",
1502             '\f' => "\f",
1503             '\b' => "\x08", # \b means backspace in character class
1504             '\a' => "\a",
1505             '\e' => "\e",
1506 0         0 }->{$1};
1507             }
1508             elsif (/\G \\ ($q_char) /oxmsgc) {
1509 0         0 push @char, $1;
1510             }
1511             elsif (/\G ($q_char) /oxmsgc) {
1512 0         0 push @char, $1;
1513             }
1514             }
1515              
1516             # join separated multiple-octet
1517 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1518              
1519             # unescape '-'
1520 0         0 my @i = ();
1521 0         0 for my $i (0 .. $#char) {
1522 0 0       0 if ($char[$i] eq '\-') {
    0          
1523 0         0 $char[$i] = '-';
1524             }
1525             elsif ($char[$i] eq '-') {
1526 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1527 0         0 push @i, $i;
1528             }
1529             }
1530             }
1531              
1532             # open character list (reverse for splice)
1533 0         0 for my $i (CORE::reverse @i) {
1534 0         0 my @range = ();
1535              
1536             # range error
1537 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1538 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1539             }
1540              
1541             # range of multiple-octet code
1542 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1543 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1544 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1545             }
1546             elsif (CORE::length($char[$i+1]) == 2) {
1547 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1548 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1549             }
1550             elsif (CORE::length($char[$i+1]) == 3) {
1551 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1552 0         0 push @range, chars2();
1553 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1554             }
1555             elsif (CORE::length($char[$i+1]) == 4) {
1556 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1557 0         0 push @range, chars2();
1558 0         0 push @range, chars3();
1559 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1560             }
1561             else {
1562 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1563             }
1564             }
1565             elsif (CORE::length($char[$i-1]) == 2) {
1566 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1567 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1568             }
1569             elsif (CORE::length($char[$i+1]) == 3) {
1570 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1571 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1572             }
1573             elsif (CORE::length($char[$i+1]) == 4) {
1574 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1575 0         0 push @range, chars3();
1576 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1577             }
1578             else {
1579 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1580             }
1581             }
1582             elsif (CORE::length($char[$i-1]) == 3) {
1583 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1584 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1585             }
1586             elsif (CORE::length($char[$i+1]) == 4) {
1587 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1588 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1589             }
1590             else {
1591 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1592             }
1593             }
1594             elsif (CORE::length($char[$i-1]) == 4) {
1595 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1596 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1597             }
1598             else {
1599 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1600             }
1601             }
1602             else {
1603 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1604             }
1605              
1606 0         0 splice @char, $i-1, 3, @range;
1607             }
1608              
1609 0         0 return @char;
1610             }
1611              
1612             #
1613             # GBK open character class
1614             #
1615             sub _cc {
1616 0 50   604   0 if (scalar(@_) == 0) {
    100          
    50          
1617 604         1328 die __FILE__, ": subroutine cc got no parameter.\n";
1618             }
1619             elsif (scalar(@_) == 1) {
1620 0         0 return sprintf('\x%02X',$_[0]);
1621             }
1622             elsif (scalar(@_) == 2) {
1623 302 50       1090 if ($_[0] > $_[1]) {
    50          
    50          
1624 302         835 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1625             }
1626             elsif ($_[0] == $_[1]) {
1627 0         0 return sprintf('\x%02X',$_[0]);
1628             }
1629             elsif (($_[0]+1) == $_[1]) {
1630 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1631             }
1632             else {
1633 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1634             }
1635             }
1636             else {
1637 302         1691 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1638             }
1639             }
1640              
1641             #
1642             # GBK octet range
1643             #
1644             sub _octets {
1645 0     668   0 my $length = shift @_;
1646              
1647 668 100       1162 if ($length == 1) {
    50          
    0          
    0          
1648 668         1564 my($a1) = unpack 'C', $_[0];
1649 406         1148 my($z1) = unpack 'C', $_[1];
1650              
1651 406 50       740 if ($a1 > $z1) {
1652 406         826 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1653             }
1654              
1655 0 100       0 if ($a1 == $z1) {
    50          
1656 406         1053 return sprintf('\x%02X',$a1);
1657             }
1658             elsif (($a1+1) == $z1) {
1659 20         90 return sprintf('\x%02X\x%02X',$a1,$z1);
1660             }
1661             else {
1662 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1663             }
1664             }
1665             elsif ($length == 2) {
1666 386         2557 my($a1,$a2) = unpack 'CC', $_[0];
1667 262         662 my($z1,$z2) = unpack 'CC', $_[1];
1668 262         515 my($A1,$A2) = unpack 'CC', $_[2];
1669 262         460 my($Z1,$Z2) = unpack 'CC', $_[3];
1670              
1671 262 100       450 if ($a1 == $z1) {
    50          
1672             return (
1673             # 11111111 222222222222
1674             # A A Z
1675 262         474 _cc($a1) . _cc($a2,$z2), # a2-z2
1676             );
1677             }
1678             elsif (($a1+1) == $z1) {
1679             return (
1680             # 11111111111 222222222222
1681             # A Z A Z
1682 222         401 _cc($a1) . _cc($a2,$Z2), # a2-
1683             _cc( $z1) . _cc($A2,$z2), # -z2
1684             );
1685             }
1686             else {
1687             return (
1688             # 1111111111111111 222222222222
1689             # A Z A Z
1690 40         74 _cc($a1) . _cc($a2,$Z2), # a2-
1691             _cc($a1+1,$z1-1) . _cc($A2,$Z2), # -
1692             _cc( $z1) . _cc($A2,$z2), # -z2
1693             );
1694             }
1695             }
1696             elsif ($length == 3) {
1697 0         0 my($a1,$a2,$a3) = unpack 'CCC', $_[0];
1698 0         0 my($z1,$z2,$z3) = unpack 'CCC', $_[1];
1699 0         0 my($A1,$A2,$A3) = unpack 'CCC', $_[2];
1700 0         0 my($Z1,$Z2,$Z3) = unpack 'CCC', $_[3];
1701              
1702 0 0       0 if ($a1 == $z1) {
    0          
1703 0 0       0 if ($a2 == $z2) {
    0          
1704             return (
1705             # 11111111 22222222 333333333333
1706             # A A A Z
1707 0         0 _cc($a1) . _cc($a2) . _cc($a3,$z3), # a3-z3
1708             );
1709             }
1710             elsif (($a2+1) == $z2) {
1711             return (
1712             # 11111111 22222222222 333333333333
1713             # A A Z A Z
1714 0         0 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
1715             _cc($a1) . _cc( $z2) . _cc($A3,$z3), # -z3
1716             );
1717             }
1718             else {
1719             return (
1720             # 11111111 2222222222222222 333333333333
1721             # A A Z A Z
1722 0         0 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
1723             _cc($a1) . _cc($a2+1,$z2-1) . _cc($A3,$Z3), # -
1724             _cc($a1) . _cc( $z2) . _cc($A3,$z3), # -z3
1725             );
1726             }
1727             }
1728             elsif (($a1+1) == $z1) {
1729             return (
1730             # 11111111111 22222222222222 333333333333
1731             # A Z A Z A Z
1732 0         0 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
1733             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3), # -
1734             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3), # -
1735             _cc( $z1) . _cc( $z2) . _cc($A3,$z3), # -z3
1736             );
1737             }
1738             else {
1739             return (
1740             # 1111111111111111 22222222222222 333333333333
1741             # A Z A Z A Z
1742 0         0 _cc($a1) . _cc($a2) . _cc($a3,$Z3), # a3-
1743             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3), # -
1744             _cc($a1+1,$z1-1) . _cc($A2,$Z2) . _cc($A3,$Z3), # -
1745             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3), # -
1746             _cc( $z1) . _cc( $z2) . _cc($A3,$z3), # -z3
1747             );
1748             }
1749             }
1750             elsif ($length == 4) {
1751 0         0 my($a1,$a2,$a3,$a4) = unpack 'CCCC', $_[0];
1752 0         0 my($z1,$z2,$z3,$z4) = unpack 'CCCC', $_[1];
1753 0         0 my($A1,$A2,$A3,$A4) = unpack 'CCCC', $_[0];
1754 0         0 my($Z1,$Z2,$Z3,$Z4) = unpack 'CCCC', $_[1];
1755              
1756 0 0       0 if ($a1 == $z1) {
    0          
1757 0 0       0 if ($a2 == $z2) {
    0          
1758 0 0       0 if ($a3 == $z3) {
    0          
1759             return (
1760             # 11111111 22222222 33333333 444444444444
1761             # A A A A Z
1762 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$z4), # a4-z4
1763             );
1764             }
1765             elsif (($a3+1) == $z3) {
1766             return (
1767             # 11111111 22222222 33333333333 444444444444
1768             # A A A Z A Z
1769 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
1770             _cc($a1) . _cc($a2) . _cc( $z3) . _cc($A4,$z4), # -z4
1771             );
1772             }
1773             else {
1774             return (
1775             # 11111111 22222222 3333333333333333 444444444444
1776             # A A A Z A Z
1777 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
1778             _cc($a1) . _cc($a2) . _cc($a3+1,$z3-1) . _cc($A4,$Z4), # -
1779             _cc($a1) . _cc($a2) . _cc( $z3) . _cc($A4,$z4), # -z4
1780             );
1781             }
1782             }
1783             elsif (($a2+1) == $z2) {
1784             return (
1785             # 11111111 22222222222 33333333333333 444444444444
1786             # A A Z A Z A Z
1787 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
1788             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
1789             _cc($a1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
1790             _cc($a1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
1791             );
1792             }
1793             else {
1794             return (
1795             # 11111111 2222222222222222 33333333333333 444444444444
1796             # A A Z A Z A Z
1797 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
1798             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
1799             _cc($a1) . _cc($a2+1,$z2-1) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
1800             _cc($a1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
1801             _cc($a1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
1802             );
1803             }
1804             }
1805             elsif (($a1+1) == $z1) {
1806             return (
1807             # 11111111111 22222222222222 33333333333333 444444444444
1808             # A Z A Z A Z A Z
1809 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
1810             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
1811             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
1812             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
1813             _cc( $z1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
1814             _cc( $z1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
1815             );
1816             }
1817             else {
1818             return (
1819             # 1111111111111111 22222222222222 33333333333333 444444444444
1820             # A Z A Z A Z A Z
1821 0         0 _cc($a1) . _cc($a2) . _cc($a3) . _cc($a4,$Z4), # a4-
1822             _cc($a1) . _cc($a2) . _cc($a3+1,$Z3) . _cc($A4,$Z4), # -
1823             _cc($a1) . _cc($a2+1,$Z2) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
1824             _cc($a1+1,$z1-1) . _cc($A2,$Z2) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
1825             _cc( $z1) . _cc($A2,$z2-1) . _cc($A3,$Z3) . _cc($A4,$Z4), # -
1826             _cc( $z1) . _cc( $z2) . _cc($A3,$z3-1) . _cc($A4,$Z4), # -
1827             _cc( $z1) . _cc( $z2) . _cc( $z3) . _cc($A4,$z4), # -z4
1828             );
1829             }
1830             }
1831             else {
1832 0         0 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1833             }
1834             }
1835              
1836             #
1837             # GBK range regexp
1838             #
1839             sub _range_regexp {
1840 0     517   0 my($length,$first,$last) = @_;
1841              
1842 517         1133 my @range_regexp = ();
1843 517 50       756 if (not exists $range_tr{$length}) {
1844 517         1327 return @range_regexp;
1845             }
1846              
1847 0         0 my @ranges = @{ $range_tr{$length} };
  517         875  
1848 517         1276 while (my @range = splice(@ranges,0,$length)) {
1849 517         1539 my $min = '';
1850 1034         1529 my $max = '';
1851 1034         1223 for (my $i=0; $i < $length; $i++) {
1852 1034         2050 $min .= pack 'C', $range[$i][0];
1853 1296         3033 $max .= pack 'C', $range[$i][-1];
1854             }
1855              
1856             # min___max
1857             # FIRST_____________LAST
1858             # (nothing)
1859              
1860 1296 50 66     2806 if ($max lt $first) {
    100 100        
    50 33        
    100 100        
    100 66        
    100 66        
    50 66        
1861             }
1862              
1863             # **********
1864             # min_________max
1865             # FIRST_____________LAST
1866             # **********
1867              
1868             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1869 1034         9230 push @range_regexp, _octets($length,$first,$max,$min,$max);
1870             }
1871              
1872             # **********************
1873             # min________________max
1874             # FIRST_____________LAST
1875             # **********************
1876              
1877             elsif (($min eq $first) and ($max eq $last)) {
1878 20         78 push @range_regexp, _octets($length,$first,$last,$min,$max);
1879             }
1880              
1881             # *********
1882             # min___max
1883             # FIRST_____________LAST
1884             # *********
1885              
1886             elsif (($first le $min) and ($max le $last)) {
1887 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1888             }
1889              
1890             # **********************
1891             # min__________________________max
1892             # FIRST_____________LAST
1893             # **********************
1894              
1895             elsif (($min le $first) and ($last le $max)) {
1896 20         39 push @range_regexp, _octets($length,$first,$last,$min,$max);
1897             }
1898              
1899             # *********
1900             # min________max
1901             # FIRST_____________LAST
1902             # *********
1903              
1904             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1905 588         1461 push @range_regexp, _octets($length,$min,$last,$min,$max);
1906             }
1907              
1908             # min___max
1909             # FIRST_____________LAST
1910             # (nothing)
1911              
1912             elsif ($last lt $min) {
1913             }
1914              
1915             else {
1916 40         95 die __FILE__, ": subroutine _range_regexp panic.\n";
1917             }
1918             }
1919              
1920 0         0 return @range_regexp;
1921             }
1922              
1923             #
1924             # GBK open character list for qr and not qr
1925             #
1926             sub _charlist {
1927              
1928 517     758   1220 my $modifier = pop @_;
1929 758         1180 my @char = @_;
1930              
1931 758 100       1834 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1932              
1933             # unescape character
1934 758         1821 for (my $i=0; $i <= $#char; $i++) {
1935              
1936             # escape - to ...
1937 758 100 100     2300 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1938 2648 100 100     18817 if ((0 < $i) and ($i < $#char)) {
1939 522         1905 $char[$i] = '...';
1940             }
1941             }
1942              
1943             # octal escape sequence
1944             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1945 497         1105 $char[$i] = octchr($1);
1946             }
1947              
1948             # hexadecimal escape sequence
1949             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1950 0         0 $char[$i] = hexchr($1);
1951             }
1952              
1953             # \b{...} --> b\{...}
1954             # \B{...} --> B\{...}
1955             # \N{CHARNAME} --> N\{CHARNAME}
1956             # \p{PROPERTY} --> p\{PROPERTY}
1957             # \P{PROPERTY} --> P\{PROPERTY}
1958             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} ) \z/oxms) {
1959 0         0 $char[$i] = $1 . '\\' . $2;
1960             }
1961              
1962             # \p, \P, \X --> p, P, X
1963             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1964 0         0 $char[$i] = $1;
1965             }
1966              
1967             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1968 0         0 $char[$i] = CORE::chr oct $1;
1969             }
1970             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1971 0         0 $char[$i] = CORE::chr hex $1;
1972             }
1973             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1974 206         1013 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1975             }
1976             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1977             $char[$i] = {
1978             '\0' => "\0",
1979             '\n' => "\n",
1980             '\r' => "\r",
1981             '\t' => "\t",
1982             '\f' => "\f",
1983             '\b' => "\x08", # \b means backspace in character class
1984             '\a' => "\a",
1985             '\e' => "\e",
1986             '\d' => '[0-9]',
1987              
1988             # Vertical tabs are now whitespace
1989             # \s in a regex now matches a vertical tab in all circumstances.
1990             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1991             # \t \n \v \f \r space
1992             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1993             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1994             '\s' => '\s',
1995              
1996             '\w' => '[0-9A-Z_a-z]',
1997             '\D' => '${Egbk::eD}',
1998             '\S' => '${Egbk::eS}',
1999             '\W' => '${Egbk::eW}',
2000              
2001             '\H' => '${Egbk::eH}',
2002             '\V' => '${Egbk::eV}',
2003             '\h' => '[\x09\x20]',
2004             '\v' => '[\x0A\x0B\x0C\x0D]',
2005             '\R' => '${Egbk::eR}',
2006              
2007 0         0 }->{$1};
2008             }
2009              
2010             # POSIX-style character classes
2011             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
2012             $char[$i] = {
2013              
2014             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
2015             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
2016             '[:^lower:]' => '${Egbk::not_lower_i}',
2017             '[:^upper:]' => '${Egbk::not_upper_i}',
2018              
2019 33         572 }->{$1};
2020             }
2021             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
2022             $char[$i] = {
2023              
2024             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
2025             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
2026             '[:ascii:]' => '[\x00-\x7F]',
2027             '[:blank:]' => '[\x09\x20]',
2028             '[:cntrl:]' => '[\x00-\x1F\x7F]',
2029             '[:digit:]' => '[\x30-\x39]',
2030             '[:graph:]' => '[\x21-\x7F]',
2031             '[:lower:]' => '[\x61-\x7A]',
2032             '[:print:]' => '[\x20-\x7F]',
2033             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
2034              
2035             # P.174 POSIX-Style Character Classes
2036             # in Chapter 5: Pattern Matching
2037             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2038              
2039             # P.311 11.2.4 Character Classes and other Special Escapes
2040             # in Chapter 11: perlre: Perl regular expressions
2041             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
2042              
2043             # P.210 POSIX-Style Character Classes
2044             # in Chapter 5: Pattern Matching
2045             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2046              
2047             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
2048              
2049             '[:upper:]' => '[\x41-\x5A]',
2050             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
2051             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
2052             '[:^alnum:]' => '${Egbk::not_alnum}',
2053             '[:^alpha:]' => '${Egbk::not_alpha}',
2054             '[:^ascii:]' => '${Egbk::not_ascii}',
2055             '[:^blank:]' => '${Egbk::not_blank}',
2056             '[:^cntrl:]' => '${Egbk::not_cntrl}',
2057             '[:^digit:]' => '${Egbk::not_digit}',
2058             '[:^graph:]' => '${Egbk::not_graph}',
2059             '[:^lower:]' => '${Egbk::not_lower}',
2060             '[:^print:]' => '${Egbk::not_print}',
2061             '[:^punct:]' => '${Egbk::not_punct}',
2062             '[:^space:]' => '${Egbk::not_space}',
2063             '[:^upper:]' => '${Egbk::not_upper}',
2064             '[:^word:]' => '${Egbk::not_word}',
2065             '[:^xdigit:]' => '${Egbk::not_xdigit}',
2066              
2067 8         79 }->{$1};
2068             }
2069             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
2070 70         1819 $char[$i] = $1;
2071             }
2072             }
2073              
2074             # open character list
2075 7         31 my @singleoctet = ();
2076 758         1410 my @multipleoctet = ();
2077 758         1073 for (my $i=0; $i <= $#char; ) {
2078              
2079             # escaped -
2080 758 100 100     1675 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
2081 2151         9961 $i += 1;
2082 497         702 next;
2083             }
2084              
2085             # make range regexp
2086             elsif ($char[$i] eq '...') {
2087              
2088             # range error
2089 497 50       1009 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    100          
2090 497         1845 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
2091             }
2092             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
2093 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
2094 477         1155 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
2095             }
2096             }
2097              
2098             # make range regexp per length
2099 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
2100 497         1432 my @regexp = ();
2101              
2102             # is first and last
2103 517 100 100     815 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    100 33        
    50          
    50          
2104 517         1996 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
2105             }
2106              
2107             # is first
2108             elsif ($length == CORE::length($char[$i-1])) {
2109 477         1335 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
2110             }
2111              
2112             # is inside in first and last
2113             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
2114 20         112 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
2115             }
2116              
2117             # is last
2118             elsif ($length == CORE::length($char[$i+1])) {
2119 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
2120             }
2121              
2122             else {
2123 20         60 die __FILE__, ": subroutine make_regexp panic.\n";
2124             }
2125              
2126 0 100       0 if ($length == 1) {
2127 517         1130 push @singleoctet, @regexp;
2128             }
2129             else {
2130 386         1103 push @multipleoctet, @regexp;
2131             }
2132             }
2133              
2134 131         350 $i += 2;
2135             }
2136              
2137             # with /i modifier
2138             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
2139 497 100       1690 if ($modifier =~ /i/oxms) {
2140 764         1218 my $uc = Egbk::uc($char[$i]);
2141 192         371 my $fc = Egbk::fc($char[$i]);
2142 192 50       388 if ($uc ne $fc) {
2143 192 50       369 if (CORE::length($fc) == 1) {
2144 192         314 push @singleoctet, $uc, $fc;
2145             }
2146             else {
2147 192         447 push @singleoctet, $uc;
2148 0         0 push @multipleoctet, $fc;
2149             }
2150             }
2151             else {
2152 0         0 push @singleoctet, $char[$i];
2153             }
2154             }
2155             else {
2156 0         0 push @singleoctet, $char[$i];
2157             }
2158 572         861 $i += 1;
2159             }
2160              
2161             # single character of single octet code
2162             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
2163 764         1370 push @singleoctet, "\t", "\x20";
2164 0         0 $i += 1;
2165             }
2166             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
2167 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
2168 0         0 $i += 1;
2169             }
2170             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
2171 0         0 push @singleoctet, $char[$i];
2172 2         7 $i += 1;
2173             }
2174              
2175             # single character of multiple-octet code
2176             else {
2177 2         5 push @multipleoctet, $char[$i];
2178 391         773 $i += 1;
2179             }
2180             }
2181              
2182             # quote metachar
2183 391         775 for (@singleoctet) {
2184 758 50       1663 if ($_ eq '...') {
    100          
    100          
    100          
    100          
2185 1364         5892 $_ = '-';
2186             }
2187             elsif (/\A \n \z/oxms) {
2188 0         0 $_ = '\n';
2189             }
2190             elsif (/\A \r \z/oxms) {
2191 8         17 $_ = '\r';
2192             }
2193             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
2194 8         19 $_ = sprintf('\x%02X', CORE::ord $1);
2195             }
2196             elsif (/\A [\x00-\xFF] \z/oxms) {
2197 1         6 $_ = quotemeta $_;
2198             }
2199             }
2200 939         1432 for (@multipleoctet) {
2201 758 100       1409 if (/\A ([\x80-\xFF].*) ([\x00-\xFF]) \z/oxms) {
2202 693         2003 $_ = $1 . quotemeta $2;
2203             }
2204             }
2205              
2206             # return character list
2207 307         841 return \@singleoctet, \@multipleoctet;
2208             }
2209              
2210             #
2211             # GBK octal escape sequence
2212             #
2213             sub octchr {
2214 758     5 0 2737 my($octdigit) = @_;
2215              
2216 5         13 my @binary = ();
2217 5         9 for my $octal (split(//,$octdigit)) {
2218             push @binary, {
2219             '0' => '000',
2220             '1' => '001',
2221             '2' => '010',
2222             '3' => '011',
2223             '4' => '100',
2224             '5' => '101',
2225             '6' => '110',
2226             '7' => '111',
2227 5         23 }->{$octal};
2228             }
2229 50         174 my $binary = join '', @binary;
2230              
2231             my $octchr = {
2232             # 1234567
2233             1 => pack('B*', "0000000$binary"),
2234             2 => pack('B*', "000000$binary"),
2235             3 => pack('B*', "00000$binary"),
2236             4 => pack('B*', "0000$binary"),
2237             5 => pack('B*', "000$binary"),
2238             6 => pack('B*', "00$binary"),
2239             7 => pack('B*', "0$binary"),
2240             0 => pack('B*', "$binary"),
2241              
2242 5         15 }->{CORE::length($binary) % 8};
2243              
2244 5         67 return $octchr;
2245             }
2246              
2247             #
2248             # GBK hexadecimal escape sequence
2249             #
2250             sub hexchr {
2251 5     5 0 21 my($hexdigit) = @_;
2252              
2253             my $hexchr = {
2254             1 => pack('H*', "0$hexdigit"),
2255             0 => pack('H*', "$hexdigit"),
2256              
2257 5         16 }->{CORE::length($_[0]) % 2};
2258              
2259 5         50 return $hexchr;
2260             }
2261              
2262             #
2263             # GBK open character list for qr
2264             #
2265             sub charlist_qr {
2266              
2267 5     519 0 31 my $modifier = pop @_;
2268 519         1179 my @char = @_;
2269              
2270 519         1419 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2271 519         1557 my @singleoctet = @$singleoctet;
2272 519         1164 my @multipleoctet = @$multipleoctet;
2273              
2274             # return character list
2275 519 100       886 if (scalar(@singleoctet) >= 1) {
2276              
2277             # with /i modifier
2278 519 100       1370 if ($modifier =~ m/i/oxms) {
2279 384         852 my %singleoctet_ignorecase = ();
2280 107         178 for (@singleoctet) {
2281 107   100     192 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2282 272         1032 for my $ord (hex($1) .. hex($2)) {
2283 80         328 my $char = CORE::chr($ord);
2284 1046         1574 my $uc = Egbk::uc($char);
2285 1046         1596 my $fc = Egbk::fc($char);
2286 1046 100       1718 if ($uc eq $fc) {
2287 1046         1775 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2288             }
2289             else {
2290 457 50       1225 if (CORE::length($fc) == 1) {
2291 589         882 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2292 589         1383 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2293             }
2294             else {
2295 589         1651 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2296 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2297             }
2298             }
2299             }
2300             }
2301 0 100       0 if ($_ ne '') {
2302 272         506 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2303             }
2304             }
2305 192         539 my $i = 0;
2306 107         234 my @singleoctet_ignorecase = ();
2307 107         180 for my $ord (0 .. 255) {
2308 107 100       241 if (exists $singleoctet_ignorecase{$ord}) {
2309 27392         36615 push @{$singleoctet_ignorecase[$i]}, $ord;
  1577         1683  
2310             }
2311             else {
2312 1577         2831 $i++;
2313             }
2314             }
2315 25815         29555 @singleoctet = ();
2316 107         193 for my $range (@singleoctet_ignorecase) {
2317 107 100       283 if (ref $range) {
2318 11412 100       20700 if (scalar(@{$range}) == 1) {
  214 50       260  
2319 214         376 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  5         10  
2320             }
2321 5         71 elsif (scalar(@{$range}) == 2) {
2322 209         339 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2323             }
2324             else {
2325 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  209         271  
  209         301  
2326             }
2327             }
2328             }
2329             }
2330              
2331 209         1131 my $not_anchor = '';
2332 384         623 $not_anchor = '(?![\x81-\xFE])';
2333              
2334 384         514 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2335             }
2336 384 100       1035 if (scalar(@multipleoctet) >= 2) {
2337 519         1150 return '(?:' . join('|', @multipleoctet) . ')';
2338             }
2339             else {
2340 131         923 return $multipleoctet[0];
2341             }
2342             }
2343              
2344             #
2345             # GBK open character list for not qr
2346             #
2347             sub charlist_not_qr {
2348              
2349 388     239 0 1784 my $modifier = pop @_;
2350 239         523 my @char = @_;
2351              
2352 239         626 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2353 239         601 my @singleoctet = @$singleoctet;
2354 239         531 my @multipleoctet = @$multipleoctet;
2355              
2356             # with /i modifier
2357 239 100       401 if ($modifier =~ m/i/oxms) {
2358 239         707 my %singleoctet_ignorecase = ();
2359 128         231 for (@singleoctet) {
2360 128   100     196 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2361 272         1003 for my $ord (hex($1) .. hex($2)) {
2362 80         321 my $char = CORE::chr($ord);
2363 1046         1521 my $uc = Egbk::uc($char);
2364 1046         1491 my $fc = Egbk::fc($char);
2365 1046 100       1649 if ($uc eq $fc) {
2366 1046         1671 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2367             }
2368             else {
2369 457 50       1133 if (CORE::length($fc) == 1) {
2370 589         801 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2371 589         1525 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2372             }
2373             else {
2374 589         1564 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2375 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2376             }
2377             }
2378             }
2379             }
2380 0 100       0 if ($_ ne '') {
2381 272         532 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2382             }
2383             }
2384 192         567 my $i = 0;
2385 128         177 my @singleoctet_ignorecase = ();
2386 128         261 for my $ord (0 .. 255) {
2387 128 100       238 if (exists $singleoctet_ignorecase{$ord}) {
2388 32768         43231 push @{$singleoctet_ignorecase[$i]}, $ord;
  1577         1594  
2389             }
2390             else {
2391 1577         2690 $i++;
2392             }
2393             }
2394 31191         35090 @singleoctet = ();
2395 128         211 for my $range (@singleoctet_ignorecase) {
2396 128 100       325 if (ref $range) {
2397 11412 100       19687 if (scalar(@{$range}) == 1) {
  214 50       236  
2398 214         375 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  5         6  
2399             }
2400 5         58 elsif (scalar(@{$range}) == 2) {
2401 209         294 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2402             }
2403             else {
2404 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  209         267  
  209         279  
2405             }
2406             }
2407             }
2408             }
2409              
2410             # return character list
2411 209 100       1021 if (scalar(@multipleoctet) >= 1) {
2412 239 100       575 if (scalar(@singleoctet) >= 1) {
2413              
2414             # any character other than multiple-octet and single octet character class
2415 114         274 return '(?!' . join('|', @multipleoctet) . ')(?:[^\x81-\xFE' . join('', @singleoctet) . ']|[\x81-\xFE][\x00-\xFF])';
2416             }
2417             else {
2418              
2419             # any character other than multiple-octet character class
2420 70         545 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2421             }
2422             }
2423             else {
2424 44 50       319 if (scalar(@singleoctet) >= 1) {
2425              
2426             # any character other than single octet character class
2427 125         245 return '(?:[^\x81-\xFE' . join('', @singleoctet) . ']|[\x81-\xFE][\x00-\xFF])';
2428             }
2429             else {
2430              
2431             # any character
2432 125         801 return "(?:$your_char)";
2433             }
2434             }
2435             }
2436              
2437             #
2438             # open file in read mode
2439             #
2440             sub _open_r {
2441 0     772   0 my(undef,$file) = @_;
2442 391     391   4332 use Fcntl qw(O_RDONLY);
  391         2400  
  391         64792  
2443 772         2231 return CORE::sysopen($_[0], $file, &O_RDONLY);
2444             }
2445              
2446             #
2447             # open file in append mode
2448             #
2449             sub _open_a {
2450 772     386   32145 my(undef,$file) = @_;
2451 391     391   6196 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  391         773  
  391         5579821  
2452 386         1287 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2453             }
2454              
2455             #
2456             # safe system
2457             #
2458             sub _systemx {
2459              
2460             # P.707 29.2.33. exec
2461             # in Chapter 29: Functions
2462             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2463             #
2464             # Be aware that in older releases of Perl, exec (and system) did not flush
2465             # your output buffer, so you needed to enable command buffering by setting $|
2466             # on one or more filehandles to avoid lost output in the case of exec, or
2467             # misordererd output in the case of system. This situation was largely remedied
2468             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2469              
2470             # P.855 exec
2471             # in Chapter 27: Functions
2472             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2473             #
2474             # In very old release of Perl (before v5.6), exec (and system) did not flush
2475             # your output buffer, so you needed to enable command buffering by setting $|
2476             # on one or more filehandles to avoid lost output with exec or misordered
2477             # output with system.
2478              
2479 386     386   50022 $| = 1;
2480              
2481             # P.565 23.1.2. Cleaning Up Your Environment
2482             # in Chapter 23: Security
2483             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2484              
2485             # P.656 Cleaning Up Your Environment
2486             # in Chapter 20: Security
2487             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2488              
2489             # local $ENV{'PATH'} = '.';
2490 386         1805 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2491              
2492             # P.707 29.2.33. exec
2493             # in Chapter 29: Functions
2494             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2495             #
2496             # As we mentioned earlier, exec treats a discrete list of arguments as an
2497             # indication that it should bypass shell processing. However, there is one
2498             # place where you might still get tripped up. The exec call (and system, too)
2499             # will not distinguish between a single scalar argument and an array containing
2500             # only one element.
2501             #
2502             # @args = ("echo surprise"); # just one element in list
2503             # exec @args # still subject to shell escapes
2504             # or die "exec: $!"; # because @args == 1
2505             #
2506             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2507             # first argument as the pathname, which forces the rest of the arguments to be
2508             # interpreted as a list, even if there is only one of them:
2509             #
2510             # exec { $args[0] } @args # safe even with one-argument list
2511             # or die "can't exec @args: $!";
2512              
2513             # P.855 exec
2514             # in Chapter 27: Functions
2515             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2516             #
2517             # As we mentioned earlier, exec treats a discrete list of arguments as a
2518             # directive to bypass shell processing. However, there is one place where
2519             # you might still get tripped up. The exec call (and system, too) cannot
2520             # distinguish between a single scalar argument and an array containing
2521             # only one element.
2522             #
2523             # @args = ("echo surprise"); # just one element in list
2524             # exec @args # still subject to shell escapes
2525             # || die "exec: $!"; # because @args == 1
2526             #
2527             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2528             # argument as the pathname, which forces the rest of the arguments to be
2529             # interpreted as a list, even if there is only one of them:
2530             #
2531             # exec { $args[0] } @args # safe even with one-argument list
2532             # || die "can't exec @args: $!";
2533              
2534 386         3937 return CORE::system { $_[0] } @_; # safe even with one-argument list
  386         1093  
2535             }
2536              
2537             #
2538             # GBK order to character (with parameter)
2539             #
2540             sub Egbk::chr(;$) {
2541              
2542 386 0   0 0 40704360 my $c = @_ ? $_[0] : $_;
2543              
2544 0 0       0 if ($c == 0x00) {
2545 0         0 return "\x00";
2546             }
2547             else {
2548 0         0 my @chr = ();
2549 0         0 while ($c > 0) {
2550 0         0 unshift @chr, ($c % 0x100);
2551 0         0 $c = int($c / 0x100);
2552             }
2553 0         0 return pack 'C*', @chr;
2554             }
2555             }
2556              
2557             #
2558             # GBK order to character (without parameter)
2559             #
2560             sub Egbk::chr_() {
2561              
2562 0     0 0 0 my $c = $_;
2563              
2564 0 0       0 if ($c == 0x00) {
2565 0         0 return "\x00";
2566             }
2567             else {
2568 0         0 my @chr = ();
2569 0         0 while ($c > 0) {
2570 0         0 unshift @chr, ($c % 0x100);
2571 0         0 $c = int($c / 0x100);
2572             }
2573 0         0 return pack 'C*', @chr;
2574             }
2575             }
2576              
2577             #
2578             # GBK stacked file test expr
2579             #
2580             sub Egbk::filetest {
2581              
2582 0     0 0 0 my $file = pop @_;
2583 0         0 my $filetest = substr(pop @_, 1);
2584              
2585 0 0       0 unless (CORE::eval qq{Egbk::$filetest(\$file)}) {
2586 0         0 return '';
2587             }
2588 0         0 for my $filetest (CORE::reverse @_) {
2589 0 0       0 unless (CORE::eval qq{ $filetest _ }) {
2590 0         0 return '';
2591             }
2592             }
2593 0         0 return 1;
2594             }
2595              
2596             #
2597             # GBK file test -r expr
2598             #
2599             sub Egbk::r(;*@) {
2600              
2601 0 0   0 0 0 local $_ = shift if @_;
2602 0 0 0     0 croak 'Too many arguments for -r (Egbk::r)' if @_ and not wantarray;
2603              
2604 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2605 0 0       0 return wantarray ? (-r _,@_) : -r _;
2606             }
2607              
2608             # P.908 32.39. Symbol
2609             # in Chapter 32: Standard Modules
2610             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2611              
2612             # P.326 Prototypes
2613             # in Chapter 7: Subroutines
2614             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2615              
2616             # (and so on)
2617              
2618             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2619 0 0       0 return wantarray ? (-r $fh,@_) : -r $fh;
2620             }
2621             elsif (-e $_) {
2622 0 0       0 return wantarray ? (-r _,@_) : -r _;
2623             }
2624             elsif (_MSWin32_5Cended_path($_)) {
2625 0 0       0 if (-d "$_/.") {
2626 0 0       0 return wantarray ? (-r _,@_) : -r _;
2627             }
2628             else {
2629              
2630             # Even if ${^WIN32_SLOPPY_STAT} is set to a true value, Egbk::*()
2631             # on Windows opens the file for the path which has 5c at end.
2632             # (and so on)
2633              
2634 0         0 my $fh = gensym();
2635 0 0       0 if (_open_r($fh, $_)) {
2636 0         0 my $r = -r $fh;
2637 0 0       0 close($fh) or die "Can't close file: $_: $!";
2638 0 0       0 return wantarray ? ($r,@_) : $r;
2639             }
2640             }
2641             }
2642 0 0       0 return wantarray ? (undef,@_) : undef;
2643             }
2644              
2645             #
2646             # GBK file test -w expr
2647             #
2648             sub Egbk::w(;*@) {
2649              
2650 0 0   0 0 0 local $_ = shift if @_;
2651 0 0 0     0 croak 'Too many arguments for -w (Egbk::w)' if @_ and not wantarray;
2652              
2653 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2654 0 0       0 return wantarray ? (-w _,@_) : -w _;
2655             }
2656             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2657 0 0       0 return wantarray ? (-w $fh,@_) : -w $fh;
2658             }
2659             elsif (-e $_) {
2660 0 0       0 return wantarray ? (-w _,@_) : -w _;
2661             }
2662             elsif (_MSWin32_5Cended_path($_)) {
2663 0 0       0 if (-d "$_/.") {
2664 0 0       0 return wantarray ? (-w _,@_) : -w _;
2665             }
2666             else {
2667 0         0 my $fh = gensym();
2668 0 0       0 if (_open_a($fh, $_)) {
2669 0         0 my $w = -w $fh;
2670 0 0       0 close($fh) or die "Can't close file: $_: $!";
2671 0 0       0 return wantarray ? ($w,@_) : $w;
2672             }
2673             }
2674             }
2675 0 0       0 return wantarray ? (undef,@_) : undef;
2676             }
2677              
2678             #
2679             # GBK file test -x expr
2680             #
2681             sub Egbk::x(;*@) {
2682              
2683 0 0   0 0 0 local $_ = shift if @_;
2684 0 0 0     0 croak 'Too many arguments for -x (Egbk::x)' if @_ and not wantarray;
2685              
2686 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2687 0 0       0 return wantarray ? (-x _,@_) : -x _;
2688             }
2689             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2690 0 0       0 return wantarray ? (-x $fh,@_) : -x $fh;
2691             }
2692             elsif (-e $_) {
2693 0 0       0 return wantarray ? (-x _,@_) : -x _;
2694             }
2695             elsif (_MSWin32_5Cended_path($_)) {
2696 0 0       0 if (-d "$_/.") {
2697 0 0       0 return wantarray ? (-x _,@_) : -x _;
2698             }
2699             else {
2700 0         0 my $fh = gensym();
2701 0 0       0 if (_open_r($fh, $_)) {
2702 0         0 my $dummy_for_underline_cache = -x $fh;
2703 0 0       0 close($fh) or die "Can't close file: $_: $!";
2704             }
2705              
2706             # filename is not .COM .EXE .BAT .CMD
2707 0 0       0 return wantarray ? ('',@_) : '';
2708             }
2709             }
2710 0 0       0 return wantarray ? (undef,@_) : undef;
2711             }
2712              
2713             #
2714             # GBK file test -o expr
2715             #
2716             sub Egbk::o(;*@) {
2717              
2718 0 0   0 0 0 local $_ = shift if @_;
2719 0 0 0     0 croak 'Too many arguments for -o (Egbk::o)' if @_ and not wantarray;
2720              
2721 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2722 0 0       0 return wantarray ? (-o _,@_) : -o _;
2723             }
2724             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2725 0 0       0 return wantarray ? (-o $fh,@_) : -o $fh;
2726             }
2727             elsif (-e $_) {
2728 0 0       0 return wantarray ? (-o _,@_) : -o _;
2729             }
2730             elsif (_MSWin32_5Cended_path($_)) {
2731 0 0       0 if (-d "$_/.") {
2732 0 0       0 return wantarray ? (-o _,@_) : -o _;
2733             }
2734             else {
2735 0         0 my $fh = gensym();
2736 0 0       0 if (_open_r($fh, $_)) {
2737 0         0 my $o = -o $fh;
2738 0 0       0 close($fh) or die "Can't close file: $_: $!";
2739 0 0       0 return wantarray ? ($o,@_) : $o;
2740             }
2741             }
2742             }
2743 0 0       0 return wantarray ? (undef,@_) : undef;
2744             }
2745              
2746             #
2747             # GBK file test -R expr
2748             #
2749             sub Egbk::R(;*@) {
2750              
2751 0 0   0 0 0 local $_ = shift if @_;
2752 0 0 0     0 croak 'Too many arguments for -R (Egbk::R)' if @_ and not wantarray;
2753              
2754 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2755 0 0       0 return wantarray ? (-R _,@_) : -R _;
2756             }
2757             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2758 0 0       0 return wantarray ? (-R $fh,@_) : -R $fh;
2759             }
2760             elsif (-e $_) {
2761 0 0       0 return wantarray ? (-R _,@_) : -R _;
2762             }
2763             elsif (_MSWin32_5Cended_path($_)) {
2764 0 0       0 if (-d "$_/.") {
2765 0 0       0 return wantarray ? (-R _,@_) : -R _;
2766             }
2767             else {
2768 0         0 my $fh = gensym();
2769 0 0       0 if (_open_r($fh, $_)) {
2770 0         0 my $R = -R $fh;
2771 0 0       0 close($fh) or die "Can't close file: $_: $!";
2772 0 0       0 return wantarray ? ($R,@_) : $R;
2773             }
2774             }
2775             }
2776 0 0       0 return wantarray ? (undef,@_) : undef;
2777             }
2778              
2779             #
2780             # GBK file test -W expr
2781             #
2782             sub Egbk::W(;*@) {
2783              
2784 0 0   0 0 0 local $_ = shift if @_;
2785 0 0 0     0 croak 'Too many arguments for -W (Egbk::W)' if @_ and not wantarray;
2786              
2787 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2788 0 0       0 return wantarray ? (-W _,@_) : -W _;
2789             }
2790             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2791 0 0       0 return wantarray ? (-W $fh,@_) : -W $fh;
2792             }
2793             elsif (-e $_) {
2794 0 0       0 return wantarray ? (-W _,@_) : -W _;
2795             }
2796             elsif (_MSWin32_5Cended_path($_)) {
2797 0 0       0 if (-d "$_/.") {
2798 0 0       0 return wantarray ? (-W _,@_) : -W _;
2799             }
2800             else {
2801 0         0 my $fh = gensym();
2802 0 0       0 if (_open_a($fh, $_)) {
2803 0         0 my $W = -W $fh;
2804 0 0       0 close($fh) or die "Can't close file: $_: $!";
2805 0 0       0 return wantarray ? ($W,@_) : $W;
2806             }
2807             }
2808             }
2809 0 0       0 return wantarray ? (undef,@_) : undef;
2810             }
2811              
2812             #
2813             # GBK file test -X expr
2814             #
2815             sub Egbk::X(;*@) {
2816              
2817 0 0   0 1 0 local $_ = shift if @_;
2818 0 0 0     0 croak 'Too many arguments for -X (Egbk::X)' if @_ and not wantarray;
2819              
2820 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2821 0 0       0 return wantarray ? (-X _,@_) : -X _;
2822             }
2823             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2824 0 0       0 return wantarray ? (-X $fh,@_) : -X $fh;
2825             }
2826             elsif (-e $_) {
2827 0 0       0 return wantarray ? (-X _,@_) : -X _;
2828             }
2829             elsif (_MSWin32_5Cended_path($_)) {
2830 0 0       0 if (-d "$_/.") {
2831 0 0       0 return wantarray ? (-X _,@_) : -X _;
2832             }
2833             else {
2834 0         0 my $fh = gensym();
2835 0 0       0 if (_open_r($fh, $_)) {
2836 0         0 my $dummy_for_underline_cache = -X $fh;
2837 0 0       0 close($fh) or die "Can't close file: $_: $!";
2838             }
2839              
2840             # filename is not .COM .EXE .BAT .CMD
2841 0 0       0 return wantarray ? ('',@_) : '';
2842             }
2843             }
2844 0 0       0 return wantarray ? (undef,@_) : undef;
2845             }
2846              
2847             #
2848             # GBK file test -O expr
2849             #
2850             sub Egbk::O(;*@) {
2851              
2852 0 0   0 0 0 local $_ = shift if @_;
2853 0 0 0     0 croak 'Too many arguments for -O (Egbk::O)' if @_ and not wantarray;
2854              
2855 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2856 0 0       0 return wantarray ? (-O _,@_) : -O _;
2857             }
2858             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2859 0 0       0 return wantarray ? (-O $fh,@_) : -O $fh;
2860             }
2861             elsif (-e $_) {
2862 0 0       0 return wantarray ? (-O _,@_) : -O _;
2863             }
2864             elsif (_MSWin32_5Cended_path($_)) {
2865 0 0       0 if (-d "$_/.") {
2866 0 0       0 return wantarray ? (-O _,@_) : -O _;
2867             }
2868             else {
2869 0         0 my $fh = gensym();
2870 0 0       0 if (_open_r($fh, $_)) {
2871 0         0 my $O = -O $fh;
2872 0 0       0 close($fh) or die "Can't close file: $_: $!";
2873 0 0       0 return wantarray ? ($O,@_) : $O;
2874             }
2875             }
2876             }
2877 0 0       0 return wantarray ? (undef,@_) : undef;
2878             }
2879              
2880             #
2881             # GBK file test -e expr
2882             #
2883             sub Egbk::e(;*@) {
2884              
2885 0 50   772 0 0 local $_ = shift if @_;
2886 772 50 33     3432 croak 'Too many arguments for -e (Egbk::e)' if @_ and not wantarray;
2887              
2888 772         2848 local $^W = 0;
2889 772     772   5795 local $SIG{__WARN__} = sub {}; # telldir() attempted on invalid dirhandle at here
2890              
2891 772         5039 my $fh = qualify_to_ref $_;
2892 772 50       2448 if ($_ eq '_') {
    50          
    50          
    50          
    50          
2893 772 0       3220 return wantarray ? (-e _,@_) : -e _;
2894             }
2895              
2896             # return false if directory handle
2897             elsif (defined Egbk::telldir($fh)) {
2898 0 0       0 return wantarray ? ('',@_) : '';
2899             }
2900              
2901             # return true if file handle
2902             elsif (defined fileno $fh) {
2903 0 0       0 return wantarray ? (1,@_) : 1;
2904             }
2905              
2906             elsif (-e $_) {
2907 0 0       0 return wantarray ? (1,@_) : 1;
2908             }
2909             elsif (_MSWin32_5Cended_path($_)) {
2910 0 0       0 if (-d "$_/.") {
2911 0 0       0 return wantarray ? (1,@_) : 1;
2912             }
2913             else {
2914 0         0 my $fh = gensym();
2915 0 0       0 if (_open_r($fh, $_)) {
2916 0         0 my $e = -e $fh;
2917 0 0       0 close($fh) or die "Can't close file: $_: $!";
2918 0 0       0 return wantarray ? ($e,@_) : $e;
2919             }
2920             }
2921             }
2922 0 50       0 return wantarray ? (undef,@_) : undef;
2923             }
2924              
2925             #
2926             # GBK file test -z expr
2927             #
2928             sub Egbk::z(;*@) {
2929              
2930 772 0   0 0 6723 local $_ = shift if @_;
2931 0 0 0     0 croak 'Too many arguments for -z (Egbk::z)' if @_ and not wantarray;
2932              
2933 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2934 0 0       0 return wantarray ? (-z _,@_) : -z _;
2935             }
2936             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2937 0 0       0 return wantarray ? (-z $fh,@_) : -z $fh;
2938             }
2939             elsif (-e $_) {
2940 0 0       0 return wantarray ? (-z _,@_) : -z _;
2941             }
2942             elsif (_MSWin32_5Cended_path($_)) {
2943 0 0       0 if (-d "$_/.") {
2944 0 0       0 return wantarray ? (-z _,@_) : -z _;
2945             }
2946             else {
2947 0         0 my $fh = gensym();
2948 0 0       0 if (_open_r($fh, $_)) {
2949 0         0 my $z = -z $fh;
2950 0 0       0 close($fh) or die "Can't close file: $_: $!";
2951 0 0       0 return wantarray ? ($z,@_) : $z;
2952             }
2953             }
2954             }
2955 0 0       0 return wantarray ? (undef,@_) : undef;
2956             }
2957              
2958             #
2959             # GBK file test -s expr
2960             #
2961             sub Egbk::s(;*@) {
2962              
2963 0 0   0 0 0 local $_ = shift if @_;
2964 0 0 0     0 croak 'Too many arguments for -s (Egbk::s)' if @_ and not wantarray;
2965              
2966 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
2967 0 0       0 return wantarray ? (-s _,@_) : -s _;
2968             }
2969             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
2970 0 0       0 return wantarray ? (-s $fh,@_) : -s $fh;
2971             }
2972             elsif (-e $_) {
2973 0 0       0 return wantarray ? (-s _,@_) : -s _;
2974             }
2975             elsif (_MSWin32_5Cended_path($_)) {
2976 0 0       0 if (-d "$_/.") {
2977 0 0       0 return wantarray ? (-s _,@_) : -s _;
2978             }
2979             else {
2980 0         0 my $fh = gensym();
2981 0 0       0 if (_open_r($fh, $_)) {
2982 0         0 my $s = -s $fh;
2983 0 0       0 close($fh) or die "Can't close file: $_: $!";
2984 0 0       0 return wantarray ? ($s,@_) : $s;
2985             }
2986             }
2987             }
2988 0 0       0 return wantarray ? (undef,@_) : undef;
2989             }
2990              
2991             #
2992             # GBK file test -f expr
2993             #
2994             sub Egbk::f(;*@) {
2995              
2996 0 0   0 0 0 local $_ = shift if @_;
2997 0 0 0     0 croak 'Too many arguments for -f (Egbk::f)' if @_ and not wantarray;
2998              
2999 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3000 0 0       0 return wantarray ? (-f _,@_) : -f _;
3001             }
3002             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3003 0 0       0 return wantarray ? (-f $fh,@_) : -f $fh;
3004             }
3005             elsif (-e $_) {
3006 0 0       0 return wantarray ? (-f _,@_) : -f _;
3007             }
3008             elsif (_MSWin32_5Cended_path($_)) {
3009 0 0       0 if (-d "$_/.") {
3010 0 0       0 return wantarray ? ('',@_) : '';
3011             }
3012             else {
3013 0         0 my $fh = gensym();
3014 0 0       0 if (_open_r($fh, $_)) {
3015 0         0 my $f = -f $fh;
3016 0 0       0 close($fh) or die "Can't close file: $_: $!";
3017 0 0       0 return wantarray ? ($f,@_) : $f;
3018             }
3019             }
3020             }
3021 0 0       0 return wantarray ? (undef,@_) : undef;
3022             }
3023              
3024             #
3025             # GBK file test -d expr
3026             #
3027             sub Egbk::d(;*@) {
3028              
3029 0 0   0 0 0 local $_ = shift if @_;
3030 0 0 0     0 croak 'Too many arguments for -d (Egbk::d)' if @_ and not wantarray;
3031              
3032 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3033 0 0       0 return wantarray ? (-d _,@_) : -d _;
3034             }
3035              
3036             # return false if file handle or directory handle
3037             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3038 0 0       0 return wantarray ? ('',@_) : '';
3039             }
3040             elsif (-e $_) {
3041 0 0       0 return wantarray ? (-d _,@_) : -d _;
3042             }
3043             elsif (_MSWin32_5Cended_path($_)) {
3044 0 0       0 return wantarray ? (-d "$_/.",@_) : -d "$_/.";
3045             }
3046 0 0       0 return wantarray ? (undef,@_) : undef;
3047             }
3048              
3049             #
3050             # GBK file test -l expr
3051             #
3052             sub Egbk::l(;*@) {
3053              
3054 0 0   0 0 0 local $_ = shift if @_;
3055 0 0 0     0 croak 'Too many arguments for -l (Egbk::l)' if @_ and not wantarray;
3056              
3057 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3058 0 0       0 return wantarray ? (-l _,@_) : -l _;
3059             }
3060             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3061 0 0       0 return wantarray ? (-l $fh,@_) : -l $fh;
3062             }
3063             elsif (-e $_) {
3064 0 0       0 return wantarray ? (-l _,@_) : -l _;
3065             }
3066             elsif (_MSWin32_5Cended_path($_)) {
3067 0 0       0 if (-d "$_/.") {
3068 0 0       0 return wantarray ? (-l _,@_) : -l _;
3069             }
3070             else {
3071 0         0 my $fh = gensym();
3072 0 0       0 if (_open_r($fh, $_)) {
3073 0         0 my $l = -l $fh;
3074 0 0       0 close($fh) or die "Can't close file: $_: $!";
3075 0 0       0 return wantarray ? ($l,@_) : $l;
3076             }
3077             }
3078             }
3079 0 0       0 return wantarray ? (undef,@_) : undef;
3080             }
3081              
3082             #
3083             # GBK file test -p expr
3084             #
3085             sub Egbk::p(;*@) {
3086              
3087 0 0   0 0 0 local $_ = shift if @_;
3088 0 0 0     0 croak 'Too many arguments for -p (Egbk::p)' if @_ and not wantarray;
3089              
3090 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3091 0 0       0 return wantarray ? (-p _,@_) : -p _;
3092             }
3093             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3094 0 0       0 return wantarray ? (-p $fh,@_) : -p $fh;
3095             }
3096             elsif (-e $_) {
3097 0 0       0 return wantarray ? (-p _,@_) : -p _;
3098             }
3099             elsif (_MSWin32_5Cended_path($_)) {
3100 0 0       0 if (-d "$_/.") {
3101 0 0       0 return wantarray ? (-p _,@_) : -p _;
3102             }
3103             else {
3104 0         0 my $fh = gensym();
3105 0 0       0 if (_open_r($fh, $_)) {
3106 0         0 my $p = -p $fh;
3107 0 0       0 close($fh) or die "Can't close file: $_: $!";
3108 0 0       0 return wantarray ? ($p,@_) : $p;
3109             }
3110             }
3111             }
3112 0 0       0 return wantarray ? (undef,@_) : undef;
3113             }
3114              
3115             #
3116             # GBK file test -S expr
3117             #
3118             sub Egbk::S(;*@) {
3119              
3120 0 0   0 0 0 local $_ = shift if @_;
3121 0 0 0     0 croak 'Too many arguments for -S (Egbk::S)' if @_ and not wantarray;
3122              
3123 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3124 0 0       0 return wantarray ? (-S _,@_) : -S _;
3125             }
3126             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3127 0 0       0 return wantarray ? (-S $fh,@_) : -S $fh;
3128             }
3129             elsif (-e $_) {
3130 0 0       0 return wantarray ? (-S _,@_) : -S _;
3131             }
3132             elsif (_MSWin32_5Cended_path($_)) {
3133 0 0       0 if (-d "$_/.") {
3134 0 0       0 return wantarray ? (-S _,@_) : -S _;
3135             }
3136             else {
3137 0         0 my $fh = gensym();
3138 0 0       0 if (_open_r($fh, $_)) {
3139 0         0 my $S = -S $fh;
3140 0 0       0 close($fh) or die "Can't close file: $_: $!";
3141 0 0       0 return wantarray ? ($S,@_) : $S;
3142             }
3143             }
3144             }
3145 0 0       0 return wantarray ? (undef,@_) : undef;
3146             }
3147              
3148             #
3149             # GBK file test -b expr
3150             #
3151             sub Egbk::b(;*@) {
3152              
3153 0 0   0 0 0 local $_ = shift if @_;
3154 0 0 0     0 croak 'Too many arguments for -b (Egbk::b)' if @_ and not wantarray;
3155              
3156 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3157 0 0       0 return wantarray ? (-b _,@_) : -b _;
3158             }
3159             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3160 0 0       0 return wantarray ? (-b $fh,@_) : -b $fh;
3161             }
3162             elsif (-e $_) {
3163 0 0       0 return wantarray ? (-b _,@_) : -b _;
3164             }
3165             elsif (_MSWin32_5Cended_path($_)) {
3166 0 0       0 if (-d "$_/.") {
3167 0 0       0 return wantarray ? (-b _,@_) : -b _;
3168             }
3169             else {
3170 0         0 my $fh = gensym();
3171 0 0       0 if (_open_r($fh, $_)) {
3172 0         0 my $b = -b $fh;
3173 0 0       0 close($fh) or die "Can't close file: $_: $!";
3174 0 0       0 return wantarray ? ($b,@_) : $b;
3175             }
3176             }
3177             }
3178 0 0       0 return wantarray ? (undef,@_) : undef;
3179             }
3180              
3181             #
3182             # GBK file test -c expr
3183             #
3184             sub Egbk::c(;*@) {
3185              
3186 0 0   0 0 0 local $_ = shift if @_;
3187 0 0 0     0 croak 'Too many arguments for -c (Egbk::c)' if @_ and not wantarray;
3188              
3189 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3190 0 0       0 return wantarray ? (-c _,@_) : -c _;
3191             }
3192             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3193 0 0       0 return wantarray ? (-c $fh,@_) : -c $fh;
3194             }
3195             elsif (-e $_) {
3196 0 0       0 return wantarray ? (-c _,@_) : -c _;
3197             }
3198             elsif (_MSWin32_5Cended_path($_)) {
3199 0 0       0 if (-d "$_/.") {
3200 0 0       0 return wantarray ? (-c _,@_) : -c _;
3201             }
3202             else {
3203 0         0 my $fh = gensym();
3204 0 0       0 if (_open_r($fh, $_)) {
3205 0         0 my $c = -c $fh;
3206 0 0       0 close($fh) or die "Can't close file: $_: $!";
3207 0 0       0 return wantarray ? ($c,@_) : $c;
3208             }
3209             }
3210             }
3211 0 0       0 return wantarray ? (undef,@_) : undef;
3212             }
3213              
3214             #
3215             # GBK file test -u expr
3216             #
3217             sub Egbk::u(;*@) {
3218              
3219 0 0   0 0 0 local $_ = shift if @_;
3220 0 0 0     0 croak 'Too many arguments for -u (Egbk::u)' if @_ and not wantarray;
3221              
3222 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3223 0 0       0 return wantarray ? (-u _,@_) : -u _;
3224             }
3225             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3226 0 0       0 return wantarray ? (-u $fh,@_) : -u $fh;
3227             }
3228             elsif (-e $_) {
3229 0 0       0 return wantarray ? (-u _,@_) : -u _;
3230             }
3231             elsif (_MSWin32_5Cended_path($_)) {
3232 0 0       0 if (-d "$_/.") {
3233 0 0       0 return wantarray ? (-u _,@_) : -u _;
3234             }
3235             else {
3236 0         0 my $fh = gensym();
3237 0 0       0 if (_open_r($fh, $_)) {
3238 0         0 my $u = -u $fh;
3239 0 0       0 close($fh) or die "Can't close file: $_: $!";
3240 0 0       0 return wantarray ? ($u,@_) : $u;
3241             }
3242             }
3243             }
3244 0 0       0 return wantarray ? (undef,@_) : undef;
3245             }
3246              
3247             #
3248             # GBK file test -g expr
3249             #
3250             sub Egbk::g(;*@) {
3251              
3252 0 0   0 0 0 local $_ = shift if @_;
3253 0 0 0     0 croak 'Too many arguments for -g (Egbk::g)' if @_ and not wantarray;
3254              
3255 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3256 0 0       0 return wantarray ? (-g _,@_) : -g _;
3257             }
3258             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3259 0 0       0 return wantarray ? (-g $fh,@_) : -g $fh;
3260             }
3261             elsif (-e $_) {
3262 0 0       0 return wantarray ? (-g _,@_) : -g _;
3263             }
3264             elsif (_MSWin32_5Cended_path($_)) {
3265 0 0       0 if (-d "$_/.") {
3266 0 0       0 return wantarray ? (-g _,@_) : -g _;
3267             }
3268             else {
3269 0         0 my $fh = gensym();
3270 0 0       0 if (_open_r($fh, $_)) {
3271 0         0 my $g = -g $fh;
3272 0 0       0 close($fh) or die "Can't close file: $_: $!";
3273 0 0       0 return wantarray ? ($g,@_) : $g;
3274             }
3275             }
3276             }
3277 0 0       0 return wantarray ? (undef,@_) : undef;
3278             }
3279              
3280             #
3281             # GBK file test -k expr
3282             #
3283             sub Egbk::k(;*@) {
3284              
3285 0 0   0 0 0 local $_ = shift if @_;
3286 0 0 0     0 croak 'Too many arguments for -k (Egbk::k)' if @_ and not wantarray;
3287              
3288 0 0       0 if ($_ eq '_') {
    0          
    0          
3289 0 0       0 return wantarray ? ('',@_) : '';
3290             }
3291             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3292 0 0       0 return wantarray ? ('',@_) : '';
3293             }
3294             elsif ($] =~ /^5\.008/oxms) {
3295 0 0       0 return wantarray ? ('',@_) : '';
3296             }
3297 0 0       0 return wantarray ? ($_,@_) : $_;
3298             }
3299              
3300             #
3301             # GBK file test -T expr
3302             #
3303             sub Egbk::T(;*@) {
3304              
3305 0 0   0 0 0 local $_ = shift if @_;
3306              
3307             # Use of croak without parentheses makes die on Strawberry Perl 5.008 and 5.010, like:
3308             # croak 'Too many arguments for -T (Egbk::T)';
3309             # Must be used by parentheses like:
3310             # croak('Too many arguments for -T (Egbk::T)');
3311              
3312 0 0 0     0 if (@_ and not wantarray) {
3313 0         0 croak('Too many arguments for -T (Egbk::T)');
3314             }
3315              
3316 0         0 my $T = 1;
3317              
3318 0         0 my $fh = qualify_to_ref $_;
3319 0 0       0 if (defined fileno $fh) {
3320              
3321 0     0   0 local $SIG{__WARN__} = sub {}; # telldir() attempted on invalid dirhandle at here
3322 0 0       0 if (defined Egbk::telldir($fh)) {
3323 0 0       0 return wantarray ? (undef,@_) : undef;
3324             }
3325              
3326             # P.813 29.2.176. tell
3327             # in Chapter 29: Functions
3328             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
3329              
3330             # P.970 tell
3331             # in Chapter 27: Functions
3332             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3333              
3334             # (and so on)
3335              
3336 0         0 my $systell = sysseek $fh, 0, 1;
3337              
3338 0 0       0 if (sysread $fh, my $block, 512) {
3339              
3340             # P.163 Binary file check in Little Perl Parlor 16
3341             # of Book No. T1008901080816 ZASSHI 08901-8 UNIX MAGAZINE 1993 Aug VOL8#8
3342             # (and so on)
3343              
3344 0 0       0 if ($block =~ /[\000\377]/oxms) {
    0          
3345 0         0 $T = '';
3346             }
3347             elsif (($block =~ tr/\000-\007\013\016-\032\034-\037\377//) * 10 > CORE::length $block) {
3348 0         0 $T = '';
3349             }
3350             }
3351              
3352             # 0 byte or eof
3353             else {
3354 0         0 $T = 1;
3355             }
3356              
3357 0         0 my $dummy_for_underline_cache = -T $fh;
3358 0         0 sysseek $fh, $systell, 0;
3359             }
3360             else {
3361 0 0 0     0 if (-d $_ or -d "$_/.") {
3362 0 0       0 return wantarray ? (undef,@_) : undef;
3363             }
3364              
3365 0         0 $fh = gensym();
3366 0 0       0 if (_open_r($fh, $_)) {
3367             }
3368             else {
3369 0 0       0 return wantarray ? (undef,@_) : undef;
3370             }
3371 0 0       0 if (sysread $fh, my $block, 512) {
3372 0 0       0 if ($block =~ /[\000\377]/oxms) {
    0          
3373 0         0 $T = '';
3374             }
3375             elsif (($block =~ tr/\000-\007\013\016-\032\034-\037\377//) * 10 > CORE::length $block) {
3376 0         0 $T = '';
3377             }
3378             }
3379              
3380             # 0 byte or eof
3381             else {
3382 0         0 $T = 1;
3383             }
3384 0         0 my $dummy_for_underline_cache = -T $fh;
3385 0 0       0 close($fh) or die "Can't close file: $_: $!";
3386             }
3387              
3388 0 0       0 return wantarray ? ($T,@_) : $T;
3389             }
3390              
3391             #
3392             # GBK file test -B expr
3393             #
3394             sub Egbk::B(;*@) {
3395              
3396 0 0   0 0 0 local $_ = shift if @_;
3397 0 0 0     0 croak 'Too many arguments for -B (Egbk::B)' if @_ and not wantarray;
3398 0         0 my $B = '';
3399              
3400 0         0 my $fh = qualify_to_ref $_;
3401 0 0       0 if (defined fileno $fh) {
3402              
3403 0     0   0 local $SIG{__WARN__} = sub {}; # telldir() attempted on invalid dirhandle at here
3404 0 0       0 if (defined Egbk::telldir($fh)) {
3405 0 0       0 return wantarray ? (undef,@_) : undef;
3406             }
3407              
3408 0         0 my $systell = sysseek $fh, 0, 1;
3409              
3410 0 0       0 if (sysread $fh, my $block, 512) {
3411 0 0       0 if ($block =~ /[\000\377]/oxms) {
    0          
3412 0         0 $B = 1;
3413             }
3414             elsif (($block =~ tr/\000-\007\013\016-\032\034-\037\377//) * 10 > CORE::length $block) {
3415 0         0 $B = 1;
3416             }
3417             }
3418              
3419             # 0 byte or eof
3420             else {
3421 0         0 $B = 1;
3422             }
3423              
3424 0         0 my $dummy_for_underline_cache = -B $fh;
3425 0         0 sysseek $fh, $systell, 0;
3426             }
3427             else {
3428 0 0 0     0 if (-d $_ or -d "$_/.") {
3429 0 0       0 return wantarray ? (undef,@_) : undef;
3430             }
3431              
3432 0         0 $fh = gensym();
3433 0 0       0 if (_open_r($fh, $_)) {
3434             }
3435             else {
3436 0 0       0 return wantarray ? (undef,@_) : undef;
3437             }
3438 0 0       0 if (sysread $fh, my $block, 512) {
3439 0 0       0 if ($block =~ /[\000\377]/oxms) {
    0          
3440 0         0 $B = 1;
3441             }
3442             elsif (($block =~ tr/\000-\007\013\016-\032\034-\037\377//) * 10 > CORE::length $block) {
3443 0         0 $B = 1;
3444             }
3445             }
3446              
3447             # 0 byte or eof
3448             else {
3449 0         0 $B = 1;
3450             }
3451 0         0 my $dummy_for_underline_cache = -B $fh;
3452 0 0       0 close($fh) or die "Can't close file: $_: $!";
3453             }
3454              
3455 0 0       0 return wantarray ? ($B,@_) : $B;
3456             }
3457              
3458             #
3459             # GBK file test -M expr
3460             #
3461             sub Egbk::M(;*@) {
3462              
3463 0 0   0 0 0 local $_ = shift if @_;
3464 0 0 0     0 croak 'Too many arguments for -M (Egbk::M)' if @_ and not wantarray;
3465              
3466 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3467 0 0       0 return wantarray ? (-M _,@_) : -M _;
3468             }
3469             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3470 0 0       0 return wantarray ? (-M $fh,@_) : -M $fh;
3471             }
3472             elsif (-e $_) {
3473 0 0       0 return wantarray ? (-M _,@_) : -M _;
3474             }
3475             elsif (_MSWin32_5Cended_path($_)) {
3476 0 0       0 if (-d "$_/.") {
3477 0 0       0 return wantarray ? (-M _,@_) : -M _;
3478             }
3479             else {
3480 0         0 my $fh = gensym();
3481 0 0       0 if (_open_r($fh, $_)) {
3482 0         0 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = CORE::stat $fh;
3483 0 0       0 close($fh) or die "Can't close file: $_: $!";
3484 0         0 my $M = ($^T - $mtime) / (24*60*60);
3485 0 0       0 return wantarray ? ($M,@_) : $M;
3486             }
3487             }
3488             }
3489 0 0       0 return wantarray ? (undef,@_) : undef;
3490             }
3491              
3492             #
3493             # GBK file test -A expr
3494             #
3495             sub Egbk::A(;*@) {
3496              
3497 0 0   0 0 0 local $_ = shift if @_;
3498 0 0 0     0 croak 'Too many arguments for -A (Egbk::A)' if @_ and not wantarray;
3499              
3500 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3501 0 0       0 return wantarray ? (-A _,@_) : -A _;
3502             }
3503             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3504 0 0       0 return wantarray ? (-A $fh,@_) : -A $fh;
3505             }
3506             elsif (-e $_) {
3507 0 0       0 return wantarray ? (-A _,@_) : -A _;
3508             }
3509             elsif (_MSWin32_5Cended_path($_)) {
3510 0 0       0 if (-d "$_/.") {
3511 0 0       0 return wantarray ? (-A _,@_) : -A _;
3512             }
3513             else {
3514 0         0 my $fh = gensym();
3515 0 0       0 if (_open_r($fh, $_)) {
3516 0         0 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = CORE::stat $fh;
3517 0 0       0 close($fh) or die "Can't close file: $_: $!";
3518 0         0 my $A = ($^T - $atime) / (24*60*60);
3519 0 0       0 return wantarray ? ($A,@_) : $A;
3520             }
3521             }
3522             }
3523 0 0       0 return wantarray ? (undef,@_) : undef;
3524             }
3525              
3526             #
3527             # GBK file test -C expr
3528             #
3529             sub Egbk::C(;*@) {
3530              
3531 0 0   0 0 0 local $_ = shift if @_;
3532 0 0 0     0 croak 'Too many arguments for -C (Egbk::C)' if @_ and not wantarray;
3533              
3534 0 0       0 if ($_ eq '_') {
    0          
    0          
    0          
3535 0 0       0 return wantarray ? (-C _,@_) : -C _;
3536             }
3537             elsif (defined fileno(my $fh = qualify_to_ref $_)) {
3538 0 0       0 return wantarray ? (-C $fh,@_) : -C $fh;
3539             }
3540             elsif (-e $_) {
3541 0 0       0 return wantarray ? (-C _,@_) : -C _;
3542             }
3543             elsif (_MSWin32_5Cended_path($_)) {
3544 0 0       0 if (-d "$_/.") {
3545 0 0       0 return wantarray ? (-C _,@_) : -C _;
3546             }
3547             else {
3548 0         0 my $fh = gensym();
3549 0 0       0 if (_open_r($fh, $_)) {
3550 0         0 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = CORE::stat $fh;
3551 0 0       0 close($fh) or die "Can't close file: $_: $!";
3552 0         0 my $C = ($^T - $ctime) / (24*60*60);
3553 0 0       0 return wantarray ? ($C,@_) : $C;
3554             }
3555             }
3556             }
3557 0 0       0 return wantarray ? (undef,@_) : undef;
3558             }
3559              
3560             #
3561             # GBK stacked file test $_
3562             #
3563             sub Egbk::filetest_ {
3564              
3565 0     0 0 0 my $filetest = substr(pop @_, 1);
3566              
3567 0 0       0 unless (CORE::eval qq{Egbk::${filetest}_}) {
3568 0         0 return '';
3569             }
3570 0         0 for my $filetest (CORE::reverse @_) {
3571 0 0       0 unless (CORE::eval qq{ $filetest _ }) {
3572 0         0 return '';
3573             }
3574             }
3575 0         0 return 1;
3576             }
3577              
3578             #
3579             # GBK file test -r $_
3580             #
3581             sub Egbk::r_() {
3582              
3583 0 0   0 0 0 if (-e $_) {
    0          
3584 0 0       0 return -r _ ? 1 : '';
3585             }
3586             elsif (_MSWin32_5Cended_path($_)) {
3587 0 0       0 if (-d "$_/.") {
3588 0 0       0 return -r _ ? 1 : '';
3589             }
3590             else {
3591 0         0 my $fh = gensym();
3592 0 0       0 if (_open_r($fh, $_)) {
3593 0         0 my $r = -r $fh;
3594 0 0       0 close($fh) or die "Can't close file: $_: $!";
3595 0 0       0 return $r ? 1 : '';
3596             }
3597             }
3598             }
3599              
3600             # 10.10. Returning Failure
3601             # in Chapter 10. Subroutines
3602             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3603             # (and so on)
3604              
3605             # 2010-01-26 The difference of "return;" and "return undef;"
3606             # http://d.hatena.ne.jp/gfx/20100126/1264474754
3607             #
3608             # "Perl Best Practices" recommends to use "return;"*1 to return nothing, but
3609             # it might be wrong in some cases. If you use this idiom for those functions
3610             # which are expected to return a scalar value, e.g. searching functions, the
3611             # user of those functions will be surprised at what they return in list
3612             # context, an empty list - note that many functions and all the methods
3613             # evaluate their arguments in list context. You'd better to use "return undef;"
3614             # for such scalar functions.
3615             #
3616             # sub search_something {
3617             # my($arg) = @_;
3618             # # search_something...
3619             # if(defined $found){
3620             # return $found;
3621             # }
3622             # return; # XXX: you'd better to "return undef;"
3623             # }
3624             #
3625             # # ...
3626             #
3627             # # you'll get what you want, but ...
3628             # my $something = search_something($source);
3629             #
3630             # # you won't get what you want here.
3631             # # @_ for doit() is (-foo => $opt), not (undef, -foo => $opt).
3632             # $obj->doit(search_something($source), -option=> $optval);
3633             #
3634             # # you have to use the "scalar" operator in such a case.
3635             # $obj->doit(scalar search_something($source), ...);
3636             #
3637             # *1: it returns an empty list in list context, or returns undef in scalar
3638             # context
3639             #
3640             # (and so on)
3641              
3642 0         0 return undef;
3643             }
3644              
3645             #
3646             # GBK file test -w $_
3647             #
3648             sub Egbk::w_() {
3649              
3650 0 0   0 0 0 if (-e $_) {
    0          
3651 0 0       0 return -w _ ? 1 : '';
3652             }
3653             elsif (_MSWin32_5Cended_path($_)) {
3654 0 0       0 if (-d "$_/.") {
3655 0 0       0 return -w _ ? 1 : '';
3656             }
3657             else {
3658 0         0 my $fh = gensym();
3659 0 0       0 if (_open_a($fh, $_)) {
3660 0         0 my $w = -w $fh;
3661 0 0       0 close($fh) or die "Can't close file: $_: $!";
3662 0 0       0 return $w ? 1 : '';
3663             }
3664             }
3665             }
3666 0         0 return undef;
3667             }
3668              
3669             #
3670             # GBK file test -x $_
3671             #
3672             sub Egbk::x_() {
3673              
3674 0 0   0 0 0 if (-e $_) {
    0          
3675 0 0       0 return -x _ ? 1 : '';
3676             }
3677             elsif (_MSWin32_5Cended_path($_)) {
3678 0 0       0 if (-d "$_/.") {
3679 0 0       0 return -x _ ? 1 : '';
3680             }
3681             else {
3682 0         0 my $fh = gensym();
3683 0 0       0 if (_open_r($fh, $_)) {
3684 0         0 my $dummy_for_underline_cache = -x $fh;
3685 0 0       0 close($fh) or die "Can't close file: $_: $!";
3686             }
3687              
3688             # filename is not .COM .EXE .BAT .CMD
3689 0         0 return '';
3690             }
3691             }
3692 0         0 return undef;
3693             }
3694              
3695             #
3696             # GBK file test -o $_
3697             #
3698             sub Egbk::o_() {
3699              
3700 0 0   0 0 0 if (-e $_) {
    0          
3701 0 0       0 return -o _ ? 1 : '';
3702             }
3703             elsif (_MSWin32_5Cended_path($_)) {
3704 0 0       0 if (-d "$_/.") {
3705 0 0       0 return -o _ ? 1 : '';
3706             }
3707             else {
3708 0         0 my $fh = gensym();
3709 0 0       0 if (_open_r($fh, $_)) {
3710 0         0 my $o = -o $fh;
3711 0 0       0 close($fh) or die "Can't close file: $_: $!";
3712 0 0       0 return $o ? 1 : '';
3713             }
3714             }
3715             }
3716 0         0 return undef;
3717             }
3718              
3719             #
3720             # GBK file test -R $_
3721             #
3722             sub Egbk::R_() {
3723              
3724 0 0   0 0 0 if (-e $_) {
    0          
3725 0 0       0 return -R _ ? 1 : '';
3726             }
3727             elsif (_MSWin32_5Cended_path($_)) {
3728 0 0       0 if (-d "$_/.") {
3729 0 0       0 return -R _ ? 1 : '';
3730             }
3731             else {
3732 0         0 my $fh = gensym();
3733 0 0       0 if (_open_r($fh, $_)) {
3734 0         0 my $R = -R $fh;
3735 0 0       0 close($fh) or die "Can't close file: $_: $!";
3736 0 0       0 return $R ? 1 : '';
3737             }
3738             }
3739             }
3740 0         0 return undef;
3741             }
3742              
3743             #
3744             # GBK file test -W $_
3745             #
3746             sub Egbk::W_() {
3747              
3748 0 0   0 0 0 if (-e $_) {
    0          
3749 0 0       0 return -W _ ? 1 : '';
3750             }
3751             elsif (_MSWin32_5Cended_path($_)) {
3752 0 0       0 if (-d "$_/.") {
3753 0 0       0 return -W _ ? 1 : '';
3754             }
3755             else {
3756 0         0 my $fh = gensym();
3757 0 0       0 if (_open_a($fh, $_)) {
3758 0         0 my $W = -W $fh;
3759 0 0       0 close($fh) or die "Can't close file: $_: $!";
3760 0 0       0 return $W ? 1 : '';
3761             }
3762             }
3763             }
3764 0         0 return undef;
3765             }
3766              
3767             #
3768             # GBK file test -X $_
3769             #
3770             sub Egbk::X_() {
3771              
3772 0 0   0 0 0 if (-e $_) {
    0          
3773 0 0       0 return -X _ ? 1 : '';
3774             }
3775             elsif (_MSWin32_5Cended_path($_)) {
3776 0 0       0 if (-d "$_/.") {
3777 0 0       0 return -X _ ? 1 : '';
3778             }
3779             else {
3780 0         0 my $fh = gensym();
3781 0 0       0 if (_open_r($fh, $_)) {
3782 0         0 my $dummy_for_underline_cache = -X $fh;
3783 0 0       0 close($fh) or die "Can't close file: $_: $!";
3784             }
3785              
3786             # filename is not .COM .EXE .BAT .CMD
3787 0         0 return '';
3788             }
3789             }
3790 0         0 return undef;
3791             }
3792              
3793             #
3794             # GBK file test -O $_
3795             #
3796             sub Egbk::O_() {
3797              
3798 0 0   0 0 0 if (-e $_) {
    0          
3799 0 0       0 return -O _ ? 1 : '';
3800             }
3801             elsif (_MSWin32_5Cended_path($_)) {
3802 0 0       0 if (-d "$_/.") {
3803 0 0       0 return -O _ ? 1 : '';
3804             }
3805             else {
3806 0         0 my $fh = gensym();
3807 0 0       0 if (_open_r($fh, $_)) {
3808 0         0 my $O = -O $fh;
3809 0 0       0 close($fh) or die "Can't close file: $_: $!";
3810 0 0       0 return $O ? 1 : '';
3811             }
3812             }
3813             }
3814 0         0 return undef;
3815             }
3816              
3817             #
3818             # GBK file test -e $_
3819             #
3820             sub Egbk::e_() {
3821              
3822 0 0   0 0 0 if (-e $_) {
    0          
3823 0         0 return 1;
3824             }
3825             elsif (_MSWin32_5Cended_path($_)) {
3826 0 0       0 if (-d "$_/.") {
3827 0         0 return 1;
3828             }
3829             else {
3830 0         0 my $fh = gensym();
3831 0 0       0 if (_open_r($fh, $_)) {
3832 0         0 my $e = -e $fh;
3833 0 0       0 close($fh) or die "Can't close file: $_: $!";
3834 0 0       0 return $e ? 1 : '';
3835             }
3836             }
3837             }
3838 0         0 return undef;
3839             }
3840              
3841             #
3842             # GBK file test -z $_
3843             #
3844             sub Egbk::z_() {
3845              
3846 0 0   0 0 0 if (-e $_) {
    0          
3847 0 0       0 return -z _ ? 1 : '';
3848             }
3849             elsif (_MSWin32_5Cended_path($_)) {
3850 0 0       0 if (-d "$_/.") {
3851 0 0       0 return -z _ ? 1 : '';
3852             }
3853             else {
3854 0         0 my $fh = gensym();
3855 0 0       0 if (_open_r($fh, $_)) {
3856 0         0 my $z = -z $fh;
3857 0 0       0 close($fh) or die "Can't close file: $_: $!";
3858 0 0       0 return $z ? 1 : '';
3859             }
3860             }
3861             }
3862 0         0 return undef;
3863             }
3864              
3865             #
3866             # GBK file test -s $_
3867             #
3868             sub Egbk::s_() {
3869              
3870 0 0   0 0 0 if (-e $_) {
    0          
3871 0         0 return -s _;
3872             }
3873             elsif (_MSWin32_5Cended_path($_)) {
3874 0 0       0 if (-d "$_/.") {
3875 0         0 return -s _;
3876             }
3877             else {
3878 0         0 my $fh = gensym();
3879 0 0       0 if (_open_r($fh, $_)) {
3880 0         0 my $s = -s $fh;
3881 0 0       0 close($fh) or die "Can't close file: $_: $!";
3882 0         0 return $s;
3883             }
3884             }
3885             }
3886 0         0 return undef;
3887             }
3888              
3889             #
3890             # GBK file test -f $_
3891             #
3892             sub Egbk::f_() {
3893              
3894 0 0   0 0 0 if (-e $_) {
    0          
3895 0 0       0 return -f _ ? 1 : '';
3896             }
3897             elsif (_MSWin32_5Cended_path($_)) {
3898 0 0       0 if (-d "$_/.") {
3899 0         0 return '';
3900             }
3901             else {
3902 0         0 my $fh = gensym();
3903 0 0       0 if (_open_r($fh, $_)) {
3904 0         0 my $f = -f $fh;
3905 0 0       0 close($fh) or die "Can't close file: $_: $!";
3906 0 0       0 return $f ? 1 : '';
3907             }
3908             }
3909             }
3910 0         0 return undef;
3911             }
3912              
3913             #
3914             # GBK file test -d $_
3915             #
3916             sub Egbk::d_() {
3917              
3918 0 0   0 0 0 if (-e $_) {
    0          
3919 0 0       0 return -d _ ? 1 : '';
3920             }
3921             elsif (_MSWin32_5Cended_path($_)) {
3922 0 0       0 return -d "$_/." ? 1 : '';
3923             }
3924 0         0 return undef;
3925             }
3926              
3927             #
3928             # GBK file test -l $_
3929             #
3930             sub Egbk::l_() {
3931              
3932 0 0   0 0 0 if (-e $_) {
    0          
3933 0 0       0 return -l _ ? 1 : '';
3934             }
3935             elsif (_MSWin32_5Cended_path($_)) {
3936 0 0       0 if (-d "$_/.") {
3937 0 0       0 return -l _ ? 1 : '';
3938             }
3939             else {
3940 0         0 my $fh = gensym();
3941 0 0       0 if (_open_r($fh, $_)) {
3942 0         0 my $l = -l $fh;
3943 0 0       0 close($fh) or die "Can't close file: $_: $!";
3944 0 0       0 return $l ? 1 : '';
3945             }
3946             }
3947             }
3948 0         0 return undef;
3949             }
3950              
3951             #
3952             # GBK file test -p $_
3953             #
3954             sub Egbk::p_() {
3955              
3956 0 0   0 0 0 if (-e $_) {
    0          
3957 0 0       0 return -p _ ? 1 : '';
3958             }
3959             elsif (_MSWin32_5Cended_path($_)) {
3960 0 0       0 if (-d "$_/.") {
3961 0 0       0 return -p _ ? 1 : '';
3962             }
3963             else {
3964 0         0 my $fh = gensym();
3965 0 0       0 if (_open_r($fh, $_)) {
3966 0         0 my $p = -p $fh;
3967 0 0       0 close($fh) or die "Can't close file: $_: $!";
3968 0 0       0 return $p ? 1 : '';
3969             }
3970             }
3971             }
3972 0         0 return undef;
3973             }
3974              
3975             #
3976             # GBK file test -S $_
3977             #
3978             sub Egbk::S_() {
3979              
3980 0 0   0 0 0 if (-e $_) {
    0          
3981 0 0       0 return -S _ ? 1 : '';
3982             }
3983             elsif (_MSWin32_5Cended_path($_)) {
3984 0 0       0 if (-d "$_/.") {
3985 0 0       0 return -S _ ? 1 : '';
3986             }
3987             else {
3988 0         0 my $fh = gensym();
3989 0 0       0 if (_open_r($fh, $_)) {
3990 0         0 my $S = -S $fh;
3991 0 0       0 close($fh) or die "Can't close file: $_: $!";
3992 0 0       0 return $S ? 1 : '';
3993             }
3994             }
3995             }
3996 0         0 return undef;
3997             }
3998              
3999             #
4000             # GBK file test -b $_
4001             #
4002             sub Egbk::b_() {
4003              
4004 0 0   0 0 0 if (-e $_) {
    0          
4005 0 0       0 return -b _ ? 1 : '';
4006             }
4007             elsif (_MSWin32_5Cended_path($_)) {
4008 0 0       0 if (-d "$_/.") {
4009 0 0       0 return -b _ ? 1 : '';
4010             }
4011             else {
4012 0         0 my $fh = gensym();
4013 0 0       0 if (_open_r($fh, $_)) {
4014 0         0 my $b = -b $fh;
4015 0 0       0 close($fh) or die "Can't close file: $_: $!";
4016 0 0       0 return $b ? 1 : '';
4017             }
4018             }
4019             }
4020 0         0 return undef;
4021             }
4022              
4023             #
4024             # GBK file test -c $_
4025             #
4026             sub Egbk::c_() {
4027              
4028 0 0   0 0 0 if (-e $_) {
    0          
4029 0 0       0 return -c _ ? 1 : '';
4030             }
4031             elsif (_MSWin32_5Cended_path($_)) {
4032 0 0       0 if (-d "$_/.") {
4033 0 0       0 return -c _ ? 1 : '';
4034             }
4035             else {
4036 0         0 my $fh = gensym();
4037 0 0       0 if (_open_r($fh, $_)) {
4038 0         0 my $c = -c $fh;
4039 0 0       0 close($fh) or die "Can't close file: $_: $!";
4040 0 0       0 return $c ? 1 : '';
4041             }
4042             }
4043             }
4044 0         0 return undef;
4045             }
4046              
4047             #
4048             # GBK file test -u $_
4049             #
4050             sub Egbk::u_() {
4051              
4052 0 0   0 0 0 if (-e $_) {
    0          
4053 0 0       0 return -u _ ? 1 : '';
4054             }
4055             elsif (_MSWin32_5Cended_path($_)) {
4056 0 0       0 if (-d "$_/.") {
4057 0 0       0 return -u _ ? 1 : '';
4058             }
4059             else {
4060 0         0 my $fh = gensym();
4061 0 0       0 if (_open_r($fh, $_)) {
4062 0         0 my $u = -u $fh;
4063 0 0       0 close($fh) or die "Can't close file: $_: $!";
4064 0 0       0 return $u ? 1 : '';
4065             }
4066             }
4067             }
4068 0         0 return undef;
4069             }
4070              
4071             #
4072             # GBK file test -g $_
4073             #
4074             sub Egbk::g_() {
4075              
4076 0 0   0 0 0 if (-e $_) {
    0          
4077 0 0       0 return -g _ ? 1 : '';
4078             }
4079             elsif (_MSWin32_5Cended_path($_)) {
4080 0 0       0 if (-d "$_/.") {
4081 0 0       0 return -g _ ? 1 : '';
4082             }
4083             else {
4084 0         0 my $fh = gensym();
4085 0 0       0 if (_open_r($fh, $_)) {
4086 0         0 my $g = -g $fh;
4087 0 0       0 close($fh) or die "Can't close file: $_: $!";
4088 0 0       0 return $g ? 1 : '';
4089             }
4090             }
4091             }
4092 0         0 return undef;
4093             }
4094              
4095             #
4096             # GBK file test -k $_
4097             #
4098             sub Egbk::k_() {
4099              
4100 0 0   0 0 0 if ($] =~ /^5\.008/oxms) {
4101 0 0       0 return wantarray ? ('',@_) : '';
4102             }
4103 0 0       0 return wantarray ? ($_,@_) : $_;
4104             }
4105              
4106             #
4107             # GBK file test -T $_
4108             #
4109             sub Egbk::T_() {
4110              
4111 0     0 0 0 my $T = 1;
4112              
4113 0 0 0     0 if (-d $_ or -d "$_/.") {
4114 0         0 return undef;
4115             }
4116 0         0 my $fh = gensym();
4117 0 0       0 if (_open_r($fh, $_)) {
4118             }
4119             else {
4120 0         0 return undef;
4121             }
4122              
4123 0 0       0 if (sysread $fh, my $block, 512) {
4124 0 0       0 if ($block =~ /[\000\377]/oxms) {
    0          
4125 0         0 $T = '';
4126             }
4127             elsif (($block =~ tr/\000-\007\013\016-\032\034-\037\377//) * 10 > CORE::length $block) {
4128 0         0 $T = '';
4129             }
4130             }
4131              
4132             # 0 byte or eof
4133             else {
4134 0         0 $T = 1;
4135             }
4136 0         0 my $dummy_for_underline_cache = -T $fh;
4137 0 0       0 close($fh) or die "Can't close file: $_: $!";
4138              
4139 0         0 return $T;
4140             }
4141              
4142             #
4143             # GBK file test -B $_
4144             #
4145             sub Egbk::B_() {
4146              
4147 0     0 0 0 my $B = '';
4148              
4149 0 0 0     0 if (-d $_ or -d "$_/.") {
4150 0         0 return undef;
4151             }
4152 0         0 my $fh = gensym();
4153 0 0       0 if (_open_r($fh, $_)) {
4154             }
4155             else {
4156 0         0 return undef;
4157             }
4158              
4159 0 0       0 if (sysread $fh, my $block, 512) {
4160 0 0       0 if ($block =~ /[\000\377]/oxms) {
    0          
4161 0         0 $B = 1;
4162             }
4163             elsif (($block =~ tr/\000-\007\013\016-\032\034-\037\377//) * 10 > CORE::length $block) {
4164 0         0 $B = 1;
4165             }
4166             }
4167              
4168             # 0 byte or eof
4169             else {
4170 0         0 $B = 1;
4171             }
4172 0         0 my $dummy_for_underline_cache = -B $fh;
4173 0 0       0 close($fh) or die "Can't close file: $_: $!";
4174              
4175 0         0 return $B;
4176             }
4177              
4178             #
4179             # GBK file test -M $_
4180             #
4181             sub Egbk::M_() {
4182              
4183 0 0   0 0 0 if (-e $_) {
    0          
4184 0         0 return -M _;
4185             }
4186             elsif (_MSWin32_5Cended_path($_)) {
4187 0 0       0 if (-d "$_/.") {
4188 0         0 return -M _;
4189             }
4190             else {
4191 0         0 my $fh = gensym();
4192 0 0       0 if (_open_r($fh, $_)) {
4193 0         0 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = CORE::stat $fh;
4194 0 0       0 close($fh) or die "Can't close file: $_: $!";
4195 0         0 my $M = ($^T - $mtime) / (24*60*60);
4196 0         0 return $M;
4197             }
4198             }
4199             }
4200 0         0 return undef;
4201             }
4202              
4203             #
4204             # GBK file test -A $_
4205             #
4206             sub Egbk::A_() {
4207              
4208 0 0   0 0 0 if (-e $_) {
    0          
4209 0         0 return -A _;
4210             }
4211             elsif (_MSWin32_5Cended_path($_)) {
4212 0 0       0 if (-d "$_/.") {
4213 0         0 return -A _;
4214             }
4215             else {
4216 0         0 my $fh = gensym();
4217 0 0       0 if (_open_r($fh, $_)) {
4218 0         0 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = CORE::stat $fh;
4219 0 0       0 close($fh) or die "Can't close file: $_: $!";
4220 0         0 my $A = ($^T - $atime) / (24*60*60);
4221 0         0 return $A;
4222             }
4223             }
4224             }
4225 0         0 return undef;
4226             }
4227              
4228             #
4229             # GBK file test -C $_
4230             #
4231             sub Egbk::C_() {
4232              
4233 0 0   0 0 0 if (-e $_) {
    0          
4234 0         0 return -C _;
4235             }
4236             elsif (_MSWin32_5Cended_path($_)) {
4237 0 0       0 if (-d "$_/.") {
4238 0         0 return -C _;
4239             }
4240             else {
4241 0         0 my $fh = gensym();
4242 0 0       0 if (_open_r($fh, $_)) {
4243 0         0 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = CORE::stat $fh;
4244 0 0       0 close($fh) or die "Can't close file: $_: $!";
4245 0         0 my $C = ($^T - $ctime) / (24*60*60);
4246 0         0 return $C;
4247             }
4248             }
4249             }
4250 0         0 return undef;
4251             }
4252              
4253             #
4254             # GBK path globbing (with parameter)
4255             #
4256             sub Egbk::glob($) {
4257              
4258 0 0   0 0 0 if (wantarray) {
4259 0         0 my @glob = _DOS_like_glob(@_);
4260 0         0 for my $glob (@glob) {
4261 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
4262             }
4263 0         0 return @glob;
4264             }
4265             else {
4266 0         0 my $glob = _DOS_like_glob(@_);
4267 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
4268 0         0 return $glob;
4269             }
4270             }
4271              
4272             #
4273             # GBK path globbing (without parameter)
4274             #
4275             sub Egbk::glob_() {
4276              
4277 0 0   0 0 0 if (wantarray) {
4278 0         0 my @glob = _DOS_like_glob();
4279 0         0 for my $glob (@glob) {
4280 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
4281             }
4282 0         0 return @glob;
4283             }
4284             else {
4285 0         0 my $glob = _DOS_like_glob();
4286 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
4287 0         0 return $glob;
4288             }
4289             }
4290              
4291             #
4292             # GBK path globbing via File::DosGlob 1.10
4293             #
4294             # Often I confuse "_dosglob" and "_doglob".
4295             # So, I renamed "_dosglob" to "_DOS_like_glob".
4296             #
4297             my %iter;
4298             my %entries;
4299             sub _DOS_like_glob {
4300              
4301             # context (keyed by second cxix argument provided by core)
4302 0     0   0 my($expr,$cxix) = @_;
4303              
4304             # glob without args defaults to $_
4305 0 0       0 $expr = $_ if not defined $expr;
4306              
4307             # represents the current user's home directory
4308             #
4309             # 7.3. Expanding Tildes in Filenames
4310             # in Chapter 7. File Access
4311             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
4312             #
4313             # and File::HomeDir, File::HomeDir::Windows module
4314              
4315             # DOS-like system
4316 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
4317 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
4318             { my_home_MSWin32() }oxmse;
4319             }
4320              
4321             # UNIX-like system
4322 0 0 0     0 else {
  0         0  
4323             $expr =~ s{ \A ~ ( (?:[^\x81-\xFE/]|[\x81-\xFE][\x00-\xFF])* ) }
4324             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
4325             }
4326 0 0       0  
4327 0 0       0 # assume global context if not provided one
4328             $cxix = '_G_' if not defined $cxix;
4329             $iter{$cxix} = 0 if not exists $iter{$cxix};
4330 0 0       0  
4331 0         0 # if we're just beginning, do it all first
4332             if ($iter{$cxix} == 0) {
4333             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
4334             }
4335 0 0       0  
4336 0         0 # chuck it all out, quick or slow
4337 0         0 if (wantarray) {
  0         0  
4338             delete $iter{$cxix};
4339             return @{delete $entries{$cxix}};
4340 0 0       0 }
  0         0  
4341 0         0 else {
  0         0  
4342             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
4343             return shift @{$entries{$cxix}};
4344             }
4345 0         0 else {
4346 0         0 # return undef for EOL
4347 0         0 delete $iter{$cxix};
4348             delete $entries{$cxix};
4349             return undef;
4350             }
4351             }
4352             }
4353              
4354             #
4355             # GBK path globbing subroutine
4356             #
4357 0     0   0 sub _do_glob {
4358 0         0  
4359 0         0 my($cond,@expr) = @_;
4360             my @glob = ();
4361             my $fix_drive_relative_paths = 0;
4362 0         0  
4363 0 0       0 OUTER:
4364 0 0       0 for my $expr (@expr) {
4365             next OUTER if not defined $expr;
4366 0         0 next OUTER if $expr eq '';
4367 0         0  
4368 0         0 my @matched = ();
4369 0         0 my @globdir = ();
4370 0         0 my $head = '.';
4371             my $pathsep = '/';
4372             my $tail;
4373 0 0       0  
4374 0         0 # if argument is within quotes strip em and do no globbing
4375 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
4376 0 0       0 $expr = $1;
4377 0         0 if ($cond eq 'd') {
4378             if (Egbk::d $expr) {
4379             push @glob, $expr;
4380             }
4381 0 0       0 }
4382 0         0 else {
4383             if (Egbk::e $expr) {
4384             push @glob, $expr;
4385 0         0 }
4386             }
4387             next OUTER;
4388             }
4389              
4390 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
4391 0 0       0 # to h:./*.pm to expand correctly
4392 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
4393             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^\x81-\xFE/\\]|[\x81-\xFE][\x00-\xFF]) #$1./$2#oxms) {
4394             $fix_drive_relative_paths = 1;
4395             }
4396 0 0       0 }
4397 0 0       0  
4398 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
4399 0         0 if ($tail eq '') {
4400             push @glob, $expr;
4401 0 0       0 next OUTER;
4402 0 0       0 }
4403 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
4404 0         0 if (@globdir = _do_glob('d', $head)) {
4405             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
4406             next OUTER;
4407 0 0 0     0 }
4408 0         0 }
4409             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
4410 0         0 $head .= $pathsep;
4411             }
4412             $expr = $tail;
4413             }
4414 0 0       0  
4415 0 0       0 # If file component has no wildcards, we can avoid opendir
4416 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
4417             if ($head eq '.') {
4418 0 0 0     0 $head = '';
4419 0         0 }
4420             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
4421 0         0 $head .= $pathsep;
4422 0 0       0 }
4423 0 0       0 $head .= $expr;
4424 0         0 if ($cond eq 'd') {
4425             if (Egbk::d $head) {
4426             push @glob, $head;
4427             }
4428 0 0       0 }
4429 0         0 else {
4430             if (Egbk::e $head) {
4431             push @glob, $head;
4432 0         0 }
4433             }
4434 0 0       0 next OUTER;
4435 0         0 }
4436 0         0 Egbk::opendir(*DIR, $head) or next OUTER;
4437             my @leaf = readdir DIR;
4438 0 0       0 closedir DIR;
4439 0         0  
4440             if ($head eq '.') {
4441 0 0 0     0 $head = '';
4442 0         0 }
4443             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
4444             $head .= $pathsep;
4445 0         0 }
4446 0         0  
4447 0         0 my $pattern = '';
4448             while ($expr =~ / \G ($q_char) /oxgc) {
4449             my $char = $1;
4450              
4451             # 6.9. Matching Shell Globs as Regular Expressions
4452             # in Chapter 6. Pattern Matching
4453             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
4454 0 0       0 # (and so on)
    0          
    0          
4455 0         0  
4456             if ($char eq '*') {
4457             $pattern .= "(?:$your_char)*",
4458 0         0 }
4459             elsif ($char eq '?') {
4460             $pattern .= "(?:$your_char)?", # DOS style
4461             # $pattern .= "(?:$your_char)", # UNIX style
4462 0         0 }
4463             elsif ((my $fc = Egbk::fc($char)) ne $char) {
4464             $pattern .= $fc;
4465 0         0 }
4466             else {
4467             $pattern .= quotemeta $char;
4468 0     0   0 }
  0         0  
4469             }
4470             my $matchsub = sub { Egbk::fc($_[0]) =~ /\A $pattern \z/xms };
4471              
4472             # if ($@) {
4473             # print STDERR "$0: $@\n";
4474             # next OUTER;
4475             # }
4476 0         0  
4477 0 0 0     0 INNER:
4478 0         0 for my $leaf (@leaf) {
4479             if ($leaf eq '.' or $leaf eq '..') {
4480 0 0 0     0 next INNER;
4481 0         0 }
4482             if ($cond eq 'd' and not Egbk::d "$head$leaf") {
4483             next INNER;
4484 0 0       0 }
4485 0         0  
4486 0         0 if (&$matchsub($leaf)) {
4487             push @matched, "$head$leaf";
4488             next INNER;
4489             }
4490              
4491             # [DOS compatibility special case]
4492 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
4493              
4494             if (Egbk::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
4495             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
4496 0 0       0 Egbk::index($pattern,'\\.') != -1 # pattern has a dot.
4497 0         0 ) {
4498 0         0 if (&$matchsub("$leaf.")) {
4499             push @matched, "$head$leaf";
4500             next INNER;
4501             }
4502 0 0       0 }
4503 0         0 }
4504             if (@matched) {
4505             push @glob, @matched;
4506 0 0       0 }
4507 0         0 }
4508 0         0 if ($fix_drive_relative_paths) {
4509             for my $glob (@glob) {
4510             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
4511 0         0 }
4512             }
4513             return @glob;
4514             }
4515              
4516             #
4517             # GBK parse line
4518             #
4519 0     0   0 sub _parse_line {
4520              
4521 0         0 my($line) = @_;
4522 0         0  
4523 0         0 $line .= ' ';
4524             my @piece = ();
4525             while ($line =~ /
4526             " ( (?>(?: [^\x81-\xFE"] |[\x81-\xFE][\x00-\xFF] )* ) ) " (?>\s+) |
4527             ( (?>(?: [^\x81-\xFE"\s]|[\x81-\xFE][\x00-\xFF] )* ) ) (?>\s+)
4528 0 0       0 /oxmsg
4529             ) {
4530 0         0 push @piece, defined($1) ? $1 : $2;
4531             }
4532             return @piece;
4533             }
4534              
4535             #
4536             # GBK parse path
4537             #
4538 0     0   0 sub _parse_path {
4539              
4540 0         0 my($path,$pathsep) = @_;
4541 0         0  
4542 0         0 $path .= '/';
4543             my @subpath = ();
4544             while ($path =~ /
4545             ((?: [^\x81-\xFE\/\\]|[\x81-\xFE][\x00-\xFF] )+?) [\/\\]
4546 0         0 /oxmsg
4547             ) {
4548             push @subpath, $1;
4549 0         0 }
4550 0         0  
4551 0         0 my $tail = pop @subpath;
4552             my $head = join $pathsep, @subpath;
4553             return $head, $tail;
4554             }
4555              
4556             #
4557             # via File::HomeDir::Windows 1.00
4558             #
4559             sub my_home_MSWin32 {
4560              
4561             # A lot of unix people and unix-derived tools rely on
4562 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
4563 0         0 # so that they can replace raw HOME calls with File::HomeDir.
4564             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
4565             return $ENV{'HOME'};
4566             }
4567              
4568 0         0 # Do we have a user profile?
4569             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
4570             return $ENV{'USERPROFILE'};
4571             }
4572              
4573 0         0 # Some Windows use something like $ENV{'HOME'}
4574             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
4575             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
4576 0         0 }
4577              
4578             return undef;
4579             }
4580              
4581             #
4582             # via File::HomeDir::Unix 1.00
4583 0     0 0 0 #
4584             sub my_home {
4585 0 0 0     0 my $home;
    0 0        
4586 0         0  
4587             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
4588             $home = $ENV{'HOME'};
4589             }
4590              
4591             # This is from the original code, but I'm guessing
4592 0         0 # it means "login directory" and exists on some Unixes.
4593             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
4594             $home = $ENV{'LOGDIR'};
4595             }
4596              
4597             ### More-desperate methods
4598              
4599 0         0 # Light desperation on any (Unixish) platform
4600             else {
4601             $home = CORE::eval q{ (getpwuid($<))[7] };
4602             }
4603              
4604 0 0 0     0 # On Unix in general, a non-existant home means "no home"
4605 0         0 # For example, "nobody"-like users might use /nonexistant
4606             if (defined $home and ! Egbk::d($home)) {
4607 0         0 $home = undef;
4608             }
4609             return $home;
4610             }
4611              
4612             #
4613             # GBK file lstat (with parameter)
4614             #
4615 0 0   0 0 0 sub Egbk::lstat(*) {
4616              
4617 0 0       0 local $_ = shift if @_;
    0          
4618 0         0  
4619             if (-e $_) {
4620             return CORE::lstat _;
4621             }
4622             elsif (_MSWin32_5Cended_path($_)) {
4623              
4624             # Even if ${^WIN32_SLOPPY_STAT} is set to a true value, Egbk::lstat()
4625             # on Windows opens the file for the path which has 5c at end.
4626 0         0 # (and so on)
4627 0 0       0  
4628 0 0       0 local *MUST_BE_BAREWORD_AT_HERE;
4629 0         0 if (CORE::open(MUST_BE_BAREWORD_AT_HERE, $_)) {
4630 0 0       0 if (wantarray) {
4631 0         0 my @stat = CORE::stat MUST_BE_BAREWORD_AT_HERE; # not CORE::lstat
4632             close(MUST_BE_BAREWORD_AT_HERE) or die "Can't close file: $_: $!";
4633             return @stat;
4634 0         0 }
4635 0 0       0 else {
4636 0         0 my $stat = CORE::stat MUST_BE_BAREWORD_AT_HERE; # not CORE::lstat
4637             close(MUST_BE_BAREWORD_AT_HERE) or die "Can't close file: $_: $!";
4638             return $stat;
4639             }
4640 0 0       0 }
4641             }
4642             return wantarray ? () : undef;
4643             }
4644              
4645             #
4646             # GBK file lstat (without parameter)
4647             #
4648 0 0   0 0 0 sub Egbk::lstat_() {
    0          
4649 0         0  
4650             if (-e $_) {
4651             return CORE::lstat _;
4652 0         0 }
4653 0 0       0 elsif (_MSWin32_5Cended_path($_)) {
4654 0 0       0 local *MUST_BE_BAREWORD_AT_HERE;
4655 0         0 if (CORE::open(MUST_BE_BAREWORD_AT_HERE, $_)) {
4656 0 0       0 if (wantarray) {
4657 0         0 my @stat = CORE::stat MUST_BE_BAREWORD_AT_HERE; # not CORE::lstat
4658             close(MUST_BE_BAREWORD_AT_HERE) or die "Can't close file: $_: $!";
4659             return @stat;
4660 0         0 }
4661 0 0       0 else {
4662 0         0 my $stat = CORE::stat MUST_BE_BAREWORD_AT_HERE; # not CORE::lstat
4663             close(MUST_BE_BAREWORD_AT_HERE) or die "Can't close file: $_: $!";
4664             return $stat;
4665             }
4666 0 0       0 }
4667             }
4668             return wantarray ? () : undef;
4669             }
4670              
4671             #
4672             # GBK path opendir
4673             #
4674 0     0 0 0 sub Egbk::opendir(*$) {
4675 0 0       0  
    0          
4676 0         0 my $dh = qualify_to_ref $_[0];
4677             if (CORE::opendir $dh, $_[1]) {
4678             return 1;
4679 0 0       0 }
4680 0         0 elsif (_MSWin32_5Cended_path($_[1])) {
4681             if (CORE::opendir $dh, "$_[1]/.") {
4682             return 1;
4683 0         0 }
4684             }
4685             return undef;
4686             }
4687              
4688             #
4689             # GBK file stat (with parameter)
4690             #
4691 0 50   386 0 0 sub Egbk::stat(*) {
4692              
4693 386         2184 local $_ = shift if @_;
4694 386 50       1987  
    50          
    0          
4695 386         13866 my $fh = qualify_to_ref $_;
4696             if (defined fileno $fh) {
4697             return CORE::stat $fh;
4698 0         0 }
4699             elsif (-e $_) {
4700             return CORE::stat _;
4701             }
4702             elsif (_MSWin32_5Cended_path($_)) {
4703              
4704             # Even if ${^WIN32_SLOPPY_STAT} is set to a true value, Egbk::stat()
4705             # on Windows opens the file for the path which has 5c at end.
4706 386         3283 # (and so on)
4707 0 0       0  
4708 0 0       0 local *MUST_BE_BAREWORD_AT_HERE;
4709 0         0 if (CORE::open(MUST_BE_BAREWORD_AT_HERE, $_)) {
4710 0 0       0 if (wantarray) {
4711 0         0 my @stat = CORE::stat MUST_BE_BAREWORD_AT_HERE;
4712             close(MUST_BE_BAREWORD_AT_HERE) or die "Can't close file: $_: $!";
4713             return @stat;
4714 0         0 }
4715 0 0       0 else {
4716 0         0 my $stat = CORE::stat MUST_BE_BAREWORD_AT_HERE;
4717             close(MUST_BE_BAREWORD_AT_HERE) or die "Can't close file: $_: $!";
4718             return $stat;
4719             }
4720 0 0       0 }
4721             }
4722             return wantarray ? () : undef;
4723             }
4724              
4725             #
4726             # GBK file stat (without parameter)
4727             #
4728 0     0 0 0 sub Egbk::stat_() {
4729 0 0       0  
    0          
    0          
4730 0         0 my $fh = qualify_to_ref $_;
4731             if (defined fileno $fh) {
4732             return CORE::stat $fh;
4733 0         0 }
4734             elsif (-e $_) {
4735             return CORE::stat _;
4736 0         0 }
4737 0 0       0 elsif (_MSWin32_5Cended_path($_)) {
4738 0 0       0 local *MUST_BE_BAREWORD_AT_HERE;
4739 0         0 if (CORE::open(MUST_BE_BAREWORD_AT_HERE, $_)) {
4740 0 0       0 if (wantarray) {
4741 0         0 my @stat = CORE::stat MUST_BE_BAREWORD_AT_HERE;
4742             close(MUST_BE_BAREWORD_AT_HERE) or die "Can't close file: $_: $!";
4743             return @stat;
4744 0         0 }
4745 0 0       0 else {
4746 0         0 my $stat = CORE::stat MUST_BE_BAREWORD_AT_HERE;
4747             close(MUST_BE_BAREWORD_AT_HERE) or die "Can't close file: $_: $!";
4748             return $stat;
4749             }
4750 0 0       0 }
4751             }
4752             return wantarray ? () : undef;
4753             }
4754              
4755             #
4756             # GBK path unlink
4757             #
4758 0 0   0 0 0 sub Egbk::unlink(@) {
4759              
4760 0         0 local @_ = ($_) unless @_;
4761 0         0  
4762 0 0       0 my $unlink = 0;
    0          
    0          
4763 0         0 for (@_) {
4764             if (CORE::unlink) {
4765             $unlink++;
4766             }
4767             elsif (Egbk::d($_)) {
4768 0         0 }
4769 0 0       0 elsif (_MSWin32_5Cended_path($_)) {
  0         0  
4770 0 0       0 my @char = /\G (?>$q_char) /oxmsg;
4771 0         0 my $file = join '', map {{'/' => '\\'}->{$_} || $_} @char;
4772             if ($file =~ / \A (?:$q_char)*? [ ] /oxms) {
4773 0         0 $file = qq{"$file"};
4774 0 0       0 }
4775 0 0       0 my $fh = gensym();
4776             if (_open_r($fh, $_)) {
4777             close($fh) or die "Can't close file: $_: $!";
4778 0 0 0     0  
    0          
4779 0         0 # cmd.exe on Windows NT, Windows 2000, Windows XP, Windows Vista, Windows 7, Windows 8, Windows 8.1, Windows 10 or later
4780             if ((defined $ENV{'OS'}) and ($ENV{'OS'} eq 'Windows_NT')) {
4781             CORE::system 'DEL', '/F', $file, '2>NUL';
4782             }
4783              
4784 0         0 # Win95Cmd.exe on any Windows (when SET PERL5SHELL=Win95Cmd.exe /c, `var` returns "Windows 2000")
4785             elsif (qx{ver} =~ /\b(?:Windows 2000)\b/oms) {
4786             CORE::system 'DEL', '/F', $file, '2>NUL';
4787             }
4788              
4789             # COMMAND.COM on Windows 95, Windows 98, Windows 98 Second Edition, Windows Millennium Edition
4790 0         0 # command.com can not "2>NUL"
4791 0         0 else {
4792             CORE::system 'ATTRIB', '-R', $file; # clears Read-only file attribute
4793             CORE::system 'DEL', $file;
4794 0 0       0 }
4795 0 0       0  
4796             if (_open_r($fh, $_)) {
4797             close($fh) or die "Can't close file: $_: $!";
4798 0         0 }
4799             else {
4800             $unlink++;
4801             }
4802             }
4803 0         0 }
4804             }
4805             return $unlink;
4806             }
4807              
4808             #
4809             # GBK chdir
4810             #
4811 0 0   0 0 0 sub Egbk::chdir(;$) {
4812 0         0  
4813             if (@_ == 0) {
4814             return CORE::chdir;
4815 0         0 }
4816              
4817 0 0       0 my($dir) = @_;
4818 0 0       0  
4819 0         0 if (_MSWin32_5Cended_path($dir)) {
4820             if (not Egbk::d $dir) {
4821             return 0;
4822 0 0 0     0 }
    0          
4823 0         0  
4824             if ($] =~ /^5\.005/oxms) {
4825             return CORE::chdir $dir;
4826 0         0 }
4827 0         0 elsif (($] =~ /^(?:5\.006|5\.008000)/oxms) and ($^O eq 'MSWin32')) {
4828             local $@;
4829             my $chdir = CORE::eval q{
4830             CORE::require 'jacode.pl';
4831              
4832             # P.676 ${^WIDE_SYSTEM_CALLS}
4833             # in Chapter 28: Special Names
4834             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4835              
4836             # P.790 ${^WIDE_SYSTEM_CALLS}
4837             # in Chapter 25: Special Names
4838             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4839              
4840             local ${^WIDE_SYSTEM_CALLS} = 1;
4841 0 0       0 return CORE::chdir jcode::utf8($dir,'sjis');
4842 0         0 };
4843             if (not $@) {
4844             return $chdir;
4845             }
4846             }
4847              
4848             # old idea (Win32 module required)
4849             elsif (0) {
4850             local $@;
4851             my $shortdir = '';
4852             my $chdir = CORE::eval q{
4853             use Win32;
4854             $shortdir = Win32::GetShortPathName($dir);
4855             if ($shortdir ne $dir) {
4856             return CORE::chdir $shortdir;
4857             }
4858             else {
4859             return 0;
4860             }
4861             };
4862             if ($@) {
4863             my @char = $dir =~ /\G (?>$q_char) /oxmsg;
4864             while ($char[-1] eq "\x5C") {
4865             pop @char;
4866             }
4867             $dir = join '', @char;
4868             croak "Perl$] can't chdir to $dir (chr(0x5C) ended path), Win32.pm module may help you";
4869             }
4870             elsif ($shortdir eq $dir) {
4871             my @char = $dir =~ /\G (?>$q_char) /oxmsg;
4872             while ($char[-1] eq "\x5C") {
4873             pop @char;
4874             }
4875             $dir = join '', @char;
4876             croak "Perl$] can't chdir to $dir (chr(0x5C) ended path)";
4877             }
4878             return $chdir;
4879             }
4880 0         0  
4881             # rejected idea ...
4882             elsif (0) {
4883              
4884             # MSDN SetCurrentDirectory function
4885             # http://msdn.microsoft.com/ja-jp/library/windows/desktop/aa365530(v=vs.85).aspx
4886             #
4887             # Data Execution Prevention (DEP)
4888             # http://vlaurie.com/computers2/Articles/dep.htm
4889             #
4890             # Learning x86 assembler with Perl -- Shibuya.pm#11
4891             # http://developer.cybozu.co.jp/takesako/2009/06/perl-x86-shibuy.html
4892             #
4893             # Introduction to Win32::API programming in Perl
4894             # http://d.hatena.ne.jp/TAKESAKO/20090324/1237879559
4895             #
4896             # DynaLoader - Dynamically load C libraries into Perl code
4897             # http://perldoc.perl.org/DynaLoader.html
4898             #
4899             # Basic knowledge of DynaLoader
4900             # http://blog.64p.org/entry/20090313/1236934042
4901              
4902             if (($] =~ /^5\.006/oxms) and
4903             ($^O eq 'MSWin32') and
4904             ($ENV{'PROCESSOR_ARCHITECTURE'} eq 'x86') and
4905             CORE::eval(q{CORE::require 'Dyna'.'Loader'})
4906             ) {
4907             my $x86 = join('',
4908              
4909             # PUSH Iv
4910             "\x68", pack('P', "$dir\\\0"),
4911              
4912             # MOV eAX, Iv
4913             "\xb8", pack('L',
4914             *{'Dyna'.'Loader::dl_find_symbol'}{'CODE'}->(
4915             *{'Dyna'.'Loader::dl_load_file'}{'CODE'}->("$ENV{'SystemRoot'}\\system32\\kernel32.dll"),
4916             'SetCurrentDirectoryA'
4917             )
4918             ),
4919              
4920             # CALL eAX
4921             "\xff\xd0",
4922              
4923             # RETN
4924             "\xc3",
4925             );
4926             *{'Dyna'.'Loader::dl_install_xsub'}{'CODE'}->('_SetCurrentDirectoryA', unpack('L', pack 'P', $x86));
4927             _SetCurrentDirectoryA();
4928             chomp(my $chdir = qx{chdir});
4929             if (Egbk::fc($chdir) eq Egbk::fc($dir)) {
4930             return 1;
4931             }
4932             else {
4933             return 0;
4934             }
4935             }
4936             }
4937              
4938             # COMMAND.COM's unhelpful tips:
4939             # Displays a list of files and subdirectories in a directory.
4940             # http://www.lagmonster.org/docs/DOS7/z-dir.html
4941             #
4942             # Syntax:
4943             #
4944             # DIR [drive:] [path] [filename] [/Switches]
4945             #
4946             # /Z Long file names are not displayed in the file listing
4947             #
4948             # Limitations
4949             # The undocumented /Z switch (no long names) would appear to
4950             # have been not fully developed and has a couple of problems:
4951             #
4952             # 1. It will only work if:
4953             # There is no path specified (ie. for the current directory in
4954             # the current drive)
4955             # The path is specified as the root directory of any drive
4956             # (eg. C:\, D:\, etc.)
4957             # The path is specified as the current directory of any drive
4958             # by using the drive letter only (eg. C:, D:, etc.)
4959             # The path is specified as the parent directory using the ..
4960             # notation (eg. DIR .. /Z)
4961             # Any other syntax results in a "File Not Found" error message.
4962             #
4963             # 2. The /Z switch is compatable with the /S switch to show
4964             # subdirectories (as long as the above rules are followed) and
4965             # all the files are shown with short names only. The
4966             # subdirectories are also shown with short names only. However,
4967             # the header for each subdirectory after the first level gives
4968             # the subdirectory's long name.
4969             #
4970             # 3. The /Z switch is also compatable with the /B switch to give
4971             # a simple list of files with short names only. When used with
4972             # the /S switch as well, all files are listed with their full
4973             # paths. The file names themselves are all in short form, and
4974             # the path of those files in the current directory are in short
4975             # form, but the paths of any files in subdirectories are in
4976 0         0 # long filename form.
4977 0         0  
4978 0         0 my $shortdir = '';
4979 0         0 my $i = 0;
4980 0         0 my @subdir = ();
4981 0 0 0     0 while ($dir =~ / \G ($q_char) /oxgc) {
4982 0         0 my $char = $1;
4983 0         0 if (($char eq '\\') or ($char eq '/')) {
4984 0         0 $i++;
4985             $subdir[$i] = $char;
4986             $i++;
4987 0         0 }
4988             else {
4989             $subdir[$i] .= $char;
4990 0 0 0     0 }
4991 0         0 }
4992             if (($subdir[-1] eq '\\') or ($subdir[-1] eq '/')) {
4993             pop @subdir;
4994             }
4995              
4996             # P.504 PERL5SHELL (Microsoft ports only)
4997             # in Chapter 19: The Command-Line Interface
4998             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4999              
5000             # P.597 PERL5SHELL (Microsoft ports only)
5001             # in Chapter 17: The Command-Line Interface
5002             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5003              
5004 0 0 0     0 # Win95Cmd.exe on any Windows (when SET PERL5SHELL=Win95Cmd.exe /c, `var` returns "Windows 2000")
    0          
5005 0         0 # cmd.exe on Windows NT, Windows 2000
5006 0         0 if (qx{ver} =~ /\b(?:Windows NT|Windows 2000)\b/oms) {
  0         0  
5007 0 0       0 chomp(my @dirx = grep //oxms, qx{dir /ad /x "$dir*" 2>NUL});
5008             for my $dirx (sort { CORE::length($a) <=> CORE::length($b) } @dirx) {
5009             if (Egbk::fc(CORE::substr $dirx,-CORE::length($subdir[-1]),CORE::length($subdir[-1])) eq Egbk::fc($subdir[-1])) {
5010 0         0  
5011 0         0 # short file name (8dot3name) here-----vv
5012 0         0 my $shortleafdir = CORE::substr $dirx, 39, 8+1+3;
5013 0         0 $shortleafdir =~ s/ [ ]+ \z//oxms;
5014             $shortdir = join '', @subdir[0..$#subdir-1], $shortleafdir;
5015             last;
5016             }
5017             }
5018             }
5019              
5020             # an idea (not so portable, only Windows 2000 or later)
5021             elsif (0) {
5022             chomp($shortdir = qx{for %I in ("$dir") do \@echo %~sI 2>NUL});
5023             }
5024              
5025 0         0 # cmd.exe on Windows XP, Windows Vista, Windows 7, Windows 8, Windows 8.1, Windows 10 or later
5026 0         0 elsif ((defined $ENV{'OS'}) and ($ENV{'OS'} eq 'Windows_NT')) {
  0         0  
5027 0 0       0 chomp(my @dirx = grep //oxms, qx{dir /ad /x "$dir*" 2>NUL});
5028             for my $dirx (sort { CORE::length($a) <=> CORE::length($b) } @dirx) {
5029             if (Egbk::fc(CORE::substr $dirx,-CORE::length($subdir[-1]),CORE::length($subdir[-1])) eq Egbk::fc($subdir[-1])) {
5030 0         0  
5031 0         0 # short file name (8dot3name) here-----vv
5032 0         0 my $shortleafdir = CORE::substr $dirx, 36, 8+1+3;
5033 0         0 $shortleafdir =~ s/ [ ]+ \z//oxms;
5034             $shortdir = join '', @subdir[0..$#subdir-1], $shortleafdir;
5035             last;
5036             }
5037             }
5038             }
5039              
5040 0         0 # COMMAND.COM on Windows 95, Windows 98, Windows 98 Second Edition, Windows Millennium Edition
5041 0         0 else {
  0         0  
5042 0 0       0 chomp(my @dirx = grep //oxms, qx{dir /ad "$dir*"});
5043             for my $dirx (sort { CORE::length($a) <=> CORE::length($b) } @dirx) {
5044             if (Egbk::fc(CORE::substr $dirx,-CORE::length($subdir[-1]),CORE::length($subdir[-1])) eq Egbk::fc($subdir[-1])) {
5045 0         0  
5046 0         0 # short file name (8dot3name) here-----v
5047 0         0 my $shortleafdir = CORE::substr $dirx, 0, 8+1+3;
5048 0         0 CORE::substr($shortleafdir,8,1) = '.';
5049 0         0 $shortleafdir =~ s/ \. [ ]+ \z//oxms;
5050             $shortdir = join '', @subdir[0..$#subdir-1], $shortleafdir;
5051             last;
5052             }
5053             }
5054 0 0       0 }
    0          
5055 0         0  
5056             if ($shortdir eq '') {
5057             return 0;
5058 0         0 }
5059             elsif (Egbk::fc($shortdir) eq Egbk::fc($dir)) {
5060 0         0 return 0;
5061             }
5062             return CORE::chdir $shortdir;
5063 0         0 }
5064             else {
5065             return CORE::chdir $dir;
5066             }
5067             }
5068              
5069             #
5070             # GBK chr(0x5C) ended path on MSWin32
5071             #
5072 0 50 33 772   0 sub _MSWin32_5Cended_path {
5073 772 50       5117  
5074 772         4234 if ((@_ >= 1) and ($_[0] ne '')) {
5075 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
5076 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
5077             if ($char[-1] =~ / \x5C \z/oxms) {
5078             return 1;
5079             }
5080 0         0 }
5081             }
5082             return undef;
5083             }
5084              
5085             #
5086             # do GBK file
5087             #
5088 772     0 0 1920 sub Egbk::do($) {
5089              
5090 0         0 my($filename) = @_;
5091              
5092             my $realfilename;
5093             my $result;
5094 0         0 ITER_DO:
  0         0  
5095 0 0       0 {
5096 0         0 for my $prefix (@INC) {
5097             if ($^O eq 'MacOS') {
5098             $realfilename = "$prefix$filename";
5099 0         0 }
5100             else {
5101             $realfilename = "$prefix/$filename";
5102 0 0       0 }
5103              
5104 0         0 if (Egbk::f($realfilename)) {
5105              
5106 0 0       0 my $script = '';
5107 0         0  
5108 0         0 if (Egbk::e("$realfilename.e")) {
5109 0         0 my $e_mtime = (Egbk::stat("$realfilename.e"))[9];
5110 0 0 0     0 my $mtime = (Egbk::stat($realfilename))[9];
5111 0         0 my $module_mtime = (Egbk::stat(__FILE__))[9];
5112             if (($e_mtime < $mtime) or ($mtime < $module_mtime)) {
5113             Egbk::unlink "$realfilename.e";
5114             }
5115 0 0       0 }
5116 0         0  
5117 0 0       0 if (Egbk::e("$realfilename.e")) {
5118 0 0       0 my $fh = gensym();
    0          
5119 0         0 if (_open_r($fh, "$realfilename.e")) {
5120             if ($^O eq 'MacOS') {
5121             CORE::eval q{
5122             CORE::require Mac::Files;
5123             Mac::Files::FSpSetFLock("$realfilename.e");
5124             };
5125             }
5126             elsif (exists $ENV{'CHAR_NONBLOCK'}) {
5127              
5128             # P.419 File Locking
5129             # in Chapter 16: Interprocess Communication
5130             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5131              
5132             # P.524 File Locking
5133             # in Chapter 15: Interprocess Communication
5134             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5135              
5136 0         0 # (and so on)
5137 0 0       0  
5138 0         0 CORE::eval q{ flock($fh, LOCK_SH | LOCK_NB) };
5139             if ($@) {
5140             carp "Can't immediately read-lock the file: $realfilename.e";
5141             }
5142 0         0 }
5143             else {
5144 0         0 CORE::eval q{ flock($fh, LOCK_SH) };
5145 0         0 }
5146 0 0       0 local $/ = undef; # slurp mode
5147 0         0 $script = <$fh>;
5148             if ($^O eq 'MacOS') {
5149             CORE::eval q{
5150             CORE::require Mac::Files;
5151             Mac::Files::FSpRstFLock("$realfilename.e");
5152 0 0       0 };
5153             }
5154             close($fh) or die "Can't close file: $realfilename.e: $!";
5155             }
5156 0         0 }
5157 0 0       0 else {
5158 0 0       0 my $fh = gensym();
    0          
5159 0         0 if (_open_r($fh, $realfilename)) {
5160             if ($^O eq 'MacOS') {
5161             CORE::eval q{
5162             CORE::require Mac::Files;
5163             Mac::Files::FSpSetFLock($realfilename);
5164             };
5165 0         0 }
5166 0 0       0 elsif (exists $ENV{'CHAR_NONBLOCK'}) {
5167 0         0 CORE::eval q{ flock($fh, LOCK_SH | LOCK_NB) };
5168             if ($@) {
5169             carp "Can't immediately read-lock the file: $realfilename";
5170             }
5171 0         0 }
5172             else {
5173 0         0 CORE::eval q{ flock($fh, LOCK_SH) };
5174 0         0 }
5175 0 0       0 local $/ = undef; # slurp mode
5176 0         0 $script = <$fh>;
5177             if ($^O eq 'MacOS') {
5178             CORE::eval q{
5179             CORE::require Mac::Files;
5180             Mac::Files::FSpRstFLock($realfilename);
5181 0 0       0 };
5182             }
5183             close($fh) or die "Can't close file: $realfilename.e: $!";
5184 0 0       0 }
5185 0         0  
5186 0         0 if ($script =~ /^ (?>\s*) use (?>\s+) GBK (?>\s*) ([^\x81-\xFE;]*) ; (?>\s*) \n? $/oxms) {
5187 0         0 CORE::require GBK;
5188 0 0       0 $script = GBK::escape_script($script);
5189 0 0       0 my $fh = gensym();
    0          
5190 0         0 open($fh, ">$realfilename.e") or die __FILE__, ": Can't write open file: $realfilename.e\n";
5191             if ($^O eq 'MacOS') {
5192             CORE::eval q{
5193             CORE::require Mac::Files;
5194             Mac::Files::FSpSetFLock("$realfilename.e");
5195             };
5196 0         0 }
5197 0 0       0 elsif (exists $ENV{'CHAR_NONBLOCK'}) {
5198 0         0 CORE::eval q{ flock($fh, LOCK_EX | LOCK_NB) };
5199             if ($@) {
5200             carp "Can't immediately write-lock the file: $realfilename.e";
5201             }
5202 0         0 }
5203             else {
5204 0         0 CORE::eval q{ flock($fh, LOCK_EX) };
5205 0 0       0 }
5206 0         0 CORE::eval q{ truncate($fh, 0) };
  0         0  
5207 0 0       0 seek($fh, 0, 0) or croak "Can't seek file: $realfilename.e";
5208 0         0 print {$fh} $script;
5209             if ($^O eq 'MacOS') {
5210             CORE::eval q{
5211             CORE::require Mac::Files;
5212             Mac::Files::FSpRstFLock("$realfilename.e");
5213 0 0       0 };
5214             }
5215             close($fh) or die "Can't close file: $realfilename.e: $!";
5216             }
5217             }
5218 391     391   6171  
  391         2330  
  391         325398  
  0         0  
5219 0         0 {
5220             no strict;
5221 0         0 $result = scalar CORE::eval $script;
5222             }
5223             last ITER_DO;
5224             }
5225             }
5226 0 0       0 }
    0          
5227 0         0  
5228 0         0 if ($@) {
5229             $INC{$filename} = undef;
5230             return undef;
5231 0         0 }
5232             elsif (not $result) {
5233             return undef;
5234 0         0 }
5235 0         0 else {
5236             $INC{$filename} = $realfilename;
5237             return $result;
5238             }
5239             }
5240              
5241             #
5242             # require GBK file
5243             #
5244              
5245             # require
5246             # in Chapter 3: Functions
5247             # of ISBN 1-56592-149-6 Programming Perl, Second Edition.
5248             #
5249             # sub require {
5250             # my($filename) = @_;
5251             # return 1 if $INC{$filename};
5252             # my($realfilename, $result);
5253             # ITER: {
5254             # foreach $prefix (@INC) {
5255             # $realfilename = "$prefix/$filename";
5256             # if (-f $realfilename) {
5257             # $result = CORE::eval `cat $realfilename`;
5258             # last ITER;
5259             # }
5260             # }
5261             # die "Can't find $filename in \@INC";
5262             # }
5263             # die $@ if $@;
5264             # die "$filename did not return true value" unless $result;
5265             # $INC{$filename} = $realfilename;
5266             # return $result;
5267             # }
5268              
5269             # require
5270             # in Chapter 9: perlfunc: Perl builtin functions
5271             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
5272             #
5273             # sub require {
5274             # my($filename) = @_;
5275             # if (exists $INC{$filename}) {
5276             # return 1 if $INC{$filename};
5277             # die "Compilation failed in require";
5278             # }
5279             # my($realfilename, $result);
5280             # ITER: {
5281             # foreach $prefix (@INC) {
5282             # $realfilename = "$prefix/$filename";
5283             # if (-f $realfilename) {
5284             # $INC{$filename} = $realfilename;
5285             # $result = do $realfilename;
5286             # last ITER;
5287             # }
5288             # }
5289             # die "Can't find $filename in \@INC";
5290             # }
5291             # if ($@) {
5292             # $INC{$filename} = undef;
5293             # die $@;
5294             # }
5295             # elsif (!$result) {
5296             # delete $INC{$filename};
5297             # die "$filename did not return true value";
5298             # }
5299             # else {
5300             # return $result;
5301             # }
5302             # }
5303              
5304 0 0   0 0 0 sub Egbk::require(;$) {
5305              
5306 0 0       0 local $_ = shift if @_;
5307 0 0       0  
5308 0         0 if (exists $INC{$_}) {
5309             return 1 if $INC{$_};
5310             croak "Compilation failed in require: $_";
5311             }
5312              
5313             # jcode.pl
5314             # ftp://ftp.iij.ad.jp/pub/IIJ/dist/utashiro/perl/
5315              
5316             # jacode.pl
5317 0 0       0 # http://search.cpan.org/dist/jacode/
5318 0         0  
5319             if (/ \b (?: jcode\.pl | jacode(?>[0-9]*)\.pl ) \z /oxms) {
5320             return CORE::require($_);
5321 0         0 }
5322              
5323             my $realfilename;
5324             my $result;
5325 0         0 ITER_REQUIRE:
  0         0  
5326 0 0       0 {
5327 0         0 for my $prefix (@INC) {
5328             if ($^O eq 'MacOS') {
5329             $realfilename = "$prefix$_";
5330 0         0 }
5331             else {
5332             $realfilename = "$prefix/$_";
5333 0 0       0 }
5334 0         0  
5335             if (Egbk::f($realfilename)) {
5336 0         0 $INC{$_} = $realfilename;
5337              
5338 0 0       0 my $script = '';
5339 0         0  
5340 0         0 if (Egbk::e("$realfilename.e")) {
5341 0         0 my $e_mtime = (Egbk::stat("$realfilename.e"))[9];
5342 0 0 0     0 my $mtime = (Egbk::stat($realfilename))[9];
5343 0         0 my $module_mtime = (Egbk::stat(__FILE__))[9];
5344             if (($e_mtime < $mtime) or ($mtime < $module_mtime)) {
5345             Egbk::unlink "$realfilename.e";
5346             }
5347 0 0       0 }
5348 0         0  
5349 0 0       0 if (Egbk::e("$realfilename.e")) {
5350 0 0       0 my $fh = gensym();
    0          
5351 0         0 _open_r($fh, "$realfilename.e") or croak "Can't open file: $realfilename.e";
5352             if ($^O eq 'MacOS') {
5353             CORE::eval q{
5354             CORE::require Mac::Files;
5355             Mac::Files::FSpSetFLock("$realfilename.e");
5356             };
5357 0         0 }
5358 0 0       0 elsif (exists $ENV{'CHAR_NONBLOCK'}) {
5359 0         0 CORE::eval q{ flock($fh, LOCK_SH | LOCK_NB) };
5360             if ($@) {
5361             carp "Can't immediately read-lock the file: $realfilename.e";
5362             }
5363 0         0 }
5364             else {
5365 0         0 CORE::eval q{ flock($fh, LOCK_SH) };
5366 0         0 }
5367 0 0       0 local $/ = undef; # slurp mode
5368 0         0 $script = <$fh>;
5369             if ($^O eq 'MacOS') {
5370             CORE::eval q{
5371             CORE::require Mac::Files;
5372             Mac::Files::FSpRstFLock("$realfilename.e");
5373 0 0       0 };
5374             }
5375             close($fh) or croak "Can't close file: $realfilename: $!";
5376 0         0 }
5377 0 0       0 else {
5378 0 0       0 my $fh = gensym();
    0          
5379 0         0 _open_r($fh, $realfilename) or croak "Can't open file: $realfilename";
5380             if ($^O eq 'MacOS') {
5381             CORE::eval q{
5382             CORE::require Mac::Files;
5383             Mac::Files::FSpSetFLock($realfilename);
5384             };
5385 0         0 }
5386 0 0       0 elsif (exists $ENV{'CHAR_NONBLOCK'}) {
5387 0         0 CORE::eval q{ flock($fh, LOCK_SH | LOCK_NB) };
5388             if ($@) {
5389             carp "Can't immediately read-lock the file: $realfilename";
5390             }
5391 0         0 }
5392             else {
5393 0         0 CORE::eval q{ flock($fh, LOCK_SH) };
5394 0         0 }
5395 0 0       0 local $/ = undef; # slurp mode
5396 0         0 $script = <$fh>;
5397             if ($^O eq 'MacOS') {
5398             CORE::eval q{
5399             CORE::require Mac::Files;
5400             Mac::Files::FSpRstFLock($realfilename);
5401 0 0       0 };
5402             }
5403 0 0       0 close($fh) or croak "Can't close file: $realfilename: $!";
5404 0         0  
5405 0         0 if ($script =~ /^ (?>\s*) use (?>\s+) GBK (?>\s*) ([^\x81-\xFE;]*) ; (?>\s*) \n? $/oxms) {
5406 0         0 CORE::require GBK;
5407 0 0       0 $script = GBK::escape_script($script);
5408 0 0       0 my $fh = gensym();
    0          
5409 0         0 open($fh, ">$realfilename.e") or croak "Can't write open file: $realfilename.e";
5410             if ($^O eq 'MacOS') {
5411             CORE::eval q{
5412             CORE::require Mac::Files;
5413             Mac::Files::FSpSetFLock("$realfilename.e");
5414             };
5415 0         0 }
5416 0 0       0 elsif (exists $ENV{'CHAR_NONBLOCK'}) {
5417 0         0 CORE::eval q{ flock($fh, LOCK_EX | LOCK_NB) };
5418             if ($@) {
5419             carp "Can't immediately write-lock the file: $realfilename.e";
5420             }
5421 0         0 }
5422             else {
5423 0         0 CORE::eval q{ flock($fh, LOCK_EX) };
5424 0 0       0 }
5425 0         0 CORE::eval q{ truncate($fh, 0) };
  0         0  
5426 0 0       0 seek($fh, 0, 0) or croak "Can't seek file: $realfilename.e";
5427 0         0 print {$fh} $script;
5428             if ($^O eq 'MacOS') {
5429             CORE::eval q{
5430             CORE::require Mac::Files;
5431             Mac::Files::FSpRstFLock("$realfilename.e");
5432 0 0       0 };
5433             }
5434             close($fh) or croak "Can't close file: $realfilename: $!";
5435             }
5436             }
5437 391     391   4757  
  391         865  
  391         371969  
  0         0  
5438 0         0 {
5439             no strict;
5440 0         0 $result = scalar CORE::eval $script;
5441             }
5442             last ITER_REQUIRE;
5443 0         0 }
5444             }
5445             croak "Can't find $_ in \@INC";
5446 0 0       0 }
    0          
5447 0         0  
5448 0         0 if ($@) {
5449             $INC{$_} = undef;
5450             croak $@;
5451 0         0 }
5452 0         0 elsif (not $result) {
5453             delete $INC{$_};
5454             croak "$_ did not return true value";
5455 0         0 }
5456             else {
5457             return $result;
5458             }
5459             }
5460              
5461             #
5462             # GBK telldir avoid warning
5463             #
5464 0     772 0 0 sub Egbk::telldir(*) {
5465              
5466 772         2111 local $^W = 0;
5467              
5468             return CORE::telldir $_[0];
5469             }
5470              
5471             #
5472             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
5473 772 0   0 0 10359 #
5474 0 0 0     0 sub Egbk::PREMATCH {
5475 0         0 if (defined($&)) {
5476             if (defined($1) and (CORE::substr($&,-CORE::length($1),CORE::length($1)) eq $1)) {
5477             return CORE::substr($&,0,CORE::length($&)-CORE::length($1));
5478 0         0 }
5479             else {
5480             croak 'Use of "$`", $PREMATCH, and ${^PREMATCH} need to /( capture all )/ in regexp';
5481             }
5482 0         0 }
5483             else {
5484 0         0 return '';
5485             }
5486             return $`;
5487             }
5488              
5489             #
5490             # ${^MATCH}, $MATCH, $& the string that matched
5491 0 0   0 0 0 #
5492 0 0       0 sub Egbk::MATCH {
5493 0         0 if (defined($&)) {
5494             if (defined($1)) {
5495             return $1;
5496 0         0 }
5497             else {
5498             croak 'Use of "$&", $MATCH, and ${^MATCH} need to /( capture all )/ in regexp';
5499             }
5500 0         0 }
5501             else {
5502 0         0 return '';
5503             }
5504             return $&;
5505             }
5506              
5507             #
5508             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
5509 0     0 0 0 #
5510             sub Egbk::POSTMATCH {
5511             return $';
5512             }
5513              
5514             #
5515             # GBK character to order (with parameter)
5516             #
5517 0 0   0 1 0 sub GBK::ord(;$) {
5518              
5519 0 0       0 local $_ = shift if @_;
5520 0         0  
5521 0         0 if (/\A ($q_char) /oxms) {
5522 0         0 my @ord = unpack 'C*', $1;
5523 0         0 my $ord = 0;
5524             while (my $o = shift @ord) {
5525 0         0 $ord = $ord * 0x100 + $o;
5526             }
5527             return $ord;
5528 0         0 }
5529             else {
5530             return CORE::ord $_;
5531             }
5532             }
5533              
5534             #
5535             # GBK character to order (without parameter)
5536             #
5537 0 0   0 0 0 sub GBK::ord_() {
5538 0         0  
5539 0         0 if (/\A ($q_char) /oxms) {
5540 0         0 my @ord = unpack 'C*', $1;
5541 0         0 my $ord = 0;
5542             while (my $o = shift @ord) {
5543 0         0 $ord = $ord * 0x100 + $o;
5544             }
5545             return $ord;
5546 0         0 }
5547             else {
5548             return CORE::ord $_;
5549             }
5550             }
5551              
5552             #
5553             # GBK reverse
5554             #
5555 0 0   0 0 0 sub GBK::reverse(@) {
5556 0         0  
5557             if (wantarray) {
5558             return CORE::reverse @_;
5559             }
5560             else {
5561              
5562             # One of us once cornered Larry in an elevator and asked him what
5563             # problem he was solving with this, but he looked as far off into
5564             # the distance as he could in an elevator and said, "It seemed like
5565 0         0 # a good idea at the time."
5566              
5567             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
5568             }
5569             }
5570              
5571             #
5572             # GBK getc (with parameter, without parameter)
5573             #
5574 0     0 0 0 sub GBK::getc(;*@) {
5575 0 0       0  
5576 0 0 0     0 my($package) = caller;
5577             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
5578 0         0 croak 'Too many arguments for GBK::getc' if @_ and not wantarray;
  0         0  
5579 0         0  
5580 0         0 my @length = sort { $a <=> $b } keys %range_tr;
5581 0         0 my $getc = '';
5582 0 0       0 for my $length ($length[0] .. $length[-1]) {
5583 0 0       0 $getc .= CORE::getc($fh);
5584 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
5585             if ($getc =~ /\A ${Egbk::dot_s} \z/oxms) {
5586             return wantarray ? ($getc,@_) : $getc;
5587             }
5588 0 0       0 }
5589             }
5590             return wantarray ? ($getc,@_) : $getc;
5591             }
5592              
5593             #
5594             # GBK length by character
5595             #
5596 0 0   0 1 0 sub GBK::length(;$) {
5597              
5598 0         0 local $_ = shift if @_;
5599 0         0  
5600             local @_ = /\G ($q_char) /oxmsg;
5601             return scalar @_;
5602             }
5603              
5604             #
5605             # GBK substr by character
5606             #
5607             BEGIN {
5608              
5609             # P.232 The lvalue Attribute
5610             # in Chapter 6: Subroutines
5611             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
5612              
5613             # P.336 The lvalue Attribute
5614             # in Chapter 7: Subroutines
5615             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5616              
5617             # P.144 8.4 Lvalue subroutines
5618             # in Chapter 8: perlsub: Perl subroutines
5619 391 50 0 391 1 254119 # 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  
5620              
5621             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
5622             # vv----------------------*******
5623             sub GBK::substr($$;$$) %s {
5624              
5625             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
5626              
5627             # If the substring is beyond either end of the string, substr() returns the undefined
5628             # value and produces a warning. When used as an lvalue, specifying a substring that
5629             # is entirely outside the string raises an exception.
5630             # http://perldoc.perl.org/functions/substr.html
5631              
5632             # A return with no argument returns the scalar value undef in scalar context,
5633             # an empty list () in list context, and (naturally) nothing at all in void
5634             # context.
5635              
5636             my $offset = $_[1];
5637             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
5638             return;
5639             }
5640              
5641             # substr($string,$offset,$length,$replacement)
5642             if (@_ == 4) {
5643             my(undef,undef,$length,$replacement) = @_;
5644             my $substr = join '', splice(@char, $offset, $length, $replacement);
5645             $_[0] = join '', @char;
5646              
5647             # return $substr; this doesn't work, don't say "return"
5648             $substr;
5649             }
5650              
5651             # substr($string,$offset,$length)
5652             elsif (@_ == 3) {
5653             my(undef,undef,$length) = @_;
5654             my $octet_offset = 0;
5655             my $octet_length = 0;
5656             if ($offset == 0) {
5657             $octet_offset = 0;
5658             }
5659             elsif ($offset > 0) {
5660             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
5661             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
5662             }
5663             else {
5664             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
5665             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
5666             }
5667             if ($length == 0) {
5668             $octet_length = 0;
5669             }
5670             elsif ($length > 0) {
5671             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
5672             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
5673             }
5674             else {
5675             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
5676             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
5677             }
5678             CORE::substr($_[0], $octet_offset, $octet_length);
5679             }
5680              
5681             # substr($string,$offset)
5682             else {
5683             my $octet_offset = 0;
5684             if ($offset == 0) {
5685             $octet_offset = 0;
5686             }
5687             elsif ($offset > 0) {
5688             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
5689             }
5690             else {
5691             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
5692             }
5693             CORE::substr($_[0], $octet_offset);
5694             }
5695             }
5696             END
5697             }
5698              
5699             #
5700             # GBK index by character
5701             #
5702 0     0 1 0 sub GBK::index($$;$) {
5703 0 0       0  
5704 0         0 my $index;
5705             if (@_ == 3) {
5706             $index = Egbk::index($_[0], $_[1], CORE::length(GBK::substr($_[0], 0, $_[2])));
5707 0         0 }
5708             else {
5709             $index = Egbk::index($_[0], $_[1]);
5710 0 0       0 }
5711 0         0  
5712             if ($index == -1) {
5713             return -1;
5714 0         0 }
5715             else {
5716             return GBK::length(CORE::substr $_[0], 0, $index);
5717             }
5718             }
5719              
5720             #
5721             # GBK rindex by character
5722             #
5723 0     0 1 0 sub GBK::rindex($$;$) {
5724 0 0       0  
5725 0         0 my $rindex;
5726             if (@_ == 3) {
5727             $rindex = Egbk::rindex($_[0], $_[1], CORE::length(GBK::substr($_[0], 0, $_[2])));
5728 0         0 }
5729             else {
5730             $rindex = Egbk::rindex($_[0], $_[1]);
5731 0 0       0 }
5732 0         0  
5733             if ($rindex == -1) {
5734             return -1;
5735 0         0 }
5736             else {
5737             return GBK::length(CORE::substr $_[0], 0, $rindex);
5738             }
5739             }
5740              
5741 391     391   4892 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  391         838  
  391         44125  
5742             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
5743             use vars qw($slash); $slash = 'm//';
5744              
5745             # ord() to ord() or GBK::ord()
5746             my $function_ord = 'ord';
5747              
5748             # ord to ord or GBK::ord_
5749             my $function_ord_ = 'ord';
5750              
5751             # reverse to reverse or GBK::reverse
5752             my $function_reverse = 'reverse';
5753              
5754             # getc to getc or GBK::getc
5755             my $function_getc = 'getc';
5756              
5757             # P.1023 Appendix W.9 Multibyte Anchoring
5758             # of ISBN 1-56592-224-7 CJKV Information Processing
5759              
5760             my $anchor = '';
5761 391     391   4039 $anchor = q{${Egbk::anchor}};
  391     0   5167  
  391         17419902  
5762              
5763             use vars qw($nest);
5764              
5765             # regexp of nested parens in qqXX
5766              
5767             # P.340 Matching Nested Constructs with Embedded Code
5768             # in Chapter 7: Perl
5769             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
5770              
5771             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
5772             [^\x81-\xFE\\()] |
5773             \( (?{$nest++}) |
5774             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
5775             [\x81-\xFE][\x00-\xFF] |
5776             \\ [^\x81-\xFEc] |
5777             \\c[\x40-\x5F] |
5778             \\ [\x81-\xFE][\x00-\xFF] |
5779             [\x00-\xFF]
5780             }xms;
5781              
5782             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
5783             [^\x81-\xFE\\{}] |
5784             \{ (?{$nest++}) |
5785             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
5786             [\x81-\xFE][\x00-\xFF] |
5787             \\ [^\x81-\xFEc] |
5788             \\c[\x40-\x5F] |
5789             \\ [\x81-\xFE][\x00-\xFF] |
5790             [\x00-\xFF]
5791             }xms;
5792              
5793             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
5794             [^\x81-\xFE\\\[\]] |
5795             \[ (?{$nest++}) |
5796             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
5797             [\x81-\xFE][\x00-\xFF] |
5798             \\ [^\x81-\xFEc] |
5799             \\c[\x40-\x5F] |
5800             \\ [\x81-\xFE][\x00-\xFF] |
5801             [\x00-\xFF]
5802             }xms;
5803              
5804             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
5805             [^\x81-\xFE\\<>] |
5806             \< (?{$nest++}) |
5807             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
5808             [\x81-\xFE][\x00-\xFF] |
5809             \\ [^\x81-\xFEc] |
5810             \\c[\x40-\x5F] |
5811             \\ [\x81-\xFE][\x00-\xFF] |
5812             [\x00-\xFF]
5813             }xms;
5814              
5815             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
5816             (?: ::)? (?:
5817             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
5818             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
5819             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
5820             ))
5821             }xms;
5822              
5823             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
5824             (?: ::)? (?:
5825             (?>[0-9]+) |
5826             [^\x81-\xFEa-zA-Z_0-9\[\]] |
5827             ^[A-Z] |
5828             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
5829             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
5830             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
5831             ))
5832             }xms;
5833              
5834             my $qq_substr = qr{(?> Char::substr | GBK::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
5835             }xms;
5836              
5837             # regexp of nested parens in qXX
5838             my $q_paren = qr{(?{local $nest=0}) (?>(?:
5839             [^\x81-\xFE()] |
5840             [\x81-\xFE][\x00-\xFF] |
5841             \( (?{$nest++}) |
5842             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
5843             [\x00-\xFF]
5844             }xms;
5845              
5846             my $q_brace = qr{(?{local $nest=0}) (?>(?:
5847             [^\x81-\xFE\{\}] |
5848             [\x81-\xFE][\x00-\xFF] |
5849             \{ (?{$nest++}) |
5850             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
5851             [\x00-\xFF]
5852             }xms;
5853              
5854             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
5855             [^\x81-\xFE\[\]] |
5856             [\x81-\xFE][\x00-\xFF] |
5857             \[ (?{$nest++}) |
5858             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
5859             [\x00-\xFF]
5860             }xms;
5861              
5862             my $q_angle = qr{(?{local $nest=0}) (?>(?:
5863             [^\x81-\xFE<>] |
5864             [\x81-\xFE][\x00-\xFF] |
5865             \< (?{$nest++}) |
5866             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
5867             [\x00-\xFF]
5868             }xms;
5869              
5870             my $matched = '';
5871             my $s_matched = '';
5872             $matched = q{$Egbk::matched};
5873             $s_matched = q{ Egbk::s_matched();};
5874              
5875             my $tr_variable = ''; # variable of tr///
5876             my $sub_variable = ''; # variable of s///
5877             my $bind_operator = ''; # =~ or !~
5878              
5879             my @heredoc = (); # here document
5880             my @heredoc_delimiter = ();
5881             my $here_script = ''; # here script
5882              
5883             #
5884             # escape GBK script
5885 0 50   386 0 0 #
5886             sub GBK::escape(;$) {
5887             local($_) = $_[0] if @_;
5888              
5889             # P.359 The Study Function
5890             # in Chapter 7: Perl
5891 386         1255 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
5892              
5893             study $_; # Yes, I studied study yesterday.
5894              
5895             # while all script
5896              
5897             # 6.14. Matching from Where the Last Pattern Left Off
5898             # in Chapter 6. Pattern Matching
5899             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
5900             # (and so on)
5901              
5902             # one member of Tag-team
5903             #
5904             # P.128 Start of match (or end of previous match): \G
5905             # P.130 Advanced Use of \G with Perl
5906             # in Chapter 3: Overview of Regular Expression Features and Flavors
5907             # P.255 Use leading anchors
5908             # P.256 Expose ^ and \G at the front expressions
5909             # in Chapter 6: Crafting an Efficient Expression
5910             # P.315 "Tag-team" matching with /gc
5911             # in Chapter 7: Perl
5912 386         809 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
5913 386         678  
5914 386         1488 my $e_script = '';
5915             while (not /\G \z/oxgc) { # member
5916             $e_script .= GBK::escape_token();
5917 186687         290730 }
5918              
5919             return $e_script;
5920             }
5921              
5922             #
5923             # escape GBK token of script
5924             #
5925             sub GBK::escape_token {
5926              
5927 386     186687 0 6123 # \n output here document
5928              
5929             my $ignore_modules = join('|', qw(
5930             utf8
5931             bytes
5932             charnames
5933             I18N::Japanese
5934             I18N::Collate
5935             I18N::JExt
5936             File::DosGlob
5937             Wild
5938             Wildcard
5939             Japanese
5940             ));
5941              
5942             # another member of Tag-team
5943             #
5944             # P.315 "Tag-team" matching with /gc
5945             # in Chapter 7: Perl
5946 186687 100 100     222825 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
    100 100        
    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          
    100          
    100          
    50          
    100          
    100          
    100          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
5947 186687         14454500  
5948 31427 100       39278 if (/\G ( \n ) /oxgc) { # another member (and so on)
5949 31427         55496 my $heredoc = '';
5950             if (scalar(@heredoc_delimiter) >= 1) {
5951 197         253 $slash = 'm//';
5952 197         378  
5953             $heredoc = join '', @heredoc;
5954             @heredoc = ();
5955 197         321  
5956 197         353 # skip here document
5957             for my $heredoc_delimiter (@heredoc_delimiter) {
5958 205         1221 /\G .*? \n $heredoc_delimiter \n/xmsgc;
5959             }
5960 197         345 @heredoc_delimiter = ();
5961              
5962 197         290 $here_script = '';
5963             }
5964             return "\n" . $heredoc;
5965             }
5966 31427         91262  
5967             # ignore space, comment
5968             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
5969              
5970             # if (, elsif (, unless (, while (, until (, given (, and when (
5971              
5972             # given, when
5973              
5974             # P.225 The given Statement
5975             # in Chapter 15: Smart Matching and given-when
5976             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
5977              
5978             # P.133 The given Statement
5979             # in Chapter 4: Statements and Declarations
5980             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5981 42684         130624  
5982 3773         5804 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
5983             $slash = 'm//';
5984             return $1;
5985             }
5986              
5987             # scalar variable ($scalar = ...) =~ tr///;
5988             # scalar variable ($scalar = ...) =~ s///;
5989              
5990             # state
5991              
5992             # P.68 Persistent, Private Variables
5993             # in Chapter 4: Subroutines
5994             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
5995              
5996             # P.160 Persistent Lexically Scoped Variables: state
5997             # in Chapter 4: Statements and Declarations
5998             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
5999              
6000             # (and so on)
6001 3773         12118  
6002             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
6003 170 50       514 my $e_string = e_string($1);
    50          
6004 170         6369  
6005 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
6006 0         0 $tr_variable = $e_string . e_string($1);
6007 0         0 $bind_operator = $2;
6008             $slash = 'm//';
6009             return '';
6010 0         0 }
6011 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
6012 0         0 $sub_variable = $e_string . e_string($1);
6013 0         0 $bind_operator = $2;
6014             $slash = 'm//';
6015             return '';
6016 0         0 }
6017 170         338 else {
6018             $slash = 'div';
6019             return $e_string;
6020             }
6021             }
6022              
6023 170         987 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egbk::PREMATCH()
6024 4         10 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
6025             $slash = 'div';
6026             return q{Egbk::PREMATCH()};
6027             }
6028              
6029 4         13 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egbk::MATCH()
6030 28         57 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
6031             $slash = 'div';
6032             return q{Egbk::MATCH()};
6033             }
6034              
6035 28         97 # $', ${'} --> $', ${'}
6036 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
6037             $slash = 'div';
6038             return $1;
6039             }
6040              
6041 1         3 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egbk::POSTMATCH()
6042 3         6 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
6043             $slash = 'div';
6044             return q{Egbk::POSTMATCH()};
6045             }
6046              
6047             # scalar variable $scalar =~ tr///;
6048             # scalar variable $scalar =~ s///;
6049             # substr() =~ tr///;
6050 3         10 # substr() =~ s///;
6051             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
6052 2890 100       6596 my $scalar = e_string($1);
    100          
6053 2890         11442  
6054 9         15 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
6055 9         28 $tr_variable = $scalar;
6056 9         15 $bind_operator = $1;
6057             $slash = 'm//';
6058             return '';
6059 9         25 }
6060 253         422 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
6061 253         450 $sub_variable = $scalar;
6062 253         319 $bind_operator = $1;
6063             $slash = 'm//';
6064             return '';
6065 253         676 }
6066 2628         4050 else {
6067             $slash = 'div';
6068             return $scalar;
6069             }
6070             }
6071              
6072 2628         6979 # end of statement
6073             elsif (/\G ( [,;] ) /oxgc) {
6074             $slash = 'm//';
6075 12229         19514  
6076             # clear tr/// variable
6077             $tr_variable = '';
6078 12229         14260  
6079             # clear s/// variable
6080 12229         13757 $sub_variable = '';
6081              
6082 12229         13130 $bind_operator = '';
6083              
6084             return $1;
6085             }
6086              
6087 12229         41519 # bareword
6088             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
6089             return $1;
6090             }
6091              
6092 0         0 # $0 --> $0
6093 2         7 elsif (/\G ( \$ 0 ) /oxmsgc) {
6094             $slash = 'div';
6095             return $1;
6096 2         10 }
6097 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
6098             $slash = 'div';
6099             return $1;
6100             }
6101              
6102 0         0 # $$ --> $$
6103 1         3 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
6104             $slash = 'div';
6105             return $1;
6106             }
6107              
6108             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6109 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
6110 219         377 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
6111             $slash = 'div';
6112             return e_capture($1);
6113 219         580 }
6114 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
6115             $slash = 'div';
6116             return e_capture($1);
6117             }
6118              
6119 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6120 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
6121             $slash = 'div';
6122             return e_capture($1.'->'.$2);
6123             }
6124              
6125 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6126 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
6127             $slash = 'div';
6128             return e_capture($1.'->'.$2);
6129             }
6130              
6131 0         0 # $$foo
6132 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
6133             $slash = 'div';
6134             return e_capture($1);
6135             }
6136              
6137 0         0 # ${ foo }
6138 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
6139             $slash = 'div';
6140             return '${' . $1 . '}';
6141             }
6142              
6143 0         0 # ${ ... }
6144 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
6145             $slash = 'div';
6146             return e_capture($1);
6147             }
6148              
6149             # variable or function
6150 0         0 # $ @ % & * $ #
6151 605         1082 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) {
6152             $slash = 'div';
6153             return $1;
6154             }
6155             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
6156 605         2245 # $ @ # \ ' " / ? ( ) [ ] < >
6157 103         216 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
6158             $slash = 'div';
6159             return $1;
6160             }
6161              
6162 103         364 # while ()
6163             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
6164             return $1;
6165             }
6166              
6167             # while () --- glob
6168              
6169             # avoid "Error: Runtime exception" of perl version 5.005_03
6170 0         0  
6171             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^\x81-\xFE>\0\a\e\f\n\r\t]|[\x81-\xFE][\x00-\xFF])+?) > (?>\s*) \) \b /oxgc) {
6172             return 'while ($_ = Egbk::glob("' . $1 . '"))';
6173             }
6174              
6175 0         0 # while (glob)
6176             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
6177             return 'while ($_ = Egbk::glob_)';
6178             }
6179              
6180 0         0 # while (glob(WILDCARD))
6181             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
6182             return 'while ($_ = Egbk::glob';
6183             }
6184 0         0  
  482         1211  
6185             # doit if, doit unless, doit while, doit until, doit for, doit when
6186             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
6187 482         1993  
  19         33  
6188 19         71 # subroutines of package Egbk
  0         0  
6189 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         22  
6190 13         32 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
6191 0         0 elsif (/\G \b GBK::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         204  
6192 114         404 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         5  
6193 2         7 elsif (/\G \b GBK::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval GBK::escape'; }
  2         5  
6194 2         6 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         4  
6195 2         6 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::chop'; }
  0         0  
6196 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  2         5  
6197 2         5 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  2         5  
6198 2         5 elsif (/\G \b GBK::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'GBK::index'; }
  2         5  
6199 2         6 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::index'; }
  0         0  
6200 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  2         4  
6201 2         10 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  2         3  
6202 2         6 elsif (/\G \b GBK::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'GBK::rindex'; }
  1         2  
6203 1         3 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::rindex'; }
  0         0  
6204 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egbk::lc'; }
  0         0  
6205 0         0 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egbk::lcfirst'; }
  0         0  
6206 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egbk::uc'; }
  3         4  
6207             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egbk::ucfirst'; }
6208             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egbk::fc'; }
6209              
6210             # stacked file test operators
6211              
6212             # P.179 File Test Operators
6213             # in Chapter 12: File Tests
6214             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6215              
6216             # P.106 Named Unary and File Test Operators
6217             # in Chapter 3: Unary and Binary Operators
6218             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6219              
6220             # (and so on)
6221 3         10  
  0         0  
6222 0         0 elsif (/\G (-[rwxoRWXOezfdlpSbcugkTB] (?>(?:\s+ -[rwxoRWXOezfdlpSbcugkTB])+))
  0         0  
6223 0         0 (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_qq('', $2,$4,$3) . ")"; }
  0         0  
6224 0         0 elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; }
  0         0  
6225 0         0 elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; }
  0         0  
6226 0         0 elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; }
  0         0  
6227 0         0 elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; }
  1         4  
6228             elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; }
6229             elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\S) ((?:$qq_char)+?) (\2) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; }
6230 1         23  
  5         11  
6231 5         20 elsif (/\G (-[rwxoRWXOezfdlpSbcugkTB] (?>(?:\s+ -[rwxoRWXOezfdlpSbcugkTB])+))
  0         0  
6232 0         0 (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_q ('', $2,$4,$3) . ")"; }
  0         0  
6233 0         0 elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; }
  0         0  
6234 0         0 elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; }
  0         0  
6235 0         0 elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; }
  0         0  
6236 0         0 elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; }
  1         3  
6237             elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; }
6238             elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\S) ((?:\\\2|\\\\|$q_char)+?) (\2) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; }
6239 1         6  
  0         0  
6240 0         0 elsif (/\G (-[rwxoRWXOezfdlpSbcugkTB] (?>(?:\s+ -[rwxoRWXOezfdlpSbcugkTB])+)) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
6241 0         0 { $slash = 'm//'; return "Egbk::filetest(qw($1),$2)"; }
  0         0  
6242 0         0 elsif (/\G (-[rwxoRWXOezfdlpSbcugkTB] (?>(?:\s+ -[rwxoRWXOezfdlpSbcugkTB])+)) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1),$2)"; }
  0         0  
6243             elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) (?= [a-z]+) /oxgc) { $slash = 'm//'; return "Egbk::filetest qw($1),"; }
6244 0         0 elsif (/\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) ((?>\w+)) /oxgc) { $slash = 'm//'; return "Egbk::filetest(qw($1),$2)"; }
  0         0  
6245 0         0  
  0         0  
6246 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_qq('', $2,$4,$3) . ")"; }
  0         0  
6247 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_qq('qq',$2,$4,$3) . ")"; }
  0         0  
6248 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_qq('qq',$2,$4,$3) . ")"; }
  0         0  
6249 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_qq('qq',$2,$4,$3) . ")"; }
  0         0  
6250 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_qq('qq',$2,$4,$3) . ")"; }
  2         4  
6251             elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_qq('qq',$2,$4,$3) . ")"; }
6252 2         9 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\2) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_qq('qq',$2,$4,$3) . ")"; }
  103         179  
6253 103         335  
  0         0  
6254 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_q ('', $2,$4,$3) . ")"; }
  0         0  
6255 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_q ('q', $2,$4,$3) . ")"; }
  0         0  
6256 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_q ('q', $2,$4,$3) . ")"; }
  0         0  
6257 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_q ('q', $2,$4,$3) . ")"; }
  0         0  
6258 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_q ('q', $2,$4,$3) . ")"; }
  2         4  
6259             elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_q ('q', $2,$4,$3) . ")"; }
6260             elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) q (?>\s*) (\S) ((?:\\\2|\\\\|$q_char)+?) (\2) /oxgc) { $slash = 'm//'; return "Egbk::$1(" . e_q ('q', $2,$4,$3) . ")"; }
6261 2         10  
  6         12  
6262 6         30 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
6263 0         0 { $slash = 'm//'; return "Egbk::$1($2)"; }
  0         0  
6264 0         0 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "Egbk::$1($2)"; }
  50         76  
6265 50         222 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return "Egbk::$1"; }
  2         6  
6266 2         8 elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC]) (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "Egbk::$1(::"."$2)"; }
  1         4  
6267 1         4 elsif (/\G -(t) (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-t $2"; }
  3         8  
6268             elsif (/\G \b lstat (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egbk::lstat'; }
6269             elsif (/\G \b stat (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egbk::stat'; }
6270 3         10  
  0         0  
6271 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
6272 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
6273 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
6274 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
6275 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
6276 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
6277             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
6278 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  
6279 0         0  
  0         0  
6280 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
6281 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
6282 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
6283 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
6284 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
6285             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
6286             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
6287 0         0  
  0         0  
6288 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
6289 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
6290 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
6291             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
6292 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         6  
6293 2         7  
  2         4  
6294 2         8 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         86  
6295 36         158 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         6  
6296 2         7 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egbk::chr'; }
  2         4  
6297 2         8 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  8         23  
6298 8         32 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
6299 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Egbk::glob'; }
  0         0  
6300 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::lc_'; }
  0         0  
6301 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::lcfirst_'; }
  0         0  
6302 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::uc_'; }
  0         0  
6303 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::ucfirst_'; }
  0         0  
6304 0         0 elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::fc_'; }
  0         0  
6305             elsif (/\G \b lstat \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::lstat_'; }
6306 0         0 elsif (/\G \b stat \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::stat_'; }
  0         0  
6307             elsif (/\G (-[rwxoRWXOezfdlpSbcugkTB] (?>(?:\s+ -[rwxoRWXOezfdlpSbcugkTB])+))
6308 0         0 \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return "Egbk::filetest_(qw($1))"; }
  0         0  
6309             elsif (/\G -([rwxoRWXOezsfdlpSbcugkTBMAC])
6310 0         0 \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return "Egbk::${1}_"; }
  0         0  
6311              
6312 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
6313 0         0  
  0         0  
6314 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
6315 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
6316 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::chr_'; }
  2         6  
6317 2         8 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
6318 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  4         11  
6319 4         15 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::glob_'; }
  8         25  
6320 8         33 elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
  2         8  
6321 2         13 elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
  0         0  
6322 0         0 elsif (/\G \b opendir ((?>\s*) \( (?>\s*)) (?=[A-Za-z_]) /oxgc) { $slash = 'm//'; return "Egbk::opendir$1*"; }
  87         222  
6323             elsif (/\G \b opendir ((?>\s+)) (?=[A-Za-z_]) /oxgc) { $slash = 'm//'; return "Egbk::opendir$1*"; }
6324             elsif (/\G \b unlink \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Egbk::unlink'; }
6325              
6326 87         331 # chdir
6327             elsif (/\G \b (chdir) \b (?! (?>\s*) => ) /oxgc) {
6328 3         7 $slash = 'm//';
6329              
6330 3         5 my $e = 'Egbk::chdir';
6331 3         12  
6332             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
6333             $e .= $1;
6334             }
6335 3 50       12  
  3 100       236  
    50          
    50          
    50          
    0          
6336             # end of chdir
6337             if (/\G (?= [,;\)\}\]] ) /oxgc) { return $e; }
6338 0         0  
6339             # chdir scalar value
6340             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return $e . e_string($1); }
6341              
6342 1 0       5 # chdir qq//
  0         0  
6343             elsif (/\G \b (qq) \b /oxgc) {
6344 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return $e . e_chdir('qq',$1,$3,$2); } # qq# # --> qr # #
6345 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6346 0         0 while (not /\G \z/oxgc) {
6347 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6348 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_chdir('qq',$1,$3,$2); } # qq ( ) --> qr ( )
6349 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_chdir('qq',$1,$3,$2); } # qq { } --> qr { }
6350 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_chdir('qq',$1,$3,$2); } # qq [ ] --> qr [ ]
6351 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_chdir('qq',$1,$3,$2); } # qq < > --> qr < >
6352             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_chdir('qq','{','}',$2); } # qq | | --> qr { }
6353 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_chdir('qq',$1,$3,$2); } # qq * * --> qr * *
6354             }
6355             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6356             }
6357             }
6358              
6359 0 0       0 # chdir q//
  0         0  
6360             elsif (/\G \b (q) \b /oxgc) {
6361 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return $e . e_chdir_q('q',$1,$3,$2); } # q# # --> qr # #
6362 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6363 0         0 while (not /\G \z/oxgc) {
6364 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6365 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return $e . e_chdir_q('q',$1,$3,$2); } # q ( ) --> qr ( )
6366 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return $e . e_chdir_q('q',$1,$3,$2); } # q { } --> qr { }
6367 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return $e . e_chdir_q('q',$1,$3,$2); } # q [ ] --> qr [ ]
6368 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return $e . e_chdir_q('q',$1,$3,$2); } # q < > --> qr < >
6369             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return $e . e_chdir_q('q','{','}',$2); } # q | | --> qr { }
6370 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return $e . e_chdir_q('q',$1,$3,$2); } # q * * --> qr * *
6371             }
6372             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6373             }
6374             }
6375              
6376 0         0 # chdir ''
6377 2         6 elsif (/\G (\') /oxgc) {
6378 2 50       5 my $q_string = '';
  13 50       61  
    100          
    50          
6379 0         0 while (not /\G \z/oxgc) {
6380 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
6381 2         7 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
6382             elsif (/\G \' /oxgc) { return $e . e_chdir_q('',"'","'",$q_string); }
6383 11         23 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
6384             }
6385             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6386             }
6387              
6388 0         0 # chdir ""
6389 0         0 elsif (/\G (\") /oxgc) {
6390 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
6391 0         0 while (not /\G \z/oxgc) {
6392 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
6393 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
6394             elsif (/\G \" /oxgc) { return $e . e_chdir('','"','"',$qq_string); }
6395 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
6396             }
6397             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6398             }
6399             }
6400              
6401 0         0 # split
6402             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
6403 404         1033 $slash = 'm//';
6404 404         604  
6405 404         1513 my $e = '';
6406             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
6407             $e .= $1;
6408             }
6409 401 100       1719  
  404 100       18902  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
6410             # end of split
6411             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Egbk::split' . $e; }
6412 3         16  
6413             # split scalar value
6414             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Egbk::split' . $e . e_string($1); }
6415 1         5  
6416 0         0 # split literal space
6417 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Egbk::split' . $e . qq {qq$1 $2}; }
6418 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Egbk::split' . $e . qq{$1qq$2 $3}; }
6419 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Egbk::split' . $e . qq{$1qq$2 $3}; }
6420 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Egbk::split' . $e . qq{$1qq$2 $3}; }
6421 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Egbk::split' . $e . qq{$1qq$2 $3}; }
6422 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Egbk::split' . $e . qq{$1qq$2 $3}; }
6423 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Egbk::split' . $e . qq {q$1 $2}; }
6424 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Egbk::split' . $e . qq {$1q$2 $3}; }
6425 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Egbk::split' . $e . qq {$1q$2 $3}; }
6426 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Egbk::split' . $e . qq {$1q$2 $3}; }
6427 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Egbk::split' . $e . qq {$1q$2 $3}; }
6428 13         71 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Egbk::split' . $e . qq {$1q$2 $3}; }
6429             elsif (/\G ' [ ] ' /oxgc) { return 'Egbk::split' . $e . qq {' '}; }
6430             elsif (/\G " [ ] " /oxgc) { return 'Egbk::split' . $e . qq {" "}; }
6431              
6432 2 0       12 # split qq//
  0         0  
6433             elsif (/\G \b (qq) \b /oxgc) {
6434 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
6435 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6436 0         0 while (not /\G \z/oxgc) {
6437 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6438 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
6439 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
6440 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
6441 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
6442             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
6443 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
6444             }
6445             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6446             }
6447             }
6448              
6449 0 50       0 # split qr//
  124         853  
6450             elsif (/\G \b (qr) \b /oxgc) {
6451 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
6452 124 50       394 else {
  124 50       5777  
    50          
    50          
    50          
    100          
    50          
    50          
6453 0         0 while (not /\G \z/oxgc) {
6454 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6455 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
6456 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
6457 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
6458 56         224 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
6459 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
6460             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
6461 68         327 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
6462             }
6463             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6464             }
6465             }
6466              
6467 0 0       0 # split q//
  0         0  
6468             elsif (/\G \b (q) \b /oxgc) {
6469 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
6470 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
6471 0         0 while (not /\G \z/oxgc) {
6472 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6473 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
6474 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
6475 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
6476 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
6477             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
6478 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
6479             }
6480             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6481             }
6482             }
6483              
6484 0 50       0 # split m//
  136         951  
6485             elsif (/\G \b (m) \b /oxgc) {
6486 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
6487 136 50       420 else {
  136 50       6983  
    50          
    50          
    50          
    100          
    50          
    50          
6488 0         0 while (not /\G \z/oxgc) {
6489 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6490 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
6491 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
6492 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
6493 56         241 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
6494 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
6495             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
6496 80         390 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
6497             }
6498             die __FILE__, ": Search pattern not terminated\n";
6499             }
6500             }
6501              
6502 0         0 # split ''
6503 0         0 elsif (/\G (\') /oxgc) {
6504 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
6505 0         0 while (not /\G \z/oxgc) {
6506 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
6507 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
6508             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
6509 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
6510             }
6511             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6512             }
6513              
6514 0         0 # split ""
6515 0         0 elsif (/\G (\") /oxgc) {
6516 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
6517 0         0 while (not /\G \z/oxgc) {
6518 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
6519 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
6520             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
6521 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
6522             }
6523             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6524             }
6525              
6526 0         0 # split //
6527 125         284 elsif (/\G (\/) /oxgc) {
6528 125 50       389 my $regexp = '';
  558 50       2612  
    100          
    50          
6529 0         0 while (not /\G \z/oxgc) {
6530 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
6531 125         538 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
6532             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
6533 433         1029 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
6534             }
6535             die __FILE__, ": Search pattern not terminated\n";
6536             }
6537             }
6538              
6539             # tr/// or y///
6540              
6541             # about [cdsrbB]* (/B modifier)
6542             #
6543             # P.559 appendix C
6544             # of ISBN 4-89052-384-7 Programming perl
6545             # (Japanese title is: Perl puroguramingu)
6546 0         0  
6547             elsif (/\G \b ( tr | y ) \b /oxgc) {
6548             my $ope = $1;
6549 11 50       36  
6550 11         157 # $1 $2 $3 $4 $5 $6
6551 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
6552             my @tr = ($tr_variable,$2);
6553             return e_tr(@tr,'',$4,$6);
6554 0         0 }
6555 11         22 else {
6556 11 50       30 my $e = '';
  11 50       822  
    50          
    50          
    50          
    50          
6557             while (not /\G \z/oxgc) {
6558 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6559 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
6560 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
6561 0         0 while (not /\G \z/oxgc) {
6562 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6563 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
6564 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
6565 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
6566             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
6567 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
6568             }
6569             die __FILE__, ": Transliteration replacement not terminated\n";
6570 0         0 }
6571 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
6572 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
6573 0         0 while (not /\G \z/oxgc) {
6574 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6575 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
6576 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
6577 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
6578             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
6579 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
6580             }
6581             die __FILE__, ": Transliteration replacement not terminated\n";
6582 0         0 }
6583 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
6584 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
6585 0         0 while (not /\G \z/oxgc) {
6586 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6587 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
6588 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
6589 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
6590             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
6591 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
6592             }
6593             die __FILE__, ": Transliteration replacement not terminated\n";
6594 0         0 }
6595 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
6596 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
6597 0         0 while (not /\G \z/oxgc) {
6598 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6599 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
6600 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
6601 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
6602             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
6603 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
6604             }
6605             die __FILE__, ": Transliteration replacement not terminated\n";
6606             }
6607 0         0 # $1 $2 $3 $4 $5 $6
6608 11         43 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
6609             my @tr = ($tr_variable,$2);
6610             return e_tr(@tr,'',$4,$6);
6611 11         33 }
6612             }
6613             die __FILE__, ": Transliteration pattern not terminated\n";
6614             }
6615             }
6616              
6617 0         0 # qq//
6618             elsif (/\G \b (qq) \b /oxgc) {
6619             my $ope = $1;
6620 5897 100       16180  
6621 5897         11416 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
6622 40         55 if (/\G (\#) /oxgc) { # qq# #
6623 40 100       87 my $qq_string = '';
  1948 50       5307  
    100          
    50          
6624 80         146 while (not /\G \z/oxgc) {
6625 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
6626 40         112 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
6627             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
6628 1828         3303 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
6629             }
6630             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6631             }
6632 0         0  
6633 5857         7785 else {
6634 5857 50       14685 my $e = '';
  5857 50       23011  
    100          
    50          
    100          
    50          
6635             while (not /\G \z/oxgc) {
6636             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6637              
6638 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
6639 0         0 elsif (/\G (\() /oxgc) { # qq ( )
6640 0         0 my $qq_string = '';
6641 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
6642 0         0 while (not /\G \z/oxgc) {
6643 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
6644             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
6645 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
6646 0         0 elsif (/\G (\)) /oxgc) {
6647             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
6648 0         0 else { $qq_string .= $1; }
6649             }
6650 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
6651             }
6652             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6653             }
6654              
6655 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
6656 5775         7853 elsif (/\G (\{) /oxgc) { # qq { }
6657 5775         8401 my $qq_string = '';
6658 5775 100       12319 local $nest = 1;
  245875 50       780542  
    100          
    100          
    50          
6659 720         1462 while (not /\G \z/oxgc) {
6660 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1384         1844  
6661             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
6662 1384 100       2397 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  7159         12128  
6663 5775         12616 elsif (/\G (\}) /oxgc) {
6664             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
6665 1384         2752 else { $qq_string .= $1; }
6666             }
6667 236612         461875 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
6668             }
6669             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6670             }
6671              
6672 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
6673 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
6674 0         0 my $qq_string = '';
6675 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
6676 0         0 while (not /\G \z/oxgc) {
6677 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
6678             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
6679 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
6680 0         0 elsif (/\G (\]) /oxgc) {
6681             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
6682 0         0 else { $qq_string .= $1; }
6683             }
6684 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
6685             }
6686             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6687             }
6688              
6689 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
6690 62         116 elsif (/\G (\<) /oxgc) { # qq < >
6691 62         144 my $qq_string = '';
6692 62 100       176 local $nest = 1;
  2040 50       7194  
    100          
    100          
    50          
6693 22         85 while (not /\G \z/oxgc) {
6694 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  2         3  
6695             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
6696 2 100       4 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  64         143  
6697 62         172 elsif (/\G (\>) /oxgc) {
6698             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
6699 2         4 else { $qq_string .= $1; }
6700             }
6701 1952         3701 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
6702             }
6703             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6704             }
6705              
6706 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
6707 20         28 elsif (/\G (\S) /oxgc) { # qq * *
6708 20         22 my $delimiter = $1;
6709 20 50       39 my $qq_string = '';
  840 50       2342  
    100          
    50          
6710 0         0 while (not /\G \z/oxgc) {
6711 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
6712 20         38 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
6713             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
6714 820         1546 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
6715             }
6716             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6717 0         0 }
6718             }
6719             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6720             }
6721             }
6722              
6723 0         0 # qr//
6724 184 50       494 elsif (/\G \b (qr) \b /oxgc) {
6725 184         724 my $ope = $1;
6726             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
6727             return e_qr($ope,$1,$3,$2,$4);
6728 0         0 }
6729 184         255 else {
6730 184 50       417 my $e = '';
  184 50       4745  
    100          
    50          
    50          
    100          
    50          
    50          
6731 0         0 while (not /\G \z/oxgc) {
6732 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6733 1         5 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
6734 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
6735 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
6736 76         225 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
6737 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
6738             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
6739 107         332 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
6740             }
6741             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6742             }
6743             }
6744              
6745 0         0 # qw//
6746 34 50       119 elsif (/\G \b (qw) \b /oxgc) {
6747 34         114 my $ope = $1;
6748             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
6749             return e_qw($ope,$1,$3,$2);
6750 0         0 }
6751 34         66 else {
6752 34 50       121 my $e = '';
  34 50       237  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
6753             while (not /\G \z/oxgc) {
6754 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6755 34         143  
6756             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
6757 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
6758 0         0  
6759             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
6760 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
6761 0         0  
6762             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
6763 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
6764 0         0  
6765             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
6766 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
6767 0         0  
6768             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
6769 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
6770             }
6771             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6772             }
6773             }
6774              
6775 0         0 # qx//
6776 3 50       10 elsif (/\G \b (qx) \b /oxgc) {
6777 3         78 my $ope = $1;
6778             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
6779             return e_qq($ope,$1,$3,$2);
6780 0         0 }
6781 3         8 else {
6782 3 50       11 my $e = '';
  3 50       380  
    100          
    50          
    50          
    50          
    50          
6783 0         0 while (not /\G \z/oxgc) {
6784 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6785 2         6 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
6786 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
6787 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
6788 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
6789             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
6790 1         5 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
6791             }
6792             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6793             }
6794             }
6795              
6796 0         0 # q//
6797             elsif (/\G \b (q) \b /oxgc) {
6798             my $ope = $1;
6799              
6800             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
6801              
6802             # avoid "Error: Runtime exception" of perl version 5.005_03
6803 606 50       1976 # (and so on)
6804 606         1855  
6805 0         0 if (/\G (\#) /oxgc) { # q# #
6806 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
6807 0         0 while (not /\G \z/oxgc) {
6808 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
6809 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
6810             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
6811 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
6812             }
6813             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6814             }
6815 0         0  
6816 606         1135 else {
6817 606 50       1986 my $e = '';
  606 100       3644  
    100          
    50          
    100          
    50          
6818             while (not /\G \z/oxgc) {
6819             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6820              
6821 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
6822 1         2 elsif (/\G (\() /oxgc) { # q ( )
6823 1         3 my $q_string = '';
6824 1 50       3 local $nest = 1;
  7 50       46  
    50          
    50          
    100          
    50          
6825 0         0 while (not /\G \z/oxgc) {
6826 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
6827 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
6828             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
6829 0 50       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  1         3  
6830 1         2 elsif (/\G (\)) /oxgc) {
6831             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
6832 0         0 else { $q_string .= $1; }
6833             }
6834 6         14 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
6835             }
6836             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6837             }
6838              
6839 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
6840 599         1118 elsif (/\G (\{) /oxgc) { # q { }
6841 599         1080 my $q_string = '';
6842 599 50       1771 local $nest = 1;
  8189 50       34924  
    50          
    100          
    100          
    50          
6843 0         0 while (not /\G \z/oxgc) {
6844 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
6845 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  114         178  
6846             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
6847 114 100       213 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  713         1666  
6848 599         2085 elsif (/\G (\}) /oxgc) {
6849             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
6850 114         236 else { $q_string .= $1; }
6851             }
6852 7362         14193 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
6853             }
6854             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6855             }
6856              
6857 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
6858 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
6859 0         0 my $q_string = '';
6860 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
6861 0         0 while (not /\G \z/oxgc) {
6862 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
6863 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
6864             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
6865 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
6866 0         0 elsif (/\G (\]) /oxgc) {
6867             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
6868 0         0 else { $q_string .= $1; }
6869             }
6870 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
6871             }
6872             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6873             }
6874              
6875 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
6876 5         11 elsif (/\G (\<) /oxgc) { # q < >
6877 5         10 my $q_string = '';
6878 5 50       17 local $nest = 1;
  82 50       413  
    50          
    50          
    100          
    50          
6879 0         0 while (not /\G \z/oxgc) {
6880 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
6881 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
6882             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
6883 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         18  
6884 5         15 elsif (/\G (\>) /oxgc) {
6885             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
6886 0         0 else { $q_string .= $1; }
6887             }
6888 77         155 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
6889             }
6890             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6891             }
6892              
6893 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
6894 1         2 elsif (/\G (\S) /oxgc) { # q * *
6895 1         2 my $delimiter = $1;
6896 1 50       6 my $q_string = '';
  14 50       67  
    100          
    50          
6897 0         0 while (not /\G \z/oxgc) {
6898 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
6899 1         3 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
6900             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
6901 13         27 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
6902             }
6903             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6904 0         0 }
6905             }
6906             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
6907             }
6908             }
6909              
6910 0         0 # m//
6911 491 50       1346 elsif (/\G \b (m) \b /oxgc) {
6912 491         2698 my $ope = $1;
6913             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
6914             return e_qr($ope,$1,$3,$2,$4);
6915 0         0 }
6916 491         727 else {
6917 491 50       1348 my $e = '';
  491 50       19882  
    50          
    50          
    50          
    100          
    100          
    50          
    50          
6918 0         0 while (not /\G \z/oxgc) {
6919 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6920 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
6921 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
6922 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
6923 92         287 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
6924 87         278 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
6925 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
6926             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
6927 312         1069 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
6928             }
6929             die __FILE__, ": Search pattern not terminated\n";
6930             }
6931             }
6932              
6933             # s///
6934              
6935             # about [cegimosxpradlunbB]* (/cg modifier)
6936             #
6937             # P.67 Pattern-Matching Operators
6938             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
6939 0         0  
6940             elsif (/\G \b (s) \b /oxgc) {
6941             my $ope = $1;
6942 290 100       831  
6943 290         4511 # $1 $2 $3 $4 $5 $6
6944             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
6945             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
6946 1         5 }
6947 289         482 else {
6948 289 50       870 my $e = '';
  289 50       28464  
    50          
    50          
    50          
    100          
    100          
    50          
    50          
6949             while (not /\G \z/oxgc) {
6950 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6951 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
6952 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
6953             while (not /\G \z/oxgc) {
6954 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6955 0         0 # $1 $2 $3 $4
6956 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6957 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6958 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6959 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6960 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6961 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6962 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6963             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6964 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6965             }
6966             die __FILE__, ": Substitution replacement not terminated\n";
6967 0         0 }
6968 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
6969 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
6970             while (not /\G \z/oxgc) {
6971 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6972 0         0 # $1 $2 $3 $4
6973 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6974 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6975 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6976 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6977 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6978 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6979 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6980             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6981 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6982             }
6983             die __FILE__, ": Substitution replacement not terminated\n";
6984 0         0 }
6985 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
6986 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
6987             while (not /\G \z/oxgc) {
6988 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
6989 0         0 # $1 $2 $3 $4
6990 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6991 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6992 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6993 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6994 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6995             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6996 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
6997             }
6998             die __FILE__, ": Substitution replacement not terminated\n";
6999 0         0 }
7000 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
7001 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
7002             while (not /\G \z/oxgc) {
7003 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
7004 0         0 # $1 $2 $3 $4
7005 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
7006 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
7007 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
7008 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
7009 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
7010 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
7011 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
7012             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
7013 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
7014             }
7015             die __FILE__, ": Substitution replacement not terminated\n";
7016             }
7017 0         0 # $1 $2 $3 $4 $5 $6
7018             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
7019             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
7020             }
7021 96         243 # $1 $2 $3 $4 $5 $6
7022             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
7023             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
7024             }
7025 2         14 # $1 $2 $3 $4 $5 $6
7026             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
7027             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
7028             }
7029 0         0 # $1 $2 $3 $4 $5 $6
7030             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
7031             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
7032 191         783 }
7033             }
7034             die __FILE__, ": Substitution pattern not terminated\n";
7035             }
7036             }
7037 0         0  
7038 1         8 # do
7039 0         0 elsif (/\G \b do (?= (?>\s*) \{ ) /oxmsgc) { return 'do'; }
7040 0         0 elsif (/\G \b do (?= (?>\s+) (?: q | qq | qx ) \b) /oxmsgc) { return 'Egbk::do'; }
7041 0         0 elsif (/\G \b do (?= (?>\s+) (?>\w+)) /oxmsgc) { return 'do'; }
7042             elsif (/\G \b do (?= (?>\s*) \$ (?> \w+ (?: ::\w+)* ) \( ) /oxmsgc) { return 'do'; }
7043             elsif (/\G \b do \b /oxmsgc) { return 'Egbk::do'; }
7044 2         9  
7045 0         0 # require ignore module
7046 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
7047             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^\x81-\xFE#]) /oxmsgc) { return "# require$1\n$2"; }
7048             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
7049 0         0  
7050 0         0 # require version number
7051 0         0 elsif (/\G \b require (?>\s+) ((?>0[0-7_]*)) (?>\s*) ; /oxmsgc) { return "require $1;"; }
7052             elsif (/\G \b require (?>\s+) ((?>[1-9][0-9_]*(?:\.[0-9_]+)*)) (?>\s*) ; /oxmsgc) { return "require $1;"; }
7053             elsif (/\G \b require (?>\s+) ((?>v[0-9][0-9_]*(?:\.[0-9_]+)*)) (?>\s*) ; /oxmsgc) { return "require $1;"; }
7054 0         0  
7055             # require bare package name
7056             elsif (/\G \b require (?>\s+) ((?>[A-Za-z_]\w* (?: :: [A-Za-z_]\w*)*)) (?>\s*) ; /oxmsgc) { return "require $1;"; }
7057 18         139  
7058 0         0 # require else
7059             elsif (/\G \b require (?>\s*) ; /oxmsgc) { return 'Egbk::require;'; }
7060             elsif (/\G \b require \b /oxmsgc) { return 'Egbk::require'; }
7061 1         5  
7062 70         652 # use strict; --> use strict; no strict qw(refs);
7063 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
7064             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^\x81-\xFE#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
7065             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
7066              
7067 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
7068 3         86 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
7069             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
7070             return "use $1; no strict qw(refs);";
7071 0         0 }
7072             else {
7073             return "use $1;";
7074             }
7075 3 0 0     21 }
      0        
7076 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
7077             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
7078             return "use $1; no strict qw(refs);";
7079 0         0 }
7080             else {
7081             return "use $1;";
7082             }
7083             }
7084 0         0  
7085 2         16 # ignore use module
7086 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
7087             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^\x81-\xFE#]) /oxmsgc) { return "# use$1\n$2"; }
7088             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
7089 0         0  
7090 0         0 # ignore no module
7091 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
7092             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^\x81-\xFE#]) /oxmsgc) { return "# no$1\n$2"; }
7093             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
7094 0         0  
7095 0         0 # use without import
7096 0         0 elsif (/\G \b use (?>\s+) ((?>0[0-7_]*)) (?>\s*) ; /oxmsgc) { return "use $1;"; }
7097 0         0 elsif (/\G \b use (?>\s+) ((?>[1-9][0-9_]*(?:\.[0-9_]+)*)) (?>\s*) ; /oxmsgc) { return "use $1;"; }
7098 0         0 elsif (/\G \b use (?>\s+) ((?>v[0-9][0-9_]*(?:\.[0-9_]+)*)) (?>\s*) ; /oxmsgc) { return "use $1;"; }
7099 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) (\() (?>\s*) \) (?>\s*) ; /oxmsgc) { return e_use_noimport($1); }
7100 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\() (?>\s*) \) (?>\s*) ; /oxmsgc) { return e_use_noimport($1); }
7101 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\{) (?>\s*) \} (?>\s*) ; /oxmsgc) { return e_use_noimport($1); }
7102 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\[) (?>\s*) \] (?>\s*) ; /oxmsgc) { return e_use_noimport($1); }
7103 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\<) (?>\s*) \> (?>\s*) ; /oxmsgc) { return e_use_noimport($1); }
7104             elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) ([\x21-\x3F]) (?>\s*) \2 (?>\s*) ; /oxmsgc) { return e_use_noimport($1); }
7105             elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\S) (?>\s*) \2 (?>\s*) ; /oxmsgc) { return e_use_noimport($1); }
7106 0         0  
7107             # use with import no parameter
7108             elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) ; /oxmsgc) { return e_use_noparam($1); }
7109 0         0  
7110 0         0 # use with import parameters
7111 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) ( (\() [^\x81-\xFE)]* \)) (?>\s*) ; /oxmsgc) { return e_use($1,$2); }
7112 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) ( (\') [^\x81-\xFE']* \') (?>\s*) ; /oxmsgc) { return e_use($1,$2); }
7113 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) ( (\") [^\x81-\xFE"]* \") (?>\s*) ; /oxmsgc) { return e_use($1,$2); }
7114 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\() [^\x81-\xFE)]* \)) (?>\s*) ; /oxmsgc) { return e_use($1,$2); }
7115 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\{) (?:$q_char)*? \}) (?>\s*) ; /oxmsgc) { return e_use($1,$2); }
7116 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\[) (?:$q_char)*? \]) (?>\s*) ; /oxmsgc) { return e_use($1,$2); }
7117 0         0 elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\<) [^\x81-\xFE>]* \>) (?>\s*) ; /oxmsgc) { return e_use($1,$2); }
7118             elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) ([\x21-\x3F]) .*? \3) (?>\s*) ; /oxmsgc) { return e_use($1,$2); }
7119             elsif (/\G \b use (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\S) (?:$q_char)*? \3) (?>\s*) ; /oxmsgc) { return e_use($1,$2); }
7120 0         0  
7121 0         0 # no without unimport
7122 0         0 elsif (/\G \b no (?>\s+) ((?>0[0-7_]*)) (?>\s*) ; /oxmsgc) { return "no $1;"; }
7123 0         0 elsif (/\G \b no (?>\s+) ((?>[1-9][0-9_]*(?:\.[0-9_]+)*)) (?>\s*) ; /oxmsgc) { return "no $1;"; }
7124 0         0 elsif (/\G \b no (?>\s+) ((?>v[0-9][0-9_]*(?:\.[0-9_]+)*)) (?>\s*) ; /oxmsgc) { return "no $1;"; }
7125 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) (\() (?>\s*) \) (?>\s*) ; /oxmsgc) { return e_no_nounimport($1); }
7126 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\() (?>\s*) \) (?>\s*) ; /oxmsgc) { return e_no_nounimport($1); }
7127 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\{) (?>\s*) \} (?>\s*) ; /oxmsgc) { return e_no_nounimport($1); }
7128 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\[) (?>\s*) \] (?>\s*) ; /oxmsgc) { return e_no_nounimport($1); }
7129 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\<) (?>\s*) \> (?>\s*) ; /oxmsgc) { return e_no_nounimport($1); }
7130             elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) ([\x21-\x3F]) (?>\s*) \2 (?>\s*) ; /oxmsgc) { return e_no_nounimport($1); }
7131             elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) qw (?>\s*) (\S) (?>\s*) \2 (?>\s*) ; /oxmsgc) { return e_no_nounimport($1); }
7132 0         0  
7133             # no with unimport no parameter
7134             elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) ; /oxmsgc) { return e_no_noparam($1); }
7135 0         0  
7136 0         0 # no with unimport parameters
7137 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) ( (\() [^\x81-\xFE)]* \)) (?>\s*) ; /oxmsgc) { return e_no($1,$2); }
7138 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) ( (\') [^\x81-\xFE']* \') (?>\s*) ; /oxmsgc) { return e_no($1,$2); }
7139 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s*) ( (\") [^\x81-\xFE"]* \") (?>\s*) ; /oxmsgc) { return e_no($1,$2); }
7140 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\() [^\x81-\xFE)]* \)) (?>\s*) ; /oxmsgc) { return e_no($1,$2); }
7141 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\{) (?:$q_char)*? \}) (?>\s*) ; /oxmsgc) { return e_no($1,$2); }
7142 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\[) (?:$q_char)*? \]) (?>\s*) ; /oxmsgc) { return e_no($1,$2); }
7143 0         0 elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\<) [^\x81-\xFE>]* \>) (?>\s*) ; /oxmsgc) { return e_no($1,$2); }
7144             elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) ([\x21-\x3F]) .*? \3) (?>\s*) ; /oxmsgc) { return e_no($1,$2); }
7145             elsif (/\G \b no (?>\s+) ((?>[A-Z]\w*(?: ::\w+)*)) (?>\s+) ((?: q | qq | qw ) (?>\s*) (\S) (?:$q_char)*? \3) (?>\s*) ; /oxmsgc) { return e_no($1,$2); }
7146 0         0  
7147             # use else
7148             elsif (/\G \b use \b /oxmsgc) { return "use"; }
7149 0         0  
7150             # use else
7151             elsif (/\G \b no \b /oxmsgc) { return "no"; }
7152              
7153 2         11 # ''
7154 3177         7501 elsif (/\G (?
7155 3177 100       8863 my $q_string = '';
  15630 100       54003  
    100          
    50          
7156 8         19 while (not /\G \z/oxgc) {
7157 48         96 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
7158 3177         7795 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
7159             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
7160 12397         27064 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
7161             }
7162             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
7163             }
7164              
7165 0         0 # ""
7166 3408         7954 elsif (/\G (\") /oxgc) {
7167 3408 100       9065 my $qq_string = '';
  69470 100       194916  
    100          
    50          
7168 109         228 while (not /\G \z/oxgc) {
7169 14         30 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
7170 3408         8717 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
7171             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
7172 65939         122867 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
7173             }
7174             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
7175             }
7176              
7177 0         0 # ``
7178 37         149 elsif (/\G (\`) /oxgc) {
7179 37 50       144 my $qx_string = '';
  313 50       1715  
    100          
    50          
7180 0         0 while (not /\G \z/oxgc) {
7181 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
7182 37         333 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
7183             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
7184 276         603 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
7185             }
7186             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
7187             }
7188              
7189 0         0 # // --- not divide operator (num / num), not defined-or
7190 1231         3139 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
7191 1231 100       3747 my $regexp = '';
  12602 50       43154  
    100          
    50          
7192 11         37 while (not /\G \z/oxgc) {
7193 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
7194 1231         3515 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
7195             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
7196 11360         23711 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
7197             }
7198             die __FILE__, ": Search pattern not terminated\n";
7199             }
7200              
7201 0         0 # ?? --- not conditional operator (condition ? then : else)
7202 92         240 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
7203 92 50       264 my $regexp = '';
  266 50       1034  
    100          
    50          
7204 0         0 while (not /\G \z/oxgc) {
7205 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
7206 92         244 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
7207             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
7208 174         476 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
7209             }
7210             die __FILE__, ": Search pattern not terminated\n";
7211             }
7212 0         0  
  0         0  
7213             # <<>> (a safer ARGV)
7214             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
7215 0         0  
  0         0  
7216             # << (bit shift) --- not here document
7217             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
7218              
7219 0         0 # <<~'HEREDOC'
7220 6         16 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
7221 6         13 $slash = 'm//';
7222             my $here_quote = $1;
7223             my $delimiter = $2;
7224 6 50       9  
7225 6         13 # get here document
7226 6         21 if ($here_script eq '') {
7227             $here_script = CORE::substr $_, pos $_;
7228 6 50       30 $here_script =~ s/.*?\n//oxm;
7229 6         63 }
7230 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
7231 6         8 my $heredoc = $1;
7232 6         44 my $indent = $2;
7233 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
7234             push @heredoc, $heredoc . qq{\n$delimiter\n};
7235             push @heredoc_delimiter, qq{\\s*$delimiter};
7236 6         12 }
7237             else {
7238 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7239             }
7240             return qq{<<'$delimiter'};
7241             }
7242              
7243             # <<~\HEREDOC
7244              
7245             # P.66 2.6.6. "Here" Documents
7246             # in Chapter 2: Bits and Pieces
7247             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7248              
7249             # P.73 "Here" Documents
7250             # in Chapter 2: Bits and Pieces
7251             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7252 6         22  
7253 3         8 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
7254 3         7 $slash = 'm//';
7255             my $here_quote = $1;
7256             my $delimiter = $2;
7257 3 50       4  
7258 3         8 # get here document
7259 3         12 if ($here_script eq '') {
7260             $here_script = CORE::substr $_, pos $_;
7261 3 50       16 $here_script =~ s/.*?\n//oxm;
7262 3         33 }
7263 3         8 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
7264 3         4 my $heredoc = $1;
7265 3         32 my $indent = $2;
7266 3         11 $heredoc =~ s{^$indent}{}msg; # no /ox
7267             push @heredoc, $heredoc . qq{\n$delimiter\n};
7268             push @heredoc_delimiter, qq{\\s*$delimiter};
7269 3         8 }
7270             else {
7271 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7272             }
7273             return qq{<<\\$delimiter};
7274             }
7275              
7276 3         10 # <<~"HEREDOC"
7277 6         14 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
7278 6         14 $slash = 'm//';
7279             my $here_quote = $1;
7280             my $delimiter = $2;
7281 6 50       11  
7282 6         11 # get here document
7283 6         21 if ($here_script eq '') {
7284             $here_script = CORE::substr $_, pos $_;
7285 6 50       31 $here_script =~ s/.*?\n//oxm;
7286 6         69 }
7287 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
7288 6         7 my $heredoc = $1;
7289 6         52 my $indent = $2;
7290 6         16 $heredoc =~ s{^$indent}{}msg; # no /ox
7291             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
7292             push @heredoc_delimiter, qq{\\s*$delimiter};
7293 6         14 }
7294             else {
7295 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7296             }
7297             return qq{<<"$delimiter"};
7298             }
7299              
7300 6         22 # <<~HEREDOC
7301 3         8 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
7302 3         7 $slash = 'm//';
7303             my $here_quote = $1;
7304             my $delimiter = $2;
7305 3 50       8  
7306 3         8 # get here document
7307 3         14 if ($here_script eq '') {
7308             $here_script = CORE::substr $_, pos $_;
7309 3 50       16 $here_script =~ s/.*?\n//oxm;
7310 3         39 }
7311 3         7 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
7312 3         6 my $heredoc = $1;
7313 3         35 my $indent = $2;
7314 3         12 $heredoc =~ s{^$indent}{}msg; # no /ox
7315             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
7316             push @heredoc_delimiter, qq{\\s*$delimiter};
7317 3         10 }
7318             else {
7319 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7320             }
7321             return qq{<<$delimiter};
7322             }
7323              
7324 3         11 # <<~`HEREDOC`
7325 6         13 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
7326 6         12 $slash = 'm//';
7327             my $here_quote = $1;
7328             my $delimiter = $2;
7329 6 50       12  
7330 6         13 # get here document
7331 6         19 if ($here_script eq '') {
7332             $here_script = CORE::substr $_, pos $_;
7333 6 50       38 $here_script =~ s/.*?\n//oxm;
7334 6         54 }
7335 6         13 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
7336 6         8 my $heredoc = $1;
7337 6         49 my $indent = $2;
7338 6         31 $heredoc =~ s{^$indent}{}msg; # no /ox
7339             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
7340             push @heredoc_delimiter, qq{\\s*$delimiter};
7341 6         14 }
7342             else {
7343 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7344             }
7345             return qq{<<`$delimiter`};
7346             }
7347              
7348 6         22 # <<'HEREDOC'
7349 86         224 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
7350 86         187 $slash = 'm//';
7351             my $here_quote = $1;
7352             my $delimiter = $2;
7353 86 100       163  
7354 86         167 # get here document
7355 83         371 if ($here_script eq '') {
7356             $here_script = CORE::substr $_, pos $_;
7357 83 50       445 $here_script =~ s/.*?\n//oxm;
7358 86         654 }
7359 86         291 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
7360             push @heredoc, $1 . qq{\n$delimiter\n};
7361             push @heredoc_delimiter, $delimiter;
7362 86         130 }
7363             else {
7364 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7365             }
7366             return $here_quote;
7367             }
7368              
7369             # <<\HEREDOC
7370              
7371             # P.66 2.6.6. "Here" Documents
7372             # in Chapter 2: Bits and Pieces
7373             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7374              
7375             # P.73 "Here" Documents
7376             # in Chapter 2: Bits and Pieces
7377             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7378 86         319  
7379 2         5 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
7380 2         5 $slash = 'm//';
7381             my $here_quote = $1;
7382             my $delimiter = $2;
7383 2 100       3  
7384 2         6 # get here document
7385 1         6 if ($here_script eq '') {
7386             $here_script = CORE::substr $_, pos $_;
7387 1 50       5 $here_script =~ s/.*?\n//oxm;
7388 2         36 }
7389 2         10 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
7390             push @heredoc, $1 . qq{\n$delimiter\n};
7391             push @heredoc_delimiter, $delimiter;
7392 2         3 }
7393             else {
7394 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7395             }
7396             return $here_quote;
7397             }
7398              
7399 2         9 # <<"HEREDOC"
7400 39         113 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
7401 39         99 $slash = 'm//';
7402             my $here_quote = $1;
7403             my $delimiter = $2;
7404 39 100       80  
7405 39         99 # get here document
7406 38         228 if ($here_script eq '') {
7407             $here_script = CORE::substr $_, pos $_;
7408 38 50       208 $here_script =~ s/.*?\n//oxm;
7409 39         561 }
7410 39         130 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
7411             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
7412             push @heredoc_delimiter, $delimiter;
7413 39         93 }
7414             else {
7415 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7416             }
7417             return $here_quote;
7418             }
7419              
7420 39         151 # <
7421 54         135 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
7422 54         117 $slash = 'm//';
7423             my $here_quote = $1;
7424             my $delimiter = $2;
7425 54 100       110  
7426 54         129 # get here document
7427 51         326 if ($here_script eq '') {
7428             $here_script = CORE::substr $_, pos $_;
7429 51 50       385 $here_script =~ s/.*?\n//oxm;
7430 54         754 }
7431 54         189 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
7432             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
7433             push @heredoc_delimiter, $delimiter;
7434 54         109 }
7435             else {
7436 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7437             }
7438             return $here_quote;
7439             }
7440              
7441 54         222 # <<`HEREDOC`
7442 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
7443 0         0 $slash = 'm//';
7444             my $here_quote = $1;
7445             my $delimiter = $2;
7446 0 0       0  
7447 0         0 # get here document
7448 0         0 if ($here_script eq '') {
7449             $here_script = CORE::substr $_, pos $_;
7450 0 0       0 $here_script =~ s/.*?\n//oxm;
7451 0         0 }
7452 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
7453             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
7454             push @heredoc_delimiter, $delimiter;
7455 0         0 }
7456             else {
7457 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
7458             }
7459             return $here_quote;
7460             }
7461              
7462 0         0 # <<= <=> <= < operator
7463             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
7464             return $1;
7465             }
7466              
7467 13         76 #
7468             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
7469             return $1;
7470             }
7471              
7472             # --- glob
7473              
7474             # avoid "Error: Runtime exception" of perl version 5.005_03
7475 0         0  
7476             elsif (/\G < ((?:[^\x81-\xFE>\0\a\e\f\n\r\t]|[\x81-\xFE][\x00-\xFF])+?) > /oxgc) {
7477             return 'Egbk::glob("' . $1 . '")';
7478             }
7479 0         0  
7480             # __DATA__
7481             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
7482 0         0  
7483             # __END__
7484             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
7485              
7486             # \cD Control-D
7487              
7488             # P.68 2.6.8. Other Literal Tokens
7489             # in Chapter 2: Bits and Pieces
7490             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
7491              
7492             # P.76 Other Literal Tokens
7493             # in Chapter 2: Bits and Pieces
7494 384         3066 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7495              
7496             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
7497 0         0  
7498             # \cZ Control-Z
7499             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
7500              
7501             # any operator before div
7502             elsif (/\G (
7503             -- | \+\+ |
7504 0         0 [\)\}\]]
  14173         32016  
7505              
7506             ) /oxgc) { $slash = 'div'; return $1; }
7507              
7508             # yada-yada or triple-dot operator
7509             elsif (/\G (
7510 14173         78197 \.\.\.
  7         29  
7511              
7512             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
7513              
7514             # any operator before m//
7515              
7516             # //, //= (defined-or)
7517              
7518             # P.164 Logical Operators
7519             # in Chapter 10: More Control Structures
7520             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
7521              
7522             # P.119 C-Style Logical (Short-Circuit) Operators
7523             # in Chapter 3: Unary and Binary Operators
7524             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7525              
7526             # (and so on)
7527              
7528             # ~~
7529              
7530             # P.221 The Smart Match Operator
7531             # in Chapter 15: Smart Matching and given-when
7532             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
7533              
7534             # P.112 Smartmatch Operator
7535             # in Chapter 3: Unary and Binary Operators
7536             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
7537              
7538             # (and so on)
7539              
7540             elsif (/\G ((?>
7541              
7542             !~~ | !~ | != | ! |
7543             %= | % |
7544             &&= | && | &= | &\.= | &\. | & |
7545             -= | -> | - |
7546             :(?>\s*)= |
7547             : |
7548             <<>> |
7549             <<= | <=> | <= | < |
7550             == | => | =~ | = |
7551             >>= | >> | >= | > |
7552             \*\*= | \*\* | \*= | \* |
7553             \+= | \+ |
7554             \.\. | \.= | \. |
7555             \/\/= | \/\/ |
7556             \/= | \/ |
7557             \? |
7558             \\ |
7559             \^= | \^\.= | \^\. | \^ |
7560             \b x= |
7561             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
7562             ~~ | ~\. | ~ |
7563             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
7564             \b(?: print )\b |
7565              
7566 7         68 [,;\(\{\[]
  23824         51225  
7567              
7568             )) /oxgc) { $slash = 'm//'; return $1; }
7569 23824         114653  
  36996         78172  
7570             # other any character
7571             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
7572              
7573 36996         196073 # system error
7574             else {
7575             die __FILE__, ": Oops, this shouldn't happen!\n";
7576             }
7577             }
7578              
7579 0     3109 0 0 # escape GBK string
7580 3109         7187 sub e_string {
7581             my($string) = @_;
7582 3109         4339 my $e_string = '';
7583              
7584             local $slash = 'm//';
7585              
7586             # P.1024 Appendix W.10 Multibyte Processing
7587             # of ISBN 1-56592-224-7 CJKV Information Processing
7588 3109         4356 # (and so on)
7589              
7590             my @char = $string =~ / \G (?>[^\x81-\xFE\\]|\\$q_char|$q_char) /oxmsg;
7591 3109 100 66     28204  
7592 3109 50       14162 # without { ... }
7593 3018         6565 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
7594             if ($string !~ /<
7595             return $string;
7596             }
7597             }
7598 3018         7354  
7599 91 50       273 E_STRING_LOOP:
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    50          
    50          
7600             while ($string !~ /\G \z/oxgc) {
7601             if (0) {
7602             }
7603 794         39963  
7604 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Egbk::PREMATCH()]}
7605 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
7606             $e_string .= q{Egbk::PREMATCH()};
7607             $slash = 'div';
7608             }
7609              
7610 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Egbk::MATCH()]}
7611 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
7612             $e_string .= q{Egbk::MATCH()};
7613             $slash = 'div';
7614             }
7615              
7616 0         0 # $', ${'} --> $', ${'}
7617 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
7618             $e_string .= $1;
7619             $slash = 'div';
7620             }
7621              
7622 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Egbk::POSTMATCH()]}
7623 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
7624             $e_string .= q{Egbk::POSTMATCH()};
7625             $slash = 'div';
7626             }
7627              
7628 0         0 # bareword
7629 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
7630             $e_string .= $1;
7631             $slash = 'div';
7632             }
7633              
7634 0         0 # $0 --> $0
7635 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
7636             $e_string .= $1;
7637             $slash = 'div';
7638 0         0 }
7639 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
7640             $e_string .= $1;
7641             $slash = 'div';
7642             }
7643              
7644 0         0 # $$ --> $$
7645 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
7646             $e_string .= $1;
7647             $slash = 'div';
7648             }
7649              
7650             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
7651 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
7652 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
7653             $e_string .= e_capture($1);
7654             $slash = 'div';
7655 0         0 }
7656 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
7657             $e_string .= e_capture($1);
7658             $slash = 'div';
7659             }
7660              
7661 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
7662 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
7663             $e_string .= e_capture($1.'->'.$2);
7664             $slash = 'div';
7665             }
7666              
7667 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7668 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
7669             $e_string .= e_capture($1.'->'.$2);
7670             $slash = 'div';
7671             }
7672              
7673 0         0 # $$foo
7674 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
7675             $e_string .= e_capture($1);
7676             $slash = 'div';
7677             }
7678              
7679 0         0 # ${ foo }
7680 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
7681             $e_string .= '${' . $1 . '}';
7682             $slash = 'div';
7683             }
7684              
7685 0         0 # ${ ... }
7686 3         14 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
7687             $e_string .= e_capture($1);
7688             $slash = 'div';
7689             }
7690              
7691             # variable or function
7692 3         18 # $ @ % & * $ #
7693 0         0 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) {
7694             $e_string .= $1;
7695             $slash = 'div';
7696             }
7697             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
7698 0         0 # $ @ # \ ' " / ? ( ) [ ] < >
7699 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
7700             $e_string .= $1;
7701             $slash = 'div';
7702             }
7703              
7704 0         0 # subroutines of package Egbk
  0         0  
7705 0         0 elsif ($string =~ /\G (-[rwxoRWXOezfdlpSbcugkTB] (?>(?:\s+ -[rwxoRWXOezfdlpSbcugkTB])+))
  0         0  
7706 0         0 (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_qq('', $2,$4,$3) . ")"; $slash = 'm//'; }
  0         0  
7707 0         0 elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; $slash = 'm//'; }
  0         0  
7708 0         0 elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; $slash = 'm//'; }
  0         0  
7709 0         0 elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; $slash = 'm//'; }
  0         0  
7710 0         0 elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; $slash = 'm//'; }
  1         8  
7711             elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; $slash = 'm//'; }
7712             elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) qq (?>\s*) (\S) ((?:$qq_char)+?) (\2) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_qq('qq',$2,$4,$3) . ")"; $slash = 'm//'; }
7713 1         5  
  1         7  
7714 1         5 elsif ($string =~ /\G (-[rwxoRWXOezfdlpSbcugkTB] (?>(?:\s+ -[rwxoRWXOezfdlpSbcugkTB])+))
  0         0  
7715 0         0 (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_q ('', $2,$4,$3) . ")"; $slash = 'm//'; }
  0         0  
7716 0         0 elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; $slash = 'm//'; }
  0         0  
7717 0         0 elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; $slash = 'm//'; }
  0         0  
7718 0         0 elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; $slash = 'm//'; }
  0         0  
7719 0         0 elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; $slash = 'm//'; }
  1         7  
7720             elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; $slash = 'm//'; }
7721             elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) q (?>\s*) (\S) ((?:\\\2|\\\\|$q_char)+?) (\2) /oxgc) { $e_string .= "Egbk::filetest(qw($1)," . e_q ('q', $2,$4,$3) . ")"; $slash = 'm//'; }
7722 1         4  
  0         0  
7723 0         0 elsif ($string =~ /\G (-[rwxoRWXOezfdlpSbcugkTB] (?>(?:\s+ -[rwxoRWXOezfdlpSbcugkTB])+)) (\$ (?> \w+ (?: ::\w+)*) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
7724 0         0 { $e_string .= "Egbk::filetest(qw($1),$2)"; $slash = 'm//'; }
  0         0  
7725 0         0 elsif ($string =~ /\G (-[rwxoRWXOezfdlpSbcugkTB] (?>(?:\s+ -[rwxoRWXOezfdlpSbcugkTB])+)) \( ((?:$qq_paren)*?) \) /oxgc) { $e_string .= "Egbk::filetest(qw($1),$2)"; $slash = 'm//'; }
  0         0  
7726             elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) (?= [a-z]+) /oxgc) { $e_string .= "Egbk::filetest qw($1),"; $slash = 'm//'; }
7727             elsif ($string =~ /\G ((?:-[rwxoRWXOezfdlpSbcugkTB](?>\s+)){2,}) ((?>\w+)) /oxgc) { $e_string .= "Egbk::filetest(qw($1),$2)"; $slash = 'm//'; }
7728              
7729 0         0 # qq//
7730 2 50       6 elsif ($string =~ /\G \b (qq) \b /oxgc) {
7731 2         40 my $ope = $1;
7732             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
7733             $e_string .= e_qq($ope,$1,$3,$2);
7734 0         0 }
7735 2         5 else {
7736 2 50       7 my $e = '';
  2 50       273  
    50          
    50          
    50          
    50          
7737 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
7738 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
7739 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
7740 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
7741 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  2         8  
7742             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
7743 2         13 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
7744             }
7745             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
7746             }
7747             }
7748              
7749 0         0 # qx//
7750 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
7751 0         0 my $ope = $1;
7752             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
7753             $e_string .= e_qq($ope,$1,$3,$2);
7754 0         0 }
7755 0         0 else {
7756 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
7757 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
7758 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
7759 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
7760 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
7761 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
7762 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
7763             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
7764 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
7765             }
7766             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
7767             }
7768             }
7769              
7770 0         0 # q//
7771 2 50       6 elsif ($string =~ /\G \b (q) \b /oxgc) {
7772 2         46 my $ope = $1;
7773             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
7774             $e_string .= e_q($ope,$1,$3,$2);
7775 0         0 }
7776 2         4 else {
7777 2 50       8 my $e = '';
  2 50       224  
    50          
    50          
    50          
    50          
7778 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
7779 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
7780 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
7781 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
7782 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  2         8  
7783             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
7784 2         18 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q * *
7785             }
7786             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
7787             }
7788             }
7789 0         0  
7790             # ''
7791             elsif ($string =~ /\G (?
7792 45         167  
7793             # ""
7794             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
7795 6         22  
7796             # ``
7797             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
7798 0         0  
7799             # other any character
7800             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
7801              
7802 733         2133 # system error
7803             else {
7804             die __FILE__, ": Oops, this shouldn't happen!\n";
7805             }
7806 0         0 }
7807              
7808             return $e_string;
7809             }
7810              
7811             #
7812             # character class
7813 91     5434 0 349 #
7814             sub character_class {
7815 5434 100       10062 my($char,$modifier) = @_;
7816 5434 100       8008  
7817 115         237 if ($char eq '.') {
7818             if ($modifier =~ /s/) {
7819             return '${Egbk::dot_s}';
7820 23         58 }
7821             else {
7822             return '${Egbk::dot}';
7823             }
7824 92         202 }
7825             else {
7826             return Egbk::classic_character_class($char);
7827             }
7828             }
7829              
7830             #
7831             # escape capture ($1, $2, $3, ...)
7832             #
7833 5319     637 0 9210 sub e_capture {
7834 637         2616  
7835             return join '', '${Egbk::capture(', $_[0], ')}';
7836             return join '', '${', $_[0], '}';
7837             }
7838              
7839             #
7840             # escape transliteration (tr/// or y///)
7841 0     11 0 0 #
7842 11         76 sub e_tr {
7843 11   100     22 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
7844             my $e_tr = '';
7845 11         31 $modifier ||= '';
7846              
7847             $slash = 'div';
7848 11         20  
7849             # quote character class 1
7850             $charclass = q_tr($charclass);
7851 11         22  
7852             # quote character class 2
7853             $charclass2 = q_tr($charclass2);
7854 11 50       39  
7855 11 0       34 # /b /B modifier
7856 0         0 if ($modifier =~ tr/bB//d) {
7857             if ($variable eq '') {
7858             $e_tr = qq{tr$charclass$e$charclass2$modifier};
7859 0         0 }
7860             else {
7861             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
7862             }
7863 0 100       0 }
7864 11         25 else {
7865             if ($variable eq '') {
7866             $e_tr = qq{Egbk::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
7867 2         8 }
7868             else {
7869             $e_tr = qq{Egbk::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
7870             }
7871             }
7872 9         27  
7873 11         16 # clear tr/// variable
7874             $tr_variable = '';
7875 11         15 $bind_operator = '';
7876              
7877             return $e_tr;
7878             }
7879              
7880             #
7881             # quote for escape transliteration (tr/// or y///)
7882 11     22 0 68 #
7883             sub q_tr {
7884             my($charclass) = @_;
7885 22 50       35  
    0          
    0          
    0          
    0          
    0          
7886 22         73 # quote character class
7887             if ($charclass !~ /'/oxms) {
7888             return e_q('', "'", "'", $charclass); # --> q' '
7889 22         41 }
7890             elsif ($charclass !~ /\//oxms) {
7891             return e_q('q', '/', '/', $charclass); # --> q/ /
7892 0         0 }
7893             elsif ($charclass !~ /\#/oxms) {
7894             return e_q('q', '#', '#', $charclass); # --> q# #
7895 0         0 }
7896             elsif ($charclass !~ /[\<\>]/oxms) {
7897             return e_q('q', '<', '>', $charclass); # --> q< >
7898 0         0 }
7899             elsif ($charclass !~ /[\(\)]/oxms) {
7900             return e_q('q', '(', ')', $charclass); # --> q( )
7901 0         0 }
7902             elsif ($charclass !~ /[\{\}]/oxms) {
7903             return e_q('q', '{', '}', $charclass); # --> q{ }
7904 0         0 }
7905 0 0       0 else {
7906 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
7907             if ($charclass !~ /\Q$char\E/xms) {
7908             return e_q('q', $char, $char, $charclass);
7909             }
7910             }
7911 0         0 }
7912              
7913             return e_q('q', '{', '}', $charclass);
7914             }
7915              
7916             #
7917             # escape q string (q//, '')
7918 0     3967 0 0 #
7919             sub e_q {
7920 3967         10390 my($ope,$delimiter,$end_delimiter,$string) = @_;
7921              
7922 3967         5685 $slash = 'div';
7923 3967         26542  
7924             my @char = $string =~ / \G (?>$q_char) /oxmsg;
7925             for (my $i=0; $i <= $#char; $i++) {
7926 3967 100 100     11010  
    100 100        
7927 21145         122147 # escape last octet of multiple-octet
7928             if ($char[$i] =~ /\A ([\x80-\xFF].*) (\Q$delimiter\E|\Q$end_delimiter\E) \z/xms) {
7929             $char[$i] = $1 . '\\' . $2;
7930 1         5 }
7931             elsif (defined($char[$i+1]) and ($char[$i+1] eq '\\') and ($char[$i] =~ /\A ([\x80-\xFF].*) (\\) \z/xms)) {
7932             $char[$i] = $1 . '\\' . $2;
7933 22 100 100     115 }
7934 3967         15329 }
7935             if (defined($char[-1]) and ($char[-1] =~ /\A ([\x80-\xFF].*) (\\) \z/xms)) {
7936             $char[-1] = $1 . '\\' . $2;
7937 204         607 }
7938 3967         21458  
7939             return join '', $ope, $delimiter, @char, $end_delimiter;
7940             return join '', $ope, $delimiter, $string, $end_delimiter;
7941             }
7942              
7943             #
7944             # escape qq string (qq//, "", qx//, ``)
7945 0     9556 0 0 #
7946             sub e_qq {
7947 9556         22136 my($ope,$delimiter,$end_delimiter,$string) = @_;
7948              
7949 9556         13153 $slash = 'div';
7950 9556         11316  
7951             my $left_e = 0;
7952             my $right_e = 0;
7953 9556         10503  
7954             # split regexp
7955             my @char = $string =~ /\G((?>
7956             [^\x81-\xFE\\\$]|[\x81-\xFE][\x00-\xFF] |
7957             \\x\{ (?>[0-9A-Fa-f]+) \} |
7958             \\o\{ (?>[0-7]+) \} |
7959             \\N\{ (?>[^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} |
7960             \\ $q_char |
7961             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
7962             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
7963             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
7964             \$ (?>\s* [0-9]+) |
7965             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
7966             \$ \$ (?![\w\{]) |
7967             \$ (?>\s*) \$ (?>\s*) $qq_variable |
7968             $q_char
7969 9556         354888 ))/oxmsg;
7970              
7971             for (my $i=0; $i <= $#char; $i++) {
7972 9556 50 66     30011  
    50 33        
    100          
    100          
    50          
7973 307188         998832 # "\L\u" --> "\u\L"
7974             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
7975             @char[$i,$i+1] = @char[$i+1,$i];
7976             }
7977              
7978 0         0 # "\U\l" --> "\l\U"
7979             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
7980             @char[$i,$i+1] = @char[$i+1,$i];
7981             }
7982              
7983 0         0 # octal escape sequence
7984             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
7985             $char[$i] = Egbk::octchr($1);
7986             }
7987              
7988 1         4 # hexadecimal escape sequence
7989             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
7990             $char[$i] = Egbk::hexchr($1);
7991             }
7992              
7993 1         5 # \N{CHARNAME} --> N{CHARNAME}
7994             elsif ($char[$i] =~ /\A \\ ( N\{ ([^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} ) \z/oxms) {
7995             $char[$i] = $1;
7996 0 100       0 }
    100          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
7997              
7998             if (0) {
7999             }
8000              
8001             # escape last octet of multiple-octet
8002 307188         2898994 # my $metachar = qr/[\@\\\|]/oxms; # '|' is for qx//, ``, open(), and system()
8003 0         0 # variable $delimiter and $end_delimiter can be ''
8004             elsif ($char[$i] =~ /\A ([\x80-\xFF].*) ([\@\\\|$delimiter$end_delimiter]) \z/xms) {
8005             $char[$i] = $1 . '\\' . $2;
8006             }
8007              
8008             # \F
8009             #
8010             # P.69 Table 2-6. Translation escapes
8011             # in Chapter 2: Bits and Pieces
8012             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
8013             # (and so on)
8014              
8015 1342 50       4541 # \u \l \U \L \F \Q \E
8016 647         1577 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
8017             if ($right_e < $left_e) {
8018             $char[$i] = '\\' . $char[$i];
8019             }
8020             }
8021             elsif ($char[$i] eq '\u') {
8022              
8023             # "STRING @{[ LIST EXPR ]} MORE STRING"
8024              
8025             # P.257 Other Tricks You Can Do with Hard References
8026             # in Chapter 8: References
8027             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
8028              
8029             # P.353 Other Tricks You Can Do with Hard References
8030             # in Chapter 8: References
8031             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
8032              
8033 0         0 # (and so on)
8034 0         0  
8035             $char[$i] = '@{[Egbk::ucfirst qq<';
8036             $left_e++;
8037 0         0 }
8038 0         0 elsif ($char[$i] eq '\l') {
8039             $char[$i] = '@{[Egbk::lcfirst qq<';
8040             $left_e++;
8041 0         0 }
8042 0         0 elsif ($char[$i] eq '\U') {
8043             $char[$i] = '@{[Egbk::uc qq<';
8044             $left_e++;
8045 0         0 }
8046 6         7 elsif ($char[$i] eq '\L') {
8047             $char[$i] = '@{[Egbk::lc qq<';
8048             $left_e++;
8049 6         11 }
8050 9         19 elsif ($char[$i] eq '\F') {
8051             $char[$i] = '@{[Egbk::fc qq<';
8052             $left_e++;
8053 9         21 }
8054 0         0 elsif ($char[$i] eq '\Q') {
8055             $char[$i] = '@{[CORE::quotemeta qq<';
8056             $left_e++;
8057 0 50       0 }
8058 12         22 elsif ($char[$i] eq '\E') {
8059 12         19 if ($right_e < $left_e) {
8060             $char[$i] = '>]}';
8061             $right_e++;
8062 12         24 }
8063             else {
8064             $char[$i] = '';
8065             }
8066 0         0 }
8067 0 0       0 elsif ($char[$i] eq '\Q') {
8068 0         0 while (1) {
8069             if (++$i > $#char) {
8070 0 0       0 last;
8071 0         0 }
8072             if ($char[$i] eq '\E') {
8073             last;
8074             }
8075             }
8076             }
8077             elsif ($char[$i] eq '\E') {
8078             }
8079              
8080             # $0 --> $0
8081             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
8082             }
8083             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
8084             }
8085              
8086             # $$ --> $$
8087             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
8088             }
8089              
8090             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
8091 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
8092             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
8093             $char[$i] = e_capture($1);
8094 415         1196 }
8095             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
8096             $char[$i] = e_capture($1);
8097             }
8098              
8099 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
8100             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
8101             $char[$i] = e_capture($1.'->'.$2);
8102             }
8103              
8104 0         0 # $$foo{ ... } --> $ $foo->{ ... }
8105             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
8106             $char[$i] = e_capture($1.'->'.$2);
8107             }
8108              
8109 0         0 # $$foo
8110             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
8111             $char[$i] = e_capture($1);
8112             }
8113              
8114 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egbk::PREMATCH()
8115             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
8116             $char[$i] = '@{[Egbk::PREMATCH()]}';
8117             }
8118              
8119 44         141 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egbk::MATCH()
8120             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
8121             $char[$i] = '@{[Egbk::MATCH()]}';
8122             }
8123              
8124 45         153 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egbk::POSTMATCH()
8125             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
8126             $char[$i] = '@{[Egbk::POSTMATCH()]}';
8127             }
8128              
8129             # ${ foo } --> ${ foo }
8130             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
8131             }
8132              
8133 33         105 # ${ ... }
8134             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
8135             $char[$i] = e_capture($1);
8136             }
8137             }
8138 0 100       0  
8139 9556         19946 # return string
8140             if ($left_e > $right_e) {
8141 3         19 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
8142             }
8143             return join '', $ope, $delimiter, @char, $end_delimiter;
8144             }
8145              
8146             #
8147             # escape qw string (qw//)
8148 9553     34 0 90207 #
8149             sub e_qw {
8150 34         213 my($ope,$delimiter,$end_delimiter,$string) = @_;
8151              
8152             $slash = 'div';
8153 34         84  
  34         352  
8154 621 50       1107 # choice again delimiter
    0          
    0          
    0          
    0          
8155 34         194 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
8156             if (not $octet{$end_delimiter}) {
8157             return join '', $ope, $delimiter, $string, $end_delimiter;
8158 34         271 }
8159             elsif (not $octet{')'}) {
8160             return join '', $ope, '(', $string, ')';
8161 0         0 }
8162             elsif (not $octet{'}'}) {
8163             return join '', $ope, '{', $string, '}';
8164 0         0 }
8165             elsif (not $octet{']'}) {
8166             return join '', $ope, '[', $string, ']';
8167 0         0 }
8168             elsif (not $octet{'>'}) {
8169             return join '', $ope, '<', $string, '>';
8170 0         0 }
8171 0 0       0 else {
8172 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
8173             if (not $octet{$char}) {
8174             return join '', $ope, $char, $string, $char;
8175             }
8176             }
8177             }
8178 0         0  
8179 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
8180 0         0 my @string = CORE::split(/\s+/, $string);
8181 0         0 for my $string (@string) {
8182 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
8183 0         0 for my $octet (@octet) {
8184             if ($octet =~ /\A (['\\]) \z/oxms) {
8185             $octet = '\\' . $1;
8186 0         0 }
8187             }
8188 0         0 $string = join '', @octet;
  0         0  
8189             }
8190             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
8191             }
8192              
8193             #
8194             # escape here document (<<"HEREDOC", <
8195 0     108 0 0 #
8196             sub e_heredoc {
8197 108         281 my($string) = @_;
8198              
8199 108         167 $slash = 'm//';
8200              
8201 108         355 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
8202 108         170  
8203             my $left_e = 0;
8204             my $right_e = 0;
8205 108         136  
8206             # split regexp
8207             my @char = $string =~ /\G((?>
8208             [^\x81-\xFE\\\$]|[\x81-\xFE][\x00-\xFF] |
8209             \\x\{ (?>[0-9A-Fa-f]+) \} |
8210             \\o\{ (?>[0-7]+) \} |
8211             \\N\{ (?>[^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} |
8212             \\ $q_char |
8213             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
8214             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
8215             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
8216             \$ (?>\s* [0-9]+) |
8217             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
8218             \$ \$ (?![\w\{]) |
8219             \$ (?>\s*) \$ (?>\s*) $qq_variable |
8220             $q_char
8221 108         10714 ))/oxmsg;
8222              
8223             for (my $i=0; $i <= $#char; $i++) {
8224 108 50 66     502  
    50 33        
    100          
    100          
    50          
8225 3199         9368 # "\L\u" --> "\u\L"
8226             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
8227             @char[$i,$i+1] = @char[$i+1,$i];
8228             }
8229              
8230 0         0 # "\U\l" --> "\l\U"
8231             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
8232             @char[$i,$i+1] = @char[$i+1,$i];
8233             }
8234              
8235 0         0 # octal escape sequence
8236             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
8237             $char[$i] = Egbk::octchr($1);
8238             }
8239              
8240 1         3 # hexadecimal escape sequence
8241             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
8242             $char[$i] = Egbk::hexchr($1);
8243             }
8244              
8245 1         3 # \N{CHARNAME} --> N{CHARNAME}
8246             elsif ($char[$i] =~ /\A \\ ( N\{ ([^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} ) \z/oxms) {
8247             $char[$i] = $1;
8248 0 100       0 }
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
8249              
8250             if (0) {
8251             }
8252 3199         26702  
8253 0         0 # escape character
8254             elsif ($char[$i] =~ /\A ([\x80-\xFF].*) ($metachar) \z/oxms) {
8255             $char[$i] = $1 . '\\' . $2;
8256             }
8257              
8258 57 50       226 # \u \l \U \L \F \Q \E
8259 72         134 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
8260             if ($right_e < $left_e) {
8261             $char[$i] = '\\' . $char[$i];
8262             }
8263 0         0 }
8264 0         0 elsif ($char[$i] eq '\u') {
8265             $char[$i] = '@{[Egbk::ucfirst qq<';
8266             $left_e++;
8267 0         0 }
8268 0         0 elsif ($char[$i] eq '\l') {
8269             $char[$i] = '@{[Egbk::lcfirst qq<';
8270             $left_e++;
8271 0         0 }
8272 0         0 elsif ($char[$i] eq '\U') {
8273             $char[$i] = '@{[Egbk::uc qq<';
8274             $left_e++;
8275 0         0 }
8276 6         10 elsif ($char[$i] eq '\L') {
8277             $char[$i] = '@{[Egbk::lc qq<';
8278             $left_e++;
8279 6         9 }
8280 0         0 elsif ($char[$i] eq '\F') {
8281             $char[$i] = '@{[Egbk::fc qq<';
8282             $left_e++;
8283 0         0 }
8284 0         0 elsif ($char[$i] eq '\Q') {
8285             $char[$i] = '@{[CORE::quotemeta qq<';
8286             $left_e++;
8287 0 50       0 }
8288 3         6 elsif ($char[$i] eq '\E') {
8289 3         5 if ($right_e < $left_e) {
8290             $char[$i] = '>]}';
8291             $right_e++;
8292 3         5 }
8293             else {
8294             $char[$i] = '';
8295             }
8296 0         0 }
8297 0 0       0 elsif ($char[$i] eq '\Q') {
8298 0         0 while (1) {
8299             if (++$i > $#char) {
8300 0 0       0 last;
8301 0         0 }
8302             if ($char[$i] eq '\E') {
8303             last;
8304             }
8305             }
8306             }
8307             elsif ($char[$i] eq '\E') {
8308             }
8309              
8310             # $0 --> $0
8311             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
8312             }
8313             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
8314             }
8315              
8316             # $$ --> $$
8317             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
8318             }
8319              
8320             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
8321 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
8322             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
8323             $char[$i] = e_capture($1);
8324 0         0 }
8325             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
8326             $char[$i] = e_capture($1);
8327             }
8328              
8329 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
8330             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
8331             $char[$i] = e_capture($1.'->'.$2);
8332             }
8333              
8334 0         0 # $$foo{ ... } --> $ $foo->{ ... }
8335             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
8336             $char[$i] = e_capture($1.'->'.$2);
8337             }
8338              
8339 0         0 # $$foo
8340             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
8341             $char[$i] = e_capture($1);
8342             }
8343              
8344 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egbk::PREMATCH()
8345             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
8346             $char[$i] = '@{[Egbk::PREMATCH()]}';
8347             }
8348              
8349 8         52 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egbk::MATCH()
8350             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
8351             $char[$i] = '@{[Egbk::MATCH()]}';
8352             }
8353              
8354 8         58 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egbk::POSTMATCH()
8355             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
8356             $char[$i] = '@{[Egbk::POSTMATCH()]}';
8357             }
8358              
8359             # ${ foo } --> ${ foo }
8360             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
8361             }
8362              
8363 6         36 # ${ ... }
8364             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
8365             $char[$i] = e_capture($1);
8366             }
8367             }
8368 0 100       0  
8369 108         227 # return string
8370             if ($left_e > $right_e) {
8371 3         23 return join '', @char, '>]}' x ($left_e - $right_e);
8372             }
8373             return join '', @char;
8374             }
8375              
8376             #
8377             # escape regexp (m//, qr//)
8378 105     1835 0 786 #
8379 1835   100     7751 sub e_qr {
8380             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8381 1835         6457 $modifier ||= '';
8382 1835 50       3477  
8383 1835         4561 $modifier =~ tr/p//d;
8384 0         0 if ($modifier =~ /([adlu])/oxms) {
8385 0 0       0 my $line = 0;
8386 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
8387 0         0 if ($filename ne __FILE__) {
8388             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
8389             last;
8390 0         0 }
8391             }
8392             die qq{Unsupported modifier "$1" used at line $line.\n};
8393 0         0 }
8394              
8395             $slash = 'div';
8396 1835 100       2960  
    100          
8397 1835         5328 # literal null string pattern
8398 8         10 if ($string eq '') {
8399 8         9 $modifier =~ tr/bB//d;
8400             $modifier =~ tr/i//d;
8401             return join '', $ope, $delimiter, $end_delimiter, $modifier;
8402             }
8403              
8404             # /b /B modifier
8405             elsif ($modifier =~ tr/bB//d) {
8406 8 50       35  
8407 240         559 # choice again delimiter
8408 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
8409 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
8410 0         0 my %octet = map {$_ => 1} @char;
8411 0         0 if (not $octet{')'}) {
8412             $delimiter = '(';
8413             $end_delimiter = ')';
8414 0         0 }
8415 0         0 elsif (not $octet{'}'}) {
8416             $delimiter = '{';
8417             $end_delimiter = '}';
8418 0         0 }
8419 0         0 elsif (not $octet{']'}) {
8420             $delimiter = '[';
8421             $end_delimiter = ']';
8422 0         0 }
8423 0         0 elsif (not $octet{'>'}) {
8424             $delimiter = '<';
8425             $end_delimiter = '>';
8426 0         0 }
8427 0 0       0 else {
8428 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
8429 0         0 if (not $octet{$char}) {
8430 0         0 $delimiter = $char;
8431             $end_delimiter = $char;
8432             last;
8433             }
8434             }
8435             }
8436 0 100 100     0 }
8437 240         1161  
8438             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
8439             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
8440 90         526 }
8441             else {
8442             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
8443             }
8444 150 100       907 }
8445 1587         4013  
8446             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
8447             my $metachar = qr/[\@\\|[\]{^]/oxms;
8448 1587         6010  
8449             # split regexp
8450             my @char = $string =~ /\G((?>
8451             [^\x81-\xFE\\\$\@\[\(]|[\x81-\xFE][\x00-\xFF] |
8452             \\x (?>[0-9A-Fa-f]{1,2}) |
8453             \\ (?>[0-7]{2,3}) |
8454             \\c [\x40-\x5F] |
8455             \\x\{ (?>[0-9A-Fa-f]+) \} |
8456             \\o\{ (?>[0-7]+) \} |
8457             \\[bBNpP]\{ (?>[^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} |
8458             \\ $q_char |
8459             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
8460             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
8461             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
8462             [\$\@] $qq_variable |
8463             \$ (?>\s* [0-9]+) |
8464             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
8465             \$ \$ (?![\w\{]) |
8466             \$ (?>\s*) \$ (?>\s*) $qq_variable |
8467             \[\^ |
8468             \[\: (?>[a-z]+) :\] |
8469             \[\:\^ (?>[a-z]+) :\] |
8470             \(\? |
8471             $q_char
8472             ))/oxmsg;
8473 1587 50       134965  
8474 1587         7177 # choice again delimiter
  0         0  
8475 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
8476 0         0 my %octet = map {$_ => 1} @char;
8477 0         0 if (not $octet{')'}) {
8478             $delimiter = '(';
8479             $end_delimiter = ')';
8480 0         0 }
8481 0         0 elsif (not $octet{'}'}) {
8482             $delimiter = '{';
8483             $end_delimiter = '}';
8484 0         0 }
8485 0         0 elsif (not $octet{']'}) {
8486             $delimiter = '[';
8487             $end_delimiter = ']';
8488 0         0 }
8489 0         0 elsif (not $octet{'>'}) {
8490             $delimiter = '<';
8491             $end_delimiter = '>';
8492 0         0 }
8493 0 0       0 else {
8494 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
8495 0         0 if (not $octet{$char}) {
8496 0         0 $delimiter = $char;
8497             $end_delimiter = $char;
8498             last;
8499             }
8500             }
8501             }
8502 0         0 }
8503 1587         2502  
8504 1587         2389 my $left_e = 0;
8505             my $right_e = 0;
8506             for (my $i=0; $i <= $#char; $i++) {
8507 1587 50 66     4414  
    50 66        
    100          
    100          
    100          
    100          
8508 5514         27317 # "\L\u" --> "\u\L"
8509             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
8510             @char[$i,$i+1] = @char[$i+1,$i];
8511             }
8512              
8513 0         0 # "\U\l" --> "\l\U"
8514             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
8515             @char[$i,$i+1] = @char[$i+1,$i];
8516             }
8517              
8518 0         0 # octal escape sequence
8519             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
8520             $char[$i] = Egbk::octchr($1);
8521             }
8522              
8523 1         3 # hexadecimal escape sequence
8524             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
8525             $char[$i] = Egbk::hexchr($1);
8526             }
8527              
8528             # \b{...} --> b\{...}
8529             # \B{...} --> B\{...}
8530             # \N{CHARNAME} --> N\{CHARNAME}
8531             # \p{PROPERTY} --> p\{PROPERTY}
8532 1         4 # \P{PROPERTY} --> P\{PROPERTY}
8533             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} ) \z/oxms) {
8534             $char[$i] = $1 . '\\' . $2;
8535             }
8536              
8537 6         20 # \p, \P, \X --> p, P, X
8538             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
8539             $char[$i] = $1;
8540 4 100 100     9 }
    100 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          
8541              
8542             if (0) {
8543             }
8544 5514         39722  
8545 0         0 # escape last octet of multiple-octet
8546             elsif ($char[$i] =~ /\A \\? ([\x80-\xFF].*) ($metachar|\Q$delimiter\E|\Q$end_delimiter\E) \z/xms) {
8547             $char[$i] = $1 . '\\' . $2;
8548             }
8549              
8550 77 50 33     350 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
8551 6         159 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
8552             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)) {
8553             $char[$i] .= join '', splice @char, $i+1, 3;
8554 0         0 }
8555             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)) {
8556             $char[$i] .= join '', splice @char, $i+1, 2;
8557 0         0 }
8558             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)) {
8559             $char[$i] .= join '', splice @char, $i+1, 1;
8560             }
8561             }
8562              
8563 0         0 # open character class [...]
8564             elsif ($char[$i] eq '[') {
8565             my $left = $i;
8566              
8567             # [] make die "Unmatched [] in regexp ...\n"
8568 586 100       867 # (and so on)
8569 586         1618  
8570             if ($char[$i+1] eq ']') {
8571             $i++;
8572 3         5 }
8573 586 50       800  
8574 2583         3996 while (1) {
8575             if (++$i > $#char) {
8576 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
8577 2583         3992 }
8578             if ($char[$i] eq ']') {
8579             my $right = $i;
8580 586 100       743  
8581 586         3175 # [...]
  90         205  
8582             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8583             splice @char, $left, $right-$left+1, sprintf(q{@{[Egbk::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8584 270         451 }
8585             else {
8586             splice @char, $left, $right-$left+1, Egbk::charlist_qr(@char[$left+1..$right-1], $modifier);
8587 496         2251 }
8588 586         1148  
8589             $i = $left;
8590             last;
8591             }
8592             }
8593             }
8594              
8595 586         1716 # open character class [^...]
8596             elsif ($char[$i] eq '[^') {
8597             my $left = $i;
8598              
8599             # [^] make die "Unmatched [] in regexp ...\n"
8600 328 100       554 # (and so on)
8601 328         765  
8602             if ($char[$i+1] eq ']') {
8603             $i++;
8604 5         9 }
8605 328 50       422  
8606 1447         2312 while (1) {
8607             if (++$i > $#char) {
8608 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
8609 1447         2410 }
8610             if ($char[$i] eq ']') {
8611             my $right = $i;
8612 328 100       413  
8613 328         1892 # [^...]
  90         307  
8614             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
8615             splice @char, $left, $right-$left+1, sprintf(q{@{[Egbk::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
8616 270         588 }
8617             else {
8618             splice @char, $left, $right-$left+1, Egbk::charlist_not_qr(@char[$left+1..$right-1], $modifier);
8619 238         1035 }
8620 328         696  
8621             $i = $left;
8622             last;
8623             }
8624             }
8625             }
8626              
8627 328         1008 # rewrite character class or escape character
8628             elsif (my $char = character_class($char[$i],$modifier)) {
8629             $char[$i] = $char;
8630             }
8631              
8632 215 50       571 # /i modifier
8633 238         396 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egbk::uc($char[$i]) ne Egbk::fc($char[$i]))) {
8634             if (CORE::length(Egbk::fc($char[$i])) == 1) {
8635             $char[$i] = '[' . Egbk::uc($char[$i]) . Egbk::fc($char[$i]) . ']';
8636 238         396 }
8637             else {
8638             $char[$i] = '(?:' . Egbk::uc($char[$i]) . '|' . Egbk::fc($char[$i]) . ')';
8639             }
8640             }
8641              
8642 0 50       0 # \u \l \U \L \F \Q \E
8643 1         5 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
8644             if ($right_e < $left_e) {
8645             $char[$i] = '\\' . $char[$i];
8646             }
8647 0         0 }
8648 0         0 elsif ($char[$i] eq '\u') {
8649             $char[$i] = '@{[Egbk::ucfirst qq<';
8650             $left_e++;
8651 0         0 }
8652 0         0 elsif ($char[$i] eq '\l') {
8653             $char[$i] = '@{[Egbk::lcfirst qq<';
8654             $left_e++;
8655 0         0 }
8656 1         2 elsif ($char[$i] eq '\U') {
8657             $char[$i] = '@{[Egbk::uc qq<';
8658             $left_e++;
8659 1         3 }
8660 1         3 elsif ($char[$i] eq '\L') {
8661             $char[$i] = '@{[Egbk::lc qq<';
8662             $left_e++;
8663 1         31 }
8664 9         23 elsif ($char[$i] eq '\F') {
8665             $char[$i] = '@{[Egbk::fc qq<';
8666             $left_e++;
8667 9         22 }
8668 22         40 elsif ($char[$i] eq '\Q') {
8669             $char[$i] = '@{[CORE::quotemeta qq<';
8670             $left_e++;
8671 22 50       52 }
8672 33         76 elsif ($char[$i] eq '\E') {
8673 33         49 if ($right_e < $left_e) {
8674             $char[$i] = '>]}';
8675             $right_e++;
8676 33         75 }
8677             else {
8678             $char[$i] = '';
8679             }
8680 0         0 }
8681 0 0       0 elsif ($char[$i] eq '\Q') {
8682 0         0 while (1) {
8683             if (++$i > $#char) {
8684 0 0       0 last;
8685 0         0 }
8686             if ($char[$i] eq '\E') {
8687             last;
8688             }
8689             }
8690             }
8691             elsif ($char[$i] eq '\E') {
8692             }
8693              
8694 0 0       0 # $0 --> $0
8695 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
8696             if ($ignorecase) {
8697             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8698             }
8699 0 0       0 }
8700 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
8701             if ($ignorecase) {
8702             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8703             }
8704             }
8705              
8706             # $$ --> $$
8707             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
8708             }
8709              
8710             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
8711 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
8712 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
8713 0         0 $char[$i] = e_capture($1);
8714             if ($ignorecase) {
8715             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8716             }
8717 0         0 }
8718 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
8719 0         0 $char[$i] = e_capture($1);
8720             if ($ignorecase) {
8721             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8722             }
8723             }
8724              
8725 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
8726 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) {
8727 0         0 $char[$i] = e_capture($1.'->'.$2);
8728             if ($ignorecase) {
8729             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8730             }
8731             }
8732              
8733 0         0 # $$foo{ ... } --> $ $foo->{ ... }
8734 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) {
8735 0         0 $char[$i] = e_capture($1.'->'.$2);
8736             if ($ignorecase) {
8737             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8738             }
8739             }
8740              
8741 0         0 # $$foo
8742 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
8743 0         0 $char[$i] = e_capture($1);
8744             if ($ignorecase) {
8745             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8746             }
8747             }
8748              
8749 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egbk::PREMATCH()
8750 8         20 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
8751             if ($ignorecase) {
8752             $char[$i] = '@{[Egbk::ignorecase(Egbk::PREMATCH())]}';
8753 0         0 }
8754             else {
8755             $char[$i] = '@{[Egbk::PREMATCH()]}';
8756             }
8757             }
8758              
8759 8 50       29 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egbk::MATCH()
8760 8         21 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
8761             if ($ignorecase) {
8762             $char[$i] = '@{[Egbk::ignorecase(Egbk::MATCH())]}';
8763 0         0 }
8764             else {
8765             $char[$i] = '@{[Egbk::MATCH()]}';
8766             }
8767             }
8768              
8769 8 50       25 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egbk::POSTMATCH()
8770 6         17 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
8771             if ($ignorecase) {
8772             $char[$i] = '@{[Egbk::ignorecase(Egbk::POSTMATCH())]}';
8773 0         0 }
8774             else {
8775             $char[$i] = '@{[Egbk::POSTMATCH()]}';
8776             }
8777             }
8778              
8779 6 0       22 # ${ foo }
8780 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) {
8781             if ($ignorecase) {
8782             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8783             }
8784             }
8785              
8786 0         0 # ${ ... }
8787 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
8788 0         0 $char[$i] = e_capture($1);
8789             if ($ignorecase) {
8790             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8791             }
8792             }
8793              
8794 0         0 # $scalar or @array
8795 31 100       95 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
8796 31         109 $char[$i] = e_string($char[$i]);
8797             if ($ignorecase) {
8798             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
8799             }
8800             }
8801              
8802 4 100 66     14 # quote character before ? + * {
    50          
8803             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
8804             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
8805 188         1431 }
8806 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
8807 0         0 my $char = $char[$i-1];
8808             if ($char[$i] eq '{') {
8809             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
8810 0         0 }
8811             else {
8812             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
8813             }
8814 0         0 }
8815             else {
8816             $char[$i-1] = '(?:' . $char[$i-1] . ')';
8817             }
8818             }
8819             }
8820 187         754  
8821 1587 50       3147 # make regexp string
8822 1587 0 0     3844 $modifier =~ tr/i//d;
8823 0         0 if ($left_e > $right_e) {
8824             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
8825             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
8826 0         0 }
8827             else {
8828             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
8829 0 100 100     0 }
8830 1587         8406 }
8831             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
8832             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
8833 94         786 }
8834             else {
8835             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
8836             }
8837             }
8838              
8839             #
8840             # double quote stuff
8841 1493     540 0 13196 #
8842             sub qq_stuff {
8843             my($delimiter,$end_delimiter,$stuff) = @_;
8844 540 100       860  
8845 540         1226 # scalar variable or array variable
8846             if ($stuff =~ /\A [\$\@] /oxms) {
8847             return $stuff;
8848             }
8849 300         1159  
  240         629  
8850 280         809 # quote by delimiter
8851 240 50       636 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
8852 240 50       461 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
8853 240 50       377 next if $char eq $delimiter;
8854 240         514 next if $char eq $end_delimiter;
8855             if (not $octet{$char}) {
8856             return join '', 'qq', $char, $stuff, $char;
8857 240         1066 }
8858             }
8859             return join '', 'qq', '<', $stuff, '>';
8860             }
8861              
8862             #
8863             # escape regexp (m'', qr'', and m''b, qr''b)
8864 0     163 0 0 #
8865 163   100     757 sub e_qr_q {
8866             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8867 163         441 $modifier ||= '';
8868 163 50       258  
8869 163         355 $modifier =~ tr/p//d;
8870 0         0 if ($modifier =~ /([adlu])/oxms) {
8871 0 0       0 my $line = 0;
8872 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
8873 0         0 if ($filename ne __FILE__) {
8874             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
8875             last;
8876 0         0 }
8877             }
8878             die qq{Unsupported modifier "$1" used at line $line.\n};
8879 0         0 }
8880              
8881             $slash = 'div';
8882 163 100       206  
    100          
8883 163         394 # literal null string pattern
8884 8         7 if ($string eq '') {
8885 8         9 $modifier =~ tr/bB//d;
8886             $modifier =~ tr/i//d;
8887             return join '', $ope, $delimiter, $end_delimiter, $modifier;
8888             }
8889              
8890 8         39 # with /b /B modifier
8891             elsif ($modifier =~ tr/bB//d) {
8892             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
8893             }
8894              
8895 89         182 # without /b /B modifier
8896             else {
8897             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
8898             }
8899             }
8900              
8901             #
8902             # escape regexp (m'', qr'')
8903 66     66 0 119 #
8904             sub e_qr_qt {
8905 66 100       141 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
8906              
8907             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
8908 66         160  
8909             # split regexp
8910             my @char = $string =~ /\G((?>
8911             [^\x81-\xFE\\\[\$\@\/] |
8912             [\x81-\xFE][\x00-\xFF] |
8913             \[\^ |
8914             \[\: (?>[a-z]+) \:\] |
8915             \[\:\^ (?>[a-z]+) \:\] |
8916             [\$\@\/] |
8917             \\ (?:$q_char) |
8918             (?:$q_char)
8919             ))/oxmsg;
8920 66         653  
8921 66 100 100     208 # unescape character
    50 100        
    50 66        
    50          
    50          
    100          
    50          
8922             for (my $i=0; $i <= $#char; $i++) {
8923             if (0) {
8924             }
8925 79         767  
8926 0         0 # escape last octet of multiple-octet
8927             elsif ($char[$i] =~ /\A ([\x80-\xFF].*) ([\\|\[\{\^]|\Q$delimiter\E|\Q$end_delimiter\E) \z/xms) {
8928             $char[$i] = $1 . '\\' . $2;
8929             }
8930              
8931 2         13 # open character class [...]
8932 0 0       0 elsif ($char[$i] eq '[') {
8933 0         0 my $left = $i;
8934             if ($char[$i+1] eq ']') {
8935 0         0 $i++;
8936 0 0       0 }
8937 0         0 while (1) {
8938             if (++$i > $#char) {
8939 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
8940 0         0 }
8941             if ($char[$i] eq ']') {
8942             my $right = $i;
8943 0         0  
8944             # [...]
8945 0         0 splice @char, $left, $right-$left+1, Egbk::charlist_qr(@char[$left+1..$right-1], $modifier);
8946 0         0  
8947             $i = $left;
8948             last;
8949             }
8950             }
8951             }
8952              
8953 0         0 # open character class [^...]
8954 0 0       0 elsif ($char[$i] eq '[^') {
8955 0         0 my $left = $i;
8956             if ($char[$i+1] eq ']') {
8957 0         0 $i++;
8958 0 0       0 }
8959 0         0 while (1) {
8960             if (++$i > $#char) {
8961 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
8962 0         0 }
8963             if ($char[$i] eq ']') {
8964             my $right = $i;
8965 0         0  
8966             # [^...]
8967 0         0 splice @char, $left, $right-$left+1, Egbk::charlist_not_qr(@char[$left+1..$right-1], $modifier);
8968 0         0  
8969             $i = $left;
8970             last;
8971             }
8972             }
8973             }
8974              
8975 0         0 # escape $ @ / and \
8976             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
8977             $char[$i] = '\\' . $char[$i];
8978             }
8979              
8980 0         0 # rewrite character class or escape character
8981             elsif (my $char = character_class($char[$i],$modifier)) {
8982             $char[$i] = $char;
8983             }
8984              
8985 0 50       0 # /i modifier
8986 16         33 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egbk::uc($char[$i]) ne Egbk::fc($char[$i]))) {
8987             if (CORE::length(Egbk::fc($char[$i])) == 1) {
8988             $char[$i] = '[' . Egbk::uc($char[$i]) . Egbk::fc($char[$i]) . ']';
8989 16         30 }
8990             else {
8991             $char[$i] = '(?:' . Egbk::uc($char[$i]) . '|' . Egbk::fc($char[$i]) . ')';
8992             }
8993             }
8994              
8995 0 0       0 # quote character before ? + * {
8996             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
8997             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
8998 0         0 }
8999             else {
9000             $char[$i-1] = '(?:' . $char[$i-1] . ')';
9001             }
9002             }
9003 0         0 }
9004 66         109  
9005             $delimiter = '/';
9006 66         72 $end_delimiter = '/';
9007 66         100  
9008             $modifier =~ tr/i//d;
9009             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
9010             }
9011              
9012             #
9013             # escape regexp (m''b, qr''b)
9014 66     89 0 424 #
9015             sub e_qr_qb {
9016             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
9017 89         192  
9018             # split regexp
9019             my @char = $string =~ /\G ((?>[^\\]|\\\\|[\x00-\xFF])) /oxmsg;
9020 89         378  
9021 89 50       247 # unescape character
    50          
9022             for (my $i=0; $i <= $#char; $i++) {
9023             if (0) {
9024             }
9025 199         684  
9026             # remain \\
9027             elsif ($char[$i] eq '\\\\') {
9028             }
9029              
9030 0         0 # escape $ @ / and \
9031             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
9032             $char[$i] = '\\' . $char[$i];
9033             }
9034 0         0 }
9035 89         129  
9036 89         127 $delimiter = '/';
9037             $end_delimiter = '/';
9038             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
9039             }
9040              
9041             #
9042             # escape regexp (s/here//)
9043 89     194 0 548 #
9044 194   100     562 sub e_s1 {
9045             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
9046 194         625 $modifier ||= '';
9047 194 50       299  
9048 194         532 $modifier =~ tr/p//d;
9049 0         0 if ($modifier =~ /([adlu])/oxms) {
9050 0 0       0 my $line = 0;
9051 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
9052 0         0 if ($filename ne __FILE__) {
9053             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
9054             last;
9055 0         0 }
9056             }
9057             die qq{Unsupported modifier "$1" used at line $line.\n};
9058 0         0 }
9059              
9060             $slash = 'div';
9061 194 100       366  
    100          
9062 194         669 # literal null string pattern
9063 8         8 if ($string eq '') {
9064 8         8 $modifier =~ tr/bB//d;
9065             $modifier =~ tr/i//d;
9066             return join '', $ope, $delimiter, $end_delimiter, $modifier;
9067             }
9068              
9069             # /b /B modifier
9070             elsif ($modifier =~ tr/bB//d) {
9071 8 50       44  
9072 44         96 # choice again delimiter
9073 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
9074 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
9075 0         0 my %octet = map {$_ => 1} @char;
9076 0         0 if (not $octet{')'}) {
9077             $delimiter = '(';
9078             $end_delimiter = ')';
9079 0         0 }
9080 0         0 elsif (not $octet{'}'}) {
9081             $delimiter = '{';
9082             $end_delimiter = '}';
9083 0         0 }
9084 0         0 elsif (not $octet{']'}) {
9085             $delimiter = '[';
9086             $end_delimiter = ']';
9087 0         0 }
9088 0         0 elsif (not $octet{'>'}) {
9089             $delimiter = '<';
9090             $end_delimiter = '>';
9091 0         0 }
9092 0 0       0 else {
9093 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
9094 0         0 if (not $octet{$char}) {
9095 0         0 $delimiter = $char;
9096             $end_delimiter = $char;
9097             last;
9098             }
9099             }
9100             }
9101 0         0 }
9102 44         58  
9103 44         52 my $prematch = '';
9104             $prematch = q{(\G[\x00-\xFF]*?)};
9105             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
9106 44 100       299 }
9107 142         472  
9108             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
9109             my $metachar = qr/[\@\\|[\]{^]/oxms;
9110 142         624  
9111             # split regexp
9112             my @char = $string =~ /\G((?>
9113             [^\x81-\xFE\\\$\@\[\(]|[\x81-\xFE][\x00-\xFF] |
9114             \\ (?>[1-9][0-9]*) |
9115             \\g (?>\s*) (?>[1-9][0-9]*) |
9116             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
9117             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
9118             \\x (?>[0-9A-Fa-f]{1,2}) |
9119             \\ (?>[0-7]{2,3}) |
9120             \\c [\x40-\x5F] |
9121             \\x\{ (?>[0-9A-Fa-f]+) \} |
9122             \\o\{ (?>[0-7]+) \} |
9123             \\[bBNpP]\{ (?>[^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} |
9124             \\ $q_char |
9125             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
9126             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
9127             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
9128             [\$\@] $qq_variable |
9129             \$ (?>\s* [0-9]+) |
9130             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
9131             \$ \$ (?![\w\{]) |
9132             \$ (?>\s*) \$ (?>\s*) $qq_variable |
9133             \[\^ |
9134             \[\: (?>[a-z]+) :\] |
9135             \[\:\^ (?>[a-z]+) :\] |
9136             \(\? |
9137             $q_char
9138             ))/oxmsg;
9139 142 50       38491  
9140 142         1144 # choice again delimiter
  0         0  
9141 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
9142 0         0 my %octet = map {$_ => 1} @char;
9143 0         0 if (not $octet{')'}) {
9144             $delimiter = '(';
9145             $end_delimiter = ')';
9146 0         0 }
9147 0         0 elsif (not $octet{'}'}) {
9148             $delimiter = '{';
9149             $end_delimiter = '}';
9150 0         0 }
9151 0         0 elsif (not $octet{']'}) {
9152             $delimiter = '[';
9153             $end_delimiter = ']';
9154 0         0 }
9155 0         0 elsif (not $octet{'>'}) {
9156             $delimiter = '<';
9157             $end_delimiter = '>';
9158 0         0 }
9159 0 0       0 else {
9160 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
9161 0         0 if (not $octet{$char}) {
9162 0         0 $delimiter = $char;
9163             $end_delimiter = $char;
9164             last;
9165             }
9166             }
9167             }
9168             }
9169 0         0  
  142         366  
9170             # count '('
9171 476         854 my $parens = grep { $_ eq '(' } @char;
9172 142         210  
9173 142         204 my $left_e = 0;
9174             my $right_e = 0;
9175             for (my $i=0; $i <= $#char; $i++) {
9176 142 50 33     421  
    50 33        
    100          
    100          
    50          
    50          
9177 397         2510 # "\L\u" --> "\u\L"
9178             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
9179             @char[$i,$i+1] = @char[$i+1,$i];
9180             }
9181              
9182 0         0 # "\U\l" --> "\l\U"
9183             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
9184             @char[$i,$i+1] = @char[$i+1,$i];
9185             }
9186              
9187 0         0 # octal escape sequence
9188             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
9189             $char[$i] = Egbk::octchr($1);
9190             }
9191              
9192 1         3 # hexadecimal escape sequence
9193             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
9194             $char[$i] = Egbk::hexchr($1);
9195             }
9196              
9197             # \b{...} --> b\{...}
9198             # \B{...} --> B\{...}
9199             # \N{CHARNAME} --> N\{CHARNAME}
9200             # \p{PROPERTY} --> p\{PROPERTY}
9201 1         4 # \P{PROPERTY} --> P\{PROPERTY}
9202             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} ) \z/oxms) {
9203             $char[$i] = $1 . '\\' . $2;
9204             }
9205              
9206 0         0 # \p, \P, \X --> p, P, X
9207             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
9208             $char[$i] = $1;
9209 0 100 100     0 }
    50 100        
    100 100        
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
9210              
9211             if (0) {
9212             }
9213 397         5294  
9214 0         0 # escape last octet of multiple-octet
9215             elsif ($char[$i] =~ /\A \\? ([\x80-\xFF].*) ($metachar|\Q$delimiter\E|\Q$end_delimiter\E) \z/xms) {
9216             $char[$i] = $1 . '\\' . $2;
9217             }
9218              
9219 23 0 0     117 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
9220 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
9221             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)) {
9222             $char[$i] .= join '', splice @char, $i+1, 3;
9223 0         0 }
9224             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)) {
9225             $char[$i] .= join '', splice @char, $i+1, 2;
9226 0         0 }
9227             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)) {
9228             $char[$i] .= join '', splice @char, $i+1, 1;
9229             }
9230             }
9231              
9232 0         0 # open character class [...]
9233 20 50       48 elsif ($char[$i] eq '[') {
9234 20         88 my $left = $i;
9235             if ($char[$i+1] eq ']') {
9236 0         0 $i++;
9237 20 50       34 }
9238 79         137 while (1) {
9239             if (++$i > $#char) {
9240 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
9241 79         219 }
9242             if ($char[$i] eq ']') {
9243             my $right = $i;
9244 20 50       167  
9245 20         167 # [...]
  0         0  
9246             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
9247             splice @char, $left, $right-$left+1, sprintf(q{@{[Egbk::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
9248 0         0 }
9249             else {
9250             splice @char, $left, $right-$left+1, Egbk::charlist_qr(@char[$left+1..$right-1], $modifier);
9251 20         126 }
9252 20         42  
9253             $i = $left;
9254             last;
9255             }
9256             }
9257             }
9258              
9259 20         66 # open character class [^...]
9260 0 0       0 elsif ($char[$i] eq '[^') {
9261 0         0 my $left = $i;
9262             if ($char[$i+1] eq ']') {
9263 0         0 $i++;
9264 0 0       0 }
9265 0         0 while (1) {
9266             if (++$i > $#char) {
9267 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
9268 0         0 }
9269             if ($char[$i] eq ']') {
9270             my $right = $i;
9271 0 0       0  
9272 0         0 # [^...]
  0         0  
9273             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
9274             splice @char, $left, $right-$left+1, sprintf(q{@{[Egbk::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
9275 0         0 }
9276             else {
9277             splice @char, $left, $right-$left+1, Egbk::charlist_not_qr(@char[$left+1..$right-1], $modifier);
9278 0         0 }
9279 0         0  
9280             $i = $left;
9281             last;
9282             }
9283             }
9284             }
9285              
9286 0         0 # rewrite character class or escape character
9287             elsif (my $char = character_class($char[$i],$modifier)) {
9288             $char[$i] = $char;
9289             }
9290              
9291 11 50       26 # /i modifier
9292 11         23 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egbk::uc($char[$i]) ne Egbk::fc($char[$i]))) {
9293             if (CORE::length(Egbk::fc($char[$i])) == 1) {
9294             $char[$i] = '[' . Egbk::uc($char[$i]) . Egbk::fc($char[$i]) . ']';
9295 11         23 }
9296             else {
9297             $char[$i] = '(?:' . Egbk::uc($char[$i]) . '|' . Egbk::fc($char[$i]) . ')';
9298             }
9299             }
9300              
9301 0 50       0 # \u \l \U \L \F \Q \E
9302 8         25 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
9303             if ($right_e < $left_e) {
9304             $char[$i] = '\\' . $char[$i];
9305             }
9306 0         0 }
9307 0         0 elsif ($char[$i] eq '\u') {
9308             $char[$i] = '@{[Egbk::ucfirst qq<';
9309             $left_e++;
9310 0         0 }
9311 0         0 elsif ($char[$i] eq '\l') {
9312             $char[$i] = '@{[Egbk::lcfirst qq<';
9313             $left_e++;
9314 0         0 }
9315 0         0 elsif ($char[$i] eq '\U') {
9316             $char[$i] = '@{[Egbk::uc qq<';
9317             $left_e++;
9318 0         0 }
9319 0         0 elsif ($char[$i] eq '\L') {
9320             $char[$i] = '@{[Egbk::lc qq<';
9321             $left_e++;
9322 0         0 }
9323 0         0 elsif ($char[$i] eq '\F') {
9324             $char[$i] = '@{[Egbk::fc qq<';
9325             $left_e++;
9326 0         0 }
9327 7         13 elsif ($char[$i] eq '\Q') {
9328             $char[$i] = '@{[CORE::quotemeta qq<';
9329             $left_e++;
9330 7 50       16 }
9331 7         16 elsif ($char[$i] eq '\E') {
9332 7         10 if ($right_e < $left_e) {
9333             $char[$i] = '>]}';
9334             $right_e++;
9335 7         15 }
9336             else {
9337             $char[$i] = '';
9338             }
9339 0         0 }
9340 0 0       0 elsif ($char[$i] eq '\Q') {
9341 0         0 while (1) {
9342             if (++$i > $#char) {
9343 0 0       0 last;
9344 0         0 }
9345             if ($char[$i] eq '\E') {
9346             last;
9347             }
9348             }
9349             }
9350             elsif ($char[$i] eq '\E') {
9351             }
9352              
9353             # \0 --> \0
9354             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
9355             }
9356              
9357             # \g{N}, \g{-N}
9358              
9359             # P.108 Using Simple Patterns
9360             # in Chapter 7: In the World of Regular Expressions
9361             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
9362              
9363             # P.221 Capturing
9364             # in Chapter 5: Pattern Matching
9365             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
9366              
9367             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
9368             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
9369             }
9370              
9371 0 0       0 # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
9372 0         0 elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
9373             if ($1 <= $parens) {
9374             $char[$i] = '\\g{' . ($1 + 1) . '}';
9375             }
9376             }
9377              
9378 0 0       0 # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
9379 0         0 elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
9380             if ($1 <= $parens) {
9381             $char[$i] = '\\g' . ($1 + 1);
9382             }
9383             }
9384              
9385 0 0       0 # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
9386 0         0 elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
9387             if ($1 <= $parens) {
9388             $char[$i] = '\\' . ($1 + 1);
9389             }
9390             }
9391              
9392 0 0       0 # $0 --> $0
9393 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
9394             if ($ignorecase) {
9395             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9396             }
9397 0 0       0 }
9398 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
9399             if ($ignorecase) {
9400             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9401             }
9402             }
9403              
9404             # $$ --> $$
9405             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
9406             }
9407              
9408             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
9409 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
9410 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
9411 0         0 $char[$i] = e_capture($1);
9412             if ($ignorecase) {
9413             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9414             }
9415 0         0 }
9416 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
9417 0         0 $char[$i] = e_capture($1);
9418             if ($ignorecase) {
9419             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9420             }
9421             }
9422              
9423 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
9424 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) {
9425 0         0 $char[$i] = e_capture($1.'->'.$2);
9426             if ($ignorecase) {
9427             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9428             }
9429             }
9430              
9431 0         0 # $$foo{ ... } --> $ $foo->{ ... }
9432 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) {
9433 0         0 $char[$i] = e_capture($1.'->'.$2);
9434             if ($ignorecase) {
9435             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9436             }
9437             }
9438              
9439 0         0 # $$foo
9440 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
9441 0         0 $char[$i] = e_capture($1);
9442             if ($ignorecase) {
9443             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9444             }
9445             }
9446              
9447 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egbk::PREMATCH()
9448 4         15 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
9449             if ($ignorecase) {
9450             $char[$i] = '@{[Egbk::ignorecase(Egbk::PREMATCH())]}';
9451 0         0 }
9452             else {
9453             $char[$i] = '@{[Egbk::PREMATCH()]}';
9454             }
9455             }
9456              
9457 4 50       17 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egbk::MATCH()
9458 4         14 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
9459             if ($ignorecase) {
9460             $char[$i] = '@{[Egbk::ignorecase(Egbk::MATCH())]}';
9461 0         0 }
9462             else {
9463             $char[$i] = '@{[Egbk::MATCH()]}';
9464             }
9465             }
9466              
9467 4 50       18 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egbk::POSTMATCH()
9468 3         9 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
9469             if ($ignorecase) {
9470             $char[$i] = '@{[Egbk::ignorecase(Egbk::POSTMATCH())]}';
9471 0         0 }
9472             else {
9473             $char[$i] = '@{[Egbk::POSTMATCH()]}';
9474             }
9475             }
9476              
9477 3 0       12 # ${ foo }
9478 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) {
9479             if ($ignorecase) {
9480             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9481             }
9482             }
9483              
9484 0         0 # ${ ... }
9485 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
9486 0         0 $char[$i] = e_capture($1);
9487             if ($ignorecase) {
9488             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9489             }
9490             }
9491              
9492 0         0 # $scalar or @array
9493 13 50       43 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
9494 13         68 $char[$i] = e_string($char[$i]);
9495             if ($ignorecase) {
9496             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
9497             }
9498             }
9499              
9500 0 50       0 # quote character before ? + * {
9501             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
9502             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
9503 23         125 }
9504             else {
9505             $char[$i-1] = '(?:' . $char[$i-1] . ')';
9506             }
9507             }
9508             }
9509 23         120  
9510 142         332 # make regexp string
9511 142         413 my $prematch = '';
9512 142 50       235 $prematch = "($anchor)";
9513 142         357 $modifier =~ tr/i//d;
9514             if ($left_e > $right_e) {
9515 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
9516             }
9517             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
9518             }
9519              
9520             #
9521             # escape regexp (s'here'' or s'here''b)
9522 142     96 0 1637 #
9523 96   100     210 sub e_s1_q {
9524             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
9525 96         212 $modifier ||= '';
9526 96 50       115  
9527 96         185 $modifier =~ tr/p//d;
9528 0         0 if ($modifier =~ /([adlu])/oxms) {
9529 0 0       0 my $line = 0;
9530 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
9531 0         0 if ($filename ne __FILE__) {
9532             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
9533             last;
9534 0         0 }
9535             }
9536             die qq{Unsupported modifier "$1" used at line $line.\n};
9537 0         0 }
9538              
9539             $slash = 'div';
9540 96 100       120  
    100          
9541 96         202 # literal null string pattern
9542 8         19 if ($string eq '') {
9543 8         12 $modifier =~ tr/bB//d;
9544             $modifier =~ tr/i//d;
9545             return join '', $ope, $delimiter, $end_delimiter, $modifier;
9546             }
9547              
9548 8         42 # with /b /B modifier
9549             elsif ($modifier =~ tr/bB//d) {
9550             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
9551             }
9552              
9553 44         88 # without /b /B modifier
9554             else {
9555             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
9556             }
9557             }
9558              
9559             #
9560             # escape regexp (s'here'')
9561 44     44 0 115 #
9562             sub e_s1_qt {
9563 44 100       94 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
9564              
9565             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
9566 44         92  
9567             # split regexp
9568             my @char = $string =~ /\G((?>
9569             [^\x81-\xFE\\\[\$\@\/] |
9570             [\x81-\xFE][\x00-\xFF] |
9571             \[\^ |
9572             \[\: (?>[a-z]+) \:\] |
9573             \[\:\^ (?>[a-z]+) \:\] |
9574             [\$\@\/] |
9575             \\ (?:$q_char) |
9576             (?:$q_char)
9577             ))/oxmsg;
9578 44         462  
9579 44 50 100     121 # unescape character
    50 100        
    50 66        
    50          
    100          
    100          
    50          
9580             for (my $i=0; $i <= $#char; $i++) {
9581             if (0) {
9582             }
9583 62         535  
9584 0         0 # escape last octet of multiple-octet
9585             elsif ($char[$i] =~ /\A ([\x80-\xFF].*) ([\\|\[\{\^]|\Q$delimiter\E|\Q$end_delimiter\E) \z/xms) {
9586             $char[$i] = $1 . '\\' . $2;
9587             }
9588              
9589 0         0 # open character class [...]
9590 0 0       0 elsif ($char[$i] eq '[') {
9591 0         0 my $left = $i;
9592             if ($char[$i+1] eq ']') {
9593 0         0 $i++;
9594 0 0       0 }
9595 0         0 while (1) {
9596             if (++$i > $#char) {
9597 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
9598 0         0 }
9599             if ($char[$i] eq ']') {
9600             my $right = $i;
9601 0         0  
9602             # [...]
9603 0         0 splice @char, $left, $right-$left+1, Egbk::charlist_qr(@char[$left+1..$right-1], $modifier);
9604 0         0  
9605             $i = $left;
9606             last;
9607             }
9608             }
9609             }
9610              
9611 0         0 # open character class [^...]
9612 0 0       0 elsif ($char[$i] eq '[^') {
9613 0         0 my $left = $i;
9614             if ($char[$i+1] eq ']') {
9615 0         0 $i++;
9616 0 0       0 }
9617 0         0 while (1) {
9618             if (++$i > $#char) {
9619 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
9620 0         0 }
9621             if ($char[$i] eq ']') {
9622             my $right = $i;
9623 0         0  
9624             # [^...]
9625 0         0 splice @char, $left, $right-$left+1, Egbk::charlist_not_qr(@char[$left+1..$right-1], $modifier);
9626 0         0  
9627             $i = $left;
9628             last;
9629             }
9630             }
9631             }
9632              
9633 0         0 # escape $ @ / and \
9634             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
9635             $char[$i] = '\\' . $char[$i];
9636             }
9637              
9638 0         0 # rewrite character class or escape character
9639             elsif (my $char = character_class($char[$i],$modifier)) {
9640             $char[$i] = $char;
9641             }
9642              
9643 6 50       14 # /i modifier
9644 8         24 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egbk::uc($char[$i]) ne Egbk::fc($char[$i]))) {
9645             if (CORE::length(Egbk::fc($char[$i])) == 1) {
9646             $char[$i] = '[' . Egbk::uc($char[$i]) . Egbk::fc($char[$i]) . ']';
9647 8         16 }
9648             else {
9649             $char[$i] = '(?:' . Egbk::uc($char[$i]) . '|' . Egbk::fc($char[$i]) . ')';
9650             }
9651             }
9652              
9653 0 0       0 # quote character before ? + * {
9654             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
9655             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
9656 0         0 }
9657             else {
9658             $char[$i-1] = '(?:' . $char[$i-1] . ')';
9659             }
9660             }
9661 0         0 }
9662 44         76  
9663 44         59 $modifier =~ tr/i//d;
9664 44         72 $delimiter = '/';
9665 44         53 $end_delimiter = '/';
9666 44         82 my $prematch = '';
9667             $prematch = "($anchor)";
9668             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
9669             }
9670              
9671             #
9672             # escape regexp (s'here''b)
9673 44     44 0 302 #
9674             sub e_s1_qb {
9675             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
9676 44         92  
9677             # split regexp
9678             my @char = $string =~ /\G (?>[^\\]|\\\\|[\x00-\xFF]) /oxmsg;
9679 44         177  
9680 44 50       119 # unescape character
    50          
9681             for (my $i=0; $i <= $#char; $i++) {
9682             if (0) {
9683             }
9684 98         304  
9685             # remain \\
9686             elsif ($char[$i] eq '\\\\') {
9687             }
9688              
9689 0         0 # escape $ @ / and \
9690             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
9691             $char[$i] = '\\' . $char[$i];
9692             }
9693 0         0 }
9694 44         68  
9695 44         50 $delimiter = '/';
9696 44         60 $end_delimiter = '/';
9697 44         62 my $prematch = '';
9698             $prematch = q{(\G[\x00-\xFF]*?)};
9699             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
9700             }
9701              
9702             #
9703             # escape regexp (s''here')
9704 44     91 0 303 #
9705             sub e_s2_q {
9706 91         162 my($ope,$delimiter,$end_delimiter,$string) = @_;
9707              
9708 91         106 $slash = 'div';
9709 91         322  
9710 91 50 66     218 my @char = $string =~ / \G (?>[^\x81-\xFE\\]|\\\\|$q_char) /oxmsg;
    50 33        
    100          
    100          
9711             for (my $i=0; $i <= $#char; $i++) {
9712             if (0) {
9713             }
9714 9         91  
9715 0         0 # escape last octet of multiple-octet
9716             elsif ($char[$i] =~ /\A ([\x80-\xFF].*) (\Q$delimiter\E|\Q$end_delimiter\E) \z/xms) {
9717             $char[$i] = $1 . '\\' . $2;
9718 0         0 }
9719             elsif (defined($char[$i+1]) and ($char[$i+1] eq '\\') and ($char[$i] =~ /\A ([\x80-\xFF].*) (\\) \z/xms)) {
9720             $char[$i] = $1 . '\\' . $2;
9721             }
9722              
9723             # not escape \\
9724             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
9725             }
9726              
9727 0         0 # escape $ @ / and \
9728             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
9729             $char[$i] = '\\' . $char[$i];
9730 5 50 66     17 }
9731 91         219 }
9732             if (defined($char[-1]) and ($char[-1] =~ /\A ([\x80-\xFF].*) (\\) \z/xms)) {
9733             $char[-1] = $1 . '\\' . $2;
9734 0         0 }
9735              
9736             return join '', $ope, $delimiter, @char, $end_delimiter;
9737             }
9738              
9739             #
9740             # escape regexp (s/here/and here/modifier)
9741 91     290 0 254 #
9742 290   100     2194 sub e_sub {
9743             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
9744 290         1071 $modifier ||= '';
9745 290 50       545  
9746 290         762 $modifier =~ tr/p//d;
9747 0         0 if ($modifier =~ /([adlu])/oxms) {
9748 0 0       0 my $line = 0;
9749 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
9750 0         0 if ($filename ne __FILE__) {
9751             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
9752             last;
9753 0         0 }
9754             }
9755             die qq{Unsupported modifier "$1" used at line $line.\n};
9756 0 100       0 }
9757 290         669  
9758 37         49 if ($variable eq '') {
9759             $variable = '$_';
9760             $bind_operator = ' =~ ';
9761 37         51 }
9762              
9763             $slash = 'div';
9764              
9765             # P.128 Start of match (or end of previous match): \G
9766             # P.130 Advanced Use of \G with Perl
9767             # in Chapter 3: Overview of Regular Expression Features and Flavors
9768             # P.312 Iterative Matching: Scalar Context, with /g
9769             # in Chapter 7: Perl
9770             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
9771              
9772             # P.181 Where You Left Off: The \G Assertion
9773             # in Chapter 5: Pattern Matching
9774             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
9775              
9776             # P.220 Where You Left Off: The \G Assertion
9777             # in Chapter 5: Pattern Matching
9778 290         421 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
9779 290         413  
9780             my $e_modifier = $modifier =~ tr/e//d;
9781 290         470 my $r_modifier = $modifier =~ tr/r//d;
9782 290 50       402  
9783 290         859 my $my = '';
9784 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
9785 0         0 $my = $variable;
9786             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
9787             $variable =~ s/ = .+ \z//oxms;
9788 0         0 }
9789 290         738  
9790             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
9791             $variable_basename =~ s/ \s+ \z//oxms;
9792 290         580  
9793 290 100       423 # quote replacement string
9794 290         587 my $e_replacement = '';
9795 17         36 if ($e_modifier >= 1) {
9796             $e_replacement = e_qq('', '', '', $replacement);
9797             $e_modifier--;
9798 17 100       22 }
9799 273         550 else {
9800             if ($delimiter2 eq "'") {
9801             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
9802 91         254 }
9803             else {
9804             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
9805             }
9806 182         421 }
9807              
9808             my $sub = '';
9809 290 100       459  
9810 290 100       551 # with /r
    50          
9811             if ($r_modifier) {
9812             if (0) {
9813             }
9814 8         27  
9815 0 50       0 # s///gr with multibyte anchoring
9816             elsif ($modifier =~ /g/oxms) {
9817             $sub = sprintf(
9818             # 1 2 3 4 5
9819             q,
9820              
9821             $variable, # 1
9822             ($delimiter1 eq "'") ? # 2
9823             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
9824             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
9825             $s_matched, # 3
9826             $e_replacement, # 4
9827             '$Egbk::re_r=CORE::eval $Egbk::re_r; ' x $e_modifier, # 5
9828             );
9829             }
9830              
9831 4 0       16 # s///gr without multibyte anchoring
9832             elsif ($modifier =~ /g/oxms) {
9833             $sub = sprintf(
9834             # 1 2 3 4 5
9835             q,
9836              
9837             $variable, # 1
9838             ($delimiter1 eq "'") ? # 2
9839             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
9840             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
9841             $s_matched, # 3
9842             $e_replacement, # 4
9843             '$Egbk::re_r=CORE::eval $Egbk::re_r; ' x $e_modifier, # 5
9844             );
9845             }
9846              
9847             # s///r
9848 0         0 else {
9849 4         6  
9850             my $prematch = q{$`};
9851 4 50       5 $prematch = q{${1}};
9852              
9853             $sub = sprintf(
9854             # 1 2 3 4 5 6 7
9855             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Egbk::re_r=%s; %s"%s$Egbk::re_r$'" } : %s>,
9856              
9857             $variable, # 1
9858             ($delimiter1 eq "'") ? # 2
9859             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
9860             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
9861             $s_matched, # 3
9862             $e_replacement, # 4
9863             '$Egbk::re_r=CORE::eval $Egbk::re_r; ' x $e_modifier, # 5
9864             $prematch, # 6
9865             $variable, # 7
9866             );
9867             }
9868 4 50       17  
9869 8         33 # $var !~ s///r doesn't make sense
9870             if ($bind_operator =~ / !~ /oxms) {
9871             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
9872             }
9873             }
9874              
9875 0 100       0 # without /r
    50          
9876             else {
9877             if (0) {
9878             }
9879 282         804  
9880 0 100       0 # s///g with multibyte anchoring
    100          
9881             elsif ($modifier =~ /g/oxms) {
9882             $sub = sprintf(
9883             # 1 2 3 4 5 6 7 8 9 10
9884             q,
9885              
9886             $variable, # 1
9887             ($delimiter1 eq "'") ? # 2
9888             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
9889             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
9890             $s_matched, # 3
9891             $e_replacement, # 4
9892             '$Egbk::re_r=CORE::eval $Egbk::re_r; ' x $e_modifier, # 5
9893             $variable, # 6
9894             $variable, # 7
9895             $variable, # 8
9896             $variable, # 9
9897              
9898             # Binary "!~" is just like "=~" except the return value is negated in the logical sense.
9899             # It returns false if the match succeeds, and true if it fails.
9900             # (and so on)
9901              
9902             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 10
9903             );
9904             }
9905              
9906 35 0       205 # s///g without multibyte anchoring
    0          
9907             elsif ($modifier =~ /g/oxms) {
9908             $sub = sprintf(
9909             # 1 2 3 4 5 6 7 8
9910             q,
9911              
9912             $variable, # 1
9913             ($delimiter1 eq "'") ? # 2
9914             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
9915             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
9916             $s_matched, # 3
9917             $e_replacement, # 4
9918             '$Egbk::re_r=CORE::eval $Egbk::re_r; ' x $e_modifier, # 5
9919             $variable, # 6
9920             $variable, # 7
9921             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
9922             );
9923             }
9924              
9925             # s///
9926 0         0 else {
9927 247         354  
9928             my $prematch = q{$`};
9929 247 100       339 $prematch = q{${1}};
    100          
9930              
9931             $sub = sprintf(
9932              
9933             ($bind_operator =~ / =~ /oxms) ?
9934              
9935             # 1 2 3 4 5 6 7 8
9936             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Egbk::re_r=%s; %s%s="%s$Egbk::re_r$'"; 1 } : undef> :
9937              
9938             # 1 2 3 4 5 6 7 8
9939             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Egbk::re_r=%s; %s%s="%s$Egbk::re_r$'"; undef }>,
9940              
9941             $variable, # 1
9942             $bind_operator, # 2
9943             ($delimiter1 eq "'") ? # 3
9944             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
9945             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
9946             $s_matched, # 4
9947             $e_replacement, # 5
9948             '$Egbk::re_r=CORE::eval $Egbk::re_r; ' x $e_modifier, # 6
9949             $variable, # 7
9950             $prematch, # 8
9951             );
9952             }
9953             }
9954 247 50       1212  
9955 290         872 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
9956             if ($my ne '') {
9957             $sub = "($my, $sub)[1]";
9958             }
9959 0         0  
9960 290         410 # clear s/// variable
9961             $sub_variable = '';
9962 290         345 $bind_operator = '';
9963              
9964             return $sub;
9965             }
9966              
9967             #
9968             # escape chdir (qq//, "")
9969 290     0 0 2150 #
9970             sub e_chdir {
9971 0 0       0 my($ope,$delimiter,$end_delimiter,$string) = @_;
9972 0 0       0  
9973 0 0       0 if ($^W) {
9974 0         0 if (Egbk::_MSWin32_5Cended_path($string)) {
9975 0         0 if ($] !~ /^5\.005/oxms) {
9976             warn <
9977             @{[__FILE__]}: Can't chdir to '$string'
9978              
9979             chdir does not work with chr(0x5C) at end of path
9980             http://bugs.activestate.com/show_bug.cgi?id=81839
9981             END
9982             }
9983             }
9984 0         0 }
9985              
9986             return e_qq($ope,$delimiter,$end_delimiter,$string);
9987             }
9988              
9989             #
9990             # escape chdir (q//, '')
9991 0     2 0 0 #
9992             sub e_chdir_q {
9993 2 50       7 my($ope,$delimiter,$end_delimiter,$string) = @_;
9994 2 0       7  
9995 0 0       0 if ($^W) {
9996 0         0 if (Egbk::_MSWin32_5Cended_path($string)) {
9997 0         0 if ($] !~ /^5\.005/oxms) {
9998             warn <
9999             @{[__FILE__]}: Can't chdir to '$string'
10000              
10001             chdir does not work with chr(0x5C) at end of path
10002             http://bugs.activestate.com/show_bug.cgi?id=81839
10003             END
10004             }
10005             }
10006 0         0 }
10007              
10008             return e_q($ope,$delimiter,$end_delimiter,$string);
10009             }
10010              
10011             #
10012             # escape regexp of split qr//
10013 2     273 0 12 #
10014 273   100     1290 sub e_split {
10015             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
10016 273         1064 $modifier ||= '';
10017 273 50       554  
10018 273         709 $modifier =~ tr/p//d;
10019 0         0 if ($modifier =~ /([adlu])/oxms) {
10020 0 0       0 my $line = 0;
10021 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
10022 0         0 if ($filename ne __FILE__) {
10023             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
10024             last;
10025 0         0 }
10026             }
10027             die qq{Unsupported modifier "$1" used at line $line.\n};
10028 0         0 }
10029              
10030             $slash = 'div';
10031 273 100       466  
10032 273         570 # /b /B modifier
10033             if ($modifier =~ tr/bB//d) {
10034             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
10035 84 100       484 }
10036 189         608  
10037             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
10038             my $metachar = qr/[\@\\|[\]{^]/oxms;
10039 189         665  
10040             # split regexp
10041             my @char = $string =~ /\G((?>
10042             [^\x81-\xFE\\\$\@\[\(]|[\x81-\xFE][\x00-\xFF] |
10043             \\x (?>[0-9A-Fa-f]{1,2}) |
10044             \\ (?>[0-7]{2,3}) |
10045             \\c [\x40-\x5F] |
10046             \\x\{ (?>[0-9A-Fa-f]+) \} |
10047             \\o\{ (?>[0-7]+) \} |
10048             \\[bBNpP]\{ (?>[^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} |
10049             \\ $q_char |
10050             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
10051             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
10052             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
10053             [\$\@] $qq_variable |
10054             \$ (?>\s* [0-9]+) |
10055             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
10056             \$ \$ (?![\w\{]) |
10057             \$ (?>\s*) \$ (?>\s*) $qq_variable |
10058             \[\^ |
10059             \[\: (?>[a-z]+) :\] |
10060             \[\:\^ (?>[a-z]+) :\] |
10061             \(\? |
10062             $q_char
10063 189         16687 ))/oxmsg;
10064 189         587  
10065 189         287 my $left_e = 0;
10066             my $right_e = 0;
10067             for (my $i=0; $i <= $#char; $i++) {
10068 189 50 33     517  
    50 33        
    100          
    100          
    50          
    50          
10069 372         2360 # "\L\u" --> "\u\L"
10070             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
10071             @char[$i,$i+1] = @char[$i+1,$i];
10072             }
10073              
10074 0         0 # "\U\l" --> "\l\U"
10075             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
10076             @char[$i,$i+1] = @char[$i+1,$i];
10077             }
10078              
10079 0         0 # octal escape sequence
10080             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
10081             $char[$i] = Egbk::octchr($1);
10082             }
10083              
10084 1         4 # hexadecimal escape sequence
10085             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
10086             $char[$i] = Egbk::hexchr($1);
10087             }
10088              
10089             # \b{...} --> b\{...}
10090             # \B{...} --> B\{...}
10091             # \N{CHARNAME} --> N\{CHARNAME}
10092             # \p{PROPERTY} --> p\{PROPERTY}
10093 1         4 # \P{PROPERTY} --> P\{PROPERTY}
10094             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^\x81-\xFE0-9\}][^\x81-\xFE\}]*) \} ) \z/oxms) {
10095             $char[$i] = $1 . '\\' . $2;
10096             }
10097              
10098 0         0 # \p, \P, \X --> p, P, X
10099             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
10100             $char[$i] = $1;
10101 0 50 100     0 }
    50 100        
    100 66        
    100 100        
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
10102              
10103             if (0) {
10104             }
10105 372         3888  
10106 0         0 # escape last octet of multiple-octet
10107             elsif ($char[$i] =~ /\A \\? ([\x80-\xFF].*) ($metachar|\Q$delimiter\E|\Q$end_delimiter\E) \z/xms) {
10108             $char[$i] = $1 . '\\' . $2;
10109             }
10110              
10111 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
10112 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
10113             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)) {
10114             $char[$i] .= join '', splice @char, $i+1, 3;
10115 0         0 }
10116             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)) {
10117             $char[$i] .= join '', splice @char, $i+1, 2;
10118 0         0 }
10119             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)) {
10120             $char[$i] .= join '', splice @char, $i+1, 1;
10121             }
10122             }
10123              
10124 0         0 # open character class [...]
10125 3 50       5 elsif ($char[$i] eq '[') {
10126 3         12 my $left = $i;
10127             if ($char[$i+1] eq ']') {
10128 0         0 $i++;
10129 3 50       5 }
10130 7         11 while (1) {
10131             if (++$i > $#char) {
10132 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
10133 7         17 }
10134             if ($char[$i] eq ']') {
10135             my $right = $i;
10136 3 50       4  
10137 3         17 # [...]
  0         0  
10138             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
10139             splice @char, $left, $right-$left+1, sprintf(q{@{[Egbk::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
10140 0         0 }
10141             else {
10142             splice @char, $left, $right-$left+1, Egbk::charlist_qr(@char[$left+1..$right-1], $modifier);
10143 3         14 }
10144 3         12  
10145             $i = $left;
10146             last;
10147             }
10148             }
10149             }
10150              
10151 3         9 # open character class [^...]
10152 1 50       3 elsif ($char[$i] eq '[^') {
10153 1         4 my $left = $i;
10154             if ($char[$i+1] eq ']') {
10155 0         0 $i++;
10156 1 50       2 }
10157 2         5 while (1) {
10158             if (++$i > $#char) {
10159 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
10160 2         6 }
10161             if ($char[$i] eq ']') {
10162             my $right = $i;
10163 1 50       1  
10164 1         8 # [^...]
  0         0  
10165             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
10166             splice @char, $left, $right-$left+1, sprintf(q{@{[Egbk::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
10167 0         0 }
10168             else {
10169             splice @char, $left, $right-$left+1, Egbk::charlist_not_qr(@char[$left+1..$right-1], $modifier);
10170 1         7 }
10171 1         3  
10172             $i = $left;
10173             last;
10174             }
10175             }
10176             }
10177              
10178 1         3 # rewrite character class or escape character
10179             elsif (my $char = character_class($char[$i],$modifier)) {
10180             $char[$i] = $char;
10181             }
10182              
10183             # P.794 29.2.161. split
10184             # in Chapter 29: Functions
10185             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
10186              
10187             # P.951 split
10188             # in Chapter 27: Functions
10189             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
10190              
10191             # said "The //m modifier is assumed when you split on the pattern /^/",
10192             # but perl5.008 is not so. Therefore, this software adds //m.
10193             # (and so on)
10194              
10195 5         17 # split(m/^/) --> split(m/^/m)
10196             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
10197             $modifier .= 'm';
10198             }
10199              
10200 11 50       37 # /i modifier
10201 18         80 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egbk::uc($char[$i]) ne Egbk::fc($char[$i]))) {
10202             if (CORE::length(Egbk::fc($char[$i])) == 1) {
10203             $char[$i] = '[' . Egbk::uc($char[$i]) . Egbk::fc($char[$i]) . ']';
10204 18         59 }
10205             else {
10206             $char[$i] = '(?:' . Egbk::uc($char[$i]) . '|' . Egbk::fc($char[$i]) . ')';
10207             }
10208             }
10209              
10210 0 50       0 # \u \l \U \L \F \Q \E
10211 2         7 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
10212             if ($right_e < $left_e) {
10213             $char[$i] = '\\' . $char[$i];
10214             }
10215 0         0 }
10216 0         0 elsif ($char[$i] eq '\u') {
10217             $char[$i] = '@{[Egbk::ucfirst qq<';
10218             $left_e++;
10219 0         0 }
10220 0         0 elsif ($char[$i] eq '\l') {
10221             $char[$i] = '@{[Egbk::lcfirst qq<';
10222             $left_e++;
10223 0         0 }
10224 0         0 elsif ($char[$i] eq '\U') {
10225             $char[$i] = '@{[Egbk::uc qq<';
10226             $left_e++;
10227 0         0 }
10228 0         0 elsif ($char[$i] eq '\L') {
10229             $char[$i] = '@{[Egbk::lc qq<';
10230             $left_e++;
10231 0         0 }
10232 0         0 elsif ($char[$i] eq '\F') {
10233             $char[$i] = '@{[Egbk::fc qq<';
10234             $left_e++;
10235 0         0 }
10236 0         0 elsif ($char[$i] eq '\Q') {
10237             $char[$i] = '@{[CORE::quotemeta qq<';
10238             $left_e++;
10239 0 0       0 }
10240 0         0 elsif ($char[$i] eq '\E') {
10241 0         0 if ($right_e < $left_e) {
10242             $char[$i] = '>]}';
10243             $right_e++;
10244 0         0 }
10245             else {
10246             $char[$i] = '';
10247             }
10248 0         0 }
10249 0 0       0 elsif ($char[$i] eq '\Q') {
10250 0         0 while (1) {
10251             if (++$i > $#char) {
10252 0 0       0 last;
10253 0         0 }
10254             if ($char[$i] eq '\E') {
10255             last;
10256             }
10257             }
10258             }
10259             elsif ($char[$i] eq '\E') {
10260             }
10261              
10262 0 0       0 # $0 --> $0
10263 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
10264             if ($ignorecase) {
10265             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
10266             }
10267 0 0       0 }
10268 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
10269             if ($ignorecase) {
10270             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
10271             }
10272             }
10273              
10274             # $$ --> $$
10275             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
10276             }
10277              
10278             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
10279 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
10280 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
10281 0         0 $char[$i] = e_capture($1);
10282             if ($ignorecase) {
10283             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
10284             }
10285 0         0 }
10286 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
10287 0         0 $char[$i] = e_capture($1);
10288             if ($ignorecase) {
10289             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
10290             }
10291             }
10292              
10293 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
10294 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) {
10295 0         0 $char[$i] = e_capture($1.'->'.$2);
10296             if ($ignorecase) {
10297             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
10298             }
10299             }
10300              
10301 0         0 # $$foo{ ... } --> $ $foo->{ ... }
10302 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) {
10303 0         0 $char[$i] = e_capture($1.'->'.$2);
10304             if ($ignorecase) {
10305             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
10306             }
10307             }
10308              
10309 0         0 # $$foo
10310 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
10311 0         0 $char[$i] = e_capture($1);
10312             if ($ignorecase) {
10313             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
10314             }
10315             }
10316              
10317 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Egbk::PREMATCH()
10318 12         53 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
10319             if ($ignorecase) {
10320             $char[$i] = '@{[Egbk::ignorecase(Egbk::PREMATCH())]}';
10321 0         0 }
10322             else {
10323             $char[$i] = '@{[Egbk::PREMATCH()]}';
10324             }
10325             }
10326              
10327 12 50       69 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Egbk::MATCH()
10328 12         39 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
10329             if ($ignorecase) {
10330             $char[$i] = '@{[Egbk::ignorecase(Egbk::MATCH())]}';
10331 0         0 }
10332             else {
10333             $char[$i] = '@{[Egbk::MATCH()]}';
10334             }
10335             }
10336              
10337 12 50       62 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Egbk::POSTMATCH()
10338 9         26 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
10339             if ($ignorecase) {
10340             $char[$i] = '@{[Egbk::ignorecase(Egbk::POSTMATCH())]}';
10341 0         0 }
10342             else {
10343             $char[$i] = '@{[Egbk::POSTMATCH()]}';
10344             }
10345             }
10346              
10347 9 0       45 # ${ foo }
10348 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) {
10349             if ($ignorecase) {
10350             $char[$i] = '@{[Egbk::ignorecase(' . $1 . ')]}';
10351             }
10352             }
10353              
10354 0         0 # ${ ... }
10355 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
10356 0         0 $char[$i] = e_capture($1);
10357             if ($ignorecase) {
10358             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
10359             }
10360             }
10361              
10362 0         0 # $scalar or @array
10363 3 50       9 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
10364 3         21 $char[$i] = e_string($char[$i]);
10365             if ($ignorecase) {
10366             $char[$i] = '@{[Egbk::ignorecase(' . $char[$i] . ')]}';
10367             }
10368             }
10369              
10370 0 100       0 # quote character before ? + * {
10371             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
10372             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
10373 7         45 }
10374             else {
10375             $char[$i-1] = '(?:' . $char[$i-1] . ')';
10376             }
10377             }
10378             }
10379 4         21  
10380 189 50       469 # make regexp string
10381 189         431 $modifier =~ tr/i//d;
10382             if ($left_e > $right_e) {
10383 0         0 return join '', 'Egbk::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
10384             }
10385             return join '', 'Egbk::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
10386             }
10387              
10388             #
10389             # escape regexp of split qr''
10390 189     112 0 1687 #
10391 112   100     607 sub e_split_q {
10392             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
10393 112         369 $modifier ||= '';
10394 112 50       234  
10395 112         298 $modifier =~ tr/p//d;
10396 0         0 if ($modifier =~ /([adlu])/oxms) {
10397 0 0       0 my $line = 0;
10398 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
10399 0         0 if ($filename ne __FILE__) {
10400             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
10401             last;
10402 0         0 }
10403             }
10404             die qq{Unsupported modifier "$1" used at line $line.\n};
10405 0         0 }
10406              
10407             $slash = 'div';
10408 112 100       189  
10409 112         230 # /b /B modifier
10410             if ($modifier =~ tr/bB//d) {
10411             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
10412 56 100       300 }
10413              
10414             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
10415 56         158  
10416             # split regexp
10417             my @char = $string =~ /\G((?>
10418             [^\x81-\xFE\\\[] |
10419             [\x81-\xFE][\x00-\xFF] |
10420             \[\^ |
10421             \[\: (?>[a-z]+) \:\] |
10422             \[\:\^ (?>[a-z]+) \:\] |
10423             \\ (?:$q_char) |
10424             (?:$q_char)
10425             ))/oxmsg;
10426 56         361  
10427 56 50 33     215 # unescape character
    50 100        
    50 66        
    50 33        
    50          
    100          
    50          
10428             for (my $i=0; $i <= $#char; $i++) {
10429             if (0) {
10430             }
10431 56         594  
10432 0         0 # escape last octet of multiple-octet
10433             elsif ($char[$i] =~ /\A ([\x80-\xFF].*) ([\\|\[\{\^]|\Q$delimiter\E|\Q$end_delimiter\E) \z/xms) {
10434             $char[$i] = $1 . '\\' . $2;
10435             }
10436              
10437 0         0 # open character class [...]
10438 0 0       0 elsif ($char[$i] eq '[') {
10439 0         0 my $left = $i;
10440             if ($char[$i+1] eq ']') {
10441 0         0 $i++;
10442 0 0       0 }
10443 0         0 while (1) {
10444             if (++$i > $#char) {
10445 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
10446 0         0 }
10447             if ($char[$i] eq ']') {
10448             my $right = $i;
10449 0         0  
10450             # [...]
10451 0         0 splice @char, $left, $right-$left+1, Egbk::charlist_qr(@char[$left+1..$right-1], $modifier);
10452 0         0  
10453             $i = $left;
10454             last;
10455             }
10456             }
10457             }
10458              
10459 0         0 # open character class [^...]
10460 0 0       0 elsif ($char[$i] eq '[^') {
10461 0         0 my $left = $i;
10462             if ($char[$i+1] eq ']') {
10463 0         0 $i++;
10464 0 0       0 }
10465 0         0 while (1) {
10466             if (++$i > $#char) {
10467 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
10468 0         0 }
10469             if ($char[$i] eq ']') {
10470             my $right = $i;
10471 0         0  
10472             # [^...]
10473 0         0 splice @char, $left, $right-$left+1, Egbk::charlist_not_qr(@char[$left+1..$right-1], $modifier);
10474 0         0  
10475             $i = $left;
10476             last;
10477             }
10478             }
10479             }
10480              
10481 0         0 # rewrite character class or escape character
10482             elsif (my $char = character_class($char[$i],$modifier)) {
10483             $char[$i] = $char;
10484             }
10485              
10486 0         0 # split(m/^/) --> split(m/^/m)
10487             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
10488             $modifier .= 'm';
10489             }
10490              
10491 0 50       0 # /i modifier
10492 12         36 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Egbk::uc($char[$i]) ne Egbk::fc($char[$i]))) {
10493             if (CORE::length(Egbk::fc($char[$i])) == 1) {
10494             $char[$i] = '[' . Egbk::uc($char[$i]) . Egbk::fc($char[$i]) . ']';
10495 12         67 }
10496             else {
10497             $char[$i] = '(?:' . Egbk::uc($char[$i]) . '|' . Egbk::fc($char[$i]) . ')';
10498             }
10499             }
10500              
10501 0 0       0 # quote character before ? + * {
10502             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
10503             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
10504 0         0 }
10505             else {
10506             $char[$i-1] = '(?:' . $char[$i-1] . ')';
10507             }
10508             }
10509 0         0 }
10510 56         150  
10511             $modifier =~ tr/i//d;
10512             return join '', 'Egbk::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
10513             }
10514              
10515             #
10516             # escape use without import
10517 56     0 0 379 #
10518             sub e_use_noimport {
10519 0           my($module) = @_;
10520              
10521 0           my $expr = _pathof($module);
10522 0            
10523             my $fh = gensym();
10524 0 0         for my $realfilename (_realfilename($expr)) {
10525 0            
10526 0           if (Egbk::_open_r($fh, $realfilename)) {
10527 0 0         local $/ = undef; # slurp mode
10528             my $script = <$fh>;
10529 0 0         close($fh) or die "Can't close file: $realfilename: $!";
10530 0            
10531             if ($script =~ /^ (?>\s*) use (?>\s+) GBK (?>\s*) ([^\x81-\xFE;]*) ; (?>\s*) \n? $/oxms) {
10532 0           return qq;
10533             }
10534             last;
10535             }
10536 0           }
10537              
10538             return qq;
10539             }
10540              
10541             #
10542             # escape no without unimport
10543 0     0 0   #
10544             sub e_no_nounimport {
10545 0           my($module) = @_;
10546              
10547 0           my $expr = _pathof($module);
10548 0            
10549             my $fh = gensym();
10550 0 0         for my $realfilename (_realfilename($expr)) {
10551 0            
10552 0           if (Egbk::_open_r($fh, $realfilename)) {
10553 0 0         local $/ = undef; # slurp mode
10554             my $script = <$fh>;
10555 0 0         close($fh) or die "Can't close file: $realfilename: $!";
10556 0            
10557             if ($script =~ /^ (?>\s*) use (?>\s+) GBK (?>\s*) ([^\x81-\xFE;]*) ; (?>\s*) \n? $/oxms) {
10558 0           return qq;
10559             }
10560             last;
10561             }
10562 0           }
10563              
10564             return qq;
10565             }
10566              
10567             #
10568             # escape use with import no parameter
10569 0     0 0   #
10570             sub e_use_noparam {
10571 0           my($module) = @_;
10572              
10573 0           my $expr = _pathof($module);
10574 0            
10575             my $fh = gensym();
10576 0 0         for my $realfilename (_realfilename($expr)) {
10577 0            
10578 0           if (Egbk::_open_r($fh, $realfilename)) {
10579 0 0         local $/ = undef; # slurp mode
10580             my $script = <$fh>;
10581 0 0         close($fh) or die "Can't close file: $realfilename: $!";
10582              
10583             if ($script =~ /^ (?>\s*) use (?>\s+) GBK (?>\s*) ([^\x81-\xFE;]*) ; (?>\s*) \n? $/oxms) {
10584              
10585             # P.326 UNIVERSAL: The Ultimate Ancestor Class
10586             # in Chapter 12: Objects
10587             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
10588              
10589             # P.435 UNIVERSAL: The Ultimate Ancestor Class
10590             # in Chapter 12: Objects
10591             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
10592              
10593 0           # (and so on)
10594              
10595 0           return qq[BEGIN { Egbk::require '$expr'; $module->import() if $module->can('import'); }];
10596             }
10597             last;
10598             }
10599 0           }
10600              
10601             return qq;
10602             }
10603              
10604             #
10605             # escape no with unimport no parameter
10606 0     0 0   #
10607             sub e_no_noparam {
10608 0           my($module) = @_;
10609              
10610 0           my $expr = _pathof($module);
10611 0            
10612             my $fh = gensym();
10613 0 0         for my $realfilename (_realfilename($expr)) {
10614 0            
10615 0           if (Egbk::_open_r($fh, $realfilename)) {
10616 0 0         local $/ = undef; # slurp mode
10617             my $script = <$fh>;
10618 0 0         close($fh) or die "Can't close file: $realfilename: $!";
10619 0            
10620             if ($script =~ /^ (?>\s*) use (?>\s+) GBK (?>\s*) ([^\x81-\xFE;]*) ; (?>\s*) \n? $/oxms) {
10621 0           return qq[BEGIN { Egbk::require '$expr'; $module->unimport() if $module->can('unimport'); }];
10622             }
10623             last;
10624             }
10625 0           }
10626              
10627             return qq;
10628             }
10629              
10630             #
10631             # escape use with import parameters
10632 0     0 0   #
10633             sub e_use {
10634 0           my($module,$list) = @_;
10635              
10636 0           my $expr = _pathof($module);
10637 0            
10638             my $fh = gensym();
10639 0 0         for my $realfilename (_realfilename($expr)) {
10640 0            
10641 0           if (Egbk::_open_r($fh, $realfilename)) {
10642 0 0         local $/ = undef; # slurp mode
10643             my $script = <$fh>;
10644 0 0         close($fh) or die "Can't close file: $realfilename: $!";
10645 0            
10646             if ($script =~ /^ (?>\s*) use (?>\s+) GBK (?>\s*) ([^\x81-\xFE;]*) ; (?>\s*) \n? $/oxms) {
10647 0           return qq[BEGIN { Egbk::require '$expr'; $module->import($list) if $module->can('import'); }];
10648             }
10649             last;
10650             }
10651 0           }
10652              
10653             return qq;
10654             }
10655              
10656             #
10657             # escape no with unimport parameters
10658 0     0 0   #
10659             sub e_no {
10660 0           my($module,$list) = @_;
10661              
10662 0           my $expr = _pathof($module);
10663 0            
10664             my $fh = gensym();
10665 0 0         for my $realfilename (_realfilename($expr)) {
10666 0            
10667 0           if (Egbk::_open_r($fh, $realfilename)) {
10668 0 0         local $/ = undef; # slurp mode
10669             my $script = <$fh>;
10670 0 0         close($fh) or die "Can't close file: $realfilename: $!";
10671 0            
10672             if ($script =~ /^ (?>\s*) use (?>\s+) GBK (?>\s*) ([^\x81-\xFE;]*) ; (?>\s*) \n? $/oxms) {
10673 0           return qq[BEGIN { Egbk::require '$expr'; $module->unimport($list) if $module->can('unimport'); }];
10674             }
10675             last;
10676             }
10677 0           }
10678              
10679             return qq;
10680             }
10681              
10682             #
10683             # file path of module
10684 0     0     #
10685             sub _pathof {
10686 0 0         my($expr) = @_;
10687 0            
10688             if ($^O eq 'MacOS') {
10689             $expr =~ s#::#:#g;
10690 0           }
10691             else {
10692 0 0         $expr =~ s#::#/#g;
10693             }
10694 0           $expr .= '.pm' if $expr !~ / \.pm \z/oxmsi;
10695              
10696             return $expr;
10697             }
10698              
10699             #
10700             # real file name of module
10701 0     0     #
10702             sub _realfilename {
10703 0 0         my($expr) = @_;
10704 0            
  0            
10705             if ($^O eq 'MacOS') {
10706             return map {"$_$expr"} @INC;
10707 0           }
  0            
10708             else {
10709             return map {"$_/$expr"} @INC;
10710             }
10711             }
10712              
10713             #
10714             # instead of Carp::carp
10715 0     0 0   #
10716 0           sub carp {
10717             my($package,$filename,$line) = caller(1);
10718             print STDERR "@_ at $filename line $line.\n";
10719             }
10720              
10721             #
10722             # instead of Carp::croak
10723 0     0 0   #
10724 0           sub croak {
10725 0           my($package,$filename,$line) = caller(1);
10726             print STDERR "@_ at $filename line $line.\n";
10727             die "\n";
10728             }
10729              
10730             #
10731             # instead of Carp::cluck
10732 0     0 0   #
10733 0           sub cluck {
10734 0           my $i = 0;
10735 0           my @cluck = ();
10736 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
10737             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
10738 0           $i++;
10739 0           }
10740 0           print STDERR CORE::reverse @cluck;
10741             print STDERR "\n";
10742             print STDERR @_;
10743             }
10744              
10745             #
10746             # instead of Carp::confess
10747 0     0 0   #
10748 0           sub confess {
10749 0           my $i = 0;
10750 0           my @confess = ();
10751 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
10752             push @confess, "[$i] $filename($line) $package::$subroutine\n";
10753 0           $i++;
10754 0           }
10755 0           print STDERR CORE::reverse @confess;
10756 0           print STDERR "\n";
10757             print STDERR @_;
10758             die "\n";
10759             }
10760              
10761             1;
10762              
10763             __END__