File Coverage

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


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